| /* source: xioclose.c */ |
| /* Copyright Gerhard Rieger 2001-2008 */ |
| /* Published under the GNU General Public License V.2, see file COPYING */ |
| |
| /* this is the source of the extended close function */ |
| |
| |
| #include "xiosysincludes.h" |
| #include "xioopen.h" |
| #include "xiolockfile.h" |
| |
| #include "xio-termios.h" |
| |
| |
| /* close the xio fd; must be valid and "simple" (not dual) */ |
| int xioclose1(struct single *pipe) { |
| |
| if (pipe->tag == XIO_TAG_INVALID) { |
| Notice("xioclose1(): invalid file descriptor"); |
| errno = EINVAL; |
| return -1; |
| } |
| |
| switch (pipe->howtoclose) { |
| |
| #if WITH_READLINE |
| case XIOCLOSE_READLINE: |
| Write_history(pipe->para.readline.history_file); |
| /*xiotermios_setflag(pipe->fd, 3, ECHO|ICANON);*/ /* error when pty closed */ |
| break; |
| #endif /* WITH_READLINE */ |
| |
| #if WITH_OPENSSL |
| case XIOCLOSE_OPENSSL: |
| if (pipe->para.openssl.ssl) { |
| /* e.g. on TCP connection refused, we do not yet have this set */ |
| sycSSL_shutdown(pipe->para.openssl.ssl); |
| sycSSL_free(pipe->para.openssl.ssl); |
| pipe->para.openssl.ssl = NULL; |
| } |
| Close(pipe->rfd); pipe->rfd = -1; |
| Close(pipe->wfd); pipe->wfd = -1; |
| if (pipe->para.openssl.ctx) { |
| sycSSL_CTX_free(pipe->para.openssl.ctx); |
| pipe->para.openssl.ctx = NULL; |
| } |
| break; |
| #endif /* WITH_OPENSSL */ |
| |
| case XIOCLOSE_SIGTERM: |
| if (pipe->child.pid > 0) { |
| if (Kill(pipe->child.pid, SIGTERM) < 0) { |
| Msg2(errno==ESRCH?E_INFO:E_WARN, "kill(%d, SIGTERM): %s", |
| pipe->child.pid, strerror(errno)); |
| } |
| } |
| break; |
| case XIOCLOSE_CLOSE_SIGTERM: |
| if (pipe->child.pid > 0) { |
| if (Kill(pipe->child.pid, SIGTERM) < 0) { |
| Msg2(errno==ESRCH?E_INFO:E_WARN, "kill(%d, SIGTERM): %s", |
| pipe->child.pid, strerror(errno)); |
| } |
| } |
| /*PASSTHROUGH*/ |
| case XIOCLOSE_CLOSE: |
| if (XIOWITHRD(pipe->flags) && pipe->rfd >= 0) { |
| if (Close(pipe->rfd) < 0) { |
| Info2("close(%d): %s", pipe->rfd, strerror(errno)); |
| } |
| } |
| if (XIOWITHWR(pipe->flags) && pipe->wfd >= 0) { |
| if (Close(pipe->wfd) < 0) { |
| Info2("close(%d): %s", pipe->wfd, strerror(errno)); |
| } |
| } |
| break; |
| |
| case XIOCLOSE_SLEEP_SIGTERM: |
| Usleep(250000); |
| if (pipe->child.pid > 0) { |
| if (Kill(pipe->child.pid, SIGTERM) < 0) { |
| Msg2(errno==ESRCH?E_INFO:E_WARN, "kill(%d, SIGTERM): %s", |
| pipe->child.pid, strerror(errno)); |
| } |
| } |
| break; |
| |
| case XIOCLOSE_NONE: |
| break; |
| |
| case XIOCLOSE_UNSPEC: |
| Warn1("xioclose(): no close action specified on 0x%x", pipe); |
| break; |
| |
| default: |
| Error2("xioclose(): bad close action 0x%x on 0x%x", pipe->howtoclose, pipe); |
| break; |
| } |
| |
| #if WITH_TERMIOS |
| if (pipe->ttyvalid) { |
| if (Tcsetattr(pipe->rfd, 0, &pipe->savetty) < 0) { |
| Warn2("cannot restore terminal settings on fd %d: %s", |
| pipe->rfd, strerror(errno)); |
| } |
| } |
| #endif /* WITH_TERMIOS */ |
| |
| /* unlock */ |
| if (pipe->havelock) { |
| xiounlock(pipe->lock.lockfile); |
| pipe->havelock = false; |
| } |
| if (pipe->opt_unlink_close && pipe->unlink_close) { |
| if (Unlink(pipe->unlink_close) < 0) { |
| Info2("unlink(\"%s\"): %s", pipe->unlink_close, strerror(errno)); |
| } |
| free(pipe->unlink_close); |
| } |
| |
| pipe->tag = XIO_TAG_INVALID; |
| return 0; /*! */ |
| } |
| |
| |
| /* close the xio fd */ |
| int xioclose(xiofile_t *file) { |
| xiofile_t *xfd = file; |
| int result; |
| |
| if (file->tag == XIO_TAG_INVALID) { |
| Error("xioclose(): invalid file descriptor"); |
| errno = EINVAL; |
| return -1; |
| } |
| |
| if (file->tag == XIO_TAG_DUAL) { |
| result = xioclose1(file->dual.stream[0]); |
| result |= xioclose1(file->dual.stream[1]); |
| file->tag = XIO_TAG_INVALID; |
| } else { |
| result = xioclose1(&file->stream); |
| } |
| if (xfd->tag != XIO_TAG_INVALID && xfd->stream.subthread != 0) { |
| Pthread_join(xfd->stream.subthread, NULL); |
| } |
| return result; |
| } |
| |