[BACK]Return to procname.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Annotation of src/usr.bin/tmux/procname.c, Revision 1.19

1.19    ! deraadt     1: /* $OpenBSD: procname.c,v 1.18 2021/12/07 00:38:42 deraadt Exp $ */
1.1       nicm        2:
                      3: /*
1.15      nicm        4:  * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
1.1       nicm        5:  *
                      6:  * Permission to use, copy, modify, and distribute this software for any
                      7:  * purpose with or without fee is hereby granted, provided that the above
                      8:  * copyright notice and this permission notice appear in all copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     14:  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
                     15:  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
                     16:  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     17:  */
                     18:
1.14      deraadt    19: #include <sys/param.h> /* MAXCOMLEN */
                     20: #include <sys/types.h>
1.19    ! deraadt    21: #include <sys/signal.h>
1.10      millert    22: #include <sys/proc.h>
1.1       nicm       23: #include <sys/sysctl.h>
                     24: #include <sys/stat.h>
                     25:
                     26: #include <errno.h>
                     27: #include <stdlib.h>
                     28: #include <string.h>
                     29: #include <unistd.h>
                     30:
1.2       nicm       31: #ifndef nitems
1.1       nicm       32: #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
1.2       nicm       33: #endif
1.1       nicm       34:
                     35: #define is_runnable(p) \
                     36:        ((p)->p_stat == SRUN || (p)->p_stat == SIDL || (p)->p_stat == SONPROC)
                     37: #define is_stopped(p) \
1.13      guenther   38:        ((p)->p_stat == SSTOP || (p)->p_stat == SDEAD)
1.1       nicm       39:
1.16      nicm       40: static struct kinfo_proc *cmp_procs(struct kinfo_proc *, struct kinfo_proc *);
                     41: char   *get_proc_name(int, char *);
1.17      nicm       42: char   *get_proc_cwd(int);
1.4       nicm       43:
1.16      nicm       44: static struct kinfo_proc *
1.7       guenther   45: cmp_procs(struct kinfo_proc *p1, struct kinfo_proc *p2)
1.4       nicm       46: {
                     47:        if (is_runnable(p1) && !is_runnable(p2))
                     48:                return (p1);
                     49:        if (!is_runnable(p1) && is_runnable(p2))
                     50:                return (p2);
                     51:
                     52:        if (is_stopped(p1) && !is_stopped(p2))
                     53:                return (p1);
                     54:        if (!is_stopped(p1) && is_stopped(p2))
                     55:                return (p2);
                     56:
                     57:        if (p1->p_estcpu > p2->p_estcpu)
                     58:                return (p1);
                     59:        if (p1->p_estcpu < p2->p_estcpu)
                     60:                return (p2);
                     61:
                     62:        if (p1->p_slptime < p2->p_slptime)
                     63:                return (p1);
                     64:        if (p1->p_slptime > p2->p_slptime)
                     65:                return (p2);
                     66:
                     67:        if ((p1->p_flag & P_SINTR) && !(p2->p_flag & P_SINTR))
                     68:                return (p1);
                     69:        if (!(p1->p_flag & P_SINTR) && (p2->p_flag & P_SINTR))
                     70:                return (p2);
                     71:
                     72:        if (strcmp(p1->p_comm, p2->p_comm) < 0)
                     73:                return (p1);
                     74:        if (strcmp(p1->p_comm, p2->p_comm) > 0)
                     75:                return (p2);
                     76:
                     77:        if (p1->p_pid > p2->p_pid)
                     78:                return (p1);
                     79:        return (p2);
                     80: }
1.1       nicm       81:
                     82: char *
                     83: get_proc_name(int fd, char *tty)
                     84: {
1.7       guenther   85:        int              mib[6] = { CTL_KERN, KERN_PROC, KERN_PROC_PGRP, 0,
                     86:                                    sizeof(struct kinfo_proc), 0 };
1.1       nicm       87:        struct stat      sb;
                     88:        size_t           len;
1.7       guenther   89:        struct kinfo_proc *buf, *newbuf, *bestp;
1.1       nicm       90:        u_int            i;
                     91:        char            *name;
                     92:
                     93:        buf = NULL;
                     94:
                     95:        if (stat(tty, &sb) == -1)
                     96:                return (NULL);
                     97:        if ((mib[3] = tcgetpgrp(fd)) == -1)
                     98:                return (NULL);
                     99:
                    100: retry:
                    101:        if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) == -1)
1.12      nicm      102:                goto error;
1.1       nicm      103:        len = (len * 5) / 4;
                    104:
1.4       nicm      105:        if ((newbuf = realloc(buf, len)) == NULL)
                    106:                goto error;
1.1       nicm      107:        buf = newbuf;
                    108:
1.7       guenther  109:        mib[5] = (int)(len / sizeof(struct kinfo_proc));
1.1       nicm      110:        if (sysctl(mib, nitems(mib), buf, &len, NULL, 0) == -1) {
                    111:                if (errno == ENOMEM)
                    112:                        goto retry;
1.4       nicm      113:                goto error;
1.1       nicm      114:        }
                    115:
                    116:        bestp = NULL;
1.7       guenther  117:        for (i = 0; i < len / sizeof (struct kinfo_proc); i++) {
1.6       guenther  118:                if ((dev_t)buf[i].p_tdev != sb.st_rdev)
1.1       nicm      119:                        continue;
1.4       nicm      120:                if (bestp == NULL)
1.6       guenther  121:                        bestp = &buf[i];
1.4       nicm      122:                else
1.6       guenther  123:                        bestp = cmp_procs(&buf[i], bestp);
1.1       nicm      124:        }
                    125:
                    126:        name = NULL;
                    127:        if (bestp != NULL)
                    128:                name = strdup(bestp->p_comm);
                    129:
                    130:        free(buf);
                    131:        return (name);
1.4       nicm      132:
                    133: error:
                    134:        free(buf);
                    135:        return (NULL);
1.17      nicm      136: }
                    137:
                    138: char *
                    139: get_proc_cwd(int fd)
                    140: {
                    141:         int             name[] = { CTL_KERN, KERN_PROC_CWD, 0 };
1.18      deraadt   142:         static char     path[PATH_MAX];
1.17      nicm      143:         size_t          pathlen = sizeof path;
                    144:
                    145:         if ((name[2] = tcgetpgrp(fd)) == -1)
                    146:                 return (NULL);
                    147:         if (sysctl(name, 3, path, &pathlen, NULL, 0) != 0)
                    148:                 return (NULL);
                    149:         return (path);
1.1       nicm      150: }