4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
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.
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]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <stdio_ext.h>
37 #include <sys/types.h>
41 #include <sys/resource.h>
43 static int count_my_files();
46 /* slop to account for extra file descriptors opened by libraries we call */
50 main(int argc
, char **argv
)
52 unsigned long remain
= 0;
53 struct pollfd
*pollfd
;
60 if ((command
= strrchr(argv
[0], '/')) != NULL
)
68 if (argc
> 0 && strcmp(argv
[0], "-v") == 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");
82 /* make sure we have enough file descriptors */
83 if (getrlimit(RLIMIT_NOFILE
, &rlim
) == 0) {
84 int nfiles
= count_my_files();
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",
95 (void) enable_extended_FILE_stdio(-1, -1);
98 pollfd
= (struct pollfd
*)malloc(argc
*sizeof (struct pollfd
));
104 for (i
= 0; i
< argc
; i
++) {
105 char psinfofile
[100];
108 if (strchr(arg
, '/') != NULL
)
109 (void) strncpy(psinfofile
, arg
, sizeof (psinfofile
));
111 (void) strcpy(psinfofile
, "/proc/");
112 (void) strncat(psinfofile
, arg
, sizeof (psinfofile
)-6);
114 (void) strncat(psinfofile
, "/psinfo",
115 sizeof (psinfofile
)-strlen(psinfofile
));
118 if ((pfd
->fd
= open(psinfofile
, O_RDONLY
)) >= 0) {
121 * We set POLLPRI to detect system processes.
122 * We will get POLLNVAL below for a POLLPRI
123 * requested event on a system process.
125 pfd
->events
= POLLPRI
;
127 } else if (errno
== ENOENT
) {
128 (void) fprintf(stderr
, "%s: no such process: %s\n",
135 while (remain
!= 0) {
136 while (poll(pollfd
, argc
, INFTIM
) < 0) {
137 if (errno
!= EAGAIN
) {
143 for (i
= 0; i
< argc
; i
++) {
145 if (pfd
->fd
< 0 || (pfd
->revents
& ~POLLPRI
) == 0) {
147 * We don't care if a non-system process
148 * stopped. Don't check for that again.
157 if (pfd
->revents
& POLLHUP
) {
160 if (pread(pfd
->fd
, &psinfo
,
161 sizeof (psinfo
), (off_t
)0)
162 == sizeof (psinfo
)) {
164 "%s: terminated, wait status 0x%.4x\n",
165 arg
, psinfo
.pr_wstat
);
168 "%s: terminated\n", arg
);
171 if (pfd
->revents
& POLLNVAL
)
172 (void) printf("%s: system process\n",
174 if (pfd
->revents
& ~(POLLPRI
|POLLHUP
|POLLNVAL
))
175 (void) printf("%s: unknown error\n",
179 (void) close(pfd
->fd
);
190 do_count(void *nofilesp
, int fd
)
192 (*(int *)nofilesp
)++;
201 (void) fdwalk(do_count
, &nofiles
);