version 1.7.3.0
[socat.git] / xioclose.c
blob3109f98a12396a88697ff954e4814c5cc4a2d983
1 /* source: xioclose.c */
2 /* Copyright Gerhard Rieger 2001-2009 */
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 if (Kill(pipe->para.exec.pid, SIGTERM) < 0) {
58 Msg2(errno==ESRCH?E_INFO:E_WARN, "kill(%d, SIGTERM): %s",
59 pipe->para.exec.pid, strerror(errno));
62 default:
63 break;
65 switch (pipe->howtoend) {
66 case END_CLOSE: case END_CLOSE_KILL:
67 if (Close(pipe->fd) < 0) {
68 Info2("close(%d): %s", pipe->fd, strerror(errno)); } break;
69 #if _WITH_SOCKET
70 case END_SHUTDOWN: case END_SHUTDOWN_KILL:
71 if (Shutdown(pipe->fd, 2) < 0) {
72 Info3("shutdown(%d, %d): %s", pipe->fd, 2, strerror(errno)); }
73 break;
74 #endif /* _WITH_SOCKET */
75 case END_NONE: default: break;
79 /* unlock */
80 if (pipe->havelock) {
81 xiounlock(pipe->lock.lockfile);
82 pipe->havelock = false;
84 if (pipe->opt_unlink_close && pipe->unlink_close) {
85 if (Unlink(pipe->unlink_close) < 0) {
86 Info2("unlink(\"%s\"): %s", pipe->unlink_close, strerror(errno));
88 free(pipe->unlink_close);
91 pipe->tag = XIO_TAG_INVALID;
92 return 0; /*! */
96 /* close the xio fd */
97 int xioclose(xiofile_t *file) {
98 int result;
100 if (file->tag == XIO_TAG_INVALID) {
101 Error("xioclose(): invalid file descriptor");
102 errno = EINVAL;
103 return -1;
106 if (file->tag == XIO_TAG_DUAL) {
107 result = xioclose1(file->dual.stream[0]);
108 result |= xioclose1(file->dual.stream[1]);
109 file->tag = XIO_TAG_INVALID;
110 } else {
111 result = xioclose1(&file->stream);
113 return result;