home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / uucp-1.04 / unix / detach.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-13  |  5.5 KB  |  187 lines

  1. /* detach.c
  2.    Detach from the controlling terminal.
  3.  
  4.    Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22.    The author of the program may be contacted at ian@airs.com or
  23.    c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
  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. /* Detach from the controlling terminal.  This is called by uucico if
  59.    it is calling out to another system, so that it can receive SIGHUP
  60.    signals from the port it calls out on.  It is also called by uucico
  61.    just before it starts uuxqt, so that uuxqt is completely
  62.    independent of the terminal.  */
  63.  
  64. void
  65. usysdep_detach ()
  66. {
  67. #if ! HAVE_BSD_PGRP || ! HAVE_TIOCNOTTY
  68.  
  69.   pid_t igrp;
  70.  
  71.   /* First make sure we are not a process group leader.  If we have
  72.      TIOCNOTTY, this doesn't matter, since TIOCNOTTY sets our process
  73.      group to 0 anyhow.  */
  74.  
  75. #if HAVE_BSD_PGRP
  76.   igrp = getpgrp (0);
  77. #else
  78.   igrp = getpgrp ();
  79. #endif
  80.  
  81.   if (igrp == getpid ())
  82.     {
  83.       boolean fignored;
  84.       pid_t ipid;
  85.  
  86.       /* Ignore SIGHUP, since our process group leader is about to
  87.      die.  */
  88.       usset_signal (SIGHUP, SIG_IGN, FALSE, &fignored);
  89.  
  90.       ipid = ixsfork ();
  91.       if (ipid < 0)
  92.     ulog (LOG_FATAL, "fork: %s", strerror (errno));
  93.  
  94.       if (ipid != 0)
  95.     _exit (EXIT_SUCCESS);
  96.  
  97.       /* We'll always wind up as a child of process number 1, right?
  98.      Right?  We have to wait for our parent to die before
  99.      reenabling SIGHUP.  */
  100.       while (getppid () != 1)
  101.     sleep (1);
  102.  
  103.       ulog_id (getpid ());
  104.  
  105.       /* Restore SIGHUP catcher if it wasn't being ignored.  */
  106.       if (! fignored)
  107.     usset_signal (SIGHUP, ussignal, TRUE, (boolean *) NULL);
  108.     }
  109.  
  110. #endif /* ! HAVE_BSD_PGRP || ! HAVE_TIOCNOTTY */
  111.  
  112. #if HAVE_TIOCNOTTY
  113.   /* Lose the original controlling terminal.  If standard input has
  114.      been reopened to /dev/null, this will do no harm.  If another
  115.      port has been opened to become the controlling terminal, it
  116.      should have been detached when it was closed.  */
  117.   (void) ioctl (0, TIOCNOTTY, (char *) NULL);
  118. #endif
  119.  
  120.   /* Close stdin, stdout and stderr and reopen them on /dev/null, to
  121.      make sure we have no connection at all to the terminal.  */
  122.   (void) close (0);
  123.   (void) close (1);
  124.   (void) close (2);
  125.   if (open ((char *) "/dev/null", O_RDONLY) != 0
  126.       || open ((char *) "/dev/null", O_WRONLY) != 1
  127.       || open ((char *) "/dev/null", O_WRONLY) != 2)
  128.     ulog (LOG_FATAL, "open (/dev/null): %s", strerror (errno));
  129.  
  130. #if HAVE_BSD_PGRP
  131.  
  132.   /* Make sure our process group ID is set to 0.  On BSD TIOCNOTTY
  133.      should already have set it 0, so this will do no harm.  On System
  134.      V we presumably did not execute the TIOCNOTTY call, but the
  135.      System V setpgrp will detach the controlling terminal anyhow.
  136.      This lets us use the same code on both BSD and System V, provided
  137.      it compiles correctly, which life easier for the configure
  138.      script.  We don't output an error if we got EPERM because some
  139.      BSD variants don't permit this usage of setpgrp (which means they
  140.      don't provide any way to pick up a new controlling terminal).  */
  141.  
  142.   if (setpgrp (0, 0) < 0)
  143.     {
  144.       if (errno != EPERM)
  145.     ulog (LOG_ERROR, "setpgrp: %s", strerror (errno));
  146.     }
  147.  
  148. #else /* ! HAVE_BSD_PGRP */
  149.  
  150. #if HAVE_SETSID
  151.  
  152.   /* Under POSIX the setsid call creates a new session for which we
  153.      are the process group leader.  It also detaches us from our
  154.      controlling terminal.  I'm using the BSD setpgrp call first
  155.      because they should be equivalent for my purposes, but it turns
  156.      out that on Ultrix 4.0 setsid prevents us from ever acquiring
  157.      another controlling terminal (it does not change our process
  158.      group, and Ultrix 4.0 prevents us from setting our process group
  159.      to 0).  */
  160.   (void) setsid ();
  161.  
  162. #else /* ! HAVE_SETSID */
  163.  
  164. #if HAVE_SETPGRP
  165.  
  166.   /* Now we assume we have the System V setpgrp, which takes no
  167.      arguments, and we couldn't compile the HAVE_BSD_PGRP code above
  168.      because there was a prototype somewhere in scope.  On System V
  169.      setpgrp makes us the leader of a new process group and also
  170.      detaches the controlling terminal.  */
  171.  
  172.   if (setpgrp () < 0)
  173.     ulog (LOG_ERROR, "setpgrp: %s", strerror (errno));
  174.  
  175. #else /* ! HAVE_SETPGRP */
  176.  
  177.  #error Must detach from controlling terminal
  178.  
  179. #endif /* HAVE_SETPGRP */
  180. #endif /* ! HAVE_SETSID */
  181. #endif /* ! HAVE_BSD_PGRP */
  182.  
  183.   /* At this point we have completely detached from our controlling
  184.      terminal.  The next terminal device we open will probably become
  185.      our controlling terminal.  */
  186. }
  187.