10daf62d9SStanislav Sedov /*- 21de7b4b8SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 31de7b4b8SPedro F. Giffuni * 40daf62d9SStanislav Sedov * Copyright (c) 2005-2009 Stanislav Sedov <stas@FreeBSD.org> 50daf62d9SStanislav Sedov * All rights reserved. 60daf62d9SStanislav Sedov * 70daf62d9SStanislav Sedov * Redistribution and use in source and binary forms, with or without 80daf62d9SStanislav Sedov * modification, are permitted provided that the following conditions 90daf62d9SStanislav Sedov * are met: 100daf62d9SStanislav Sedov * 1. Redistributions of source code must retain the above copyright 110daf62d9SStanislav Sedov * notice, this list of conditions and the following disclaimer. 120daf62d9SStanislav Sedov * 2. Redistributions in binary form must reproduce the above copyright 130daf62d9SStanislav Sedov * notice, this list of conditions and the following disclaimer in the 140daf62d9SStanislav Sedov * documentation and/or other materials provided with the distribution. 150daf62d9SStanislav Sedov * 160daf62d9SStanislav Sedov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 170daf62d9SStanislav Sedov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 180daf62d9SStanislav Sedov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 190daf62d9SStanislav Sedov * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 200daf62d9SStanislav Sedov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 210daf62d9SStanislav Sedov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 220daf62d9SStanislav Sedov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 230daf62d9SStanislav Sedov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 240daf62d9SStanislav Sedov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 250daf62d9SStanislav Sedov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 260daf62d9SStanislav Sedov * SUCH DAMAGE. 270daf62d9SStanislav Sedov * 280daf62d9SStanislav Sedov */ 290daf62d9SStanislav Sedov #include <sys/cdefs.h> 300daf62d9SStanislav Sedov __FBSDID("$FreeBSD$"); 310daf62d9SStanislav Sedov 320daf62d9SStanislav Sedov #include <sys/queue.h> 330daf62d9SStanislav Sedov #include <sys/stat.h> 340daf62d9SStanislav Sedov #include <sys/sysctl.h> 350daf62d9SStanislav Sedov #include <sys/user.h> 360daf62d9SStanislav Sedov 370daf62d9SStanislav Sedov #include <assert.h> 380daf62d9SStanislav Sedov #include <ctype.h> 390daf62d9SStanislav Sedov #include <err.h> 400daf62d9SStanislav Sedov #include <fcntl.h> 410daf62d9SStanislav Sedov #include <libprocstat.h> 420daf62d9SStanislav Sedov #include <limits.h> 430daf62d9SStanislav Sedov #include <paths.h> 440daf62d9SStanislav Sedov #include <pwd.h> 450daf62d9SStanislav Sedov #include <signal.h> 460daf62d9SStanislav Sedov #include <stdio.h> 470daf62d9SStanislav Sedov #include <stdlib.h> 480daf62d9SStanislav Sedov #include <string.h> 490daf62d9SStanislav Sedov #include <sysexits.h> 500daf62d9SStanislav Sedov #include <unistd.h> 510daf62d9SStanislav Sedov 520daf62d9SStanislav Sedov #include "functions.h" 530daf62d9SStanislav Sedov 540daf62d9SStanislav Sedov /* 550daf62d9SStanislav Sedov * File access mode flags table. 560daf62d9SStanislav Sedov */ 57357050fcSEd Schouten static const struct { 580daf62d9SStanislav Sedov int flag; 590daf62d9SStanislav Sedov char ch; 600daf62d9SStanislav Sedov } fflags[] = { 610daf62d9SStanislav Sedov {PS_FST_FFLAG_WRITE, 'w'}, 620daf62d9SStanislav Sedov {PS_FST_FFLAG_APPEND, 'a'}, 630daf62d9SStanislav Sedov {PS_FST_FFLAG_DIRECT, 'd'}, 640daf62d9SStanislav Sedov {PS_FST_FFLAG_SHLOCK, 's'}, 650daf62d9SStanislav Sedov {PS_FST_FFLAG_EXLOCK, 'e'} 660daf62d9SStanislav Sedov }; 670daf62d9SStanislav Sedov #define NFFLAGS (sizeof(fflags) / sizeof(*fflags)) 680daf62d9SStanislav Sedov 690daf62d9SStanislav Sedov /* 700daf62d9SStanislav Sedov * Usage flags translation table. 710daf62d9SStanislav Sedov */ 72357050fcSEd Schouten static const struct { 730daf62d9SStanislav Sedov int flag; 740daf62d9SStanislav Sedov char ch; 750daf62d9SStanislav Sedov } uflags[] = { 760daf62d9SStanislav Sedov {PS_FST_UFLAG_RDIR, 'r'}, 770daf62d9SStanislav Sedov {PS_FST_UFLAG_CDIR, 'c'}, 780daf62d9SStanislav Sedov {PS_FST_UFLAG_JAIL, 'j'}, 790daf62d9SStanislav Sedov {PS_FST_UFLAG_TRACE, 't'}, 800daf62d9SStanislav Sedov {PS_FST_UFLAG_TEXT, 'x'}, 810daf62d9SStanislav Sedov {PS_FST_UFLAG_MMAP, 'm'}, 820daf62d9SStanislav Sedov {PS_FST_UFLAG_CTTY, 'y'} 830daf62d9SStanislav Sedov }; 840daf62d9SStanislav Sedov #define NUFLAGS (sizeof(uflags) / sizeof(*uflags)) 850daf62d9SStanislav Sedov 860daf62d9SStanislav Sedov struct consumer { 870daf62d9SStanislav Sedov pid_t pid; 880daf62d9SStanislav Sedov uid_t uid; 890daf62d9SStanislav Sedov int fd; 900daf62d9SStanislav Sedov int flags; 910daf62d9SStanislav Sedov int uflags; 920daf62d9SStanislav Sedov STAILQ_ENTRY(consumer) next; 930daf62d9SStanislav Sedov }; 940daf62d9SStanislav Sedov struct reqfile { 95*e18fbe6fSAndriy Gapon dev_t fsid; 96*e18fbe6fSAndriy Gapon ino_t fileid; 970daf62d9SStanislav Sedov const char *name; 980daf62d9SStanislav Sedov STAILQ_HEAD(, consumer) consumers; 990daf62d9SStanislav Sedov }; 1000daf62d9SStanislav Sedov 1010daf62d9SStanislav Sedov /* 1020daf62d9SStanislav Sedov * Option flags. 1030daf62d9SStanislav Sedov */ 1040daf62d9SStanislav Sedov #define UFLAG 0x01 /* -u flag: show users */ 1050daf62d9SStanislav Sedov #define FFLAG 0x02 /* -f flag: specified files only */ 1060daf62d9SStanislav Sedov #define CFLAG 0x04 /* -c flag: treat as mpoints */ 1070daf62d9SStanislav Sedov #define MFLAG 0x10 /* -m flag: mmapped files too */ 1080daf62d9SStanislav Sedov #define KFLAG 0x20 /* -k flag: send signal (SIGKILL by default) */ 1090daf62d9SStanislav Sedov 1100daf62d9SStanislav Sedov static int flags = 0; /* Option flags. */ 1110daf62d9SStanislav Sedov 1120daf62d9SStanislav Sedov static void printflags(struct consumer *consumer); 1130daf62d9SStanislav Sedov static int str2sig(const char *str); 1140daf62d9SStanislav Sedov static void usage(void) __dead2; 1150daf62d9SStanislav Sedov static int addfile(const char *path, struct reqfile *reqfile); 1160daf62d9SStanislav Sedov static void dofiles(struct procstat *procstat, struct kinfo_proc *kp, 1170daf62d9SStanislav Sedov struct reqfile *reqfiles, size_t nfiles); 1180daf62d9SStanislav Sedov 1190daf62d9SStanislav Sedov static void 1200daf62d9SStanislav Sedov usage(void) 1210daf62d9SStanislav Sedov { 1220daf62d9SStanislav Sedov 1230daf62d9SStanislav Sedov fprintf(stderr, 1240daf62d9SStanislav Sedov "usage: fuser [-cfhkmu] [-M core] [-N system] [-s signal] file ...\n"); 1250daf62d9SStanislav Sedov exit(EX_USAGE); 1260daf62d9SStanislav Sedov } 1270daf62d9SStanislav Sedov 1280daf62d9SStanislav Sedov static void 1290daf62d9SStanislav Sedov printflags(struct consumer *cons) 1300daf62d9SStanislav Sedov { 1310daf62d9SStanislav Sedov unsigned int i; 1320daf62d9SStanislav Sedov 1330daf62d9SStanislav Sedov assert(cons); 1340daf62d9SStanislav Sedov for (i = 0; i < NUFLAGS; i++) 1350daf62d9SStanislav Sedov if ((cons->uflags & uflags[i].flag) != 0) 1360daf62d9SStanislav Sedov fputc(uflags[i].ch, stderr); 1370daf62d9SStanislav Sedov for (i = 0; i < NFFLAGS; i++) 1380daf62d9SStanislav Sedov if ((cons->flags & fflags[i].flag) != 0) 1390daf62d9SStanislav Sedov fputc(fflags[i].ch, stderr); 1400daf62d9SStanislav Sedov } 1410daf62d9SStanislav Sedov 1420daf62d9SStanislav Sedov /* 1430daf62d9SStanislav Sedov * Add file to the list. 1440daf62d9SStanislav Sedov */ 1450daf62d9SStanislav Sedov static int 1460daf62d9SStanislav Sedov addfile(const char *path, struct reqfile *reqfile) 1470daf62d9SStanislav Sedov { 1480daf62d9SStanislav Sedov struct stat sb; 1490daf62d9SStanislav Sedov 1500daf62d9SStanislav Sedov assert(path); 1510daf62d9SStanislav Sedov if (stat(path, &sb) != 0) { 1520daf62d9SStanislav Sedov warn("%s", path); 1530daf62d9SStanislav Sedov return (1); 1540daf62d9SStanislav Sedov } 1550daf62d9SStanislav Sedov reqfile->fileid = sb.st_ino; 1560daf62d9SStanislav Sedov reqfile->fsid = sb.st_dev; 1570daf62d9SStanislav Sedov reqfile->name = path; 1580daf62d9SStanislav Sedov STAILQ_INIT(&reqfile->consumers); 1590daf62d9SStanislav Sedov return (0); 1600daf62d9SStanislav Sedov } 1610daf62d9SStanislav Sedov 1620daf62d9SStanislav Sedov int 1630daf62d9SStanislav Sedov do_fuser(int argc, char *argv[]) 1640daf62d9SStanislav Sedov { 1650daf62d9SStanislav Sedov struct consumer *consumer; 1660daf62d9SStanislav Sedov struct kinfo_proc *p, *procs; 1670daf62d9SStanislav Sedov struct procstat *procstat; 1680daf62d9SStanislav Sedov struct reqfile *reqfiles; 1690daf62d9SStanislav Sedov char *ep, *nlistf, *memf; 1700daf62d9SStanislav Sedov int ch, cnt, sig; 1710daf62d9SStanislav Sedov unsigned int i, nfiles; 1720daf62d9SStanislav Sedov 1730daf62d9SStanislav Sedov sig = SIGKILL; /* Default to kill. */ 1740daf62d9SStanislav Sedov nlistf = NULL; 1750daf62d9SStanislav Sedov memf = NULL; 1760daf62d9SStanislav Sedov while ((ch = getopt(argc, argv, "M:N:cfhkms:u")) != -1) 1770daf62d9SStanislav Sedov switch(ch) { 1780daf62d9SStanislav Sedov case 'f': 1790daf62d9SStanislav Sedov if ((flags & CFLAG) != 0) 1800daf62d9SStanislav Sedov usage(); 1810daf62d9SStanislav Sedov flags |= FFLAG; 1820daf62d9SStanislav Sedov break; 1830daf62d9SStanislav Sedov case 'c': 1840daf62d9SStanislav Sedov if ((flags & FFLAG) != 0) 1850daf62d9SStanislav Sedov usage(); 1860daf62d9SStanislav Sedov flags |= CFLAG; 1870daf62d9SStanislav Sedov break; 1880daf62d9SStanislav Sedov case 'N': 1890daf62d9SStanislav Sedov nlistf = optarg; 1900daf62d9SStanislav Sedov break; 1910daf62d9SStanislav Sedov case 'M': 1920daf62d9SStanislav Sedov memf = optarg; 1930daf62d9SStanislav Sedov break; 1940daf62d9SStanislav Sedov case 'u': 1950daf62d9SStanislav Sedov flags |= UFLAG; 1960daf62d9SStanislav Sedov break; 1970daf62d9SStanislav Sedov case 'm': 1980daf62d9SStanislav Sedov flags |= MFLAG; 1990daf62d9SStanislav Sedov break; 2000daf62d9SStanislav Sedov case 'k': 2010daf62d9SStanislav Sedov flags |= KFLAG; 2020daf62d9SStanislav Sedov break; 2030daf62d9SStanislav Sedov case 's': 2040daf62d9SStanislav Sedov if (isdigit(*optarg)) { 2050daf62d9SStanislav Sedov sig = strtol(optarg, &ep, 10); 2060daf62d9SStanislav Sedov if (*ep != '\0' || sig < 0 || sig >= sys_nsig) 2070daf62d9SStanislav Sedov errx(EX_USAGE, "illegal signal number" ": %s", 2080daf62d9SStanislav Sedov optarg); 2090daf62d9SStanislav Sedov } else { 2100daf62d9SStanislav Sedov sig = str2sig(optarg); 2110daf62d9SStanislav Sedov if (sig < 0) 2120daf62d9SStanislav Sedov errx(EX_USAGE, "illegal signal name: " 2130daf62d9SStanislav Sedov "%s", optarg); 2140daf62d9SStanislav Sedov } 2150daf62d9SStanislav Sedov break; 2160daf62d9SStanislav Sedov case 'h': 2170daf62d9SStanislav Sedov /* PASSTHROUGH */ 2180daf62d9SStanislav Sedov default: 2190daf62d9SStanislav Sedov usage(); 2200daf62d9SStanislav Sedov /* NORETURN */ 2210daf62d9SStanislav Sedov } 2220daf62d9SStanislav Sedov argv += optind; 2230daf62d9SStanislav Sedov argc -= optind; 2240daf62d9SStanislav Sedov 2250daf62d9SStanislav Sedov assert(argc >= 0); 2260daf62d9SStanislav Sedov if (argc == 0) 2270daf62d9SStanislav Sedov usage(); 2280daf62d9SStanislav Sedov /* NORETURN */ 2290daf62d9SStanislav Sedov 2300daf62d9SStanislav Sedov /* 2310daf62d9SStanislav Sedov * Process named files. 2320daf62d9SStanislav Sedov */ 2330daf62d9SStanislav Sedov reqfiles = malloc(argc * sizeof(struct reqfile)); 2340daf62d9SStanislav Sedov if (reqfiles == NULL) 2350daf62d9SStanislav Sedov err(EX_OSERR, "malloc()"); 2360daf62d9SStanislav Sedov nfiles = 0; 2370daf62d9SStanislav Sedov while (argc--) 2380daf62d9SStanislav Sedov if (!addfile(*(argv++), &reqfiles[nfiles])) 2390daf62d9SStanislav Sedov nfiles++; 2400daf62d9SStanislav Sedov if (nfiles == 0) 2410daf62d9SStanislav Sedov errx(EX_IOERR, "files not accessible"); 2420daf62d9SStanislav Sedov 2430daf62d9SStanislav Sedov if (memf != NULL) 2440daf62d9SStanislav Sedov procstat = procstat_open_kvm(nlistf, memf); 2450daf62d9SStanislav Sedov else 2460daf62d9SStanislav Sedov procstat = procstat_open_sysctl(); 2470daf62d9SStanislav Sedov if (procstat == NULL) 2480daf62d9SStanislav Sedov errx(1, "procstat_open()"); 2490daf62d9SStanislav Sedov procs = procstat_getprocs(procstat, KERN_PROC_PROC, 0, &cnt); 2500daf62d9SStanislav Sedov if (procs == NULL) 2510daf62d9SStanislav Sedov errx(1, "procstat_getprocs()"); 2520daf62d9SStanislav Sedov 2530daf62d9SStanislav Sedov /* 2540daf62d9SStanislav Sedov * Walk through process table and look for matching files. 2550daf62d9SStanislav Sedov */ 2560daf62d9SStanislav Sedov p = procs; 2570daf62d9SStanislav Sedov while(cnt--) 2580daf62d9SStanislav Sedov if (p->ki_stat != SZOMB) 2590daf62d9SStanislav Sedov dofiles(procstat, p++, reqfiles, nfiles); 2600daf62d9SStanislav Sedov 2610daf62d9SStanislav Sedov for (i = 0; i < nfiles; i++) { 2620daf62d9SStanislav Sedov fprintf(stderr, "%s:", reqfiles[i].name); 2630daf62d9SStanislav Sedov fflush(stderr); 2640daf62d9SStanislav Sedov STAILQ_FOREACH(consumer, &reqfiles[i].consumers, next) { 2650daf62d9SStanislav Sedov if (consumer->flags != 0) { 2660daf62d9SStanislav Sedov fprintf(stdout, "%6d", consumer->pid); 2670daf62d9SStanislav Sedov fflush(stdout); 2680daf62d9SStanislav Sedov printflags(consumer); 2690daf62d9SStanislav Sedov if ((flags & UFLAG) != 0) 2700daf62d9SStanislav Sedov fprintf(stderr, "(%s)", 2710daf62d9SStanislav Sedov user_from_uid(consumer->uid, 0)); 2720daf62d9SStanislav Sedov if ((flags & KFLAG) != 0) 2730daf62d9SStanislav Sedov kill(consumer->pid, sig); 2740daf62d9SStanislav Sedov fflush(stderr); 2750daf62d9SStanislav Sedov } 2760daf62d9SStanislav Sedov } 2770daf62d9SStanislav Sedov (void)fprintf(stderr, "\n"); 2780daf62d9SStanislav Sedov } 2790daf62d9SStanislav Sedov procstat_freeprocs(procstat, procs); 2800daf62d9SStanislav Sedov procstat_close(procstat); 2810daf62d9SStanislav Sedov free(reqfiles); 2820daf62d9SStanislav Sedov return (0); 2830daf62d9SStanislav Sedov } 2840daf62d9SStanislav Sedov 2850daf62d9SStanislav Sedov static void 2860daf62d9SStanislav Sedov dofiles(struct procstat *procstat, struct kinfo_proc *kp, 2870daf62d9SStanislav Sedov struct reqfile *reqfiles, size_t nfiles) 2880daf62d9SStanislav Sedov { 2890daf62d9SStanislav Sedov struct vnstat vn; 2900daf62d9SStanislav Sedov struct consumer *cons; 2910daf62d9SStanislav Sedov struct filestat *fst; 2920daf62d9SStanislav Sedov struct filestat_list *head; 2930daf62d9SStanislav Sedov int error, match; 2940daf62d9SStanislav Sedov unsigned int i; 2950daf62d9SStanislav Sedov char errbuf[_POSIX2_LINE_MAX]; 2960daf62d9SStanislav Sedov 2970daf62d9SStanislav Sedov head = procstat_getfiles(procstat, kp, flags & MFLAG); 2980daf62d9SStanislav Sedov if (head == NULL) 2990daf62d9SStanislav Sedov return; 3000daf62d9SStanislav Sedov STAILQ_FOREACH(fst, head, next) { 3010daf62d9SStanislav Sedov if (fst->fs_type != PS_FST_TYPE_VNODE) 3020daf62d9SStanislav Sedov continue; 3030daf62d9SStanislav Sedov error = procstat_get_vnode_info(procstat, fst, &vn, errbuf); 3040daf62d9SStanislav Sedov if (error != 0) 3050daf62d9SStanislav Sedov continue; 3060daf62d9SStanislav Sedov for (i = 0; i < nfiles; i++) { 3070daf62d9SStanislav Sedov if (flags & CFLAG && reqfiles[i].fsid == vn.vn_fsid) { 3080daf62d9SStanislav Sedov break; 3090daf62d9SStanislav Sedov } 3100daf62d9SStanislav Sedov else if (reqfiles[i].fsid == vn.vn_fsid && 3110daf62d9SStanislav Sedov reqfiles[i].fileid == vn.vn_fileid) { 3120daf62d9SStanislav Sedov break; 3130daf62d9SStanislav Sedov } 3140daf62d9SStanislav Sedov else if (!(flags & FFLAG) && 3150daf62d9SStanislav Sedov (vn.vn_type == PS_FST_VTYPE_VCHR || 3160daf62d9SStanislav Sedov vn.vn_type == PS_FST_VTYPE_VBLK) && 3170daf62d9SStanislav Sedov vn.vn_fsid == reqfiles[i].fileid) { 3180daf62d9SStanislav Sedov break; 3190daf62d9SStanislav Sedov } 3200daf62d9SStanislav Sedov } 3210daf62d9SStanislav Sedov if (i == nfiles) 3220daf62d9SStanislav Sedov continue; /* No match. */ 3230daf62d9SStanislav Sedov 3240daf62d9SStanislav Sedov /* 3250daf62d9SStanislav Sedov * Look for existing entries. 3260daf62d9SStanislav Sedov */ 3270daf62d9SStanislav Sedov match = 0; 3280daf62d9SStanislav Sedov STAILQ_FOREACH(cons, &reqfiles[i].consumers, next) 3290daf62d9SStanislav Sedov if (cons->pid == kp->ki_pid) { 3300daf62d9SStanislav Sedov match = 1; 3310daf62d9SStanislav Sedov break; 3320daf62d9SStanislav Sedov } 3330daf62d9SStanislav Sedov if (match == 1) { /* Use old entry. */ 3340daf62d9SStanislav Sedov cons->flags |= fst->fs_fflags; 3350daf62d9SStanislav Sedov cons->uflags |= fst->fs_uflags; 3360daf62d9SStanislav Sedov } else { 3370daf62d9SStanislav Sedov /* 3380daf62d9SStanislav Sedov * Create new entry in the consumer chain. 3390daf62d9SStanislav Sedov */ 3400daf62d9SStanislav Sedov cons = calloc(1, sizeof(struct consumer)); 3410daf62d9SStanislav Sedov if (cons == NULL) { 3420daf62d9SStanislav Sedov warn("malloc()"); 3430daf62d9SStanislav Sedov continue; 3440daf62d9SStanislav Sedov } 3450daf62d9SStanislav Sedov cons->uid = kp->ki_uid; 3460daf62d9SStanislav Sedov cons->pid = kp->ki_pid; 3470daf62d9SStanislav Sedov cons->uflags = fst->fs_uflags; 3480daf62d9SStanislav Sedov cons->flags = fst->fs_fflags; 3490daf62d9SStanislav Sedov STAILQ_INSERT_TAIL(&reqfiles[i].consumers, cons, next); 3500daf62d9SStanislav Sedov } 3510daf62d9SStanislav Sedov } 3520daf62d9SStanislav Sedov procstat_freefiles(procstat, head); 3530daf62d9SStanislav Sedov } 3540daf62d9SStanislav Sedov 3550daf62d9SStanislav Sedov /* 3560daf62d9SStanislav Sedov * Returns signal number for it's string representation. 3570daf62d9SStanislav Sedov */ 3580daf62d9SStanislav Sedov static int 3590daf62d9SStanislav Sedov str2sig(const char *str) 3600daf62d9SStanislav Sedov { 3610daf62d9SStanislav Sedov int i; 3620daf62d9SStanislav Sedov 36316962744SJilles Tjoelker if (!strncasecmp(str, "SIG", 3)) 36416962744SJilles Tjoelker str += 3; 3650daf62d9SStanislav Sedov for (i = 1; i < sys_nsig; i++) { 3660daf62d9SStanislav Sedov if (!strcasecmp(sys_signame[i], str)) 3670daf62d9SStanislav Sedov return (i); 3680daf62d9SStanislav Sedov } 3690daf62d9SStanislav Sedov return (-1); 3700daf62d9SStanislav Sedov } 371