Print this page
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/pgrep/pgrep.c
+++ new/usr/src/cmd/pgrep/pgrep.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 /* Copyright (c) 2012 by Delphix. All rights reserved */
26 26
27 27 #include <sys/types.h>
28 28 #include <sys/stat.h>
29 29 #include <sys/param.h>
30 30 #include <sys/task.h>
31 31 #include <sys/contract.h>
32 32
33 33 #include <signal.h>
34 34 #include <unistd.h>
35 35 #include <dirent.h>
36 36 #include <stdlib.h>
37 37 #include <string.h>
38 38
39 39 #include <libintl.h>
40 40 #include <locale.h>
41 41 #include <stdio.h>
42 42 #include <fcntl.h>
43 43 #include <ctype.h>
44 44 #include <wchar.h>
45 45 #include <limits.h>
46 46 #include <libuutil.h>
47 47 #include <libcontract_priv.h>
48 48
49 49 #include <procfs.h>
50 50 #include <project.h>
51 51 #include <pwd.h>
52 52 #include <grp.h>
53 53 #include <zone.h>
54 54
55 55 #include "psexp.h"
56 56 #include "pgrep.h"
57 57
58 58 #ifndef TEXT_DOMAIN
59 59 #define TEXT_DOMAIN "SYS_TEST"
60 60 #endif
61 61
62 62 #define OPT_SETB 0x0001 /* Set the bits specified by o_bits */
63 63 #define OPT_CLRB 0x0002 /* Clear the bits specified by o_bits */
64 64 #define OPT_FUNC 0x0004 /* Call the function specified by o_func */
65 65 #define OPT_STR 0x0008 /* Set the string specified by o_ptr */
66 66 #define OPT_CRIT 0x0010 /* Option is part of selection criteria */
67 67
68 68 #define F_LONG_FMT 0x0001 /* Match against long format cmd */
69 69 #define F_NEWEST 0x0002 /* Match only newest pid */
70 70 #define F_REVERSE 0x0004 /* Reverse matching criteria */
71 71 #define F_EXACT_MATCH 0x0008 /* Require exact match */
72 72 #define F_HAVE_CRIT 0x0010 /* Criteria specified */
73 73 #define F_OUTPUT 0x0020 /* Some output has been printed */
74 74 #define F_KILL 0x0040 /* Pkill semantics active (vs pgrep) */
75 75 #define F_LONG_OUT 0x0080 /* Long output format (pgrep -l) */
76 76 #define F_OLDEST 0x0100 /* Match only oldest pid */
77 77
78 78 static int opt_euid(char, char *);
79 79 static int opt_uid(char, char *);
80 80 static int opt_gid(char, char *);
81 81 static int opt_ppid(char, char *);
82 82 static int opt_pgrp(char, char *);
83 83 static int opt_sid(char, char *);
84 84 static int opt_term(char, char *);
85 85 static int opt_projid(char, char *);
86 86 static int opt_taskid(char, char *);
87 87 static int opt_zoneid(char, char *);
88 88 static int opt_ctid(char, char *);
89 89
90 90 static const char *g_procdir = "/proc"; /* Default procfs mount point */
91 91 static const char *g_delim = "\n"; /* Default output delimiter */
92 92 static const char *g_pname; /* Program name for error messages */
93 93 static ushort_t g_flags; /* Miscellaneous flags */
94 94
95 95 static optdesc_t g_optdtab[] = {
96 96 { 0, 0, 0, 0 }, /* 'A' */
97 97 { 0, 0, 0, 0 }, /* 'B' */
98 98 { 0, 0, 0, 0 }, /* 'C' */
99 99 { OPT_STR, 0, 0, &g_procdir }, /* -D procfsdir */
100 100 { 0, 0, 0, 0 }, /* 'E' */
101 101 { 0, 0, 0, 0 }, /* 'F' */
102 102 { OPT_FUNC | OPT_CRIT, 0, opt_gid, 0 }, /* -G gid */
103 103 { 0, 0, 0, 0 }, /* 'H' */
104 104 { 0, 0, 0, 0 }, /* 'I' */
105 105 { OPT_FUNC | OPT_CRIT, 0, opt_projid, 0 }, /* -J projid */
106 106 { 0, 0, 0, 0 }, /* 'K' */
107 107 { 0, 0, 0, 0 }, /* 'L' */
108 108 { 0, 0, 0, 0 }, /* 'M' */
109 109 { 0, 0, 0, 0 }, /* 'N' */
110 110 { 0, 0, 0, 0 }, /* 'O' */
111 111 { OPT_FUNC | OPT_CRIT, 0, opt_ppid, 0 }, /* -P ppid */
112 112 { 0, 0, 0, 0 }, /* 'Q' */
113 113 { 0, 0, 0, 0 }, /* 'R' */
114 114 { 0, 0, 0, 0 }, /* 'S' */
115 115 { OPT_FUNC | OPT_CRIT, 0, opt_taskid, 0 }, /* -T taskid */
116 116 { OPT_FUNC | OPT_CRIT, 0, opt_uid, 0 }, /* -U uid */
117 117 { 0, 0, 0, 0 }, /* 'V' */
118 118 { 0, 0, 0, 0 }, /* 'W' */
119 119 { 0, 0, 0, 0 }, /* 'X' */
120 120 { 0, 0, 0, 0 }, /* 'Y' */
121 121 { 0, 0, 0, 0 }, /* 'Z' */
122 122 { 0, 0, 0, 0 }, /* '[' */
123 123 { 0, 0, 0, 0 }, /* '\\' */
124 124 { 0, 0, 0, 0 }, /* ']' */
125 125 { 0, 0, 0, 0 }, /* '^' */
126 126 { 0, 0, 0, 0 }, /* '_' */
127 127 { 0, 0, 0, 0 }, /* '`' */
128 128 { 0, 0, 0, 0 }, /* 'a' */
129 129 { 0, 0, 0, 0 }, /* 'b' */
130 130 { OPT_FUNC | OPT_CRIT, 0, opt_ctid, 0 }, /* -c ctid */
131 131 { OPT_STR, 0, 0, &g_delim }, /* -d delim */
132 132 { 0, 0, 0, 0 }, /* 'e' */
133 133 { OPT_SETB, F_LONG_FMT, 0, &g_flags }, /* -f */
134 134 { OPT_FUNC | OPT_CRIT, 0, opt_pgrp, 0 }, /* -g pgrp */
135 135 { 0, 0, 0, 0 }, /* 'h' */
136 136 { 0, 0, 0, 0 }, /* 'i' */
137 137 { 0, 0, 0, 0 }, /* 'j' */
138 138 { 0, 0, 0, 0 }, /* 'k' */
139 139 { OPT_SETB, F_LONG_OUT, 0, &g_flags }, /* 'l' */
140 140 { 0, 0, 0, 0 }, /* 'm' */
141 141 { OPT_SETB, F_NEWEST, 0, &g_flags }, /* -n */
142 142 { OPT_SETB, F_OLDEST, 0, &g_flags }, /* -o */
143 143 { 0, 0, 0, 0 }, /* 'p' */
144 144 { 0, 0, 0, 0 }, /* 'q' */
145 145 { 0, 0, 0, 0 }, /* 'r' */
146 146 { OPT_FUNC | OPT_CRIT, 0, opt_sid, 0 }, /* -s sid */
147 147 { OPT_FUNC | OPT_CRIT, 0, opt_term, 0 }, /* -t term */
148 148 { OPT_FUNC | OPT_CRIT, 0, opt_euid, 0 }, /* -u euid */
149 149 { OPT_SETB, F_REVERSE, 0, &g_flags }, /* -v */
150 150 { 0, 0, 0, 0 }, /* 'w' */
151 151 { OPT_SETB, F_EXACT_MATCH, 0, &g_flags }, /* -x */
152 152 { 0, 0, 0, 0 }, /* 'y' */
153 153 { OPT_FUNC | OPT_CRIT, 0, opt_zoneid, 0 } /* -z zoneid */
154 154 };
155 155
156 156 static const char PGREP_USAGE[] = "\
157 157 Usage: %s [-flnovx] [-d delim] [-P ppidlist] [-g pgrplist] [-s sidlist]\n\
158 158 [-u euidlist] [-U uidlist] [-G gidlist] [-J projidlist]\n\
159 159 [-T taskidlist] [-t termlist] [-z zonelist] [-c ctidlist] [pattern]\n";
160 160
161 161 static const char PKILL_USAGE[] = "\
162 162 Usage: %s [-signal] [-fnovx] [-P ppidlist] [-g pgrplist] [-s sidlist]\n\
163 163 [-u euidlist] [-U uidlist] [-G gidlist] [-J projidlist]\n\
164 164 [-T taskidlist] [-t termlist] [-z zonelist] [-c ctidlist] [pattern]\n";
165 165
166 166 static const char PGREP_OPTS[] = ":flnovxc:d:D:u:U:G:P:g:s:t:z:J:T:";
167 167 static const char PKILL_OPTS[] = ":fnovxc:D:u:U:G:P:g:s:t:z:J:T:";
168 168
169 169 static const char LSEP[] = ",\t "; /* Argument list delimiter chars */
170 170
171 171 static psexp_t g_psexp; /* Process matching expression */
172 172 static pid_t g_pid; /* Current pid */
173 173 static int g_signal = SIGTERM; /* Signal to send */
174 174
175 175 static void
176 176 print_proc(psinfo_t *psinfo)
177 177 {
178 178 if (g_flags & F_OUTPUT)
179 179 (void) printf("%s%d", g_delim, (int)psinfo->pr_pid);
180 180 else {
181 181 (void) printf("%d", (int)psinfo->pr_pid);
182 182 g_flags |= F_OUTPUT;
183 183 }
184 184 }
185 185
186 186 static char *
187 187 mbstrip(char *buf, size_t nbytes)
188 188 {
189 189 wchar_t wc;
190 190 char *p;
191 191 int n;
192 192
193 193 buf[nbytes - 1] = '\0';
194 194 p = buf;
195 195
196 196 while (*p != '\0') {
197 197 n = mbtowc(&wc, p, MB_LEN_MAX);
198 198
199 199 if (n < 0 || !iswprint(wc)) {
200 200 if (n < 0)
201 201 n = sizeof (char);
202 202
203 203 if (nbytes <= n) {
204 204 *p = '\0';
205 205 break;
206 206 }
207 207
208 208 (void) memmove(p, p + n, nbytes - n);
209 209
210 210 } else {
211 211 nbytes -= n;
212 212 p += n;
213 213 }
214 214 }
215 215
216 216 return (buf);
217 217 }
218 218
219 219 static void
220 220 print_proc_long(psinfo_t *psinfo)
221 221 {
222 222 char *name;
223 223
224 224 if (g_flags & F_LONG_FMT)
225 225 name = mbstrip(psinfo->pr_psargs, PRARGSZ);
226 226 else
227 227 name = psinfo->pr_fname;
228 228
229 229 if (g_flags & F_OUTPUT)
230 230 (void) printf("%s%5d %s", g_delim, (int)psinfo->pr_pid, name);
231 231 else {
232 232 (void) printf("%5d %s", (int)psinfo->pr_pid, name);
233 233 g_flags |= F_OUTPUT;
234 234 }
235 235 }
236 236
237 237 static void
238 238 kill_proc(psinfo_t *psinfo)
239 239 {
240 240 if (psinfo->pr_pid > 0 && kill(psinfo->pr_pid, g_signal) == -1)
241 241 uu_warn(gettext("Failed to signal pid %d"),
242 242 (int)psinfo->pr_pid);
243 243 }
244 244
245 245 static DIR *
246 246 open_proc_dir(const char *dirpath)
247 247 {
248 248 struct stat buf;
249 249 DIR *dirp;
250 250
251 251 if ((dirp = opendir(dirpath)) == NULL) {
252 252 uu_warn(gettext("Failed to open %s"), dirpath);
253 253 return (NULL);
254 254 }
255 255
256 256 if (fstat(dirp->dd_fd, &buf) == -1) {
257 257 uu_warn(gettext("Failed to stat %s"), dirpath);
258 258 (void) closedir(dirp);
259 259 return (NULL);
260 260 }
261 261
262 262 if (strcmp(buf.st_fstype, "proc") != 0) {
263 263 uu_warn(gettext("%s is not a procfs mount point\n"), dirpath);
264 264 (void) closedir(dirp);
265 265 return (NULL);
266 266 }
267 267
268 268 return (dirp);
269 269 }
270 270
271 271 #define NEWER(ps1, ps2) \
272 272 ((ps1.pr_start.tv_sec > ps2.pr_start.tv_sec) || \
273 273 (ps1.pr_start.tv_sec == ps2.pr_start.tv_sec && \
274 274 ps1.pr_start.tv_nsec > ps2.pr_start.tv_nsec))
275 275
276 276 static int
277 277 scan_proc_dir(const char *dirpath, DIR *dirp, psexp_t *psexp,
278 278 void (*funcp)(psinfo_t *))
279 279 {
280 280 char procpath[MAXPATHLEN];
281 281 psinfo_t ps, ops;
282 282 dirent_t *dent;
283 283 int procfd;
284 284
285 285 int reverse = (g_flags & F_REVERSE) ? 1 : 0;
286 286 int ovalid = 0, nmatches = 0, flags = 0;
287 287
288 288 if (g_flags & F_LONG_FMT)
289 289 flags |= PSEXP_PSARGS;
290 290
291 291 if (g_flags & F_EXACT_MATCH)
292 292 flags |= PSEXP_EXACT;
293 293
294 294 while ((dent = readdir(dirp)) != NULL) {
295 295
296 296 if (dent->d_name[0] == '.')
297 297 continue;
298 298
299 299 (void) snprintf(procpath, sizeof (procpath), "%s/%s/psinfo",
300 300 dirpath, dent->d_name);
301 301
302 302 if ((procfd = open(procpath, O_RDONLY)) == -1)
303 303 continue;
304 304
305 305 if ((read(procfd, &ps, sizeof (ps)) == sizeof (psinfo_t)) &&
306 306 (ps.pr_nlwp != 0) && (ps.pr_pid != g_pid) &&
307 307 (psexp_match(psexp, &ps, flags) ^ reverse)) {
308 308
309 309 if (g_flags & F_NEWEST) {
310 310 /* LINTED - opsinfo use ok */
311 311 if (!ovalid || NEWER(ps, ops)) {
312 312 (void) memcpy(&ops, &ps,
313 313 sizeof (psinfo_t));
314 314 ovalid = 1;
315 315 }
316 316 } else if (g_flags & F_OLDEST) {
317 317 if (!ovalid || NEWER(ops, ps)) {
318 318 (void) memcpy(&ops, &ps,
319 319 sizeof (psinfo_t));
320 320 ovalid = 1;
321 321 }
322 322 } else {
323 323 (*funcp)(&ps);
324 324 nmatches++;
325 325 }
326 326 }
327 327
328 328 (void) close(procfd);
329 329 }
330 330
331 331 if ((g_flags & (F_NEWEST | F_OLDEST)) && ovalid) {
332 332 (*funcp)(&ops);
333 333 nmatches++;
334 334 }
335 335
336 336 return (nmatches);
337 337 }
338 338
339 339 static int
340 340 parse_ids(idtab_t *idt, char *arg, int base, int opt, idkey_t zero)
341 341 {
342 342 char *ptr, *next;
343 343 idkey_t id;
344 344
345 345 for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) {
346 346 if ((id = (idkey_t)strtoul(ptr, &next, base)) != 0)
347 347 idtab_append(idt, id);
348 348 else
349 349 idtab_append(idt, zero);
350 350
351 351 if (next == ptr || *next != 0) {
352 352 uu_warn("invalid argument for option '%c' -- %s\n",
353 353 opt, ptr);
354 354 return (-1);
355 355 }
356 356 }
357 357
358 358 return (0);
359 359 }
360 360
361 361 static int
362 362 parse_uids(idtab_t *idt, char *arg)
363 363 {
364 364 char *ptr, *next;
365 365 struct passwd *pwent;
366 366 idkey_t id;
367 367
368 368 for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) {
369 369 if (isdigit(ptr[0])) {
370 370 id = strtol(ptr, &next, 10);
371 371
372 372 if (next != ptr && *next == '\0') {
373 373 idtab_append(idt, id);
374 374 continue;
375 375 }
376 376 }
377 377
378 378 if ((pwent = getpwnam(ptr)) != NULL)
379 379 idtab_append(idt, pwent->pw_uid);
380 380 else
381 381 goto err;
382 382 }
383 383
384 384 return (0);
385 385
386 386 err:
387 387 uu_warn(gettext("invalid user name -- %s\n"), ptr);
388 388 return (-1);
389 389 }
390 390
391 391 static int
392 392 parse_gids(idtab_t *idt, char *arg)
393 393 {
394 394 char *ptr, *next;
395 395 struct group *grent;
396 396 idkey_t id;
397 397
398 398 for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) {
399 399 if (isdigit(ptr[0])) {
400 400 id = strtol(ptr, &next, 10);
401 401
402 402 if (next != ptr && *next == '\0') {
403 403 idtab_append(idt, id);
404 404 continue;
405 405 }
406 406 }
407 407
408 408 if ((grent = getgrnam(ptr)) != NULL)
409 409 idtab_append(idt, grent->gr_gid);
410 410 else
411 411 goto err;
412 412 }
413 413
414 414 return (0);
415 415
416 416 err:
417 417 uu_warn(gettext("invalid group name -- %s\n"), ptr);
418 418 return (-1);
419 419 }
420 420
421 421 static int
422 422 parse_ttys(idtab_t *idt, char *arg)
423 423 {
424 424 char devpath[MAXPATHLEN];
425 425 struct stat buf;
426 426 char *ptr;
427 427
428 428 int seen_console = 0; /* Flag so we only stat syscon and systty once */
429 429
430 430 for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) {
431 431 if (strcmp(ptr, "none") == 0) {
432 432 idtab_append(idt, (idkey_t)PRNODEV);
433 433 continue;
434 434 }
435 435
436 436 if (strcmp(ptr, "console") == 0) {
437 437 if (seen_console)
438 438 continue;
439 439
440 440 if (stat("/dev/syscon", &buf) == 0)
441 441 idtab_append(idt, (idkey_t)buf.st_rdev);
442 442
443 443 if (stat("/dev/systty", &buf) == 0)
444 444 idtab_append(idt, (idkey_t)buf.st_rdev);
445 445
446 446 seen_console++;
447 447 }
448 448
449 449 (void) snprintf(devpath, MAXPATHLEN - 1, "/dev/%s", ptr);
450 450
451 451 if (stat(devpath, &buf) == -1)
452 452 goto err;
453 453
454 454 idtab_append(idt, (idkey_t)buf.st_rdev);
455 455 }
456 456
457 457 return (0);
458 458
459 459 err:
460 460 uu_warn(gettext("unknown terminal name -- %s\n"), ptr);
461 461 return (-1);
462 462 }
463 463
464 464 static int
465 465 parse_projects(idtab_t *idt, char *arg)
466 466 {
467 467 char *ptr, *next;
468 468 projid_t projid;
469 469 idkey_t id;
470 470
471 471 for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) {
472 472 if (isdigit(ptr[0])) {
473 473 id = strtol(ptr, &next, 10);
474 474
475 475 if (next != ptr && *next == '\0') {
476 476 idtab_append(idt, id);
477 477 continue;
478 478 }
479 479 }
480 480
481 481 if ((projid = getprojidbyname(ptr)) != -1)
482 482 idtab_append(idt, projid);
483 483 else
484 484 goto err;
485 485 }
486 486
487 487 return (0);
488 488
489 489 err:
490 490 uu_warn(gettext("invalid project name -- %s\n"), ptr);
491 491 return (-1);
492 492 }
493 493
494 494 static int
495 495 parse_zones(idtab_t *idt, char *arg)
496 496 {
497 497 char *ptr;
498 498 zoneid_t id;
499 499
500 500 for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) {
501 501 if (zone_get_id(ptr, &id) != 0) {
502 502 uu_warn(gettext("invalid zone name -- %s\n"), ptr);
503 503 return (-1);
504 504 }
505 505 idtab_append(idt, id);
506 506 }
507 507
508 508 return (0);
509 509 }
510 510
511 511 /*ARGSUSED*/
512 512 static int
513 513 opt_euid(char c, char *arg)
514 514 {
515 515 return (parse_uids(&g_psexp.ps_euids, arg));
516 516 }
517 517
518 518 /*ARGSUSED*/
519 519 static int
520 520 opt_uid(char c, char *arg)
521 521 {
522 522 return (parse_uids(&g_psexp.ps_ruids, arg));
523 523 }
524 524
525 525 /*ARGSUSED*/
526 526 static int
527 527 opt_gid(char c, char *arg)
528 528 {
529 529 return (parse_gids(&g_psexp.ps_rgids, arg));
530 530 }
531 531
532 532 static int
533 533 opt_ppid(char c, char *arg)
534 534 {
535 535 return (parse_ids(&g_psexp.ps_ppids, arg, 10, c, 0));
536 536 }
537 537
538 538 static int
539 539 opt_pgrp(char c, char *arg)
540 540 {
541 541 return (parse_ids(&g_psexp.ps_pgids, arg, 10, c, getpgrp()));
542 542 }
543 543
544 544 static int
545 545 opt_sid(char c, char *arg)
546 546 {
547 547 return (parse_ids(&g_psexp.ps_sids, arg, 10, c, getsid(0)));
548 548 }
549 549
550 550 /*ARGSUSED*/
551 551 static int
552 552 opt_term(char c, char *arg)
553 553 {
554 554 return (parse_ttys(&g_psexp.ps_ttys, arg));
555 555 }
556 556
557 557 /*ARGSUSED*/
558 558 static int
559 559 opt_projid(char c, char *arg)
560 560 {
561 561 return (parse_projects(&g_psexp.ps_projids, arg));
562 562 }
563 563
564 564 static int
565 565 opt_taskid(char c, char *arg)
566 566 {
567 567 return (parse_ids(&g_psexp.ps_taskids, arg, 10, c, gettaskid()));
568 568 }
569 569
570 570 /*ARGSUSED*/
571 571 static int
572 572 opt_zoneid(char c, char *arg)
573 573 {
574 574 return (parse_zones(&g_psexp.ps_zoneids, arg));
575 575 }
576 576
577 577 static int
578 578 opt_ctid(char c, char *arg)
579 579 {
580 580 return (parse_ids(&g_psexp.ps_ctids, arg, 10, c, getctid()));
581 581 }
582 582
583 583 static void
584 584 print_usage(FILE *stream)
585 585 {
586 586 if (g_flags & F_KILL)
587 587 (void) fprintf(stream, gettext(PKILL_USAGE), g_pname);
588 588 else
589 589 (void) fprintf(stream, gettext(PGREP_USAGE), g_pname);
590 590 }
591 591
592 592 int
593 593 main(int argc, char *argv[])
594 594 {
595 595 void (*funcp)(psinfo_t *);
596 596
597 597 const char *optstr;
598 598 optdesc_t *optd;
599 599 int nmatches, c;
600 600 const char *zroot;
601 601 char buf[PATH_MAX];
602 602
603 603 DIR *dirp;
604 604
605 605 (void) setlocale(LC_ALL, "");
606 606 (void) textdomain(TEXT_DOMAIN);
607 607
608 608 UU_EXIT_FATAL = E_ERROR;
609 609
610 610 g_pname = uu_setpname(argv[0]);
611 611 g_pid = getpid();
612 612
613 613 psexp_create(&g_psexp);
614 614
615 615 if (strcmp(g_pname, "pkill") == 0) {
616 616
617 617 if (argc > 1 && argv[1][0] == '-' &&
618 618 str2sig(&argv[1][1], &g_signal) == 0) {
619 619 argv[1] = argv[0];
620 620 argv++;
621 621 argc--;
622 622 }
623 623
624 624 optstr = PKILL_OPTS;
625 625 g_flags |= F_KILL;
626 626 } else
627 627 optstr = PGREP_OPTS;
628 628
629 629 opterr = 0;
630 630
631 631 zroot = zone_get_nroot();
632 632 if (zroot != NULL) {
633 633 (void) snprintf(buf, sizeof (buf), "%s/%s", zroot, g_procdir);
634 634 g_procdir = buf;
635 635 }
636 636
637 637 while (optind < argc) {
638 638 while ((c = getopt(argc, argv, optstr)) != (int)EOF) {
639 639
640 640 if (c == ':' || c == '?' ||
641 641 g_optdtab[c - 'A'].o_opts == 0) {
642 642 if (c == ':') {
643 643 uu_warn(
644 644 gettext("missing argument -- %c\n"),
645 645 optopt);
646 646 } else if (optopt != '?') {
647 647 uu_warn(
648 648 gettext("illegal option -- %c\n"),
649 649 optopt);
650 650 }
651 651
652 652 print_usage(stderr);
653 653 return (E_USAGE);
654 654 }
655 655
656 656 optd = &g_optdtab[c - 'A'];
657 657
658 658 if (optd->o_opts & OPT_SETB)
659 659 *((ushort_t *)optd->o_ptr) |= optd->o_bits;
660 660
661 661 if (optd->o_opts & OPT_CLRB)
662 662 *((ushort_t *)optd->o_ptr) &= ~optd->o_bits;
663 663
664 664 if (optd->o_opts & OPT_STR)
665 665 *((char **)optd->o_ptr) = optarg;
666 666
667 667 if (optd->o_opts & OPT_CRIT)
668 668 g_flags |= F_HAVE_CRIT;
669 669
670 670 if (optd->o_opts & OPT_FUNC) {
671 671 if (optd->o_func(c, optarg) == -1)
672 672 return (E_USAGE);
673 673 }
674 674 }
675 675
676 676 if (optind < argc) {
677 677 if (g_psexp.ps_pat != NULL) {
678 678 uu_warn(gettext("illegal argument -- %s\n"),
679 679 argv[optind]);
680 680 print_usage(stderr);
681 681 return (E_USAGE);
682 682 }
683 683
684 684 g_psexp.ps_pat = argv[optind++];
685 685 g_flags |= F_HAVE_CRIT;
686 686 }
687 687 }
688 688
689 689 if ((g_flags & F_NEWEST) && (g_flags & F_OLDEST)) {
690 690 uu_warn(gettext("-n and -o are mutually exclusive\n"));
691 691 print_usage(stderr);
692 692 return (E_USAGE);
693 693 }
694 694
695 695 if ((g_flags & F_HAVE_CRIT) == 0) {
696 696 uu_warn(gettext("No matching criteria specified\n"));
697 697 print_usage(stderr);
698 698 return (E_USAGE);
699 699 }
700 700
701 701 if (psexp_compile(&g_psexp) == -1) {
702 702 psexp_destroy(&g_psexp);
703 703 return (E_USAGE);
704 704 }
705 705
706 706 if ((dirp = open_proc_dir(g_procdir)) == NULL)
707 707 return (E_ERROR);
708 708
709 709 if (g_flags & F_KILL)
710 710 funcp = kill_proc;
711 711 else if (g_flags & F_LONG_OUT)
712 712 funcp = print_proc_long;
713 713 else
714 714 funcp = print_proc;
715 715
716 716 nmatches = scan_proc_dir(g_procdir, dirp, &g_psexp, funcp);
717 717
718 718 if (g_flags & F_OUTPUT)
719 719 (void) fputc('\n', stdout);
720 720
721 721 psexp_destroy(&g_psexp);
722 722 return (nmatches ? E_MATCH : E_NOMATCH);
723 723 }
|
↓ open down ↓ |
723 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX