Print this page
    
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/ptools/pwait/pwait.c
          +++ new/usr/src/cmd/ptools/pwait/pwait.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
  25   25  
  26   26  #include <stdio.h>
  27   27  #include <stdio_ext.h>
  28   28  #include <ctype.h>
  29   29  #include <stdlib.h>
  30   30  #include <unistd.h>
  31   31  #include <fcntl.h>
  32   32  #include <string.h>
  33   33  #include <dirent.h>
  34   34  #include <errno.h>
  35   35  #include <sys/types.h>
  36   36  #include <stropts.h>
  37   37  #include <poll.h>
  38   38  #include <procfs.h>
  39   39  #include <sys/resource.h>
  40   40  #include <limits.h>
  41   41  #include "ptools_common.h"
  42   42  
  43   43  static int count_my_files();
  44   44  static char *command;
  45   45  
  46   46  /* slop to account for extra file descriptors opened by libraries we call */
  47   47  #define SLOP    5
  48   48  
  49   49  int
  50   50  main(int argc, char **argv)
  51   51  {
  52   52          char buf[PATH_MAX];
  53   53          unsigned long remain = 0;
  54   54          struct pollfd *pollfd;
  55   55          struct pollfd *pfd;
  56   56          struct rlimit rlim;
  57   57          char *arg;
  58   58          unsigned i;
  59   59          int verbose = 0;
  60   60  
  61   61          if ((command = strrchr(argv[0], '/')) != NULL)
  62   62                  command++;
  63   63          else
  64   64                  command = argv[0];
  65   65  
  66   66          argc--;
  67   67          argv++;
  68   68  
  69   69          if (argc > 0 && strcmp(argv[0], "-v") == 0) {
  70   70                  verbose = 1;
  71   71                  argc--;
  72   72                  argv++;
  73   73          }
  74   74  
  75   75          if (argc <= 0) {
  76   76                  (void) fprintf(stderr, "usage:\t%s [-v] pid ...\n", command);
  77   77                  (void) fprintf(stderr, "  (wait for processes to terminate)\n");
  78   78                  (void) fprintf(stderr,
  79   79                      "  -v: verbose; report terminations to standard out\n");
  80   80                  return (2);
  81   81          }
  82   82  
  83   83          (void) proc_snprintf(buf, sizeof (buf), "/proc/");
  84   84  
  85   85          /* make sure we have enough file descriptors */
  86   86          if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
  87   87                  int nfiles = count_my_files();
  88   88  
  89   89                  if (rlim.rlim_cur < argc + nfiles + SLOP) {
  90   90                          rlim.rlim_cur = argc + nfiles + SLOP;
  91   91                          if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
  92   92                                  (void) fprintf(stderr,
  93   93                                      "%s: insufficient file descriptors\n",
  94   94                                      command);
  95   95                                  return (2);
  96   96                          }
  97   97                  }
  98   98                  (void) enable_extended_FILE_stdio(-1, -1);
  99   99          }
 100  100  
 101  101          pollfd = (struct pollfd *)malloc(argc*sizeof (struct pollfd));
 102  102          if (pollfd == NULL) {
 103  103                  perror("malloc");
 104  104                  return (2);
 105  105          }
 106  106  
 107  107          for (i = 0; i < argc; i++) {
 108  108                  char psinfofile[100];
 109  109  
 110  110                  arg = argv[i];
 111  111                  if (strchr(arg, '/') != NULL)
 112  112                          (void) strncpy(psinfofile, arg, sizeof (psinfofile));
 113  113                  else {
 114  114                          (void) strcpy(psinfofile, buf);
 115  115                          (void) strncat(psinfofile, arg, sizeof (psinfofile)-6);
 116  116                  }
 117  117                  (void) strncat(psinfofile, "/psinfo",
 118  118                      sizeof (psinfofile)-strlen(psinfofile));
 119  119  
 120  120                  pfd = &pollfd[i];
 121  121                  if ((pfd->fd = open(psinfofile, O_RDONLY)) >= 0) {
 122  122                          remain++;
 123  123                          /*
 124  124                           * We set POLLPRI to detect system processes.
 125  125                           * We will get POLLNVAL below for a POLLPRI
 126  126                           * requested event on a system process.
 127  127                           */
 128  128                          pfd->events = POLLPRI;
 129  129                          pfd->revents = 0;
 130  130                  } else if (errno == ENOENT) {
 131  131                          (void) fprintf(stderr, "%s: no such process: %s\n",
 132  132                              command, arg);
 133  133                  } else {
 134  134                          perror(arg);
 135  135                  }
 136  136          }
 137  137  
 138  138          while (remain != 0) {
 139  139                  while (poll(pollfd, argc, INFTIM) < 0) {
 140  140                          if (errno != EAGAIN) {
 141  141                                  perror("poll");
 142  142                                  return (2);
 143  143                          }
 144  144                          (void) sleep(2);
 145  145                  }
 146  146                  for (i = 0; i < argc; i++) {
 147  147                          pfd = &pollfd[i];
 148  148                          if (pfd->fd < 0 || (pfd->revents & ~POLLPRI) == 0) {
 149  149                                  /*
 150  150                                   * We don't care if a non-system process
 151  151                                   * stopped.  Don't check for that again.
 152  152                                   */
 153  153                                  pfd->events = 0;
 154  154                                  pfd->revents = 0;
 155  155                                  continue;
 156  156                          }
 157  157  
 158  158                          if (verbose) {
 159  159                                  arg = argv[i];
 160  160                                  if (pfd->revents & POLLHUP) {
 161  161                                          psinfo_t psinfo;
 162  162  
 163  163                                          if (pread(pfd->fd, &psinfo,
 164  164                                              sizeof (psinfo), (off_t)0)
 165  165                                              == sizeof (psinfo)) {
 166  166                                                  (void) printf("%s: terminated, "
 167  167                                                      "wait status 0x%.4x\n",
 168  168                                                      arg, psinfo.pr_wstat);
 169  169                                          } else {
 170  170                                                  (void) printf(
 171  171                                                      "%s: terminated\n", arg);
 172  172                                          }
 173  173                                  }
 174  174                                  if (pfd->revents & POLLNVAL)
 175  175                                          (void) printf("%s: system process\n",
 176  176                                              arg);
 177  177                                  if (pfd->revents & ~(POLLPRI|POLLHUP|POLLNVAL))
 178  178                                          (void) printf("%s: unknown error\n",
 179  179                                              arg);
 180  180                          }
 181  181  
 182  182                          (void) close(pfd->fd);
 183  183                          pfd->fd = -1;
 184  184                          remain--;
 185  185                  }
 186  186          }
 187  187  
 188  188          return (0);
 189  189  }
 190  190  
 191  191  /* ARGSUSED1 */
 192  192  static int
 193  193  do_count(void *nofilesp, int fd)
 194  194  {
 195  195          (*(int *)nofilesp)++;
 196  196          return (0);
 197  197  }
 198  198  
 199  199  static int
 200  200  count_my_files()
 201  201  {
 202  202          int nofiles = 0;
 203  203  
 204  204          (void) fdwalk(do_count, &nofiles);
 205  205          return (nofiles);
 206  206  }
  
    | 
      ↓ open down ↓ | 
    206 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX