1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
/* $Id: xiowrite.c,v 1.22 2005/09/05 06:45:41 gerhard Exp $ */
/* Copyright Gerhard Rieger 2001-2005 */
/* Published under the GNU General Public License V.2, see file COPYING */
/* this is the source of the extended write function */
#include "xiosysincludes.h"
#include "xioopen.h"
#include "xio-readline.h"
#include "xio-openssl.h"
/* ...
on return value < 0: errno reflects the value from write() */
ssize_t xiowrite(xiofile_t *file, const void *buff, size_t bytes) {
ssize_t writt;
struct single *pipe;
int _errno;
if (file->tag == XIO_TAG_INVALID) {
Error("xiowrite(): invalid file descriptor");
errno = EINVAL;
return -1;
}
if (file->tag == XIO_TAG_DUAL) {
pipe = &file->dual.stream[1]->stream;
if (pipe->tag == XIO_TAG_INVALID) {
Error("xiowrite(): invalid file descriptor");
errno = EINVAL;
return -1;
}
} else {
pipe = &file->stream;
}
#if WITH_READLINE
/* try to extract a prompt from the write data */
if (pipe->dtype == DATA_READLINE) {
xioscan_readline(pipe, buff, bytes);
}
#endif /* WITH_READLINE */
if (pipe->dtype == DATA_STREAM || pipe->dtype == DATA_READLINE ||
pipe->dtype == DATA_PTY) {
do {
writt = Write(pipe->fd, buff, bytes);
} while (writt < 0 && errno == EINTR);
if (writt < 0) {
_errno = errno;
switch (_errno) {
case EPIPE:
Notice4("write(%d, %p, "F_Zu"): %s",
pipe->fd, buff, bytes, strerror(_errno));
break;
#if 1
case ECONNRESET:
Warn4("write(%d, %p, "F_Zu"): %s",
pipe->fd, buff, bytes, strerror(_errno));
break;
#endif
default:
Error4("write(%d, %p, "F_Zu"): %s",
pipe->fd, buff, bytes, strerror(_errno));
}
errno = _errno;
return -1;
}
if ((size_t)writt < bytes) {
Warn2("write() only wrote "F_Zu" of "F_Zu" bytes",
writt, bytes);
}
#if WITH_SOCKET
} else if (pipe->dtype == DATA_RECV) {
/*union {
char space[sizeof(struct sockaddr_un)];
struct sockaddr sa;
} from;*/
/*socklen_t fromlen;*/
do {
writt = Sendto(pipe->fd, buff, bytes, 0,
&pipe->peersa.soa, pipe->salen);
} while (writt < 0 && errno == EINTR);
if (writt < 0) {
char infobuff[256];
_errno = errno;
Error6("sendto(%d, %p, "F_Zu", 0, %s, "F_socklen"): %s",
pipe->fd, buff, bytes,
sockaddr_info(&pipe->peersa.soa,
infobuff, sizeof(infobuff)),
pipe->salen, strerror(_errno));
errno = _errno;
return -1;
}
if ((size_t)writt < bytes) {
char infobuff[256];
Warn7("sendto(%d, %p, "F_Zu", 0, %s, "F_socklen") only wrote "F_Zu" of "F_Zu" bytes",
pipe->fd, buff, bytes,
sockaddr_info(&pipe->peersa.soa,
infobuff, sizeof(infobuff)),
pipe->salen, writt, bytes);
} else {
}
#endif /* WITH_SOCKET */
} else if (pipe->dtype == DATA_PIPE) {
do {
writt = Write(pipe->para.bipipe.fdout, buff, bytes);
} while (writt < 0 && errno == EINTR);
_errno = errno;
if (writt < 0) {
Error4("write(%d, %p, "F_Zu"): %s",
pipe->para.bipipe.fdout, buff, bytes, strerror(_errno));
errno = _errno;
return -1;
}
if ((size_t)writt < bytes) {
Warn2("write() only wrote "F_Zu" of "F_Zu" bytes",
writt, bytes);
}
} else if (pipe->dtype == DATA_2PIPE) {
do {
writt = Write(pipe->para.exec.fdout, buff, bytes);
} while (writt < 0 && errno == EINTR);
_errno = errno;
if (writt < 0) {
Error4("write(%d, %p, "F_Zu"): %s",
pipe->para.exec.fdout, buff, bytes, strerror(_errno));
errno = _errno;
return -1;
}
if ((size_t)writt < bytes) {
Warn2("write() only processed "F_Zu" of "F_Zu" bytes",
writt, bytes);
}
#if WITH_OPENSSL
} else if (pipe->dtype == DATA_OPENSSL) {
/* this function prints its own error messages */
return xiowrite_openssl(pipe, buff, bytes);
#endif /* WITH_OPENSSL */
} else {
Error1("xiowrite(): bad data type specification %d", pipe->dtype);
errno = EINVAL;
return -1;
}
return writt;
}
|