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"
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");
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 */
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
;
46 #endif /* WITH_OPENSSL */
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 */
56 if ((pipe
->dtype
& XIODATA_MASK
) == XIODATA_POSIXMQ
) {
57 xioclose_posixmq(pipe
);
59 #endif /* WITH_POSIXMQ */
61 switch (pipe
->howtoend
) {
62 case END_KILL
: case END_SHUTDOWN_KILL
: case END_CLOSE_KILL
:
63 if (pipe
->para
.exec
.pid
> 0) {
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
));
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;
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
)); }
86 #endif /* _WITH_SOCKET */
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;
98 #endif /* WITH_INTERFACE */
99 case END_NONE
: default: break;
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
;
120 /* close the xio fd */
121 int xioclose(xiofile_t
*file
) {
124 if (file
->tag
== XIO_TAG_INVALID
) {
125 Error("xioclose(): invalid file descriptor");
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
;
135 result
= xioclose1(&file
->stream
);