home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / socket / utils.c < prev   
Encoding:
C/C++ Source or Header  |  1992-09-07  |  4.9 KB  |  261 lines

  1. /*
  2.  
  3. $Header: utils.c[1.14] Wed Sep  9 16:34:03 1992 nickel@cs.tu-berlin.de proposed $
  4. This file is part of socket(1).
  5. Copyright (C) 1992 by Juergen Nickelsen <nickel@cs.tu-berlin.de>
  6. Please read the file COPYRIGHT for further details.
  7.  
  8. */
  9.  
  10. #ifdef sgi
  11. #define _BSD_SIGNALS
  12. #define SIG_HANDLER_RET int
  13. #else /* !sgi */
  14. #define SIG_HANDLER_RET void
  15. #endif
  16.  
  17. #include <stdio.h>
  18. #include <signal.h>
  19. #include <sys/wait.h>
  20. #include <sys/time.h>
  21. #include <fcntl.h>
  22. #include <sys/ioctl.h>
  23. #ifdef ISC
  24. #define WNOHANG 1
  25. #else
  26. #include <sys/resource.h>
  27. #endif
  28. #include "globals.h"
  29.  
  30.  
  31. /* Signal handler, print message and exit */
  32. SIG_HANDLER_RET exitsig(sig)
  33. int sig ;
  34. {
  35.     if (sig != SIGUSR1) {
  36.     fprintf(stderr, "\n%s occured, exiting\n", sys_siglist[sig]) ;
  37.     }
  38.     exit(-sig) ;
  39. }
  40.  
  41. /* Give usage message */
  42. void usage()
  43. {
  44.     static char ustring[] =
  45.     "Usage: %s [-bclqrvw] [-p prog] [-s | host] port\n" ;
  46.  
  47.     fprintf(stderr, ustring, progname) ;
  48. }
  49.  
  50. /* perror with progname */
  51. void perror2(s)
  52. char *s ;
  53. {
  54.     fprintf(stderr, "%s: ", progname) ;
  55.     perror(s) ;
  56. }
  57.  
  58. /* is s a number? */
  59. int is_number(s)
  60. char *s ;
  61. {
  62.     while (*s) {
  63.     if (*s < '0' || *s > '9') {
  64.         return 0 ;
  65.     }
  66.     s++ ;
  67.     }
  68.     return 1 ;
  69. }
  70.  
  71. /* set up signal handling. All except TSTP, CONT, CLD, and QUIT
  72.  * are caught with exitsig(). */
  73. init_signals()
  74. {
  75.     int i ;
  76. #ifdef SIG_SETMASK        /* only with BSD signals */
  77.     static struct sigvec svec = { exitsig, ~0, 0 } ;
  78. #endif
  79.  
  80.     initialize_siglist() ;    /* shamelessly stolen from BASH */
  81.     
  82.     for (i = 0; i < NSIG; i++) {
  83.     switch (i) {
  84. #ifdef SIGTSTP
  85.       case SIGTSTP:
  86.       case SIGTTOU:
  87.       case SIGTTIN:
  88.       case SIGSTOP:
  89.       case SIGCONT:
  90.         continue ;
  91. #endif
  92. #if !defined (SIGCHLD) && defined (SIGCLD)
  93. #define SIGCHLD SIGCLD
  94. #endif
  95. #ifdef SIGCHLD
  96.       case SIGCHLD:
  97.         continue ;
  98. #endif
  99. #ifdef SIGWINCH
  100.       case SIGWINCH:    /* it is ridiculous to exit on WINCH */
  101.         continue ;
  102. #endif
  103.       case SIGQUIT:        /* if the user wants a core dump, */
  104.         continue ;        /* they can have it. */
  105.       default:        
  106. #ifdef SIG_SETMASK
  107.         sigvec(i, &svec, NULL) ;
  108. #else
  109.         signal(i, exitsig) ;
  110. #endif
  111.     }
  112.     }
  113. }
  114.  
  115. /* connect stdin with prog's stdout/stderr and stdout
  116.  * with prog's stdin. */
  117. void open_pipes(prog)
  118. char *prog ;
  119. {
  120.     int from_cld[2] ;        /* from child process */
  121.     int to_cld[2] ;        /* to child process */
  122.  
  123.     /* create pipes */
  124.     if (pipe(from_cld) == -1) {
  125.     perror2("pipe") ;
  126.     exit(errno) ;
  127.     }
  128.     if (pipe(to_cld) == -1) {
  129.     perror2("pipe") ;
  130.     exit(errno) ;
  131.     }
  132.  
  133.     /* for child process */
  134.     switch (fork()) {
  135.       case 0:            /* this is the child process */
  136.     /* connect stdin to pipe */
  137.     close(0) ;
  138.     close(to_cld[1]) ;
  139.     dup2(to_cld[0], 0) ;
  140.     close(to_cld[0]) ;
  141.     /* connect stdout to pipe */
  142.     close(1) ;
  143.     close(from_cld[0]) ;
  144.     dup2(from_cld[1], 1) ;
  145.     /* connect stderr to pipe */
  146.     close(2) ;
  147.     dup2(from_cld[1], 2) ;
  148.     close(from_cld[1]) ;
  149.     /* call program via sh */
  150.     execl("/bin/sh", "sh", "-c", prog, NULL) ;
  151.     perror2("exec /bin/sh") ;
  152.     /* terminate parent silently */
  153.     kill(getppid(), SIGUSR1) ;
  154.     exit(255) ;
  155.       case -1:
  156.     perror2("fork") ;    /* fork failed */
  157.     exit(errno) ;
  158.       default:            /* parent process */
  159.     /* connect stderr to pipe */
  160.     close(0) ;
  161.     close(from_cld[1]) ;
  162.     dup2(from_cld[0], 0) ;
  163.     close(from_cld[0]) ;
  164.     /* connect stderr to pipe */
  165.     close(1) ;
  166.     close(to_cld[0]) ;
  167.     dup2(to_cld[1], 1) ;
  168.     close(to_cld[1]) ;
  169.     }
  170. }
  171.  
  172. /* remove zombie child processes */
  173. void wait_for_children()
  174. {
  175.     int wret, status ;
  176. #ifndef ISC
  177.     struct rusage rusage ;
  178. #endif
  179.  
  180.     /* Just do a wait, forget result */
  181. #ifndef ISC
  182.     while ((wret = wait3(&status, WNOHANG, &rusage)) > 0) ;
  183. #else
  184.     while ((wret = waitpid(-1, &status, WNOHANG)) > 0) ;
  185. #endif
  186. }
  187.  
  188. /* expand LF characters to CRLF and adjust *sizep */
  189. void add_crs(from, to, sizep)
  190. char *from, *to ;        /* *from is copied to *to */
  191. int *sizep ;
  192. {
  193.     int countdown ;        /* counter */
  194.  
  195.     countdown = *sizep ;
  196.     while (countdown) {
  197.     if (*from == '\n') {
  198.         *to++ = '\r' ;
  199.         (*sizep)++ ;
  200.     }
  201.     *to++ = *from++ ;
  202.     countdown-- ;
  203.     }
  204. }
  205.  
  206. /* strip CR characters from buffer and adjust *sizep */
  207. void strip_crs(from, to, sizep)
  208. char *from, *to ;        /* *from is copied to *to */
  209. int *sizep ;
  210. {
  211.  
  212.     int countdown ;        /* counter */
  213.  
  214.     countdown = *sizep ;
  215.     while (countdown) {
  216.     if (*from == '\r') {
  217.         from++ ;
  218.         (*sizep)-- ;
  219.     } else {
  220.         *to++ = *from++ ;
  221.     }
  222.     countdown-- ;
  223.     }
  224. }
  225.  
  226. #define NULL_DEVICE "/dev/null"
  227.  
  228. /* put yourself in the background */
  229. void background()
  230. {
  231.     int child_pid ;        /* PID of child process */
  232.     int nulldev_fd ;        /* file descriptor for null device */
  233.  
  234.     child_pid = fork() ;
  235.     switch (child_pid) {
  236.       case -1:
  237.     perror2("fork") ;
  238.     exit(1) ;
  239.       case 0:
  240. #ifdef NOSETSID
  241.     ioctl(0, TIOCNOTTY, 0) ;
  242. #else
  243.     setsid() ;
  244. #endif
  245.     chdir("/") ;
  246.     if ((nulldev_fd = open(NULL_DEVICE, O_RDWR, 0)) != -1) {
  247.         int i ;
  248.  
  249.         for (i = 0; i < 3; i++) {
  250.         if (isatty(i)) {
  251.             dup2(nulldev_fd, i) ;
  252.         }
  253.         }
  254.         close(nulldev_fd) ;
  255.     }
  256.     break ;
  257.       default:
  258.     exit(0) ;
  259.     }
  260. }
  261.