mirror of
https://repo.or.cz/socat.git
synced 2025-07-12 22:53: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
134
xioshutdown.c
Normal file
134
xioshutdown.c
Normal file
|
@ -0,0 +1,134 @@
|
|||
/* $Id: xioshutdown.c,v 1.21 2007/01/25 21:36:11 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 shutdown function */
|
||||
|
||||
|
||||
#include "xiosysincludes.h"
|
||||
#include "xioopen.h"
|
||||
|
||||
static pid_t socat_kill_pid; /* here we pass the pid to be killed in sighandler */
|
||||
|
||||
static void signal_kill_pid(int dummy) {
|
||||
Notice("SIGALRM while waiting for w/o child process to die, killing it now");
|
||||
Kill(socat_kill_pid, SIGTERM);
|
||||
}
|
||||
|
||||
int xioshutdown(xiofile_t *sock, int how) {
|
||||
int result = 0;
|
||||
|
||||
if (sock->tag == XIO_TAG_INVALID) {
|
||||
Error("xioshutdown(): invalid file descriptor");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sock->tag == XIO_TAG_DUAL) {
|
||||
if ((how+1)&1) {
|
||||
result = xioshutdown((xiofile_t *)sock->dual.stream[0], 0);
|
||||
}
|
||||
if ((how+1)&2) {
|
||||
result |= xioshutdown((xiofile_t *)sock->dual.stream[1], 1);
|
||||
}
|
||||
|
||||
#if WITH_OPENSSL
|
||||
} else if ((sock->stream.dtype & XIODATA_MASK) == XIODATA_OPENSSL) {
|
||||
sycSSL_shutdown (sock->stream.para.openssl.ssl);
|
||||
/*! what about half/full close? */
|
||||
#endif /* WITH_OPENSSL */
|
||||
|
||||
} else if ((sock->stream.dtype & XIODATA_MASK) == XIODATA_PIPE) {
|
||||
if ((how+1)&1) {
|
||||
if (Close(sock->stream.fd) < 0) {
|
||||
Info2("close(%d): %s",
|
||||
sock->stream.fd, strerror(errno));
|
||||
}
|
||||
}
|
||||
if ((how+1)&2) {
|
||||
if (Close(sock->stream.para.bipipe.fdout) < 0) {
|
||||
Info2("close(%d): %s",
|
||||
sock->stream.para.bipipe.fdout, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
} else if ((sock->stream.dtype & XIODATA_MASK) == XIODATA_2PIPE) {
|
||||
if ((how+1)&1) {
|
||||
if (Close(sock->stream.fd) < 0) {
|
||||
Info2("close(%d): %s",
|
||||
sock->stream.fd, strerror(errno));
|
||||
}
|
||||
}
|
||||
if ((how+1)&2) {
|
||||
if (Close(sock->stream.para.exec.fdout) < 0) {
|
||||
Info2("close(%d): %s",
|
||||
sock->stream.para.exec.fdout, strerror(errno));
|
||||
}
|
||||
}
|
||||
#if WITH_SOCKET
|
||||
} else if (sock->stream.howtoend == END_SHUTDOWN) {
|
||||
if ((result = Shutdown(sock->stream.fd, how)) < 0) {
|
||||
Info3("shutdown(%d, %d): %s",
|
||||
sock->stream.fd, how, strerror(errno));
|
||||
}
|
||||
} else if (sock->stream.howtoend == END_SHUTDOWN_KILL) {
|
||||
if ((result = Shutdown(sock->stream.fd, how)) < 0) {
|
||||
Info3("shutdown(%d, %d): %s",
|
||||
sock->stream.fd, how, strerror(errno));
|
||||
}
|
||||
if ((sock->stream.flags&XIO_ACCMODE) == XIO_WRONLY) {
|
||||
/* the child process might want to flush some data before terminating
|
||||
*/
|
||||
int status = 0;
|
||||
|
||||
/* we wait for the child process to die, but to prevent timeout
|
||||
we raise an alarm after some time.
|
||||
NOTE: the alarm does not terminate waitpid() on Linux/glibc (BUG?),
|
||||
therefore we have to do the kill in the signal handler */
|
||||
Signal(SIGALRM, signal_kill_pid);
|
||||
socat_kill_pid = sock->stream.para.exec.pid;
|
||||
#if HAVE_SETITIMER
|
||||
/*! with next feature release, we get usec resolution and an option */
|
||||
#else
|
||||
Alarm(1 /*! sock->stream.para.exec.waitdie */);
|
||||
#endif /* !HAVE_SETITIMER */
|
||||
if (Waitpid(sock->stream.para.exec.pid, &status, 0) < 0) {
|
||||
Warn3("waitpid("F_pid", %p, 0): %s",
|
||||
sock->stream.para.exec.pid, &status, strerror(errno));
|
||||
}
|
||||
Alarm(0);
|
||||
}
|
||||
} else if ((sock->stream.dtype & XIODATA_MASK) == XIODATA_RECVFROM) {
|
||||
if (how >= 1) {
|
||||
if (Close(sock->stream.fd) < 0) {
|
||||
Info2("close(%d): %s",
|
||||
sock->stream.fd, strerror(errno));
|
||||
}
|
||||
sock->stream.eof = 2;
|
||||
sock->stream.fd = -1;
|
||||
}
|
||||
#endif /* WITH_SOCKET */
|
||||
#if 0
|
||||
} else {
|
||||
Error1("xioshutdown(): bad data type specification %d", sock->stream.dtype);
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
}
|
||||
#if 0
|
||||
else if (sock->stream.howtoend == END_CLOSE &&
|
||||
sock->stream.dtype == DATA_STREAM) {
|
||||
return result;
|
||||
}
|
||||
#if WITH_TERMIOS
|
||||
if (sock->stream.ttyvalid) {
|
||||
if (Tcsetattr(sock->stream.fd, 0, &sock->stream.savetty) < 0) {
|
||||
Warn2("cannot restore terminal settings on fd %d: %s",
|
||||
sock->stream.fd, strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif /* WITH_TERMIOS */
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue