taskrambler  0.1.9
Web server and task management solution.
stream/write.c
Go to the documentation of this file.
1 /**
2  * \file
3  *
4  * \author Georg Hopp
5  *
6  * \copyright
7  * Copyright © 2012 Georg Hopp
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #include <openssl/err.h>
24 #include <openssl/ssl.h>
25 #include <unistd.h>
26 #include <errno.h>
27 
28 #include "stream.h"
29 #include "logger.h"
30 
31 extern Logger logger;
32 
33 
34 ssize_t
35 streamWrite(Stream this, void * buf, size_t count)
36 {
37  ssize_t done;
38 
39  switch(this->type) {
40  ssize_t written;
41 
42  case STREAM_FD:
43  written = write((this->handle).fd, buf, count);
44 
45  if (written < 0) {
46  switch (errno) {
47  case EINTR:
48  case ENOBUFS:
49  case ENOMEM:
50  done = 0;
51  break;
52  case (EAGAIN|EWOULDBLOCK):
53  done = -1;
54  break;
55  default:
56  done = -2;
57  break;
58  }
59  } else {
60  done = written;
61  }
62 
63  break;
64 
65  case STREAM_SSL:
66  /**
67  * \todo I got a segfault in this call under unclear
68  * circumstances. Most likely it has to do with a
69  * write on a closed connection.
70  */
71  done = SSL_write((this->handle).ssl, buf, count);
72 
73  if (0 == done) {
74  done = -2;
75  } else if (0 > done) {
76  switch (SSL_get_error((this->handle).ssl, done)) {
77  case SSL_ERROR_SYSCALL:
78  {
79  switch (errno) {
80  case EINTR:
81  case ENOBUFS:
82  case ENOMEM:
83  done = 0;
84  break;
85  case (EAGAIN|EWOULDBLOCK):
86  done = -1;
87  break;
88  default:
89  done = -2;
90  break;
91  }
92  }
93  break;
94 
95  case SSL_ERROR_SSL:
96  {
97  unsigned long err;
98 
99  while (0 != (err = ERR_get_error())) {
100  loggerLog(
101  logger,
102  LOGGER_DEBUG,
103  ERR_error_string(err, NULL));
104  }
105  }
106  // DROP THROUGH
107 
108  case SSL_ERROR_ZERO_RETURN:
109  done = -2;
110  break;
111  }
112  }
113 
114  break;
115 
116  default:
117  done = -2;
118  break;
119  }
120 
121  return done;
122 }
123 
124 // vim: set ts=4 sw=4:
ssize_t streamWrite(Stream this, void *buf, size_t count)
Definition: stream/write.c:35
void loggerLog(void *, logger_level, const char *const,...)
Definition: i_logger.c:38
Logger logger
Definition: taskrambler.c:66