home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume7 / forktest / forktest.c next >
C/C++ Source or Header  |  1986-12-09  |  3KB  |  126 lines

  1. /* Fork Test: display args, open files, signals, etc.
  2.  *
  3.  * Simple as this program is, it has found bugs in the
  4.  * way a number of programs fork off children.  To test
  5.  * how a program is invoking its children, run this
  6.  * program as a child.
  7.  *
  8.  * Generally, processes should be created with:
  9.  *
  10.  * - a reasonable arg count & list
  11.  * - arg 0 should look like the name of the command
  12.  *
  13.  * - real and effective UIDs and GIDs should be reasonable.
  14.  *   Beware setuid programs that fork children!
  15.  *
  16.  * - no pending alarm.  Version 7 apparently does not
  17.  *   reset alarms upon an exec!
  18.  *
  19.  * - file descriptors 0 (STDIN), 1 (STDOUT), and 2 (STDERR)
  20.  *   opened reasonably
  21.  * - all other file descriptors closed (this program will
  22.  *   describe all open channels)
  23.  *
  24.  * - all signals (except SIGKILL) set to SIG_DFL (this
  25.  *   program will print all signals set otherwise)
  26.  *
  27.  * The output is fairly simple to understand.  When in
  28.  * doubt, read the code (and a UNIX manual: exec(2),
  29.  * getuid(2), alarm(2), signal(2), stat(2)).
  30.  *
  31.  * Room for Improvement:
  32.  *
  33.  * - strings should be printed in a way that shows funny characters.
  34.  * - show misc. other bits of state
  35.  *    - PID (who cares?)
  36.  *    - umask
  37.  *    - ulimit (System V)
  38.  *    - stty settings of open TTYs
  39.  *
  40.  * Copyright (c) 1986 March 11  D. Hugh Redelmeier
  41.  *
  42.  * This program may be distributed and used without restriction.
  43.  */
  44.  
  45. #include <stdio.h>
  46.  
  47. extern unsigned alarm();    /* should be unsigned, but may be int */
  48.  
  49. #include <sys/types.h>
  50. #include <sys/stat.h>
  51.  
  52. struct stat sb;
  53.  
  54. #include <errno.h>
  55. extern int errno;
  56. extern char *sys_errlist[];
  57.  
  58. #include <signal.h>
  59.  
  60. int (*signal())();
  61.  
  62. main(argc, argv, envp)
  63. int argc;
  64. char **argv, **envp;
  65. {
  66.     register int i;
  67.     unsigned al = alarm(0);    /* get it while it is hot */
  68.  
  69.     printf("%d arg(s):", argc);
  70.     for (i=0; i<argc; i++)
  71.         if (argv[i] == NULL)
  72.             printf(" NULL!");
  73.         else
  74.             printf(" \"%s\"", argv[i]);
  75.     printf("\n");
  76.     if (argv[argc] != NULL)
  77.         printf("Arg list is not ended with a NULL!\n");
  78.  
  79.     printf("Real UID = %d, GID = %d; Effective UID = %d, GID = %d.\n",
  80.         getuid(), getgid(), geteuid(), getegid());
  81.  
  82.     if (al)
  83.         printf("Alarm set to go off in %u seconds.\n", al);
  84.  
  85.     printf("File Descriptors:\n");
  86.     for (i=0; i!=40; i++)    /* I hope 40 is enough. */
  87.         if (fstat(i, &sb) == -1) {
  88.             if (errno != EBADF)
  89.                 printf("\t%d error: %s\n", i, sys_errlist[errno]);
  90.         } else {
  91.             printf("\t%d: dev=%d, ino=%d, perm=0%04o, ",
  92.                 i, sb.st_dev, sb.st_ino, sb.st_mode&07777);
  93.             switch (sb.st_mode & S_IFMT) {
  94.             case S_IFREG:
  95.                 printf("pipe or regular file\n");
  96.                 break;
  97.             /* extend as desired */
  98.             default:
  99.                 printf("IFMT=0%o\n", sb.st_mode>>12);
  100.                 break;
  101.             }
  102.         }
  103.  
  104.     printf("Signals:\n");
  105.     for (i=1; i!=40; i++) {    /* I hope 40 is enough. */
  106.         register int n = (int) signal(i, SIG_IGN);
  107.         switch (n) {
  108.         case -1:
  109.         case SIG_DFL:
  110.             break;
  111.         case SIG_IGN:
  112.             printf("\t%d: SIG_IGN\n", i);
  113.             break;
  114.         default:
  115.             printf("\t%d: %d\n", i, n);
  116.             break;
  117.         }
  118.     }
  119.  
  120.     printf("Environment:\n");
  121.     for (i=0; envp[i]!=NULL; i++)
  122.         printf("\t\"%s\"\n", envp[i]);
  123.  
  124.     exit(0);
  125. }
  126.