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