mirror of
https://repo.or.cz/socat.git
synced 2025-07-12 14:43:24 +00:00
socat V1.6.0.0 (initial GIT commit)
This commit is contained in:
commit
b819572f5e
170 changed files with 59193 additions and 0 deletions
168
xiowrite.c
Normal file
168
xiowrite.c
Normal file
|
@ -0,0 +1,168 @@
|
|||
/* $Id: xiowrite.c,v 1.29 2007/02/08 18:27:00 gerhard Exp $ */
|
||||
/* Copyright Gerhard Rieger 2001-2007 */
|
||||
/* 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"
|
||||
|
||||
|
||||
/* ...
|
||||
note that the write() call can block even if the select() call reported the
|
||||
FD writeable: in case the FD is not nonblocking and a lock defers the
|
||||
operation.
|
||||
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) {
|
||||
Error1("xiowrite(): invalid xiofile descriptor %p", file);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (file->tag == XIO_TAG_DUAL) {
|
||||
pipe = file->dual.stream[1];
|
||||
if (pipe->tag == XIO_TAG_INVALID) {
|
||||
Error1("xiowrite(): invalid xiofile sub descriptor %p[1]", file);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
pipe = &file->stream;
|
||||
}
|
||||
|
||||
#if WITH_READLINE
|
||||
/* try to extract a prompt from the write data */
|
||||
if ((pipe->dtype & XIODATA_READMASK) == XIOREAD_READLINE) {
|
||||
xioscan_readline(pipe, buff, bytes);
|
||||
}
|
||||
#endif /* WITH_READLINE */
|
||||
|
||||
switch (pipe->dtype & XIODATA_WRITEMASK) {
|
||||
|
||||
case XIOWRITE_STREAM:
|
||||
do {
|
||||
writt = Write(pipe->fd, buff, bytes);
|
||||
} while (writt < 0 && errno == EINTR);
|
||||
if (writt < 0) {
|
||||
_errno = errno;
|
||||
switch (_errno) {
|
||||
case EPIPE:
|
||||
case ECONNRESET:
|
||||
if (pipe->cool_write) {
|
||||
Notice4("write(%d, %p, "F_Zu"): %s",
|
||||
pipe->fd, buff, bytes, strerror(_errno));
|
||||
break;
|
||||
}
|
||||
/*PASSTRHOUGH*/
|
||||
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);
|
||||
}
|
||||
break;
|
||||
|
||||
#if WITH_SOCKET
|
||||
case XIOWRITE_SENDTO:
|
||||
/*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, pipe->salen,
|
||||
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, pipe->salen,
|
||||
infobuff, sizeof(infobuff)),
|
||||
pipe->salen, writt, bytes);
|
||||
} else {
|
||||
}
|
||||
{
|
||||
char infobuff[256];
|
||||
union sockaddr_union us;
|
||||
socklen_t uslen = sizeof(us);
|
||||
Getsockname(pipe->fd, &us.soa, &uslen);
|
||||
Notice1("local address: %s",
|
||||
sockaddr_info(&us.soa, uslen, infobuff, sizeof(infobuff)));
|
||||
}
|
||||
break;
|
||||
#endif /* WITH_SOCKET */
|
||||
|
||||
case XIOWRITE_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);
|
||||
}
|
||||
break;
|
||||
|
||||
case XIOWRITE_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);
|
||||
}
|
||||
break;
|
||||
|
||||
#if WITH_OPENSSL
|
||||
case XIOWRITE_OPENSSL:
|
||||
/* this function prints its own error messages */
|
||||
return xiowrite_openssl(pipe, buff, bytes);
|
||||
#endif /* WITH_OPENSSL */
|
||||
|
||||
default:
|
||||
Error1("xiowrite(): bad data type specification %d", pipe->dtype);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return writt;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue