add listen-timeout to function as an accept timeout
[socat/sam.git] / xiowrite.c
blob2bc9379b9c1418b2e05fd8e5098dffd878cc1258
1 /* source: xiowrite.c */
2 /* Copyright Gerhard Rieger 2001-2008 */
3 /* Published under the GNU General Public License V.2, see file COPYING */
5 /* this is the source of the extended write function */
8 #include "xiosysincludes.h"
9 #include "xioopen.h"
11 #include "xio-readline.h"
12 #include "xio-openssl.h"
15 /* ...
16 note that the write() call can block even if the select()/poll() call
17 reported the FD writeable: in case the FD is not nonblocking and a lock
18 defers the operation.
19 on return value < 0: errno reflects the value from write() */
20 ssize_t xiowrite(xiofile_t *file, const void *buff, size_t bytes) {
21 ssize_t writt;
22 struct single *pipe;
23 int _errno;
25 if (file->tag == XIO_TAG_INVALID) {
26 Error1("xiowrite(): invalid xiofile descriptor %p", file);
27 errno = EINVAL;
28 return -1;
31 if (file->tag == XIO_TAG_DUAL) {
32 pipe = file->dual.stream[1];
33 if (pipe->tag == XIO_TAG_INVALID) {
34 Error1("xiowrite(): invalid xiofile sub descriptor %p[1]", file);
35 errno = EINVAL;
36 return -1;
38 } else {
39 pipe = &file->stream;
42 #if WITH_READLINE
43 /* try to extract a prompt from the write data */
44 if ((pipe->dtype & XIODATA_READMASK) == XIOREAD_READLINE) {
45 xioscan_readline(pipe, buff, bytes);
47 #endif /* WITH_READLINE */
49 switch (pipe->dtype & XIODATA_WRITEMASK) {
51 case XIOWRITE_STREAM:
52 do {
53 writt = Write(pipe->fd, buff, bytes);
54 } while (writt < 0 && errno == EINTR);
55 if (writt < 0) {
56 _errno = errno;
57 switch (_errno) {
58 case EPIPE:
59 case ECONNRESET:
60 if (pipe->cool_write) {
61 Notice4("write(%d, %p, "F_Zu"): %s",
62 pipe->fd, buff, bytes, strerror(_errno));
63 break;
65 /*PASSTRHOUGH*/
66 default:
67 Error4("write(%d, %p, "F_Zu"): %s",
68 pipe->fd, buff, bytes, strerror(_errno));
70 errno = _errno;
71 return -1;
73 if ((size_t)writt < bytes) {
74 Warn2("write() only wrote "F_Zu" of "F_Zu" bytes",
75 writt, bytes);
77 break;
79 #if _WITH_SOCKET
80 case XIOWRITE_SENDTO:
81 /*union {
82 char space[sizeof(struct sockaddr_un)];
83 struct sockaddr sa;
84 } from;*/
85 /*socklen_t fromlen;*/
87 do {
88 writt = Sendto(pipe->fd, buff, bytes, 0,
89 &pipe->peersa.soa, pipe->salen);
90 } while (writt < 0 && errno == EINTR);
91 if (writt < 0) {
92 char infobuff[256];
93 _errno = errno;
94 Error6("sendto(%d, %p, "F_Zu", 0, %s, "F_socklen"): %s",
95 pipe->fd, buff, bytes,
96 sockaddr_info(&pipe->peersa.soa, pipe->salen,
97 infobuff, sizeof(infobuff)),
98 pipe->salen, strerror(_errno));
99 errno = _errno;
100 return -1;
102 if ((size_t)writt < bytes) {
103 char infobuff[256];
104 Warn7("sendto(%d, %p, "F_Zu", 0, %s, "F_socklen") only wrote "F_Zu" of "F_Zu" bytes",
105 pipe->fd, buff, bytes,
106 sockaddr_info(&pipe->peersa.soa, pipe->salen,
107 infobuff, sizeof(infobuff)),
108 pipe->salen, writt, bytes);
109 } else {
112 char infobuff[256];
113 union sockaddr_union us;
114 socklen_t uslen = sizeof(us);
115 Getsockname(pipe->fd, &us.soa, &uslen);
116 Notice1("local address: %s",
117 sockaddr_info(&us.soa, uslen, infobuff, sizeof(infobuff)));
119 break;
120 #endif /* _WITH_SOCKET */
122 case XIOWRITE_PIPE:
123 do {
124 writt = Write(pipe->para.bipipe.fdout, buff, bytes);
125 } while (writt < 0 && errno == EINTR);
126 _errno = errno;
127 if (writt < 0) {
128 Error4("write(%d, %p, "F_Zu"): %s",
129 pipe->para.bipipe.fdout, buff, bytes, strerror(_errno));
130 errno = _errno;
131 return -1;
133 if ((size_t)writt < bytes) {
134 Warn2("write() only wrote "F_Zu" of "F_Zu" bytes",
135 writt, bytes);
137 break;
139 case XIOWRITE_2PIPE:
140 do {
141 writt = Write(pipe->para.exec.fdout, buff, bytes);
142 } while (writt < 0 && errno == EINTR);
143 _errno = errno;
144 if (writt < 0) {
145 Error4("write(%d, %p, "F_Zu"): %s",
146 pipe->para.exec.fdout, buff, bytes, strerror(_errno));
147 errno = _errno;
148 return -1;
150 if ((size_t)writt < bytes) {
151 Warn2("write() only processed "F_Zu" of "F_Zu" bytes",
152 writt, bytes);
154 break;
156 #if WITH_OPENSSL
157 case XIOWRITE_OPENSSL:
158 /* this function prints its own error messages */
159 return xiowrite_openssl(pipe, buff, bytes);
160 #endif /* WITH_OPENSSL */
162 default:
163 Error1("xiowrite(): bad data type specification %d", pipe->dtype);
164 errno = EINVAL;
165 return -1;
167 return writt;