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
5*004388ebScasper * Common Development and Distribution License (the "License").
6*004388ebScasper * 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 */
217c478bd9Sstevel@tonic-gate /*
22*004388ebScasper * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
277c478bd9Sstevel@tonic-gate
287c478bd9Sstevel@tonic-gate #include <stdio.h>
29*004388ebScasper #include <stdio_ext.h>
307c478bd9Sstevel@tonic-gate #include <stdlib.h>
317c478bd9Sstevel@tonic-gate #include <unistd.h>
327c478bd9Sstevel@tonic-gate #include <ctype.h>
337c478bd9Sstevel@tonic-gate #include <fcntl.h>
347c478bd9Sstevel@tonic-gate #include <string.h>
357c478bd9Sstevel@tonic-gate #include <signal.h>
367c478bd9Sstevel@tonic-gate #include <stddef.h>
377c478bd9Sstevel@tonic-gate #include <sys/types.h>
387c478bd9Sstevel@tonic-gate #include <sys/stat.h>
397c478bd9Sstevel@tonic-gate #include <libproc.h>
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate /* evil knowledge of libc internals */
427c478bd9Sstevel@tonic-gate #include "../../../lib/libc/inc/thr_uberdata.h"
437c478bd9Sstevel@tonic-gate
447c478bd9Sstevel@tonic-gate #define MAX_SYMNAMLEN 1024 /* Recommended max symbol name length */
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate static char *sigflags(int, int);
477c478bd9Sstevel@tonic-gate static int look(char *);
487c478bd9Sstevel@tonic-gate static void perr(char *);
497c478bd9Sstevel@tonic-gate static int usage(void);
507c478bd9Sstevel@tonic-gate static uintptr_t deinterpose(int, void *, psinfo_t *, struct sigaction *);
517c478bd9Sstevel@tonic-gate
527c478bd9Sstevel@tonic-gate static char *command;
537c478bd9Sstevel@tonic-gate static char *procname;
547c478bd9Sstevel@tonic-gate static int all_flag = 0;
557c478bd9Sstevel@tonic-gate static int lookuphandlers_flag = 1;
567c478bd9Sstevel@tonic-gate
577c478bd9Sstevel@tonic-gate int
main(int argc,char ** argv)587c478bd9Sstevel@tonic-gate main(int argc, char **argv)
597c478bd9Sstevel@tonic-gate {
607c478bd9Sstevel@tonic-gate int rc = 0;
617c478bd9Sstevel@tonic-gate int c;
627c478bd9Sstevel@tonic-gate struct rlimit rlim;
637c478bd9Sstevel@tonic-gate
647c478bd9Sstevel@tonic-gate if ((command = strrchr(argv[0], '/')) != NULL)
657c478bd9Sstevel@tonic-gate command++;
667c478bd9Sstevel@tonic-gate else
677c478bd9Sstevel@tonic-gate command = argv[0];
687c478bd9Sstevel@tonic-gate
697c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "an")) != EOF) {
707c478bd9Sstevel@tonic-gate switch (c) {
717c478bd9Sstevel@tonic-gate case 'a':
727c478bd9Sstevel@tonic-gate all_flag = 1;
737c478bd9Sstevel@tonic-gate break;
747c478bd9Sstevel@tonic-gate case 'n':
757c478bd9Sstevel@tonic-gate lookuphandlers_flag = 0;
767c478bd9Sstevel@tonic-gate break;
777c478bd9Sstevel@tonic-gate default:
787c478bd9Sstevel@tonic-gate return (usage());
797c478bd9Sstevel@tonic-gate }
807c478bd9Sstevel@tonic-gate }
817c478bd9Sstevel@tonic-gate
827c478bd9Sstevel@tonic-gate if (argc - optind < 1) {
837c478bd9Sstevel@tonic-gate return (usage());
847c478bd9Sstevel@tonic-gate }
857c478bd9Sstevel@tonic-gate
867c478bd9Sstevel@tonic-gate /*
877c478bd9Sstevel@tonic-gate * Make sure we'll have enough file descriptors to handle a target
887c478bd9Sstevel@tonic-gate * that has many many mappings.
897c478bd9Sstevel@tonic-gate */
907c478bd9Sstevel@tonic-gate if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
917c478bd9Sstevel@tonic-gate rlim.rlim_cur = rlim.rlim_max;
927c478bd9Sstevel@tonic-gate (void) setrlimit(RLIMIT_NOFILE, &rlim);
93*004388ebScasper (void) enable_extended_FILE_stdio(-1, -1);
947c478bd9Sstevel@tonic-gate }
957c478bd9Sstevel@tonic-gate
967c478bd9Sstevel@tonic-gate for (; optind != argc; optind++) {
977c478bd9Sstevel@tonic-gate rc += look(argv[optind]);
987c478bd9Sstevel@tonic-gate }
997c478bd9Sstevel@tonic-gate
1007c478bd9Sstevel@tonic-gate return (rc);
1017c478bd9Sstevel@tonic-gate }
1027c478bd9Sstevel@tonic-gate
1037c478bd9Sstevel@tonic-gate static int
usage(void)1047c478bd9Sstevel@tonic-gate usage(void)
1057c478bd9Sstevel@tonic-gate {
1067c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "usage:\t%s [-n] pid ...\n", command);
1077c478bd9Sstevel@tonic-gate (void) fprintf(stderr, " (report process signal actions)\n");
1087c478bd9Sstevel@tonic-gate
1097c478bd9Sstevel@tonic-gate return (2);
1107c478bd9Sstevel@tonic-gate }
1117c478bd9Sstevel@tonic-gate
1127c478bd9Sstevel@tonic-gate static uintptr_t
uberdata_addr(struct ps_prochandle * Pr,char dmodel)1137c478bd9Sstevel@tonic-gate uberdata_addr(struct ps_prochandle *Pr, char dmodel)
1147c478bd9Sstevel@tonic-gate {
1157c478bd9Sstevel@tonic-gate GElf_Sym sym;
1167c478bd9Sstevel@tonic-gate
1177c478bd9Sstevel@tonic-gate if (Plookup_by_name(Pr, "libc.so", "_tdb_bootstrap", &sym) < 0)
1187c478bd9Sstevel@tonic-gate return (NULL);
1197c478bd9Sstevel@tonic-gate #ifdef _LP64
1207c478bd9Sstevel@tonic-gate if (dmodel != PR_MODEL_NATIVE) {
1217c478bd9Sstevel@tonic-gate caddr32_t uaddr;
1227c478bd9Sstevel@tonic-gate caddr32_t addr;
1237c478bd9Sstevel@tonic-gate
1247c478bd9Sstevel@tonic-gate if (Pread(Pr, &addr, sizeof (addr), sym.st_value)
1257c478bd9Sstevel@tonic-gate == sizeof (addr) &&
1267c478bd9Sstevel@tonic-gate addr != 0 &&
1277c478bd9Sstevel@tonic-gate Pread(Pr, &uaddr, sizeof (uaddr), (uintptr_t)addr)
1287c478bd9Sstevel@tonic-gate == sizeof (uaddr) &&
1297c478bd9Sstevel@tonic-gate uaddr != 0)
1307c478bd9Sstevel@tonic-gate return ((uintptr_t)uaddr);
1317c478bd9Sstevel@tonic-gate }
1327c478bd9Sstevel@tonic-gate #endif
1337c478bd9Sstevel@tonic-gate if (dmodel == PR_MODEL_NATIVE) {
1347c478bd9Sstevel@tonic-gate uintptr_t uaddr;
1357c478bd9Sstevel@tonic-gate uintptr_t addr;
1367c478bd9Sstevel@tonic-gate
1377c478bd9Sstevel@tonic-gate if (Pread(Pr, &addr, sizeof (addr), sym.st_value)
1387c478bd9Sstevel@tonic-gate == sizeof (addr) &&
1397c478bd9Sstevel@tonic-gate addr != 0 &&
1407c478bd9Sstevel@tonic-gate Pread(Pr, &uaddr, sizeof (uaddr), addr)
1417c478bd9Sstevel@tonic-gate == sizeof (uaddr) &&
1427c478bd9Sstevel@tonic-gate uaddr != 0)
1437c478bd9Sstevel@tonic-gate return (uaddr);
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate if (Plookup_by_name(Pr, "libc.so", "_uberdata", &sym) < 0)
1467c478bd9Sstevel@tonic-gate return (0);
1477c478bd9Sstevel@tonic-gate return (sym.st_value);
1487c478bd9Sstevel@tonic-gate }
1497c478bd9Sstevel@tonic-gate
1507c478bd9Sstevel@tonic-gate /*
1517c478bd9Sstevel@tonic-gate * Iterator function used to generate the process sigmask
1527c478bd9Sstevel@tonic-gate * from the individual lwp sigmasks.
1537c478bd9Sstevel@tonic-gate */
1547c478bd9Sstevel@tonic-gate static int
lwp_iter(void * cd,const lwpstatus_t * lwpstatus)1557c478bd9Sstevel@tonic-gate lwp_iter(void *cd, const lwpstatus_t *lwpstatus)
1567c478bd9Sstevel@tonic-gate {
1577c478bd9Sstevel@tonic-gate sigset_t *ssp = cd;
1587c478bd9Sstevel@tonic-gate
1597c478bd9Sstevel@tonic-gate ssp->__sigbits[0] &= lwpstatus->pr_lwphold.__sigbits[0];
1607c478bd9Sstevel@tonic-gate ssp->__sigbits[1] &= lwpstatus->pr_lwphold.__sigbits[1];
1617c478bd9Sstevel@tonic-gate ssp->__sigbits[2] &= lwpstatus->pr_lwphold.__sigbits[2];
1627c478bd9Sstevel@tonic-gate ssp->__sigbits[3] &= lwpstatus->pr_lwphold.__sigbits[3];
1637c478bd9Sstevel@tonic-gate
1647c478bd9Sstevel@tonic-gate /*
1657c478bd9Sstevel@tonic-gate * Return non-zero to terminate the iteration
1667c478bd9Sstevel@tonic-gate * if the sigmask has become all zeros.
1677c478bd9Sstevel@tonic-gate */
1687c478bd9Sstevel@tonic-gate return ((ssp->__sigbits[0] | ssp->__sigbits[1] |
1697c478bd9Sstevel@tonic-gate ssp->__sigbits[2] | ssp->__sigbits[3]) == 0);
1707c478bd9Sstevel@tonic-gate }
1717c478bd9Sstevel@tonic-gate
1727c478bd9Sstevel@tonic-gate static int
look(char * arg)1737c478bd9Sstevel@tonic-gate look(char *arg)
1747c478bd9Sstevel@tonic-gate {
1757c478bd9Sstevel@tonic-gate char pathname[100];
1767c478bd9Sstevel@tonic-gate struct stat statb;
1777c478bd9Sstevel@tonic-gate int fd = -1;
1787c478bd9Sstevel@tonic-gate int sig, gcode;
1797c478bd9Sstevel@tonic-gate sigset_t holdmask;
1807c478bd9Sstevel@tonic-gate int maxsig;
1817c478bd9Sstevel@tonic-gate struct sigaction *action = NULL;
1827c478bd9Sstevel@tonic-gate psinfo_t psinfo;
1837c478bd9Sstevel@tonic-gate const psinfo_t *psinfop;
1847c478bd9Sstevel@tonic-gate struct ps_prochandle *Pr = NULL;
1857c478bd9Sstevel@tonic-gate uintptr_t uberaddr;
1867c478bd9Sstevel@tonic-gate uintptr_t aharraddr;
1877c478bd9Sstevel@tonic-gate uintptr_t intfnaddr;
1887c478bd9Sstevel@tonic-gate size_t aharrlen;
1897c478bd9Sstevel@tonic-gate void *aharr = NULL;
1907c478bd9Sstevel@tonic-gate int error = 1;
1917c478bd9Sstevel@tonic-gate
1927c478bd9Sstevel@tonic-gate procname = arg; /* for perr() */
1937c478bd9Sstevel@tonic-gate if ((Pr = proc_arg_grab(arg, PR_ARG_PIDS, PGRAB_RDONLY|PGRAB_FORCE,
1947c478bd9Sstevel@tonic-gate &gcode)) == NULL || (psinfop = Ppsinfo(Pr)) == NULL) {
1957c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: cannot examine %s: %s\n",
1967c478bd9Sstevel@tonic-gate command, arg, Pgrab_error(gcode));
1977c478bd9Sstevel@tonic-gate goto look_error;
1987c478bd9Sstevel@tonic-gate }
1997c478bd9Sstevel@tonic-gate (void) memcpy(&psinfo, psinfop, sizeof (psinfo_t));
2007c478bd9Sstevel@tonic-gate proc_unctrl_psinfo(&psinfo);
2017c478bd9Sstevel@tonic-gate
2027c478bd9Sstevel@tonic-gate (void) sprintf(pathname, "/proc/%d/sigact", (int)psinfo.pr_pid);
2037c478bd9Sstevel@tonic-gate if ((fd = open(pathname, O_RDONLY)) < 0) {
2047c478bd9Sstevel@tonic-gate perr("open sigact");
2057c478bd9Sstevel@tonic-gate goto look_error;
2067c478bd9Sstevel@tonic-gate }
2077c478bd9Sstevel@tonic-gate
2087c478bd9Sstevel@tonic-gate if (fstat(fd, &statb) != 0) {
2097c478bd9Sstevel@tonic-gate perr("fstat sigact");
2107c478bd9Sstevel@tonic-gate goto look_error;
2117c478bd9Sstevel@tonic-gate }
2127c478bd9Sstevel@tonic-gate maxsig = statb.st_size / sizeof (struct sigaction);
2137c478bd9Sstevel@tonic-gate action = malloc(maxsig * sizeof (struct sigaction));
2147c478bd9Sstevel@tonic-gate if (action == NULL) {
2157c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
2167c478bd9Sstevel@tonic-gate "%s: cannot malloc() space for %d sigaction structures\n",
2177c478bd9Sstevel@tonic-gate command, maxsig);
2187c478bd9Sstevel@tonic-gate goto look_error;
2197c478bd9Sstevel@tonic-gate }
2207c478bd9Sstevel@tonic-gate if (read(fd, (char *)action, maxsig * sizeof (struct sigaction)) !=
2217c478bd9Sstevel@tonic-gate maxsig * sizeof (struct sigaction)) {
2227c478bd9Sstevel@tonic-gate perr("read sigact");
2237c478bd9Sstevel@tonic-gate goto look_error;
2247c478bd9Sstevel@tonic-gate }
2257c478bd9Sstevel@tonic-gate (void) close(fd);
2267c478bd9Sstevel@tonic-gate fd = -1;
2277c478bd9Sstevel@tonic-gate
2287c478bd9Sstevel@tonic-gate (void) printf("%d:\t%.70s\n", (int)psinfo.pr_pid, psinfo.pr_psargs);
2297c478bd9Sstevel@tonic-gate
2307c478bd9Sstevel@tonic-gate (void) sigfillset(&holdmask);
2317c478bd9Sstevel@tonic-gate (void) Plwp_iter(Pr, lwp_iter, &holdmask);
2327c478bd9Sstevel@tonic-gate
2337c478bd9Sstevel@tonic-gate if ((uberaddr = uberdata_addr(Pr, psinfo.pr_dmodel)) == 0) {
2347c478bd9Sstevel@tonic-gate aharraddr = 0;
2357c478bd9Sstevel@tonic-gate aharrlen = 0;
2367c478bd9Sstevel@tonic-gate intfnaddr = 0;
2377c478bd9Sstevel@tonic-gate } else {
2387c478bd9Sstevel@tonic-gate #ifdef _LP64
2397c478bd9Sstevel@tonic-gate if (psinfo.pr_dmodel != PR_MODEL_NATIVE) {
2407c478bd9Sstevel@tonic-gate caddr32_t addr;
2417c478bd9Sstevel@tonic-gate aharraddr = uberaddr +
2427c478bd9Sstevel@tonic-gate offsetof(uberdata32_t, siguaction);
2437c478bd9Sstevel@tonic-gate aharrlen = sizeof (siguaction32_t) * NSIG;
2447c478bd9Sstevel@tonic-gate (void) Pread(Pr, &addr, sizeof (addr),
2457c478bd9Sstevel@tonic-gate uberaddr + offsetof(uberdata32_t, sigacthandler));
2467c478bd9Sstevel@tonic-gate intfnaddr = (uintptr_t)addr;
2477c478bd9Sstevel@tonic-gate } else
2487c478bd9Sstevel@tonic-gate #endif
2497c478bd9Sstevel@tonic-gate {
2507c478bd9Sstevel@tonic-gate aharraddr = uberaddr +
2517c478bd9Sstevel@tonic-gate offsetof(uberdata_t, siguaction);
2527c478bd9Sstevel@tonic-gate aharrlen = sizeof (siguaction_t) * NSIG;
2537c478bd9Sstevel@tonic-gate (void) Pread(Pr, &intfnaddr, sizeof (intfnaddr),
2547c478bd9Sstevel@tonic-gate uberaddr + offsetof(uberdata_t, sigacthandler));
2557c478bd9Sstevel@tonic-gate }
2567c478bd9Sstevel@tonic-gate }
2577c478bd9Sstevel@tonic-gate
2587c478bd9Sstevel@tonic-gate if (aharraddr) {
2597c478bd9Sstevel@tonic-gate aharr = malloc(aharrlen);
2607c478bd9Sstevel@tonic-gate if (aharr == NULL) {
2617c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
2627c478bd9Sstevel@tonic-gate "%s: cannot malloc() space for actual handler array\n",
2637c478bd9Sstevel@tonic-gate command);
2647c478bd9Sstevel@tonic-gate goto look_error;
2657c478bd9Sstevel@tonic-gate }
2667c478bd9Sstevel@tonic-gate
2677c478bd9Sstevel@tonic-gate if (Pread(Pr, aharr, aharrlen, aharraddr) != aharrlen) {
2687c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
2697c478bd9Sstevel@tonic-gate "%s: signal handler data at %p cannot be read.\n",
2707c478bd9Sstevel@tonic-gate command, (void *)aharraddr);
2717c478bd9Sstevel@tonic-gate free(aharr);
2727c478bd9Sstevel@tonic-gate aharr = NULL;
2737c478bd9Sstevel@tonic-gate }
2747c478bd9Sstevel@tonic-gate }
2757c478bd9Sstevel@tonic-gate
2767c478bd9Sstevel@tonic-gate for (sig = 1; sig <= maxsig; sig++) {
2777c478bd9Sstevel@tonic-gate struct sigaction *sp = &action[sig - 1];
2787c478bd9Sstevel@tonic-gate int caught = 0;
2797c478bd9Sstevel@tonic-gate char buf[SIG2STR_MAX];
2807c478bd9Sstevel@tonic-gate char *s;
2817c478bd9Sstevel@tonic-gate
2827c478bd9Sstevel@tonic-gate /* proc_signame() returns "SIG..."; skip the "SIG" part */
2837c478bd9Sstevel@tonic-gate (void) printf("%s\t", proc_signame(sig, buf, sizeof (buf)) + 3);
2847c478bd9Sstevel@tonic-gate
2857c478bd9Sstevel@tonic-gate if (prismember(&holdmask, sig))
2867c478bd9Sstevel@tonic-gate (void) printf("blocked,");
2877c478bd9Sstevel@tonic-gate
2887c478bd9Sstevel@tonic-gate if (sp->sa_handler == SIG_DFL)
2897c478bd9Sstevel@tonic-gate (void) printf("default");
2907c478bd9Sstevel@tonic-gate else if (sp->sa_handler == SIG_IGN)
2917c478bd9Sstevel@tonic-gate (void) printf("ignored");
2927c478bd9Sstevel@tonic-gate else
2937c478bd9Sstevel@tonic-gate caught = 1;
2947c478bd9Sstevel@tonic-gate
2957c478bd9Sstevel@tonic-gate if (caught || all_flag) {
2967c478bd9Sstevel@tonic-gate uintptr_t haddr;
2977c478bd9Sstevel@tonic-gate GElf_Sym hsym;
2987c478bd9Sstevel@tonic-gate char hname[MAX_SYMNAMLEN];
2997c478bd9Sstevel@tonic-gate char buf[PRSIGBUFSZ];
3007c478bd9Sstevel@tonic-gate
3017c478bd9Sstevel@tonic-gate haddr = (uintptr_t)sp->sa_handler;
3027c478bd9Sstevel@tonic-gate
3037c478bd9Sstevel@tonic-gate if (aharr && intfnaddr && haddr == intfnaddr)
3047c478bd9Sstevel@tonic-gate haddr = deinterpose(sig, aharr, &psinfo, sp);
3057c478bd9Sstevel@tonic-gate
3067c478bd9Sstevel@tonic-gate if (haddr == (uintptr_t)SIG_DFL) {
3077c478bd9Sstevel@tonic-gate if (caught)
3087c478bd9Sstevel@tonic-gate (void) printf("default");
3097c478bd9Sstevel@tonic-gate caught = 0;
3107c478bd9Sstevel@tonic-gate } else if (haddr == (uintptr_t)SIG_IGN) {
3117c478bd9Sstevel@tonic-gate if (caught)
3127c478bd9Sstevel@tonic-gate (void) printf("ignored");
3137c478bd9Sstevel@tonic-gate caught = 0;
3147c478bd9Sstevel@tonic-gate } else {
3157c478bd9Sstevel@tonic-gate if (caught)
3167c478bd9Sstevel@tonic-gate (void) printf("caught");
3177c478bd9Sstevel@tonic-gate }
3187c478bd9Sstevel@tonic-gate
3197c478bd9Sstevel@tonic-gate if (caught || all_flag) {
3207c478bd9Sstevel@tonic-gate if (lookuphandlers_flag && haddr > 1 &&
3217c478bd9Sstevel@tonic-gate Plookup_by_addr(Pr, haddr, hname,
3227c478bd9Sstevel@tonic-gate sizeof (hname), &hsym) == 0)
3237c478bd9Sstevel@tonic-gate (void) printf("\t%-8s", hname);
3247c478bd9Sstevel@tonic-gate else
3257c478bd9Sstevel@tonic-gate (void) printf("\t0x%-8lx",
3267c478bd9Sstevel@tonic-gate (ulong_t)haddr);
3277c478bd9Sstevel@tonic-gate
3287c478bd9Sstevel@tonic-gate s = sigflags(sig, sp->sa_flags);
3297c478bd9Sstevel@tonic-gate (void) printf("%s", (*s != '\0')? s : "\t0");
3307c478bd9Sstevel@tonic-gate (void) proc_sigset2str(&sp->sa_mask, ",", 1,
3317c478bd9Sstevel@tonic-gate buf, sizeof (buf));
3327c478bd9Sstevel@tonic-gate if (buf[0] != '\0')
3337c478bd9Sstevel@tonic-gate (void) printf("\t%s", buf);
3347c478bd9Sstevel@tonic-gate }
3357c478bd9Sstevel@tonic-gate } else if (sig == SIGCLD) {
3367c478bd9Sstevel@tonic-gate s = sigflags(sig,
3377c478bd9Sstevel@tonic-gate sp->sa_flags & (SA_NOCLDWAIT|SA_NOCLDSTOP));
3387c478bd9Sstevel@tonic-gate if (*s != '\0')
3397c478bd9Sstevel@tonic-gate (void) printf("\t\t%s", s);
3407c478bd9Sstevel@tonic-gate }
3417c478bd9Sstevel@tonic-gate (void) printf("\n");
3427c478bd9Sstevel@tonic-gate }
3437c478bd9Sstevel@tonic-gate
3447c478bd9Sstevel@tonic-gate error = 0;
3457c478bd9Sstevel@tonic-gate
3467c478bd9Sstevel@tonic-gate look_error:
3477c478bd9Sstevel@tonic-gate if (fd >= 0)
3487c478bd9Sstevel@tonic-gate (void) close(fd);
3497c478bd9Sstevel@tonic-gate if (aharr)
3507c478bd9Sstevel@tonic-gate free(aharr);
3517c478bd9Sstevel@tonic-gate if (action)
3527c478bd9Sstevel@tonic-gate free(action);
3537c478bd9Sstevel@tonic-gate if (Pr)
3547c478bd9Sstevel@tonic-gate Prelease(Pr, 0);
3557c478bd9Sstevel@tonic-gate return (error);
3567c478bd9Sstevel@tonic-gate }
3577c478bd9Sstevel@tonic-gate
3587c478bd9Sstevel@tonic-gate static void
perr(char * s)3597c478bd9Sstevel@tonic-gate perr(char *s)
3607c478bd9Sstevel@tonic-gate {
3617c478bd9Sstevel@tonic-gate if (s)
3627c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: ", procname);
3637c478bd9Sstevel@tonic-gate else
3647c478bd9Sstevel@tonic-gate s = procname;
3657c478bd9Sstevel@tonic-gate perror(s);
3667c478bd9Sstevel@tonic-gate }
3677c478bd9Sstevel@tonic-gate
3687c478bd9Sstevel@tonic-gate static char *
sigflags(int sig,int flags)3697c478bd9Sstevel@tonic-gate sigflags(int sig, int flags)
3707c478bd9Sstevel@tonic-gate {
3717c478bd9Sstevel@tonic-gate static char code_buf[100];
3727c478bd9Sstevel@tonic-gate char *str = code_buf;
3737c478bd9Sstevel@tonic-gate int flagmask =
3747c478bd9Sstevel@tonic-gate (SA_ONSTACK|SA_RESETHAND|SA_RESTART|SA_SIGINFO|SA_NODEFER);
3757c478bd9Sstevel@tonic-gate
3767c478bd9Sstevel@tonic-gate if (sig == SIGCLD)
3777c478bd9Sstevel@tonic-gate flagmask |= (SA_NOCLDSTOP|SA_NOCLDWAIT);
3787c478bd9Sstevel@tonic-gate
3797c478bd9Sstevel@tonic-gate *str = '\0';
3807c478bd9Sstevel@tonic-gate if (flags & ~flagmask)
3817c478bd9Sstevel@tonic-gate (void) sprintf(str, ",0x%x,", flags & ~flagmask);
3827c478bd9Sstevel@tonic-gate else if (flags == 0)
3837c478bd9Sstevel@tonic-gate return (str);
3847c478bd9Sstevel@tonic-gate
3857c478bd9Sstevel@tonic-gate if (flags & SA_RESTART)
3867c478bd9Sstevel@tonic-gate (void) strcat(str, ",RESTART");
3877c478bd9Sstevel@tonic-gate if (flags & SA_RESETHAND)
3887c478bd9Sstevel@tonic-gate (void) strcat(str, ",RESETHAND");
3897c478bd9Sstevel@tonic-gate if (flags & SA_ONSTACK)
3907c478bd9Sstevel@tonic-gate (void) strcat(str, ",ONSTACK");
3917c478bd9Sstevel@tonic-gate if (flags & SA_SIGINFO)
3927c478bd9Sstevel@tonic-gate (void) strcat(str, ",SIGINFO");
3937c478bd9Sstevel@tonic-gate if (flags & SA_NODEFER)
3947c478bd9Sstevel@tonic-gate (void) strcat(str, ",NODEFER");
3957c478bd9Sstevel@tonic-gate
3967c478bd9Sstevel@tonic-gate if (sig == SIGCLD) {
3977c478bd9Sstevel@tonic-gate if (flags & SA_NOCLDWAIT)
3987c478bd9Sstevel@tonic-gate (void) strcat(str, ",NOCLDWAIT");
3997c478bd9Sstevel@tonic-gate if (flags & SA_NOCLDSTOP)
4007c478bd9Sstevel@tonic-gate (void) strcat(str, ",NOCLDSTOP");
4017c478bd9Sstevel@tonic-gate }
4027c478bd9Sstevel@tonic-gate
4037c478bd9Sstevel@tonic-gate *str = '\t';
4047c478bd9Sstevel@tonic-gate
4057c478bd9Sstevel@tonic-gate return (str);
4067c478bd9Sstevel@tonic-gate }
4077c478bd9Sstevel@tonic-gate
4087c478bd9Sstevel@tonic-gate /*ARGSUSED2*/
4097c478bd9Sstevel@tonic-gate static uintptr_t
deinterpose(int sig,void * aharr,psinfo_t * psinfo,struct sigaction * sp)4107c478bd9Sstevel@tonic-gate deinterpose(int sig, void *aharr, psinfo_t *psinfo, struct sigaction *sp)
4117c478bd9Sstevel@tonic-gate {
4127c478bd9Sstevel@tonic-gate if (sp->sa_handler == SIG_DFL || sp->sa_handler == SIG_IGN)
4137c478bd9Sstevel@tonic-gate return ((uintptr_t)sp->sa_handler);
4147c478bd9Sstevel@tonic-gate #ifdef _LP64
4157c478bd9Sstevel@tonic-gate if (psinfo->pr_dmodel != PR_MODEL_NATIVE) {
4167c478bd9Sstevel@tonic-gate struct sigaction32 *sa32 = (struct sigaction32 *)
4177c478bd9Sstevel@tonic-gate ((uintptr_t)aharr + sig * sizeof (siguaction32_t) +
4187c478bd9Sstevel@tonic-gate offsetof(siguaction32_t, sig_uaction));
4197c478bd9Sstevel@tonic-gate
4207c478bd9Sstevel@tonic-gate sp->sa_flags = sa32->sa_flags;
4217c478bd9Sstevel@tonic-gate sp->sa_handler = (void (*)())(uintptr_t)sa32->sa_handler;
4227c478bd9Sstevel@tonic-gate (void) memcpy(&sp->sa_mask, &sa32->sa_mask,
4237c478bd9Sstevel@tonic-gate sizeof (sp->sa_mask));
4247c478bd9Sstevel@tonic-gate } else
4257c478bd9Sstevel@tonic-gate #endif
4267c478bd9Sstevel@tonic-gate {
4277c478bd9Sstevel@tonic-gate struct sigaction *sa = (struct sigaction *)
4287c478bd9Sstevel@tonic-gate ((uintptr_t)aharr + sig * sizeof (siguaction_t) +
4297c478bd9Sstevel@tonic-gate offsetof(siguaction_t, sig_uaction));
4307c478bd9Sstevel@tonic-gate
4317c478bd9Sstevel@tonic-gate sp->sa_flags = sa->sa_flags;
4327c478bd9Sstevel@tonic-gate sp->sa_handler = sa->sa_handler;
4337c478bd9Sstevel@tonic-gate sp->sa_mask = sa->sa_mask;
4347c478bd9Sstevel@tonic-gate }
4357c478bd9Sstevel@tonic-gate return ((uintptr_t)sp->sa_handler);
4367c478bd9Sstevel@tonic-gate }
437