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 */ 4 5 /* this is the source of the extended close function */ 6 7 8 #include "xiosysincludes.h" 9 #include "xioopen.h" 10 #include "xiolockfile.h" 11 12 #include "xio-termios.h" 13 14 15 /* close the xio fd; must be valid and "simple" (not dual) */ 16 int xioclose1(struct single *pipe) { 17 18 if (pipe->tag == XIO_TAG_INVALID) { 19 Notice("xioclose1(): invalid file descriptor"); 20 errno = EINVAL; 21 return -1; 22 } 23 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 */ 28 } 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; 37 } 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; 42 } 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)); 50 } 51 } 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; 58 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)); 65 } 66 } 67 default: 68 break; 69 } 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; 81 } 82 } 83 84 /* unlock */ 85 if (pipe->havelock) { 86 xiounlock(pipe->lock.lockfile); 87 pipe->havelock = false; 88 } 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)); 92 } 93 free(pipe->unlink_close); 94 } 95 96 pipe->tag = XIO_TAG_INVALID; 97 return 0; /*! */ 98 } 99 100 101 /* close the xio fd */ 102 int xioclose(xiofile_t *file) { 103 int result; 104 105 if (file->tag == XIO_TAG_INVALID) { 106 Error("xioclose(): invalid file descriptor"); 107 errno = EINVAL; 108 return -1; 109 } 110 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); 117 } 118 return result; 119 } 120 121