home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / uucp / Uucp.framework / unix.subproj / detach.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-09  |  4.9 KB  |  182 lines

  1. /* detach.c
  2.    Detach from the controlling terminal.
  3.  
  4.    Copyright (C) 1992, 1993, 1995 Ian Lance Taylor
  5.  
  6.    This file is part of the Taylor UUCP package.
  7.  
  8.    This program is free software; you can redistribute it and/or
  9.    modify it under the terms of the GNU General Public License as
  10.    published by the Free Software Foundation; either version 2 of the
  11.    License, or (at your option) any later version.
  12.  
  13.    This program is distributed in the hope that it will be useful, but
  14.    WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.    General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU General Public License
  19.    along with this program; if not, write to the Free Software
  20.    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22.    The author of the program may be contacted at ian@airs.com or
  23.    c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
  24.    */
  25.  
  26. #include "uucp.h"
  27.  
  28. #include "uudefs.h"
  29. #include "system.h"
  30. #include "sysdep.h"
  31.  
  32. #include <errno.h>
  33.  
  34. #if HAVE_SYS_IOCTL_H
  35. #include <sys/ioctl.h>
  36. #endif
  37.  
  38. #ifdef TIOCNOTTY
  39. #define HAVE_TIOCNOTTY 1
  40. #else
  41. #define HAVE_TIOCNOTTY 0 
  42. #endif
  43.  
  44. #if HAVE_FCNTL_H
  45. #include <fcntl.h>
  46. #else
  47. #if HAVE_SYS_FILE_H
  48. #include <sys/file.h>
  49. #endif
  50. #endif
  51.  
  52. #ifndef O_RDONLY
  53. #define O_RDONLY 0
  54. #define O_WRONLY 1
  55. #define O_RDWR 2
  56. #endif
  57.  
  58. #if HAVE_BROKEN_SETSID
  59. #undef HAVE_SETSID
  60. #define HAVE_SETSID 0
  61. #endif
  62.  
  63. /* Detach from the controlling terminal.  This is called by uucico if
  64.    it is calling out to another system, so that it can receive SIGHUP
  65.    signals from the port it calls out on.  It is also called by uucico
  66.    just before it starts uuxqt, so that uuxqt is completely
  67.    independent of the terminal.  */
  68.  
  69. void
  70. usysdep_detach ()
  71. {
  72.   pid_t igrp;
  73.  
  74.   /* Make sure that we can open the log file.  We do this now so that,
  75.      if we can't, a message will be written to stderr.  After we leave
  76.      this routine, stderr will be closed.  */
  77.   ulog (LOG_NORMAL, (const char *) NULL);
  78.  
  79.   /* Make sure we are not a process group leader.  */
  80. #if HAVE_BSD_PGRP
  81.   igrp = getpgrp (0);
  82. #else
  83.   igrp = getpgrp ();
  84. #endif
  85.  
  86.   if (igrp == getpid ())
  87.     {
  88.       boolean fignored;
  89.       pid_t ipid;
  90.  
  91.       /* Ignore SIGHUP, since our process group leader is about to
  92.      die.  */
  93.       usset_signal (SIGHUP, SIG_IGN, FALSE, &fignored);
  94.  
  95.       ipid = ixsfork ();
  96.       if (ipid < 0)
  97.     ulog (LOG_FATAL, "fork: %s", strerror (errno));
  98.  
  99.       if (ipid != 0)
  100.     _exit (EXIT_SUCCESS);
  101.  
  102.       /* We'll always wind up as a child of process number 1, right?
  103.      Right?  We have to wait for our parent to die before
  104.      reenabling SIGHUP.  */
  105.       while (getppid () != 1)
  106.     sleep (1);
  107.  
  108.       ipid = getpid ();
  109.       ulog_id (ipid);
  110.  
  111.       /* Restore SIGHUP catcher if it wasn't being ignored.  */
  112.       if (! fignored)
  113.     usset_signal (SIGHUP, ussignal, TRUE, (boolean *) NULL);
  114.  
  115.       DEBUG_MESSAGE2 (DEBUG_PORT,
  116.               "usysdep_detach: Forked; old PID %ld, new pid %ld",
  117.               (long) igrp, (long) ipid);
  118.     }
  119.  
  120. #if ! HAVE_SETSID && HAVE_TIOCNOTTY
  121.   /* Lose the original controlling terminal as well as our process
  122.      group.  */
  123.   {
  124.     int o;
  125.  
  126.     o = open ((char *) "/dev/tty", O_RDONLY);
  127.     if (o >= 0)
  128.       {
  129.     (void) ioctl (o, TIOCNOTTY, (char *) NULL);
  130.     (void) close (o);
  131.       }
  132.   }
  133. #endif /* ! HAVE_SETSID && HAVE_TIOCNOTTY */
  134.  
  135.   /* Close stdin, stdout and stderr and reopen them on /dev/null, to
  136.      make sure we have no connection at all to the terminal.  */
  137.   (void) close (0);
  138.   (void) close (1);
  139.   (void) close (2);
  140.   if (open ((char *) "/dev/null", O_RDONLY) != 0
  141.       || open ((char *) "/dev/null", O_WRONLY) != 1
  142.       || open ((char *) "/dev/null", O_WRONLY) != 2)
  143.     ulog (LOG_FATAL, "open (/dev/null): %s", strerror (errno));
  144.  
  145. #if HAVE_SETSID
  146.  
  147.   /* Under POSIX the setsid call creates a new session for which we
  148.      are the process group leader.  It also detaches us from our
  149.      controlling terminal.  */
  150.   if (setsid () < 0)
  151.     ulog (LOG_ERROR, "setsid: %s", strerror (errno));
  152.  
  153. #else /* ! HAVE_SETSID */
  154.  
  155. #if ! HAVE_SETPGRP
  156.  #error Cannot detach from controlling terminal
  157. #endif
  158.  
  159.   /* If we don't have setsid, we must use setpgrp.  On an old System V
  160.      system setpgrp will make us the leader of a new process group and
  161.      detach the controlling terminal.  On an old BSD system the call
  162.      setpgrp (0, 0) will set our process group to 0 so that we can
  163.      acquire a new controlling terminal (TIOCNOTTY may or may not have
  164.      already done that anyhow).  */
  165. #if HAVE_BSD_PGRP
  166.   if (setpgrp (0, 0) < 0)
  167. #else
  168.   if (setpgrp () < 0)
  169. #endif
  170.     {
  171.       /* Some systems seem to give EPERM errors inappropriately.  */
  172.       if (errno != EPERM)
  173.     ulog (LOG_ERROR, "setpgrp: %s", strerror (errno));
  174.     }
  175.  
  176. #endif /* ! HAVE_SETSID */
  177.  
  178.   /* At this point we have completely detached from our controlling
  179.      terminal.  The next terminal device we open will probably become
  180.      our controlling terminal.  */
  181. }
  182.