17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5657b1f3dSraf * Common Development and Distribution License (the "License"). 6657b1f3dSraf * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21657b1f3dSraf 227c478bd9Sstevel@tonic-gate /* 23*a574db85Sraf * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 287c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.2 */ 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate #include <stdio.h> 337c478bd9Sstevel@tonic-gate #include <stdlib.h> 347c478bd9Sstevel@tonic-gate #include <unistd.h> 357c478bd9Sstevel@tonic-gate #include <ctype.h> 367c478bd9Sstevel@tonic-gate #include <string.h> 377c478bd9Sstevel@tonic-gate #include <memory.h> 387c478bd9Sstevel@tonic-gate #include <sys/types.h> 397c478bd9Sstevel@tonic-gate #include <signal.h> 407c478bd9Sstevel@tonic-gate #include <libproc.h> 417c478bd9Sstevel@tonic-gate #include "ramdata.h" 427c478bd9Sstevel@tonic-gate #include "systable.h" 437c478bd9Sstevel@tonic-gate #include "proto.h" 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate /* XXX A bug in the <string.h> header file requires this */ 467c478bd9Sstevel@tonic-gate extern char *strtok_r(char *s1, const char *s2, char **lasts); 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate /* 497c478bd9Sstevel@tonic-gate * option procesing --- 507c478bd9Sstevel@tonic-gate * Routines for scanning syscall, signal, fault 517c478bd9Sstevel@tonic-gate * and file descriptor lists. 527c478bd9Sstevel@tonic-gate */ 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate /* 557c478bd9Sstevel@tonic-gate * Function prototypes for static routines in this module. 567c478bd9Sstevel@tonic-gate */ 577c478bd9Sstevel@tonic-gate void upcase(char *); 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate const char white[] = " \t\n"; /* white space characters */ 607c478bd9Sstevel@tonic-gate const char sepr[] = " ,\t\n"; /* list separator characters */ 617c478bd9Sstevel@tonic-gate const char csepr[] = " :,\t\n"; /* same, with ':' added */ 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate /* 647c478bd9Sstevel@tonic-gate * Scan list of syscall names. 657c478bd9Sstevel@tonic-gate * Return 0 on success, != 0 on any failure. 667c478bd9Sstevel@tonic-gate */ 677c478bd9Sstevel@tonic-gate int 687c478bd9Sstevel@tonic-gate syslist(char *str, /* string of syscall names */ 697c478bd9Sstevel@tonic-gate sysset_t *setp, /* syscall set */ 707c478bd9Sstevel@tonic-gate int *fp) /* first-time flag */ 717c478bd9Sstevel@tonic-gate { 727c478bd9Sstevel@tonic-gate char *name; 737c478bd9Sstevel@tonic-gate int exclude = FALSE; 747c478bd9Sstevel@tonic-gate int rc = 0; 757c478bd9Sstevel@tonic-gate char *lasts; 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate name = strtok_r(str, sepr, &lasts); 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate if (name != NULL && *name == '!') { /* exclude from set */ 807c478bd9Sstevel@tonic-gate exclude = TRUE; 817c478bd9Sstevel@tonic-gate if (*++name == '\0') 827c478bd9Sstevel@tonic-gate name = strtok_r(NULL, sepr, &lasts); 837c478bd9Sstevel@tonic-gate } else if (!*fp) { /* first time, clear the set */ 847c478bd9Sstevel@tonic-gate premptyset(setp); 857c478bd9Sstevel@tonic-gate *fp = TRUE; 867c478bd9Sstevel@tonic-gate } 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate for (; name; name = strtok_r(NULL, sepr, &lasts)) { 897c478bd9Sstevel@tonic-gate int sys; 907c478bd9Sstevel@tonic-gate int sysx; 91657b1f3dSraf int sysxx; 927c478bd9Sstevel@tonic-gate int sys64; 937c478bd9Sstevel@tonic-gate char *next; 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate if (*name == '!') { /* exclude remainder from set */ 967c478bd9Sstevel@tonic-gate exclude = TRUE; 977c478bd9Sstevel@tonic-gate while (*++name == '!') 987c478bd9Sstevel@tonic-gate /* empty */; 997c478bd9Sstevel@tonic-gate if (*name == '\0') 1007c478bd9Sstevel@tonic-gate continue; 1017c478bd9Sstevel@tonic-gate } 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate sys = strtol(name, &next, 0); 104657b1f3dSraf sysx = sysxx = sys64 = 0; 1057c478bd9Sstevel@tonic-gate if (sys < 0 || sys > PRMAXSYS || *next != '\0') 1067c478bd9Sstevel@tonic-gate sys = 0; 1077c478bd9Sstevel@tonic-gate if (sys == 0) { 1087c478bd9Sstevel@tonic-gate const struct systable *stp = systable; 1097c478bd9Sstevel@tonic-gate for (; sys == 0 && stp->nargs >= 0; stp++) 1107c478bd9Sstevel@tonic-gate if (stp->name && strcmp(stp->name, name) == 0) 1117c478bd9Sstevel@tonic-gate sys = stp-systable; 1127c478bd9Sstevel@tonic-gate } 1137c478bd9Sstevel@tonic-gate if (sys == 0) { 1147c478bd9Sstevel@tonic-gate const struct sysalias *sap = sysalias; 1157c478bd9Sstevel@tonic-gate for (; sys == 0 && sap->name; sap++) 1167c478bd9Sstevel@tonic-gate if (strcmp(sap->name, name) == 0) 1177c478bd9Sstevel@tonic-gate sys = sap->number; 1187c478bd9Sstevel@tonic-gate } 1197c478bd9Sstevel@tonic-gate if (sys > 0 && sys <= PRMAXSYS) { 1207c478bd9Sstevel@tonic-gate switch (sys) { 1217c478bd9Sstevel@tonic-gate case SYS_xstat: /* set all if any */ 1227c478bd9Sstevel@tonic-gate case SYS_stat: 1237c478bd9Sstevel@tonic-gate case SYS_stat64: 1247c478bd9Sstevel@tonic-gate sys = SYS_stat; 1257c478bd9Sstevel@tonic-gate sysx = SYS_xstat; 1267c478bd9Sstevel@tonic-gate sys64 = SYS_stat64; 1277c478bd9Sstevel@tonic-gate goto def; 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate case SYS_lxstat: /* set all if any */ 1307c478bd9Sstevel@tonic-gate case SYS_lstat: 1317c478bd9Sstevel@tonic-gate case SYS_lstat64: 1327c478bd9Sstevel@tonic-gate sys = SYS_lstat; 1337c478bd9Sstevel@tonic-gate sysx = SYS_lxstat; 1347c478bd9Sstevel@tonic-gate sys64 = SYS_lstat64; 1357c478bd9Sstevel@tonic-gate goto def; 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate case SYS_fxstat: /* set all if any */ 1387c478bd9Sstevel@tonic-gate case SYS_fstat: 1397c478bd9Sstevel@tonic-gate case SYS_fstat64: 1407c478bd9Sstevel@tonic-gate sys = SYS_fstat; 1417c478bd9Sstevel@tonic-gate sysx = SYS_fxstat; 1427c478bd9Sstevel@tonic-gate sys64 = SYS_fstat64; 1437c478bd9Sstevel@tonic-gate goto def; 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate case SYS_getdents: /* set both if either */ 1467c478bd9Sstevel@tonic-gate case SYS_getdents64: 1477c478bd9Sstevel@tonic-gate sys = SYS_getdents; 1487c478bd9Sstevel@tonic-gate sys64 = SYS_getdents64; 1497c478bd9Sstevel@tonic-gate goto def; 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate case SYS_mmap: /* set both if either */ 1527c478bd9Sstevel@tonic-gate case SYS_mmap64: 1537c478bd9Sstevel@tonic-gate sys = SYS_mmap; 1547c478bd9Sstevel@tonic-gate sys64 = SYS_mmap64; 1557c478bd9Sstevel@tonic-gate goto def; 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate case SYS_statvfs: /* set both if either */ 1587c478bd9Sstevel@tonic-gate case SYS_statvfs64: 1597c478bd9Sstevel@tonic-gate sys = SYS_statvfs; 1607c478bd9Sstevel@tonic-gate sys64 = SYS_statvfs64; 1617c478bd9Sstevel@tonic-gate goto def; 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate case SYS_fstatvfs: /* set both if either */ 1647c478bd9Sstevel@tonic-gate case SYS_fstatvfs64: 1657c478bd9Sstevel@tonic-gate sys = SYS_fstatvfs; 1667c478bd9Sstevel@tonic-gate sys64 = SYS_fstatvfs64; 1677c478bd9Sstevel@tonic-gate goto def; 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate case SYS_setrlimit: /* set both if either */ 1707c478bd9Sstevel@tonic-gate case SYS_setrlimit64: 1717c478bd9Sstevel@tonic-gate sys = SYS_setrlimit; 1727c478bd9Sstevel@tonic-gate sys64 = SYS_setrlimit64; 1737c478bd9Sstevel@tonic-gate goto def; 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate case SYS_getrlimit: /* set both if either */ 1767c478bd9Sstevel@tonic-gate case SYS_getrlimit64: 1777c478bd9Sstevel@tonic-gate sys = SYS_getrlimit; 1787c478bd9Sstevel@tonic-gate sys64 = SYS_getrlimit64; 1797c478bd9Sstevel@tonic-gate goto def; 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate case SYS_pread: /* set both if either */ 1827c478bd9Sstevel@tonic-gate case SYS_pread64: 1837c478bd9Sstevel@tonic-gate sys = SYS_pread; 1847c478bd9Sstevel@tonic-gate sys64 = SYS_pread64; 1857c478bd9Sstevel@tonic-gate goto def; 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate case SYS_pwrite: /* set both if either */ 1887c478bd9Sstevel@tonic-gate case SYS_pwrite64: 1897c478bd9Sstevel@tonic-gate sys = SYS_pwrite; 1907c478bd9Sstevel@tonic-gate sys64 = SYS_pwrite64; 1917c478bd9Sstevel@tonic-gate goto def; 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate case SYS_creat: /* set both if either */ 1947c478bd9Sstevel@tonic-gate case SYS_creat64: 1957c478bd9Sstevel@tonic-gate sys = SYS_creat; 1967c478bd9Sstevel@tonic-gate sys64 = SYS_creat64; 1977c478bd9Sstevel@tonic-gate goto def; 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate case SYS_open: /* set both if either */ 2007c478bd9Sstevel@tonic-gate case SYS_open64: 2017c478bd9Sstevel@tonic-gate sys = SYS_open; 2027c478bd9Sstevel@tonic-gate sys64 = SYS_open64; 2037c478bd9Sstevel@tonic-gate goto def; 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate case SYS_xmknod: /* set both if either */ 2067c478bd9Sstevel@tonic-gate case SYS_mknod: 2077c478bd9Sstevel@tonic-gate sysx = SYS_xmknod; 2087c478bd9Sstevel@tonic-gate sys = SYS_mknod; 2097c478bd9Sstevel@tonic-gate goto def; 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate case SYS_forkall: /* set all if any */ 2127c478bd9Sstevel@tonic-gate case SYS_fork1: 2137c478bd9Sstevel@tonic-gate case SYS_vfork: 214657b1f3dSraf case SYS_forksys: 2157c478bd9Sstevel@tonic-gate sys = SYS_forkall; 2167c478bd9Sstevel@tonic-gate sysx = SYS_fork1; 2177c478bd9Sstevel@tonic-gate sys64 = SYS_vfork; 218657b1f3dSraf sysxx = SYS_forksys; 2197c478bd9Sstevel@tonic-gate goto def; 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate case SYS_exec: /* set both if either */ 2227c478bd9Sstevel@tonic-gate case SYS_execve: 2237c478bd9Sstevel@tonic-gate sysx = SYS_exec; 2247c478bd9Sstevel@tonic-gate sys = SYS_execve; 2257c478bd9Sstevel@tonic-gate goto def; 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate case SYS_poll: /* set both if either */ 2287c478bd9Sstevel@tonic-gate case SYS_pollsys: 2297c478bd9Sstevel@tonic-gate sysx = SYS_poll; 2307c478bd9Sstevel@tonic-gate sys = SYS_pollsys; 2317c478bd9Sstevel@tonic-gate goto def; 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate case SYS_sigprocmask: /* set both if either */ 2347c478bd9Sstevel@tonic-gate case SYS_lwp_sigmask: 2357c478bd9Sstevel@tonic-gate sysx = SYS_sigprocmask; 2367c478bd9Sstevel@tonic-gate sys = SYS_lwp_sigmask; 2377c478bd9Sstevel@tonic-gate goto def; 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate case SYS_wait: /* set both if either */ 240*a574db85Sraf case SYS_waitid: 2417c478bd9Sstevel@tonic-gate sysx = SYS_wait; 242*a574db85Sraf sys = SYS_waitid; 2437c478bd9Sstevel@tonic-gate goto def; 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate case SYS_lseek: /* set both if either */ 2467c478bd9Sstevel@tonic-gate case SYS_llseek: 2477c478bd9Sstevel@tonic-gate sysx = SYS_lseek; 2487c478bd9Sstevel@tonic-gate sys = SYS_llseek; 2497c478bd9Sstevel@tonic-gate goto def; 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate case SYS_lwp_mutex_lock: /* set both if either */ 2527c478bd9Sstevel@tonic-gate case SYS_lwp_mutex_timedlock: 2537c478bd9Sstevel@tonic-gate sysx = SYS_lwp_mutex_lock; 2547c478bd9Sstevel@tonic-gate sys = SYS_lwp_mutex_timedlock; 2557c478bd9Sstevel@tonic-gate goto def; 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate case SYS_lwp_sema_wait: /* set both if either */ 2587c478bd9Sstevel@tonic-gate case SYS_lwp_sema_timedwait: 2597c478bd9Sstevel@tonic-gate sysx = SYS_lwp_sema_wait; 2607c478bd9Sstevel@tonic-gate sys = SYS_lwp_sema_timedwait; 2617c478bd9Sstevel@tonic-gate goto def; 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate default: 2647c478bd9Sstevel@tonic-gate def: 2657c478bd9Sstevel@tonic-gate if (exclude) { 2667c478bd9Sstevel@tonic-gate prdelset(setp, sys); 2677c478bd9Sstevel@tonic-gate if (sysx) 2687c478bd9Sstevel@tonic-gate prdelset(setp, sysx); 269657b1f3dSraf if (sysxx) 270657b1f3dSraf prdelset(setp, sysxx); 2717c478bd9Sstevel@tonic-gate if (sys64) 2727c478bd9Sstevel@tonic-gate prdelset(setp, sys64); 2737c478bd9Sstevel@tonic-gate } else { 2747c478bd9Sstevel@tonic-gate praddset(setp, sys); 2757c478bd9Sstevel@tonic-gate if (sysx) 2767c478bd9Sstevel@tonic-gate praddset(setp, sysx); 277657b1f3dSraf if (sysxx) 278657b1f3dSraf praddset(setp, sysxx); 2797c478bd9Sstevel@tonic-gate if (sys64) 2807c478bd9Sstevel@tonic-gate praddset(setp, sys64); 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate break; 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate } else if (strcmp(name, "all") == 0 || 2857c478bd9Sstevel@tonic-gate strcmp(name, "ALL") == 0) { 2867c478bd9Sstevel@tonic-gate if (exclude) { 2877c478bd9Sstevel@tonic-gate premptyset(setp); 2887c478bd9Sstevel@tonic-gate } else { 2897c478bd9Sstevel@tonic-gate prfillset(setp); 2907c478bd9Sstevel@tonic-gate } 2917c478bd9Sstevel@tonic-gate } else { 2927c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 293*a574db85Sraf "%s: unrecognized syscall: %s\n", 294*a574db85Sraf command, name); 2957c478bd9Sstevel@tonic-gate rc = -1; 2967c478bd9Sstevel@tonic-gate } 2977c478bd9Sstevel@tonic-gate } 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate return (rc); 3007c478bd9Sstevel@tonic-gate } 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate /* 3037c478bd9Sstevel@tonic-gate * List of signals to trace. 3047c478bd9Sstevel@tonic-gate * Return 0 on success, != 0 on any failure. 3057c478bd9Sstevel@tonic-gate */ 3067c478bd9Sstevel@tonic-gate int 3077c478bd9Sstevel@tonic-gate siglist(private_t *pri, 3087c478bd9Sstevel@tonic-gate char *str, /* string of signal names */ 3097c478bd9Sstevel@tonic-gate sigset_t *setp, /* signal set */ 3107c478bd9Sstevel@tonic-gate int *fp) /* first-time flag */ 3117c478bd9Sstevel@tonic-gate { 3127c478bd9Sstevel@tonic-gate char *name; 3137c478bd9Sstevel@tonic-gate int exclude = FALSE; 3147c478bd9Sstevel@tonic-gate int rc = 0; 3157c478bd9Sstevel@tonic-gate char *lasts; 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate upcase(str); 3187c478bd9Sstevel@tonic-gate name = strtok_r(str, sepr, &lasts); 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate if (name != NULL && *name == '!') { /* exclude from set */ 3217c478bd9Sstevel@tonic-gate exclude = TRUE; 3227c478bd9Sstevel@tonic-gate if (*++name == '\0') 3237c478bd9Sstevel@tonic-gate name = strtok_r(NULL, sepr, &lasts); 3247c478bd9Sstevel@tonic-gate } else if (!*fp) { /* first time, clear the set */ 3257c478bd9Sstevel@tonic-gate premptyset(setp); 3267c478bd9Sstevel@tonic-gate *fp = TRUE; 3277c478bd9Sstevel@tonic-gate } 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate for (; name; name = strtok_r(NULL, sepr, &lasts)) { 3307c478bd9Sstevel@tonic-gate int sig; 3317c478bd9Sstevel@tonic-gate char *next; 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate if (*name == '!') { /* exclude remainder from set */ 3347c478bd9Sstevel@tonic-gate exclude = TRUE; 3357c478bd9Sstevel@tonic-gate while (*++name == '!') 3367c478bd9Sstevel@tonic-gate /* empty */; 3377c478bd9Sstevel@tonic-gate if (*name == '\0') 3387c478bd9Sstevel@tonic-gate continue; 3397c478bd9Sstevel@tonic-gate } 3407c478bd9Sstevel@tonic-gate 3417c478bd9Sstevel@tonic-gate sig = strtol(name, &next, 0); 3427c478bd9Sstevel@tonic-gate if (sig <= 0 || sig > PRMAXSIG || *next != '\0') { 3437c478bd9Sstevel@tonic-gate for (sig = 1; sig <= PRMAXSIG; sig++) { 3447c478bd9Sstevel@tonic-gate const char *sname = rawsigname(pri, sig); 3457c478bd9Sstevel@tonic-gate if (sname == NULL) 3467c478bd9Sstevel@tonic-gate continue; 3477c478bd9Sstevel@tonic-gate if (strcmp(sname, name) == 0 || 3487c478bd9Sstevel@tonic-gate strcmp(sname+3, name) == 0) 3497c478bd9Sstevel@tonic-gate break; 3507c478bd9Sstevel@tonic-gate } 3517c478bd9Sstevel@tonic-gate if (sig > PRMAXSIG) 3527c478bd9Sstevel@tonic-gate sig = 0; 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate if (sig > 0 && sig <= PRMAXSIG) { 3557c478bd9Sstevel@tonic-gate if (exclude) { 3567c478bd9Sstevel@tonic-gate prdelset(setp, sig); 3577c478bd9Sstevel@tonic-gate } else { 3587c478bd9Sstevel@tonic-gate praddset(setp, sig); 3597c478bd9Sstevel@tonic-gate } 3607c478bd9Sstevel@tonic-gate } else if (strcmp(name, "ALL") == 0) { 3617c478bd9Sstevel@tonic-gate if (exclude) { 3627c478bd9Sstevel@tonic-gate premptyset(setp); 3637c478bd9Sstevel@tonic-gate } else { 3647c478bd9Sstevel@tonic-gate prfillset(setp); 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate } else { 3677c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 368*a574db85Sraf "%s: unrecognized signal name/number: %s\n", 369*a574db85Sraf command, name); 3707c478bd9Sstevel@tonic-gate rc = -1; 3717c478bd9Sstevel@tonic-gate } 3727c478bd9Sstevel@tonic-gate } 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate return (rc); 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate /* 3787c478bd9Sstevel@tonic-gate * List of faults to trace. 3797c478bd9Sstevel@tonic-gate * return 0 on success, != 0 on any failure. 3807c478bd9Sstevel@tonic-gate */ 3817c478bd9Sstevel@tonic-gate int 3827c478bd9Sstevel@tonic-gate fltlist(char *str, /* string of fault names */ 3837c478bd9Sstevel@tonic-gate fltset_t *setp, /* fault set */ 3847c478bd9Sstevel@tonic-gate int *fp) /* first-time flag */ 3857c478bd9Sstevel@tonic-gate { 3867c478bd9Sstevel@tonic-gate char *name; 3877c478bd9Sstevel@tonic-gate int exclude = FALSE; 3887c478bd9Sstevel@tonic-gate int rc = 0; 3897c478bd9Sstevel@tonic-gate char *lasts; 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate upcase(str); 3927c478bd9Sstevel@tonic-gate name = strtok_r(str, sepr, &lasts); 3937c478bd9Sstevel@tonic-gate 3947c478bd9Sstevel@tonic-gate if (name != NULL && *name == '!') { /* exclude from set */ 3957c478bd9Sstevel@tonic-gate exclude = TRUE; 3967c478bd9Sstevel@tonic-gate if (*++name == '\0') 3977c478bd9Sstevel@tonic-gate name = strtok_r(NULL, sepr, &lasts); 3987c478bd9Sstevel@tonic-gate } else if (!*fp) { /* first time, clear the set */ 3997c478bd9Sstevel@tonic-gate premptyset(setp); 4007c478bd9Sstevel@tonic-gate *fp = TRUE; 4017c478bd9Sstevel@tonic-gate } 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate for (; name; name = strtok_r(NULL, sepr, &lasts)) { 4047c478bd9Sstevel@tonic-gate int flt; 4057c478bd9Sstevel@tonic-gate char *next; 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate if (*name == '!') { /* exclude remainder from set */ 4087c478bd9Sstevel@tonic-gate exclude = TRUE; 4097c478bd9Sstevel@tonic-gate while (*++name == '!') 4107c478bd9Sstevel@tonic-gate /* empty */; 4117c478bd9Sstevel@tonic-gate if (*name == '\0') 4127c478bd9Sstevel@tonic-gate continue; 4137c478bd9Sstevel@tonic-gate } 4147c478bd9Sstevel@tonic-gate 4157c478bd9Sstevel@tonic-gate flt = strtol(name, &next, 0); 4167c478bd9Sstevel@tonic-gate if (flt <= 0 || flt > PRMAXFAULT || *next != '\0') { 4177c478bd9Sstevel@tonic-gate for (flt = 1; flt <= PRMAXFAULT; flt++) { 4187c478bd9Sstevel@tonic-gate char fname[32]; 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate if (proc_fltname(flt, fname, 4217c478bd9Sstevel@tonic-gate sizeof (fname)) == NULL) 4227c478bd9Sstevel@tonic-gate continue; 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate if (strcmp(fname, name) == 0 || 4257c478bd9Sstevel@tonic-gate strcmp(fname+3, name) == 0) 4267c478bd9Sstevel@tonic-gate break; 4277c478bd9Sstevel@tonic-gate } 4287c478bd9Sstevel@tonic-gate if (flt > PRMAXFAULT) 4297c478bd9Sstevel@tonic-gate flt = 0; 4307c478bd9Sstevel@tonic-gate } 4317c478bd9Sstevel@tonic-gate if (flt > 0 && flt <= PRMAXFAULT) { 4327c478bd9Sstevel@tonic-gate if (exclude) { 4337c478bd9Sstevel@tonic-gate prdelset(setp, flt); 4347c478bd9Sstevel@tonic-gate } else { 4357c478bd9Sstevel@tonic-gate praddset(setp, flt); 4367c478bd9Sstevel@tonic-gate } 4377c478bd9Sstevel@tonic-gate } else if (strcmp(name, "ALL") == 0) { 4387c478bd9Sstevel@tonic-gate if (exclude) { 4397c478bd9Sstevel@tonic-gate premptyset(setp); 4407c478bd9Sstevel@tonic-gate } else { 4417c478bd9Sstevel@tonic-gate prfillset(setp); 4427c478bd9Sstevel@tonic-gate } 4437c478bd9Sstevel@tonic-gate } else { 4447c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 445*a574db85Sraf "%s: unrecognized fault name/number: %s\n", 446*a574db85Sraf command, name); 4477c478bd9Sstevel@tonic-gate rc = -1; 4487c478bd9Sstevel@tonic-gate } 4497c478bd9Sstevel@tonic-gate } 4507c478bd9Sstevel@tonic-gate 4517c478bd9Sstevel@tonic-gate return (rc); 4527c478bd9Sstevel@tonic-gate } 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate /* 4557c478bd9Sstevel@tonic-gate * Gather file descriptors to dump. 4567c478bd9Sstevel@tonic-gate * Return 0 on success, != 0 on any failure. 4577c478bd9Sstevel@tonic-gate */ 4587c478bd9Sstevel@tonic-gate int 4597c478bd9Sstevel@tonic-gate fdlist(char *str, /* string of filedescriptors */ 4607c478bd9Sstevel@tonic-gate fileset_t *setp) /* set of boolean flags */ 4617c478bd9Sstevel@tonic-gate { 4627c478bd9Sstevel@tonic-gate char *name; 4637c478bd9Sstevel@tonic-gate int exclude = FALSE; 4647c478bd9Sstevel@tonic-gate int rc = 0; 4657c478bd9Sstevel@tonic-gate char *lasts; 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate upcase(str); 4687c478bd9Sstevel@tonic-gate name = strtok_r(str, sepr, &lasts); 4697c478bd9Sstevel@tonic-gate 4707c478bd9Sstevel@tonic-gate if (name != NULL && *name == '!') { /* exclude from set */ 4717c478bd9Sstevel@tonic-gate exclude = TRUE; 4727c478bd9Sstevel@tonic-gate if (*++name == '\0') 4737c478bd9Sstevel@tonic-gate name = strtok_r(NULL, sepr, &lasts); 4747c478bd9Sstevel@tonic-gate } 4757c478bd9Sstevel@tonic-gate 4767c478bd9Sstevel@tonic-gate for (; name; name = strtok_r(NULL, sepr, &lasts)) { 4777c478bd9Sstevel@tonic-gate int fd; 4787c478bd9Sstevel@tonic-gate char *next; 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gate if (*name == '!') { /* exclude remainder from set */ 4817c478bd9Sstevel@tonic-gate exclude = TRUE; 4827c478bd9Sstevel@tonic-gate while (*++name == '!') 4837c478bd9Sstevel@tonic-gate /* empty */; 4847c478bd9Sstevel@tonic-gate if (*name == '\0') 4857c478bd9Sstevel@tonic-gate continue; 4867c478bd9Sstevel@tonic-gate } 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate fd = strtol(name, &next, 0); 4897c478bd9Sstevel@tonic-gate if (fd >= 0 && fd < NOFILES_MAX && *next == '\0') { 4907c478bd9Sstevel@tonic-gate fd++; 4917c478bd9Sstevel@tonic-gate if (exclude) { 4927c478bd9Sstevel@tonic-gate prdelset(setp, fd); 4937c478bd9Sstevel@tonic-gate } else { 4947c478bd9Sstevel@tonic-gate praddset(setp, fd); 4957c478bd9Sstevel@tonic-gate } 4967c478bd9Sstevel@tonic-gate } else if (strcmp(name, "ALL") == 0) { 4977c478bd9Sstevel@tonic-gate if (exclude) { 4987c478bd9Sstevel@tonic-gate premptyset(setp); 4997c478bd9Sstevel@tonic-gate } else { 5007c478bd9Sstevel@tonic-gate prfillset(setp); 5017c478bd9Sstevel@tonic-gate } 5027c478bd9Sstevel@tonic-gate } else { 5037c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 504*a574db85Sraf "%s: filedescriptor not in range[0..%d]: %s\n", 505*a574db85Sraf command, NOFILES_MAX-1, name); 5067c478bd9Sstevel@tonic-gate rc = -1; 5077c478bd9Sstevel@tonic-gate } 5087c478bd9Sstevel@tonic-gate } 5097c478bd9Sstevel@tonic-gate 5107c478bd9Sstevel@tonic-gate return (rc); 5117c478bd9Sstevel@tonic-gate } 5127c478bd9Sstevel@tonic-gate 5137c478bd9Sstevel@tonic-gate void 5147c478bd9Sstevel@tonic-gate upcase(char *str) 5157c478bd9Sstevel@tonic-gate { 5167c478bd9Sstevel@tonic-gate int c; 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate while ((c = *str) != '\0') 5197c478bd9Sstevel@tonic-gate *str++ = toupper(c); 5207c478bd9Sstevel@tonic-gate } 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate /* 5237c478bd9Sstevel@tonic-gate * 'arg' points to a string like: 5247c478bd9Sstevel@tonic-gate * libc,libnsl,... : printf,read,write,... 5257c478bd9Sstevel@tonic-gate * or 5267c478bd9Sstevel@tonic-gate * libc,libnsl,... :: printf,read,write,... 5277c478bd9Sstevel@tonic-gate * with possible filename pattern-matching metacharacters. 5287c478bd9Sstevel@tonic-gate * 5297c478bd9Sstevel@tonic-gate * Assumption: No library or function name can contain ',' or ':'. 5307c478bd9Sstevel@tonic-gate */ 5317c478bd9Sstevel@tonic-gate int 5327c478bd9Sstevel@tonic-gate liblist(char *arg, int hang) 5337c478bd9Sstevel@tonic-gate { 5347c478bd9Sstevel@tonic-gate const char *star = "*"; 5357c478bd9Sstevel@tonic-gate struct dynpat *Dyp; 5367c478bd9Sstevel@tonic-gate char *pat; 5377c478bd9Sstevel@tonic-gate char *fpat; 5387c478bd9Sstevel@tonic-gate char *lasts; 5397c478bd9Sstevel@tonic-gate uint_t maxpat; 5407c478bd9Sstevel@tonic-gate 5417c478bd9Sstevel@tonic-gate /* append a new dynpat structure to the end of the Dynpat list */ 5427c478bd9Sstevel@tonic-gate Dyp = my_malloc(sizeof (struct dynpat), NULL); 5437c478bd9Sstevel@tonic-gate Dyp->next = NULL; 5447c478bd9Sstevel@tonic-gate if (Lastpat == NULL) 5457c478bd9Sstevel@tonic-gate Dynpat = Lastpat = Dyp; 5467c478bd9Sstevel@tonic-gate else { 5477c478bd9Sstevel@tonic-gate Lastpat->next = Dyp; 5487c478bd9Sstevel@tonic-gate Lastpat = Dyp; 5497c478bd9Sstevel@tonic-gate } 5507c478bd9Sstevel@tonic-gate Dyp->flag = hang? BPT_HANG : 0; 5517c478bd9Sstevel@tonic-gate Dyp->exclude_lib = 0; 5527c478bd9Sstevel@tonic-gate Dyp->exclude = 0; 5537c478bd9Sstevel@tonic-gate Dyp->internal = 0; 5547c478bd9Sstevel@tonic-gate Dyp->Dp = NULL; 5557c478bd9Sstevel@tonic-gate 5567c478bd9Sstevel@tonic-gate /* 5577c478bd9Sstevel@tonic-gate * Find the beginning of the filename patterns 5587c478bd9Sstevel@tonic-gate * and null-terminate the library name patterns. 5597c478bd9Sstevel@tonic-gate */ 5607c478bd9Sstevel@tonic-gate if ((fpat = strchr(arg, ':')) != NULL) 5617c478bd9Sstevel@tonic-gate *fpat++ = '\0'; 5627c478bd9Sstevel@tonic-gate 5637c478bd9Sstevel@tonic-gate /* 5647c478bd9Sstevel@tonic-gate * Library name patterns. 5657c478bd9Sstevel@tonic-gate */ 5667c478bd9Sstevel@tonic-gate pat = strtok_r(arg, sepr, &lasts); 5677c478bd9Sstevel@tonic-gate 5687c478bd9Sstevel@tonic-gate /* '!' introduces an exclusion list */ 5697c478bd9Sstevel@tonic-gate if (pat != NULL && *pat == '!') { 5707c478bd9Sstevel@tonic-gate Dyp->exclude_lib = 1; 5717c478bd9Sstevel@tonic-gate pat += strspn(pat, "!"); 5727c478bd9Sstevel@tonic-gate if (*pat == '\0') 5737c478bd9Sstevel@tonic-gate pat = strtok_r(NULL, sepr, &lasts); 5747c478bd9Sstevel@tonic-gate /* force exclusion of all functions as well */ 5757c478bd9Sstevel@tonic-gate Dyp->exclude = 1; 5767c478bd9Sstevel@tonic-gate Dyp->internal = 1; 5777c478bd9Sstevel@tonic-gate fpat = NULL; 5787c478bd9Sstevel@tonic-gate } 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate if (pat == NULL) { 5817c478bd9Sstevel@tonic-gate /* empty list means all libraries */ 5827c478bd9Sstevel@tonic-gate Dyp->libpat = my_malloc(sizeof (char *), NULL); 5837c478bd9Sstevel@tonic-gate Dyp->libpat[0] = star; 5847c478bd9Sstevel@tonic-gate Dyp->nlibpat = 1; 5857c478bd9Sstevel@tonic-gate } else { 5867c478bd9Sstevel@tonic-gate /* 5877c478bd9Sstevel@tonic-gate * We are now at the library list. 5887c478bd9Sstevel@tonic-gate * Generate the list and count the library name patterns. 5897c478bd9Sstevel@tonic-gate */ 5907c478bd9Sstevel@tonic-gate maxpat = 1; 5917c478bd9Sstevel@tonic-gate Dyp->libpat = my_malloc(maxpat * sizeof (char *), NULL); 5927c478bd9Sstevel@tonic-gate Dyp->nlibpat = 0; 5937c478bd9Sstevel@tonic-gate Dyp->libpat[Dyp->nlibpat++] = pat; 5947c478bd9Sstevel@tonic-gate while ((pat = strtok_r(NULL, sepr, &lasts)) != NULL) { 5957c478bd9Sstevel@tonic-gate if (Dyp->nlibpat == maxpat) { 5967c478bd9Sstevel@tonic-gate maxpat *= 2; 5977c478bd9Sstevel@tonic-gate Dyp->libpat = my_realloc(Dyp->libpat, 598*a574db85Sraf maxpat * sizeof (char *), NULL); 5997c478bd9Sstevel@tonic-gate } 6007c478bd9Sstevel@tonic-gate Dyp->libpat[Dyp->nlibpat++] = pat; 6017c478bd9Sstevel@tonic-gate } 6027c478bd9Sstevel@tonic-gate } 6037c478bd9Sstevel@tonic-gate 6047c478bd9Sstevel@tonic-gate /* 6057c478bd9Sstevel@tonic-gate * Function name patterns. 6067c478bd9Sstevel@tonic-gate */ 6077c478bd9Sstevel@tonic-gate if (fpat == NULL) 6087c478bd9Sstevel@tonic-gate pat = NULL; 6097c478bd9Sstevel@tonic-gate else { 6107c478bd9Sstevel@tonic-gate /* 6117c478bd9Sstevel@tonic-gate * We have already seen a ':'. Look for another. 6127c478bd9Sstevel@tonic-gate * Double ':' means trace internal calls. 6137c478bd9Sstevel@tonic-gate */ 6147c478bd9Sstevel@tonic-gate fpat += strspn(fpat, white); 6157c478bd9Sstevel@tonic-gate if (*fpat == ':') { 6167c478bd9Sstevel@tonic-gate Dyp->internal = 1; 6177c478bd9Sstevel@tonic-gate *fpat++ = '\0'; 6187c478bd9Sstevel@tonic-gate } 6197c478bd9Sstevel@tonic-gate pat = strtok_r(fpat, csepr, &lasts); 6207c478bd9Sstevel@tonic-gate } 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate /* '!' introduces an exclusion list */ 6237c478bd9Sstevel@tonic-gate if (pat != NULL && *pat == '!') { 6247c478bd9Sstevel@tonic-gate Dyp->exclude = 1; 6257c478bd9Sstevel@tonic-gate Dyp->internal = 1; 6267c478bd9Sstevel@tonic-gate pat += strspn(pat, "!"); 6277c478bd9Sstevel@tonic-gate if (*pat == '\0') 6287c478bd9Sstevel@tonic-gate pat = strtok_r(NULL, sepr, &lasts); 6297c478bd9Sstevel@tonic-gate } 6307c478bd9Sstevel@tonic-gate 6317c478bd9Sstevel@tonic-gate if (pat == NULL) { 6327c478bd9Sstevel@tonic-gate /* empty function list means exclude all functions */ 6337c478bd9Sstevel@tonic-gate Dyp->sympat = my_malloc(sizeof (char *), NULL); 6347c478bd9Sstevel@tonic-gate Dyp->sympat[0] = star; 6357c478bd9Sstevel@tonic-gate Dyp->nsympat = 1; 6367c478bd9Sstevel@tonic-gate } else { 6377c478bd9Sstevel@tonic-gate /* 6387c478bd9Sstevel@tonic-gate * We are now at the function list. 6397c478bd9Sstevel@tonic-gate * Generate the list and count the symbol name patterns. 6407c478bd9Sstevel@tonic-gate */ 6417c478bd9Sstevel@tonic-gate maxpat = 1; 6427c478bd9Sstevel@tonic-gate Dyp->sympat = my_malloc(maxpat * sizeof (char *), NULL); 6437c478bd9Sstevel@tonic-gate Dyp->nsympat = 0; 6447c478bd9Sstevel@tonic-gate Dyp->sympat[Dyp->nsympat++] = pat; 6457c478bd9Sstevel@tonic-gate while ((pat = strtok_r(NULL, sepr, &lasts)) != NULL) { 6467c478bd9Sstevel@tonic-gate if (Dyp->nsympat == maxpat) { 6477c478bd9Sstevel@tonic-gate maxpat *= 2; 6487c478bd9Sstevel@tonic-gate Dyp->sympat = my_realloc(Dyp->sympat, 649*a574db85Sraf maxpat * sizeof (char *), NULL); 6507c478bd9Sstevel@tonic-gate } 6517c478bd9Sstevel@tonic-gate Dyp->sympat[Dyp->nsympat++] = pat; 6527c478bd9Sstevel@tonic-gate } 6537c478bd9Sstevel@tonic-gate } 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate return (0); 6567c478bd9Sstevel@tonic-gate } 657