GOPEN handles UNIX seqpacket sockets
[socat.git] / xioclose.c
blobd2922f177c69f41fedc2fecd8c798f0a52643455
1 /* source: xioclose.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 close function */
8 #include "xiosysincludes.h"
9 #include "xioopen.h"
10 #include "xiolockfile.h"
12 #include "xio-termios.h"
15 /* close the xio fd; must be valid and "simple" (not dual) */
16 int xioclose1(struct single *pipe) {
18 if (pipe->tag == XIO_TAG_INVALID) {
19 Notice("xioclose1(): invalid file descriptor");
20 errno = EINVAL;
21 return -1;
24 #if WITH_READLINE
25 if ((pipe->dtype & XIODATA_MASK) == XIODATA_READLINE) {
26 Write_history(pipe->para.readline.history_file);
27 /*xiotermios_setflag(pipe->fd, 3, ECHO|ICANON);*/ /* error when pty closed */
29 #endif /* WITH_READLINE */
30 #if WITH_OPENSSL
31 if ((pipe->dtype & XIODATA_MASK) == XIODATA_OPENSSL) {
32 if (pipe->para.openssl.ssl) {
33 /* e.g. on TCP connection refused, we do not yet have this set */
34 sycSSL_shutdown(pipe->para.openssl.ssl);
35 sycSSL_free(pipe->para.openssl.ssl);
36 pipe->para.openssl.ssl = NULL;
38 Close(pipe->fd); pipe->fd = -1;
39 if (pipe->para.openssl.ctx) {
40 sycSSL_CTX_free(pipe->para.openssl.ctx);
41 pipe->para.openssl.ctx = NULL;
43 } else
44 #endif /* WITH_OPENSSL */
45 #if WITH_TERMIOS
46 if (pipe->ttyvalid) {
47 if (Tcsetattr(pipe->fd, 0, &pipe->savetty) < 0) {
48 Warn2("cannot restore terminal settings on fd %d: %s",
49 pipe->fd, strerror(errno));
52 #endif /* WITH_TERMIOS */
53 if (pipe->fd >= 0) {
54 switch (pipe->howtoend) {
55 case END_KILL: case END_SHUTDOWN_KILL: case END_CLOSE_KILL:
56 if (pipe->para.exec.pid > 0) {
57 pid_t pid;
59 /* first unregister child pid, so our sigchld handler will not throw an error */
60 pid = pipe->para.exec.pid;
61 pipe->para.exec.pid = 0;
62 if (Kill(pid, SIGTERM) < 0) {
63 Msg2(errno==ESRCH?E_INFO:E_WARN, "kill(%d, SIGTERM): %s",
64 pid, strerror(errno));
67 default:
68 break;
70 switch (pipe->howtoend) {
71 case END_CLOSE: case END_CLOSE_KILL:
72 if (Close(pipe->fd) < 0) {
73 Info2("close(%d): %s", pipe->fd, strerror(errno)); } break;
74 #if _WITH_SOCKET
75 case END_SHUTDOWN: case END_SHUTDOWN_KILL:
76 if (Shutdown(pipe->fd, 2) < 0) {
77 Info3("shutdown(%d, %d): %s", pipe->fd, 2, strerror(errno)); }
78 break;
79 #endif /* _WITH_SOCKET */
80 case END_NONE: default: break;
84 /* unlock */
85 if (pipe->havelock) {
86 xiounlock(pipe->lock.lockfile);
87 pipe->havelock = false;
89 if (pipe->opt_unlink_close && pipe->unlink_close) {
90 if (Unlink(pipe->unlink_close) < 0) {
91 Info2("unlink(\"%s\"): %s", pipe->unlink_close, strerror(errno));
93 free(pipe->unlink_close);
96 pipe->tag = XIO_TAG_INVALID;
97 return 0; /*! */
101 /* close the xio fd */
102 int xioclose(xiofile_t *file) {
103 int result;
105 if (file->tag == XIO_TAG_INVALID) {
106 Error("xioclose(): invalid file descriptor");
107 errno = EINVAL;
108 return -1;
111 if (file->tag == XIO_TAG_DUAL) {
112 result = xioclose1(file->dual.stream[0]);
113 result |= xioclose1(file->dual.stream[1]);
114 file->tag = XIO_TAG_INVALID;
115 } else {
116 result = xioclose1(&file->stream);
118 return result;