2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A#include <stdio.h>
2N/A#include <string.h>
2N/A#include <signal.h>
2N/A#include <errno.h>
2N/A#include "libproc.h"
2N/A
2N/Astatic const char *
2N/Arawfltname(int flt)
2N/A{
2N/A const char *name;
2N/A
2N/A switch (flt) {
2N/A case FLTILL: name = "FLTILL"; break;
2N/A case FLTPRIV: name = "FLTPRIV"; break;
2N/A case FLTBPT: name = "FLTBPT"; break;
2N/A case FLTTRACE: name = "FLTTRACE"; break;
2N/A case FLTACCESS: name = "FLTACCESS"; break;
2N/A case FLTBOUNDS: name = "FLTBOUNDS"; break;
2N/A case FLTIOVF: name = "FLTIOVF"; break;
2N/A case FLTIZDIV: name = "FLTIZDIV"; break;
2N/A case FLTFPE: name = "FLTFPE"; break;
2N/A case FLTSTACK: name = "FLTSTACK"; break;
2N/A case FLTPAGE: name = "FLTPAGE"; break;
2N/A case FLTWATCH: name = "FLTWATCH"; break;
2N/A case FLTCPCOVF: name = "FLTCPCOVF"; break;
2N/A default: name = NULL; break;
2N/A }
2N/A
2N/A return (name);
2N/A}
2N/A
2N/A/*
2N/A * Return the name of a fault.
2N/A * Manufacture a name for unknown fault.
2N/A */
2N/Achar *
2N/Aproc_fltname(int flt, char *buf, size_t bufsz)
2N/A{
2N/A const char *name = rawfltname(flt);
2N/A size_t len;
2N/A
2N/A if (bufsz == 0) /* force a program failure */
2N/A return (NULL);
2N/A
2N/A if (name != NULL) {
2N/A len = strlen(name);
2N/A (void) strncpy(buf, name, bufsz);
2N/A } else {
2N/A len = snprintf(buf, bufsz, "FLT#%d", flt);
2N/A }
2N/A
2N/A if (len >= bufsz) /* ensure null-termination */
2N/A buf[bufsz-1] = '\0';
2N/A
2N/A return (buf);
2N/A}
2N/A
2N/A/*
2N/A * Return the name of a signal.
2N/A * Manufacture a name for unknown signal.
2N/A */
2N/Achar *
2N/Aproc_signame(int sig, char *buf, size_t bufsz)
2N/A{
2N/A char name[SIG2STR_MAX+4];
2N/A size_t len;
2N/A
2N/A if (bufsz == 0) /* force a program failure */
2N/A return (NULL);
2N/A
2N/A /* sig2str() omits the leading "SIG" */
2N/A (void) strcpy(name, "SIG");
2N/A
2N/A if (sig2str(sig, name+3) == 0) {
2N/A len = strlen(name);
2N/A (void) strncpy(buf, name, bufsz);
2N/A } else {
2N/A len = snprintf(buf, bufsz, "SIG#%d", sig);
2N/A }
2N/A
2N/A if (len >= bufsz) /* ensure null-termination */
2N/A buf[bufsz-1] = '\0';
2N/A
2N/A return (buf);
2N/A}
2N/A
2N/Astatic const char *const systable[] = {
2N/A NULL, /* 0 */
2N/A "_exit", /* 1 */
2N/A NULL, /* 2 */
2N/A "read", /* 3 */
2N/A "write", /* 4 */
2N/A NULL, /* 5 */
2N/A "close", /* 6 */
2N/A "linkat", /* 7 */
2N/A NULL, /* 8 */
2N/A NULL, /* 9 */
2N/A NULL, /* 10 */
2N/A "symlinkat", /* 11 */
2N/A "chdir", /* 12 */
2N/A "time", /* 13 */
2N/A NULL, /* 14 */
2N/A NULL, /* 15 */
2N/A NULL, /* 16 */
2N/A "brk", /* 17 */
2N/A NULL, /* 18 */
2N/A "lseek", /* 19 */
2N/A "getpid", /* 20 */
2N/A "mount", /* 21 */
2N/A "readlinkat", /* 22 */
2N/A "setuid", /* 23 */
2N/A "getuid", /* 24 */
2N/A "stime", /* 25 */
2N/A "pcsample", /* 26 */
2N/A "alarm", /* 27 */
2N/A NULL, /* 28 */
2N/A "pause", /* 29 */
2N/A "frealpathat", /* 30 */
2N/A "stty", /* 31 */
2N/A "gtty", /* 32 */
2N/A NULL, /* 33 */
2N/A "nice", /* 34 */
2N/A "statfs", /* 35 */
2N/A "sync", /* 36 */
2N/A "kill", /* 37 */
2N/A "fstatfs", /* 38 */
2N/A "pgrpsys", /* 39 */
2N/A "uucopystr", /* 40 */
2N/A NULL, /* 41 */
2N/A "pipe", /* 42 */
2N/A "times", /* 43 */
2N/A "profil", /* 44 */
2N/A "faccessat", /* 45 */
2N/A "setgid", /* 46 */
2N/A "getgid", /* 47 */
2N/A "mknodat", /* 48 */
2N/A "msgsys", /* 49 */
2N/A "sysi86", /* 50 */
2N/A "acct", /* 51 */
2N/A "shmsys", /* 52 */
2N/A "semsys", /* 53 */
2N/A "ioctl", /* 54 */
2N/A "uadmin", /* 55 */
2N/A "fchownat", /* 56 */
2N/A "utssys", /* 57 */
2N/A "fdsync", /* 58 */
2N/A "execve", /* 59 */
2N/A "umask", /* 60 */
2N/A "chroot", /* 61 */
2N/A "fcntl", /* 62 */
2N/A "ulimit", /* 63 */
2N/A "renameat", /* 64 */
2N/A NULL, /* 65 */
2N/A "fstatat", /* 66 */
2N/A "fstatat64", /* 67 */
2N/A "openat", /* 68 */
2N/A "openat64", /* 69 */
2N/A "tasksys", /* 70 */
2N/A "acctctl", /* 71 */
2N/A "exacctsys", /* 72 */
2N/A "getpagesizes", /* 73 */
2N/A "rctlsys", /* 74 */
2N/A "sidsys", /* 75 */
2N/A "unlinkat", /* 76 */
2N/A "lwp_park", /* 77 */
2N/A "sendfilev", /* 78 */
2N/A NULL, /* 79 */
2N/A NULL, /* 80 */
2N/A "getdents", /* 81 */
2N/A "privsys", /* 82 */
2N/A "ucredsys", /* 83 */
2N/A "sysfs", /* 84 */
2N/A "getmsg", /* 85 */
2N/A "putmsg", /* 86 */
2N/A NULL, /* 87 */
2N/A NULL, /* 88 */
2N/A NULL, /* 89 */
2N/A NULL, /* 90 */
2N/A "setgroups", /* 91 */
2N/A "getgroups", /* 92 */
2N/A NULL, /* 93 */
2N/A NULL, /* 94 */
2N/A "sigprocmask", /* 95 */
2N/A "sigsuspend", /* 96 */
2N/A "sigaltstack", /* 97 */
2N/A "sigaction", /* 98 */
2N/A "sigpending", /* 99 */
2N/A "context", /* 100 */
2N/A "fchmodat", /* 101 */
2N/A "mkdirat", /* 102 */
2N/A "statvfs", /* 103 */
2N/A "fstatvfs", /* 104 */
2N/A "getloadavg", /* 105 */
2N/A "nfssys", /* 106 */
2N/A "waitid", /* 107 */
2N/A "sigsendsys", /* 108 */
2N/A "hrtsys", /* 109 */
2N/A "utimensat", /* 110 */
2N/A "sigresend", /* 111 */
2N/A "priocntlsys", /* 112 */
2N/A "pathconf", /* 113 */
2N/A "mincore", /* 114 */
2N/A "mmap", /* 115 */
2N/A "mprotect", /* 116 */
2N/A "munmap", /* 117 */
2N/A "fpathconf", /* 118 */
2N/A "vfork", /* 119 */
2N/A "fchdir", /* 120 */
2N/A "readv", /* 121 */
2N/A "writev", /* 122 */
2N/A NULL, /* 123 */
2N/A NULL, /* 124 */
2N/A NULL, /* 125 */
2N/A NULL, /* 126 */
2N/A "mmapobj", /* 127 */
2N/A "setrlimit", /* 128 */
2N/A "getrlimit", /* 129 */
2N/A NULL, /* 130 */
2N/A "memcntl", /* 131 */
2N/A "getpmsg", /* 132 */
2N/A "putpmsg", /* 133 */
2N/A NULL, /* 134 */
2N/A "uname", /* 135 */
2N/A "setegid", /* 136 */
2N/A "sysconfig", /* 137 */
2N/A "adjtime", /* 138 */
2N/A "systeminfo", /* 139 */
2N/A "sharefs", /* 140 */
2N/A "seteuid", /* 141 */
2N/A "forksys", /* 142 */
2N/A NULL, /* 143 */
2N/A "sigwait", /* 144 */
2N/A "lwp_info", /* 145 */
2N/A "yield", /* 146 */
2N/A "secsys", /* 147 */
2N/A "lwp_sema_post", /* 148 */
2N/A "lwp_sema_trywait", /* 149 */
2N/A "lwp_detatch", /* 150 */
2N/A "corectl", /* 151 */
2N/A "modctl", /* 152 */
2N/A "fchroot", /* 153 */
2N/A NULL, /* 154 */
2N/A "vhangup", /* 155 */
2N/A "gettimeofday", /* 156 */
2N/A "getitimer", /* 157 */
2N/A "setitimer", /* 158 */
2N/A "lwp_create", /* 159 */
2N/A "lwp_exit", /* 160 */
2N/A "lwp_suspend", /* 161 */
2N/A "lwp_continue", /* 162 */
2N/A "lwp_kill", /* 163 */
2N/A "lwp_self", /* 164 */
2N/A "lwp_sigmask", /* 165 */
2N/A "lwp_private", /* 166 */
2N/A "lwp_wait", /* 167 */
2N/A "lwp_mutex_wakeup", /* 168 */
2N/A NULL, /* 169 */
2N/A "lwp_cond_wait", /* 170 */
2N/A "lwp_cond_signal", /* 171 */
2N/A "lwp_cond_broadcast", /* 172 */
2N/A "pread", /* 173 */
2N/A "pwrite", /* 174 */
2N/A "llseek", /* 175 */
2N/A "inst_sync", /* 176 */
2N/A "brand", /* 177 */
2N/A "kaio", /* 178 */
2N/A "cpc", /* 179 */
2N/A "lgrpsys", /* 180 */
2N/A "rusagesys", /* 181 */
2N/A "portfs", /* 182 */
2N/A "pollsys", /* 183 */
2N/A "labelsys", /* 184 */
2N/A "acl", /* 185 */
2N/A "auditsys", /* 186 */
2N/A "processor_bind", /* 187 */
2N/A "processor_info", /* 188 */
2N/A "p_online", /* 189 */
2N/A "sigqueue", /* 190 */
2N/A "clock_gettime", /* 191 */
2N/A "clock_settime", /* 192 */
2N/A "clock_getres", /* 193 */
2N/A "timer_create", /* 194 */
2N/A "timer_delete", /* 195 */
2N/A "timer_settime", /* 196 */
2N/A "timer_gettime", /* 197 */
2N/A "timer_getoverrun", /* 198 */
2N/A "nanosleep", /* 199 */
2N/A "facl", /* 200 */
2N/A "door", /* 201 */
2N/A "setreuid", /* 202 */
2N/A "setregid", /* 203 */
2N/A "install_utrap", /* 204 */
2N/A "signotify", /* 205 */
2N/A "schedctl", /* 206 */
2N/A "pset", /* 207 */
2N/A "sparc_utrap_install", /* 208 */
2N/A "resolvepath", /* 209 */
2N/A "lwp_mutex_timedlock", /* 210 */
2N/A "lwp_sema_timedwait", /* 211 */
2N/A "lwp_rwlock_sys", /* 212 */
2N/A "getdents64", /* 213 */
2N/A "mmap64", /* 214 */
2N/A NULL, /* 215 */
2N/A NULL, /* 216 */
2N/A NULL, /* 217 */
2N/A "statvfs64", /* 218 */
2N/A "fstatvfs64", /* 219 */
2N/A "setrlimit64", /* 220 */
2N/A "getrlimit64", /* 221 */
2N/A "pread64", /* 222 */
2N/A "pwrite64", /* 223 */
2N/A NULL, /* 224 */
2N/A NULL, /* 225 */
2N/A "rpcmod", /* 226 */
2N/A "zone", /* 227 */
2N/A "autofssys", /* 228 */
2N/A "getcwd", /* 229 */
2N/A "so_socket", /* 230 */
2N/A "so_socketpair", /* 231 */
2N/A "bind", /* 232 */
2N/A "listen", /* 233 */
2N/A "accept", /* 234 */
2N/A "connect", /* 235 */
2N/A "shutdown", /* 236 */
2N/A "recv", /* 237 */
2N/A "recvfrom", /* 238 */
2N/A "recvmsg", /* 239 */
2N/A "send", /* 240 */
2N/A "sendmsg", /* 241 */
2N/A "sendto", /* 242 */
2N/A "getpeername", /* 243 */
2N/A "getsockname", /* 244 */
2N/A "getsockopt", /* 245 */
2N/A "setsockopt", /* 246 */
2N/A "sockconfig", /* 247 */
2N/A "ntp_gettime", /* 248 */
2N/A "ntp_adjtime", /* 249 */
2N/A "lwp_mutex_unlock", /* 250 */
2N/A "lwp_mutex_trylock", /* 251 */
2N/A "lwp_mutex_register", /* 252 */
2N/A "cladm", /* 253 */
2N/A "uucopy", /* 254 */
2N/A "umount2" /* 255 */
2N/A};
2N/A
2N/A/* SYSEND == max syscall number + 1 */
2N/A#define SYSEND (sizeof (systable) / sizeof (systable[0]))
2N/A
2N/A/*
2N/A * Return the name of a system call.
2N/A * Manufacture a name for unknown system call.
2N/A */
2N/Achar *
2N/Aproc_sysname(int sys, char *buf, size_t bufsz)
2N/A{
2N/A const char *name;
2N/A size_t len;
2N/A
2N/A if (bufsz == 0) /* force a program failure */
2N/A return (NULL);
2N/A
2N/A if (sys >= 0 && sys < SYSEND)
2N/A name = systable[sys];
2N/A else
2N/A name = NULL;
2N/A
2N/A if (name != NULL) {
2N/A len = strlen(name);
2N/A (void) strncpy(buf, name, bufsz);
2N/A } else {
2N/A len = snprintf(buf, bufsz, "SYS#%d", sys);
2N/A }
2N/A
2N/A if (len >= bufsz) /* ensure null-termination */
2N/A buf[bufsz-1] = '\0';
2N/A
2N/A return (buf);
2N/A}
2N/A
2N/A/*
2N/A * Convert a string representation of a fault to the corresponding number.
2N/A */
2N/Aint
2N/Aproc_str2flt(const char *str, int *fltnum)
2N/A{
2N/A char *next;
2N/A int i;
2N/A
2N/A i = strtol(str, &next, 0);
2N/A if (i > 0 && i <= PRMAXFAULT && *next == '\0') {
2N/A *fltnum = i;
2N/A return (0);
2N/A }
2N/A
2N/A for (i = 1; i <= PRMAXFAULT; i++) {
2N/A const char *s = rawfltname(i);
2N/A
2N/A if (s && (strcasecmp(s, str) == 0 ||
2N/A strcasecmp(s + 3, str) == 0)) {
2N/A *fltnum = i;
2N/A return (0);
2N/A }
2N/A }
2N/A
2N/A return (-1);
2N/A}
2N/A
2N/A/*
2N/A * Convert a string representation of a signal to the signal number. This
2N/A * functionality is already available in libc, but the interface doesn't
2N/A * optionally accept a "SIG" prefix. We strip that first, and then call libc.
2N/A */
2N/Aint
2N/Aproc_str2sig(const char *str, int *signum)
2N/A{
2N/A if (strncasecmp(str, "SIG", 3) == 0)
2N/A str += 3; /* skip prefix */
2N/A
2N/A return (str2sig(str, signum));
2N/A}
2N/A
2N/A/*
2N/A * Convert a string representation of a system call to the corresponding number.
2N/A * We do this by performing a simple linear search of the table above.
2N/A */
2N/Aint
2N/Aproc_str2sys(const char *str, int *sysnum)
2N/A{
2N/A char *next;
2N/A int i;
2N/A
2N/A i = strtol(str, &next, 0);
2N/A if (i > 0 && i <= PRMAXSYS && *next == '\0') {
2N/A *sysnum = i;
2N/A return (0);
2N/A }
2N/A
2N/A for (i = 1; i < SYSEND; i++) {
2N/A if (systable[i] != NULL && strcmp(systable[i], str) == 0) {
2N/A *sysnum = i;
2N/A return (0);
2N/A }
2N/A }
2N/A
2N/A return (-1);
2N/A}
2N/A
2N/A/*
2N/A * Convert a fltset_t to a string representation consisting of canonical
2N/A * machine fault names separated by the given delimeter string. If
2N/A * m is non-zero (TRUE), set members are printed. If m is zero (FALSE), set
2N/A * non-members are printed. If the specified buf is too small to hold the
2N/A * complete formatted set, NULL is returned; otherwise buf is returned.
2N/A */
2N/Achar *
2N/Aproc_fltset2str(const fltset_t *set, const char *delim, int m,
2N/A char *buf, size_t len)
2N/A{
2N/A char name[FLT2STR_MAX], *p = buf;
2N/A size_t n;
2N/A int i;
2N/A
2N/A if (buf == NULL || len < 1) {
2N/A errno = EINVAL;
2N/A return (NULL);
2N/A }
2N/A
2N/A buf[0] = '\0'; /* Set first byte to \0 */
2N/A
2N/A for (i = 1; i <= PRMAXFAULT; i++) {
2N/A if ((prismember(set, i) != 0) ^ (m == 0)) {
2N/A (void) proc_fltname(i, name, sizeof (name));
2N/A
2N/A if (buf[0] != '\0')
2N/A n = snprintf(p, len, "%s%s", delim, name);
2N/A else
2N/A n = snprintf(p, len, "%s", name);
2N/A
2N/A if (n != strlen(p)) {
2N/A errno = ENAMETOOLONG; /* Output was truncated */
2N/A return (NULL);
2N/A }
2N/A len -= n;
2N/A p += n;
2N/A }
2N/A }
2N/A return (buf);
2N/A}
2N/A
2N/A/*
2N/A * Convert a sigset_t to a string representation consisting of canonical signal
2N/A * names (without the SIG prefix). Parameters and return values analogous to
2N/A * proc_fltset2str().
2N/A */
2N/Achar *
2N/Aproc_sigset2str(const sigset_t *set, const char *delim, int m,
2N/A char *buf, size_t len)
2N/A{
2N/A char name[SIG2STR_MAX], *p = buf;
2N/A size_t n;
2N/A int i;
2N/A
2N/A if (buf == NULL || len < 1) {
2N/A errno = EINVAL;
2N/A return (NULL);
2N/A }
2N/A
2N/A m = (m != 0); /* Make sure m is 0 or 1 */
2N/A buf[0] = '\0'; /* Set first byte to \0 */
2N/A
2N/A /*
2N/A * Unlike proc_fltset2str() and proc_sysset2str(), we don't loop
2N/A * until i <= NSIG here, because sigismember() rejects i == NSIG.
2N/A */
2N/A for (i = 1; i < NSIG; i++) {
2N/A if (sigismember(set, i) == m) {
2N/A (void) sig2str(i, name);
2N/A
2N/A if (buf[0] != '\0')
2N/A n = snprintf(p, len, "%s%s", delim, name);
2N/A else
2N/A n = snprintf(p, len, "%s", name);
2N/A
2N/A if (n != strlen(p)) {
2N/A errno = ENAMETOOLONG; /* Output was truncated */
2N/A return (NULL);
2N/A }
2N/A
2N/A len -= n;
2N/A p += n;
2N/A }
2N/A }
2N/A
2N/A return (buf);
2N/A}
2N/A
2N/A/*
2N/A * Convert a sysset_t to a string representation consisting of canonical system
2N/A * call names. Parameters and return values analogous to proc_fltset2str().
2N/A */
2N/Achar *
2N/Aproc_sysset2str(const sysset_t *set, const char *delim, int m,
2N/A char *buf, size_t len)
2N/A{
2N/A char name[SYS2STR_MAX], *p = buf;
2N/A size_t n;
2N/A int i;
2N/A
2N/A if (buf == NULL || len < 1) {
2N/A errno = EINVAL;
2N/A return (NULL);
2N/A }
2N/A
2N/A buf[0] = '\0'; /* Set first byte to \0 */
2N/A
2N/A for (i = 1; i <= PRMAXSYS; i++) {
2N/A if ((prismember(set, i) != 0) ^ (m == 0)) {
2N/A (void) proc_sysname(i, name, sizeof (name));
2N/A
2N/A if (buf[0] != '\0')
2N/A n = snprintf(p, len, "%s%s", delim, name);
2N/A else
2N/A n = snprintf(p, len, "%s", name);
2N/A
2N/A if (n != strlen(p)) {
2N/A errno = ENAMETOOLONG; /* Output was truncated */
2N/A return (NULL);
2N/A }
2N/A len -= n;
2N/A p += n;
2N/A }
2N/A }
2N/A return (buf);
2N/A}
2N/A
2N/A/*
2N/A * Convert a string representation of a fault set (names separated by
2N/A * one or more of the given delimeters) to a fltset_t.
2N/A * If m is non-zero (TRUE), members of the string representation are set.
2N/A * If m is zero (FALSE), non-members of the string representation are set.
2N/A * This function returns NULL for success. Otherwise it returns a pointer
2N/A * to the token of the string that couldn't be identified as a string
2N/A * representation of a fault.
2N/A */
2N/Achar *
2N/Aproc_str2fltset(const char *s, const char *delim, int m, fltset_t *set)
2N/A{
2N/A char *p, *q, *t;
2N/A int flt;
2N/A
2N/A if (m) {
2N/A premptyset(set);
2N/A } else {
2N/A prfillset(set);
2N/A }
2N/A
2N/A t = strdupa(s);
2N/A
2N/A for (p = strtok_r(t, delim, &q); p != NULL;
2N/A p = strtok_r(NULL, delim, &q)) {
2N/A if (proc_str2flt(p, &flt) == -1) {
2N/A errno = EINVAL;
2N/A return ((char *)s + (p - t));
2N/A }
2N/A if (m)
2N/A praddset(set, flt);
2N/A else
2N/A prdelset(set, flt);
2N/A }
2N/A return (NULL);
2N/A}
2N/A
2N/A/*
2N/A * Convert a string representation of a signal set (names with or without the
2N/A * SIG prefix separated by one or more of the given delimeters) to a sigset_t.
2N/A * Parameters and return values analogous to proc_str2fltset().
2N/A */
2N/Achar *
2N/Aproc_str2sigset(const char *s, const char *delim, int m, sigset_t *set)
2N/A{
2N/A char *p, *q, *t;
2N/A int sig;
2N/A
2N/A if (m) {
2N/A premptyset(set);
2N/A } else {
2N/A prfillset(set);
2N/A }
2N/A
2N/A t = strdupa(s);
2N/A
2N/A for (p = strtok_r(t, delim, &q); p != NULL;
2N/A p = strtok_r(NULL, delim, &q)) {
2N/A if (proc_str2sig(p, &sig) == -1) {
2N/A errno = EINVAL;
2N/A return ((char *)s + (p - t));
2N/A }
2N/A if (m)
2N/A praddset(set, sig);
2N/A else
2N/A prdelset(set, sig);
2N/A }
2N/A return (NULL);
2N/A}
2N/A
2N/A/*
2N/A * Convert a string representation of a system call set (names separated by
2N/A * one or more of the given delimeters) to a sysset_t. Parameters and return
2N/A * values analogous to proc_str2fltset().
2N/A */
2N/Achar *
2N/Aproc_str2sysset(const char *s, const char *delim, int m, sysset_t *set)
2N/A{
2N/A char *p, *q, *t;
2N/A int sys;
2N/A
2N/A if (m) {
2N/A premptyset(set);
2N/A } else {
2N/A prfillset(set);
2N/A }
2N/A
2N/A t = strdupa(s);
2N/A
2N/A for (p = strtok_r(t, delim, &q); p != NULL;
2N/A p = strtok_r(NULL, delim, &q)) {
2N/A if (proc_str2sys(p, &sys) == -1) {
2N/A errno = EINVAL;
2N/A return ((char *)s + (p - t));
2N/A }
2N/A if (m)
2N/A praddset(set, sys);
2N/A else
2N/A prdelset(set, sys);
2N/A }
2N/A return (NULL);
2N/A}