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