[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.4

1.4     ! nicm        1: /* $OpenBSD: procname.c,v 1.3 2009/07/26 19:42:26 nicm Exp $ */
1.1       nicm        2:
                      3: /*
                      4:  * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
                      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:
                     19: #include <sys/param.h>
                     20: #include <sys/sysctl.h>
                     21: #include <sys/stat.h>
                     22:
                     23: #include <errno.h>
                     24: #include <stdlib.h>
                     25: #include <string.h>
                     26: #include <unistd.h>
                     27:
1.2       nicm       28: #ifndef nitems
1.1       nicm       29: #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
1.2       nicm       30: #endif
1.1       nicm       31:
                     32: #define is_runnable(p) \
                     33:        ((p)->p_stat == SRUN || (p)->p_stat == SIDL || (p)->p_stat == SONPROC)
                     34: #define is_stopped(p) \
                     35:        ((p)->p_stat == SSTOP || (p)->p_stat == SZOMB || (p)->p_stat == SDEAD)
                     36:
1.4     ! nicm       37: struct proc    *cmp_procs(struct proc *, struct proc *);
        !            38: char           *get_proc_name(int, char *);
        !            39:
        !            40: struct proc *
        !            41: cmp_procs(struct proc *p1, struct proc *p2)
        !            42: {
        !            43:        void    *ptr1, *ptr2;
        !            44:
        !            45:        if (is_runnable(p1) && !is_runnable(p2))
        !            46:                return (p1);
        !            47:        if (!is_runnable(p1) && is_runnable(p2))
        !            48:                return (p2);
        !            49:
        !            50:        if (is_stopped(p1) && !is_stopped(p2))
        !            51:                return (p1);
        !            52:        if (!is_stopped(p1) && is_stopped(p2))
        !            53:                return (p2);
        !            54:
        !            55:        if (p1->p_estcpu > p2->p_estcpu)
        !            56:                return (p1);
        !            57:        if (p1->p_estcpu < p2->p_estcpu)
        !            58:                return (p2);
        !            59:
        !            60:        if (p1->p_slptime < p2->p_slptime)
        !            61:                return (p1);
        !            62:        if (p1->p_slptime > p2->p_slptime)
        !            63:                return (p2);
        !            64:
        !            65:        if ((p1->p_flag & P_SINTR) && !(p2->p_flag & P_SINTR))
        !            66:                return (p1);
        !            67:        if (!(p1->p_flag & P_SINTR) && (p2->p_flag & P_SINTR))
        !            68:                return (p2);
        !            69:
        !            70:        ptr1 = LIST_FIRST(&p1->p_children);
        !            71:        ptr2 = LIST_FIRST(&p2->p_children);
        !            72:        if (ptr1 == NULL && ptr2 != NULL)
        !            73:                return (p1);
        !            74:        if (ptr1 != NULL && ptr2 == NULL)
        !            75:                return (p2);
        !            76:
        !            77:        if (strcmp(p1->p_comm, p2->p_comm) < 0)
        !            78:                return (p1);
        !            79:        if (strcmp(p1->p_comm, p2->p_comm) > 0)
        !            80:                return (p2);
        !            81:
        !            82:        if (p1->p_pid > p2->p_pid)
        !            83:                return (p1);
        !            84:        return (p2);
        !            85: }
1.1       nicm       86:
                     87: char *
                     88: get_proc_name(int fd, char *tty)
                     89: {
                     90:        int              mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PGRP, 0 };
                     91:        struct stat      sb;
                     92:        size_t           len;
                     93:        struct kinfo_proc *buf, *newbuf;
                     94:        struct proc     *p, *bestp;
                     95:        u_int            i;
                     96:        char            *name;
                     97:
                     98:        buf = NULL;
                     99:
                    100:        if (stat(tty, &sb) == -1)
                    101:                return (NULL);
                    102:        if ((mib[3] = tcgetpgrp(fd)) == -1)
                    103:                return (NULL);
                    104:
                    105: retry:
                    106:        if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) == -1)
                    107:                return (NULL);
                    108:        len = (len * 5) / 4;
                    109:
1.4     ! nicm      110:        if ((newbuf = realloc(buf, len)) == NULL)
        !           111:                goto error;
1.1       nicm      112:        buf = newbuf;
                    113:
                    114:        if (sysctl(mib, nitems(mib), buf, &len, NULL, 0) == -1) {
                    115:                if (errno == ENOMEM)
                    116:                        goto retry;
1.4     ! nicm      117:                goto error;
1.1       nicm      118:        }
                    119:
                    120:        bestp = NULL;
                    121:        for (i = 0; i < len / sizeof (struct kinfo_proc); i++) {
                    122:                if (buf[i].kp_eproc.e_tdev != sb.st_rdev)
                    123:                        continue;
                    124:                p = &buf[i].kp_proc;
1.4     ! nicm      125:                if (bestp == NULL)
        !           126:                        bestp = &buf[i].kp_proc;
        !           127:                else
        !           128:                        bestp = cmp_procs(&buf[i].kp_proc, bestp);
1.1       nicm      129:        }
                    130:
                    131:        name = NULL;
                    132:        if (bestp != NULL)
                    133:                name = strdup(bestp->p_comm);
                    134:
                    135:        free(buf);
                    136:        return (name);
1.4     ! nicm      137:
        !           138: error:
        !           139:        free(buf);
        !           140:        return (NULL);
1.1       nicm      141: }