Version 1.8.0.0
[socat.git] / xioclose.c
blob8fefe1671e7924fabdefacab0f2a024f1c75f476
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"
13 #include "xio-interface.h"
14 #include "xio-posixmq.h"
17 /* close the xio fd; must be valid and "simple" (not dual) */
18 int xioclose1(struct single *pipe) {
20 if (pipe->tag == XIO_TAG_INVALID) {
21 Notice("xioclose1(): invalid file descriptor");
22 errno = EINVAL;
23 return -1;
26 #if WITH_READLINE
27 if ((pipe->dtype & XIODATA_MASK) == XIODATA_READLINE) {
28 Write_history(pipe->para.readline.history_file);
29 /*xiotermios_setflag(pipe->fd, 3, ECHO|ICANON);*/ /* error when pty closed */
31 #endif /* WITH_READLINE */
32 #if WITH_OPENSSL
33 if ((pipe->dtype & XIODATA_MASK) == XIODATA_OPENSSL) {
34 if (pipe->para.openssl.ssl) {
35 /* e.g. on TCP connection refused, we do not yet have this set */
36 sycSSL_shutdown(pipe->para.openssl.ssl);
37 sycSSL_free(pipe->para.openssl.ssl);
38 pipe->para.openssl.ssl = NULL;
40 Close(pipe->fd); pipe->fd = -1;
41 if (pipe->para.openssl.ctx) {
42 sycSSL_CTX_free(pipe->para.openssl.ctx);
43 pipe->para.openssl.ctx = NULL;
45 } else
46 #endif /* WITH_OPENSSL */
47 #if WITH_TERMIOS
48 if (pipe->ttyvalid) {
49 if (Tcsetattr(pipe->fd, TCSANOW, &pipe->savetty) < 0) {
50 Warn2("cannot restore terminal settings on fd %d: %s",
51 pipe->fd, strerror(errno));
54 #endif /* WITH_TERMIOS */
55 #if WITH_POSIXMQ
56 if ((pipe->dtype & XIODATA_MASK) == XIODATA_POSIXMQ) {
57 xioclose_posixmq(pipe);
59 #endif /* WITH_POSIXMQ */
60 if (pipe->fd >= 0) {
61 switch (pipe->howtoend) {
62 case END_KILL: case END_SHUTDOWN_KILL: case END_CLOSE_KILL:
63 if (pipe->para.exec.pid > 0) {
64 pid_t pid;
66 /* first unregister child pid, so our sigchld handler will not throw an error */
67 pid = pipe->para.exec.pid;
68 pipe->para.exec.pid = 0;
69 if (Kill(pid, SIGTERM) < 0) {
70 Msg2(errno==ESRCH?E_INFO:E_WARN, "kill(%d, SIGTERM): %s",
71 pid, strerror(errno));
74 default:
75 break;
77 switch (pipe->howtoend) {
78 case END_CLOSE: case END_CLOSE_KILL:
79 if (Close(pipe->fd) < 0) {
80 Info2("close(%d): %s", pipe->fd, strerror(errno)); } break;
81 #if _WITH_SOCKET
82 case END_SHUTDOWN: case END_SHUTDOWN_KILL:
83 if (Shutdown(pipe->fd, 2) < 0) {
84 Info3("shutdown(%d, %d): %s", pipe->fd, 2, strerror(errno)); }
85 break;
86 #endif /* _WITH_SOCKET */
87 #if WITH_INTERFACE
88 case END_INTERFACE:
90 if (pipe->para.interface.name[0] != '\0') {
91 _xiointerface_set_iff(pipe->fd, pipe->para.interface.name,
92 pipe->para.interface.save_iff);
94 if (Close(pipe->fd) < 0) {
95 Info2("close(%d): %s", pipe->fd, strerror(errno)); } break;
97 break;
98 #endif /* WITH_INTERFACE */
99 case END_NONE: default: break;
103 /* unlock */
104 if (pipe->havelock) {
105 xiounlock(pipe->lock.lockfile);
106 pipe->havelock = false;
108 if (pipe->opt_unlink_close && pipe->unlink_close) {
109 if (Unlink(pipe->unlink_close) < 0) {
110 Warn2("unlink(\"%s\"): %s", pipe->unlink_close, strerror(errno));
112 free(pipe->unlink_close);
115 pipe->tag |= XIO_TAG_CLOSED;
116 return 0; /*! */
120 /* close the xio fd */
121 int xioclose(xiofile_t *file) {
122 int result;
124 if (file->tag == XIO_TAG_INVALID) {
125 Error("xioclose(): invalid file descriptor");
126 errno = EINVAL;
127 return -1;
130 if (file->tag == XIO_TAG_DUAL) {
131 result = xioclose1(file->dual.stream[0]);
132 result |= xioclose1(file->dual.stream[1]);
133 file->tag |= XIO_TAG_CLOSED;
134 } else {
135 result = xioclose1(&file->stream);
137 return result;