Solved more testing issues
[socat.git] / xiowrite.c
blob7264ca60c4da76363b29fee3e22e0fdf25e542ea
1 /* source: xiowrite.c */
2 /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
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 writt = writefull(pipe->fd, buff, bytes);
53 if (writt < 0) {
54 _errno = errno;
55 switch (_errno) {
56 case EPIPE:
57 case ECONNRESET:
58 if (pipe->cool_write) {
59 Notice4("write(%d, %p, "F_Zu"): %s",
60 pipe->fd, buff, bytes, strerror(_errno));
61 break;
63 /*PASSTRHOUGH*/
64 default:
65 Error4("write(%d, %p, "F_Zu"): %s",
66 pipe->fd, buff, bytes, strerror(_errno));
68 errno = _errno;
69 return -1;
71 break;
73 #if _WITH_SOCKET
74 case XIOWRITE_SENDTO:
75 /*union {
76 char space[sizeof(struct sockaddr_un)];
77 struct sockaddr sa;
78 } from;*/
79 /*socklen_t fromlen;*/
81 do {
82 writt = Sendto(pipe->fd, buff, bytes, 0,
83 &pipe->peersa.soa, pipe->salen);
84 } while (writt < 0 && errno == EINTR);
85 if (writt < 0) {
86 char infobuff[256];
87 _errno = errno;
88 Error6("sendto(%d, %p, "F_Zu", 0, %s, "F_socklen"): %s",
89 pipe->fd, buff, bytes,
90 sockaddr_info(&pipe->peersa.soa, pipe->salen,
91 infobuff, sizeof(infobuff)),
92 pipe->salen, strerror(_errno));
93 errno = _errno;
94 return -1;
96 if ((size_t)writt < bytes) {
97 char infobuff[256];
98 Warn7("sendto(%d, %p, "F_Zu", 0, %s, "F_socklen") only wrote "F_Zu" of "F_Zu" bytes",
99 pipe->fd, buff, bytes,
100 sockaddr_info(&pipe->peersa.soa, pipe->salen,
101 infobuff, sizeof(infobuff)),
102 pipe->salen, writt, bytes);
103 } else {
106 char infobuff[256];
107 union sockaddr_union us;
108 socklen_t uslen = sizeof(us);
109 Getsockname(pipe->fd, &us.soa, &uslen);
110 Notice1("local address: %s",
111 sockaddr_info(&us.soa, uslen, infobuff, sizeof(infobuff)));
113 break;
114 #endif /* _WITH_SOCKET */
116 case XIOWRITE_PIPE:
117 writt = Write(pipe->para.bipipe.fdout, buff, bytes);
118 _errno = errno;
119 if (writt < 0) {
120 Error4("write(%d, %p, "F_Zu"): %s",
121 pipe->para.bipipe.fdout, buff, bytes, strerror(_errno));
122 errno = _errno;
123 return -1;
125 break;
127 case XIOWRITE_2PIPE:
128 writt = Write(pipe->para.exec.fdout, buff, bytes);
129 _errno = errno;
130 if (writt < 0) {
131 Error4("write(%d, %p, "F_Zu"): %s",
132 pipe->para.exec.fdout, buff, bytes, strerror(_errno));
133 errno = _errno;
134 return -1;
136 break;
138 #if WITH_OPENSSL
139 case XIOWRITE_OPENSSL:
140 /* this function prints its own error messages */
141 return xiowrite_openssl(pipe, buff, bytes);
142 #endif /* WITH_OPENSSL */
144 default:
145 Error1("xiowrite(): bad data type specification %d", pipe->dtype);
146 errno = EINVAL;
147 return -1;
149 return writt;