Print this page
    
OS-3280 need a way to specify the root of a native system in the lx brand
OS-3279 lx brand should allow delegated datasets
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/pgrep/pgrep.c
          +++ new/usr/src/cmd/pgrep/pgrep.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
  25   25  /* Copyright (c) 2012 by Delphix. All rights reserved */
  26   26  
  27   27  #include <sys/types.h>
  28   28  #include <sys/stat.h>
  29   29  #include <sys/param.h>
  30   30  #include <sys/task.h>
  31   31  #include <sys/contract.h>
  32   32  
  33   33  #include <signal.h>
  34   34  #include <unistd.h>
  35   35  #include <dirent.h>
  36   36  #include <stdlib.h>
  37   37  #include <string.h>
  38   38  
  39   39  #include <libintl.h>
  40   40  #include <locale.h>
  41   41  #include <stdio.h>
  42   42  #include <fcntl.h>
  43   43  #include <ctype.h>
  44   44  #include <wchar.h>
  45   45  #include <limits.h>
  46   46  #include <libuutil.h>
  47   47  #include <libcontract_priv.h>
  48   48  
  49   49  #include <procfs.h>
  50   50  #include <project.h>
  51   51  #include <pwd.h>
  52   52  #include <grp.h>
  53   53  #include <zone.h>
  54   54  
  55   55  #include "psexp.h"
  56   56  #include "pgrep.h"
  57   57  
  58   58  #ifndef TEXT_DOMAIN
  59   59  #define TEXT_DOMAIN     "SYS_TEST"
  60   60  #endif
  61   61  
  62   62  #define OPT_SETB        0x0001  /* Set the bits specified by o_bits */
  63   63  #define OPT_CLRB        0x0002  /* Clear the bits specified by o_bits */
  64   64  #define OPT_FUNC        0x0004  /* Call the function specified by o_func */
  65   65  #define OPT_STR         0x0008  /* Set the string specified by o_ptr */
  66   66  #define OPT_CRIT        0x0010  /* Option is part of selection criteria */
  67   67  
  68   68  #define F_LONG_FMT      0x0001  /* Match against long format cmd */
  69   69  #define F_NEWEST        0x0002  /* Match only newest pid */
  70   70  #define F_REVERSE       0x0004  /* Reverse matching criteria */
  71   71  #define F_EXACT_MATCH   0x0008  /* Require exact match */
  72   72  #define F_HAVE_CRIT     0x0010  /* Criteria specified */
  73   73  #define F_OUTPUT        0x0020  /* Some output has been printed */
  74   74  #define F_KILL          0x0040  /* Pkill semantics active (vs pgrep) */
  75   75  #define F_LONG_OUT      0x0080  /* Long output format (pgrep -l) */
  76   76  #define F_OLDEST        0x0100  /* Match only oldest pid */
  77   77  
  78   78  static int opt_euid(char, char *);
  79   79  static int opt_uid(char, char *);
  80   80  static int opt_gid(char, char *);
  81   81  static int opt_ppid(char, char *);
  82   82  static int opt_pgrp(char, char *);
  83   83  static int opt_sid(char, char *);
  84   84  static int opt_term(char, char *);
  85   85  static int opt_projid(char, char *);
  86   86  static int opt_taskid(char, char *);
  87   87  static int opt_zoneid(char, char *);
  88   88  static int opt_ctid(char, char *);
  89   89  
  90   90  static const char *g_procdir = "/proc"; /* Default procfs mount point */
  91   91  static const char *g_delim = "\n";      /* Default output delimiter */
  92   92  static const char *g_pname;             /* Program name for error messages */
  93   93  static ushort_t g_flags;                /* Miscellaneous flags */
  94   94  
  95   95  static optdesc_t g_optdtab[] = {
  96   96          { 0, 0, 0, 0 },                                 /* 'A' */
  97   97          { 0, 0, 0, 0 },                                 /* 'B' */
  98   98          { 0, 0, 0, 0 },                                 /* 'C' */
  99   99          { OPT_STR, 0, 0, &g_procdir },                  /* -D procfsdir */
 100  100          { 0, 0, 0, 0 },                                 /* 'E' */
 101  101          { 0, 0, 0, 0 },                                 /* 'F' */
 102  102          { OPT_FUNC | OPT_CRIT, 0, opt_gid, 0 },         /* -G gid */
 103  103          { 0, 0, 0, 0 },                                 /* 'H' */
 104  104          { 0, 0, 0, 0 },                                 /* 'I' */
 105  105          { OPT_FUNC | OPT_CRIT, 0, opt_projid, 0 },      /* -J projid */
 106  106          { 0, 0, 0, 0 },                                 /* 'K' */
 107  107          { 0, 0, 0, 0 },                                 /* 'L' */
 108  108          { 0, 0, 0, 0 },                                 /* 'M' */
 109  109          { 0, 0, 0, 0 },                                 /* 'N' */
 110  110          { 0, 0, 0, 0 },                                 /* 'O' */
 111  111          { OPT_FUNC | OPT_CRIT, 0, opt_ppid, 0 },        /* -P ppid */
 112  112          { 0, 0, 0, 0 },                                 /* 'Q' */
 113  113          { 0, 0, 0, 0 },                                 /* 'R' */
 114  114          { 0, 0, 0, 0 },                                 /* 'S' */
 115  115          { OPT_FUNC | OPT_CRIT, 0, opt_taskid, 0 },      /* -T taskid */
 116  116          { OPT_FUNC | OPT_CRIT, 0, opt_uid, 0 },         /* -U uid */
 117  117          { 0, 0, 0, 0 },                                 /* 'V' */
 118  118          { 0, 0, 0, 0 },                                 /* 'W' */
 119  119          { 0, 0, 0, 0 },                                 /* 'X' */
 120  120          { 0, 0, 0, 0 },                                 /* 'Y' */
 121  121          { 0, 0, 0, 0 },                                 /* 'Z' */
 122  122          { 0, 0, 0, 0 },                                 /* '[' */
 123  123          { 0, 0, 0, 0 },                                 /* '\\' */
 124  124          { 0, 0, 0, 0 },                                 /* ']' */
 125  125          { 0, 0, 0, 0 },                                 /* '^' */
 126  126          { 0, 0, 0, 0 },                                 /* '_' */
 127  127          { 0, 0, 0, 0 },                                 /* '`' */
 128  128          { 0, 0, 0, 0 },                                 /* 'a' */
 129  129          { 0, 0, 0, 0 },                                 /* 'b' */
 130  130          { OPT_FUNC | OPT_CRIT, 0, opt_ctid, 0 },        /* -c ctid */
 131  131          { OPT_STR, 0, 0, &g_delim },                    /* -d delim */
 132  132          { 0, 0, 0, 0 },                                 /* 'e' */
 133  133          { OPT_SETB, F_LONG_FMT, 0, &g_flags },          /* -f */
 134  134          { OPT_FUNC | OPT_CRIT, 0, opt_pgrp, 0 },        /* -g pgrp */
 135  135          { 0, 0, 0, 0 },                                 /* 'h' */
 136  136          { 0, 0, 0, 0 },                                 /* 'i' */
 137  137          { 0, 0, 0, 0 },                                 /* 'j' */
 138  138          { 0, 0, 0, 0 },                                 /* 'k' */
 139  139          { OPT_SETB, F_LONG_OUT, 0, &g_flags },          /* 'l' */
 140  140          { 0, 0, 0, 0 },                                 /* 'm' */
 141  141          { OPT_SETB, F_NEWEST, 0, &g_flags },            /* -n */
 142  142          { OPT_SETB, F_OLDEST, 0, &g_flags },            /* -o */
 143  143          { 0, 0, 0, 0 },                                 /* 'p' */
 144  144          { 0, 0, 0, 0 },                                 /* 'q' */
 145  145          { 0, 0, 0, 0 },                                 /* 'r' */
 146  146          { OPT_FUNC | OPT_CRIT, 0, opt_sid, 0 },         /* -s sid */
 147  147          { OPT_FUNC | OPT_CRIT, 0, opt_term, 0 },        /* -t term */
 148  148          { OPT_FUNC | OPT_CRIT, 0, opt_euid, 0 },        /* -u euid */
 149  149          { OPT_SETB, F_REVERSE, 0, &g_flags },           /* -v */
 150  150          { 0, 0, 0, 0 },                                 /* 'w' */
 151  151          { OPT_SETB, F_EXACT_MATCH, 0, &g_flags },       /* -x */
 152  152          { 0, 0, 0, 0 },                                 /* 'y' */
 153  153          { OPT_FUNC | OPT_CRIT, 0, opt_zoneid, 0 }       /* -z zoneid */
 154  154  };
 155  155  
 156  156  static const char PGREP_USAGE[] = "\
 157  157  Usage: %s [-flnovx] [-d delim] [-P ppidlist] [-g pgrplist] [-s sidlist]\n\
 158  158          [-u euidlist] [-U uidlist] [-G gidlist] [-J projidlist]\n\
 159  159          [-T taskidlist] [-t termlist] [-z zonelist] [-c ctidlist] [pattern]\n";
 160  160  
 161  161  static const char PKILL_USAGE[] = "\
 162  162  Usage: %s [-signal] [-fnovx] [-P ppidlist] [-g pgrplist] [-s sidlist]\n\
 163  163          [-u euidlist] [-U uidlist] [-G gidlist] [-J projidlist]\n\
 164  164          [-T taskidlist] [-t termlist] [-z zonelist] [-c ctidlist] [pattern]\n";
 165  165  
 166  166  static const char PGREP_OPTS[] = ":flnovxc:d:D:u:U:G:P:g:s:t:z:J:T:";
 167  167  static const char PKILL_OPTS[] = ":fnovxc:D:u:U:G:P:g:s:t:z:J:T:";
 168  168  
 169  169  static const char LSEP[] = ",\t ";      /* Argument list delimiter chars */
 170  170  
 171  171  static psexp_t g_psexp;                 /* Process matching expression */
 172  172  static pid_t g_pid;                     /* Current pid */
 173  173  static int g_signal = SIGTERM;          /* Signal to send */
 174  174  
 175  175  static void
 176  176  print_proc(psinfo_t *psinfo)
 177  177  {
 178  178          if (g_flags & F_OUTPUT)
 179  179                  (void) printf("%s%d", g_delim, (int)psinfo->pr_pid);
 180  180          else {
 181  181                  (void) printf("%d", (int)psinfo->pr_pid);
 182  182                  g_flags |= F_OUTPUT;
 183  183          }
 184  184  }
 185  185  
 186  186  static char *
 187  187  mbstrip(char *buf, size_t nbytes)
 188  188  {
 189  189          wchar_t wc;
 190  190          char *p;
 191  191          int n;
 192  192  
 193  193          buf[nbytes - 1] = '\0';
 194  194          p = buf;
 195  195  
 196  196          while (*p != '\0') {
 197  197                  n = mbtowc(&wc, p, MB_LEN_MAX);
 198  198  
 199  199                  if (n < 0 || !iswprint(wc)) {
 200  200                          if (n < 0)
 201  201                                  n = sizeof (char);
 202  202  
 203  203                          if (nbytes <= n) {
 204  204                                  *p = '\0';
 205  205                                  break;
 206  206                          }
 207  207  
 208  208                          (void) memmove(p, p + n, nbytes - n);
 209  209  
 210  210                  } else {
 211  211                          nbytes -= n;
 212  212                          p += n;
 213  213                  }
 214  214          }
 215  215  
 216  216          return (buf);
 217  217  }
 218  218  
 219  219  static void
 220  220  print_proc_long(psinfo_t *psinfo)
 221  221  {
 222  222          char *name;
 223  223  
 224  224          if (g_flags & F_LONG_FMT)
 225  225                  name = mbstrip(psinfo->pr_psargs, PRARGSZ);
 226  226          else
 227  227                  name = psinfo->pr_fname;
 228  228  
 229  229          if (g_flags & F_OUTPUT)
 230  230                  (void) printf("%s%5d %s", g_delim, (int)psinfo->pr_pid, name);
 231  231          else {
 232  232                  (void) printf("%5d %s", (int)psinfo->pr_pid, name);
 233  233                  g_flags |= F_OUTPUT;
 234  234          }
 235  235  }
 236  236  
 237  237  static void
 238  238  kill_proc(psinfo_t *psinfo)
 239  239  {
 240  240          if (psinfo->pr_pid > 0 && kill(psinfo->pr_pid, g_signal) == -1)
 241  241                  uu_warn(gettext("Failed to signal pid %d"),
 242  242                      (int)psinfo->pr_pid);
 243  243  }
 244  244  
 245  245  static DIR *
 246  246  open_proc_dir(const char *dirpath)
 247  247  {
 248  248          struct stat buf;
 249  249          DIR *dirp;
 250  250  
 251  251          if ((dirp = opendir(dirpath)) == NULL) {
 252  252                  uu_warn(gettext("Failed to open %s"), dirpath);
 253  253                  return (NULL);
 254  254          }
 255  255  
 256  256          if (fstat(dirp->dd_fd, &buf) == -1) {
 257  257                  uu_warn(gettext("Failed to stat %s"), dirpath);
 258  258                  (void) closedir(dirp);
 259  259                  return (NULL);
 260  260          }
 261  261  
 262  262          if (strcmp(buf.st_fstype, "proc") != 0) {
 263  263                  uu_warn(gettext("%s is not a procfs mount point\n"), dirpath);
 264  264                  (void) closedir(dirp);
 265  265                  return (NULL);
 266  266          }
 267  267  
 268  268          return (dirp);
 269  269  }
 270  270  
 271  271  #define NEWER(ps1, ps2) \
 272  272          ((ps1.pr_start.tv_sec > ps2.pr_start.tv_sec) || \
 273  273              (ps1.pr_start.tv_sec == ps2.pr_start.tv_sec && \
 274  274              ps1.pr_start.tv_nsec > ps2.pr_start.tv_nsec))
 275  275  
 276  276  static int
 277  277  scan_proc_dir(const char *dirpath, DIR *dirp, psexp_t *psexp,
 278  278          void (*funcp)(psinfo_t *))
 279  279  {
 280  280          char procpath[MAXPATHLEN];
 281  281          psinfo_t ps, ops;
 282  282          dirent_t *dent;
 283  283          int procfd;
 284  284  
 285  285          int reverse = (g_flags & F_REVERSE) ? 1 : 0;
 286  286          int ovalid = 0, nmatches = 0, flags = 0;
 287  287  
 288  288          if (g_flags & F_LONG_FMT)
 289  289                  flags |= PSEXP_PSARGS;
 290  290  
 291  291          if (g_flags & F_EXACT_MATCH)
 292  292                  flags |= PSEXP_EXACT;
 293  293  
 294  294          while ((dent = readdir(dirp)) != NULL) {
 295  295  
 296  296                  if (dent->d_name[0] == '.')
 297  297                          continue;
 298  298  
 299  299                  (void) snprintf(procpath, sizeof (procpath), "%s/%s/psinfo",
 300  300                      dirpath, dent->d_name);
 301  301  
 302  302                  if ((procfd = open(procpath, O_RDONLY)) == -1)
 303  303                          continue;
 304  304  
 305  305                  if ((read(procfd, &ps, sizeof (ps)) == sizeof (psinfo_t)) &&
 306  306                      (ps.pr_nlwp != 0) && (ps.pr_pid != g_pid) &&
 307  307                      (psexp_match(psexp, &ps, flags) ^ reverse)) {
 308  308  
 309  309                          if (g_flags & F_NEWEST) {
 310  310                                  /* LINTED - opsinfo use ok */
 311  311                                  if (!ovalid || NEWER(ps, ops)) {
 312  312                                          (void) memcpy(&ops, &ps,
 313  313                                              sizeof (psinfo_t));
 314  314                                          ovalid = 1;
 315  315                                  }
 316  316                          } else if (g_flags & F_OLDEST) {
 317  317                                  if (!ovalid || NEWER(ops, ps)) {
 318  318                                          (void) memcpy(&ops, &ps,
 319  319                                              sizeof (psinfo_t));
 320  320                                          ovalid = 1;
 321  321                                  }
 322  322                          } else {
 323  323                                  (*funcp)(&ps);
 324  324                                  nmatches++;
 325  325                          }
 326  326                  }
 327  327  
 328  328                  (void) close(procfd);
 329  329          }
 330  330  
 331  331          if ((g_flags & (F_NEWEST | F_OLDEST)) && ovalid) {
 332  332                  (*funcp)(&ops);
 333  333                  nmatches++;
 334  334          }
 335  335  
 336  336          return (nmatches);
 337  337  }
 338  338  
 339  339  static int
 340  340  parse_ids(idtab_t *idt, char *arg, int base, int opt, idkey_t zero)
 341  341  {
 342  342          char *ptr, *next;
 343  343          idkey_t id;
 344  344  
 345  345          for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) {
 346  346                  if ((id = (idkey_t)strtoul(ptr, &next, base)) != 0)
 347  347                          idtab_append(idt, id);
 348  348                  else
 349  349                          idtab_append(idt, zero);
 350  350  
 351  351                  if (next == ptr || *next != 0) {
 352  352                          uu_warn("invalid argument for option '%c' -- %s\n",
 353  353                              opt, ptr);
 354  354                          return (-1);
 355  355                  }
 356  356          }
 357  357  
 358  358          return (0);
 359  359  }
 360  360  
 361  361  static int
 362  362  parse_uids(idtab_t *idt, char *arg)
 363  363  {
 364  364          char *ptr, *next;
 365  365          struct passwd *pwent;
 366  366          idkey_t id;
 367  367  
 368  368          for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) {
 369  369                  if (isdigit(ptr[0])) {
 370  370                          id = strtol(ptr, &next, 10);
 371  371  
 372  372                          if (next != ptr && *next == '\0') {
 373  373                                  idtab_append(idt, id);
 374  374                                  continue;
 375  375                          }
 376  376                  }
 377  377  
 378  378                  if ((pwent = getpwnam(ptr)) != NULL)
 379  379                          idtab_append(idt, pwent->pw_uid);
 380  380                  else
 381  381                          goto err;
 382  382          }
 383  383  
 384  384          return (0);
 385  385  
 386  386  err:
 387  387          uu_warn(gettext("invalid user name -- %s\n"), ptr);
 388  388          return (-1);
 389  389  }
 390  390  
 391  391  static int
 392  392  parse_gids(idtab_t *idt, char *arg)
 393  393  {
 394  394          char *ptr, *next;
 395  395          struct group *grent;
 396  396          idkey_t id;
 397  397  
 398  398          for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) {
 399  399                  if (isdigit(ptr[0])) {
 400  400                          id = strtol(ptr, &next, 10);
 401  401  
 402  402                          if (next != ptr && *next == '\0') {
 403  403                                  idtab_append(idt, id);
 404  404                                  continue;
 405  405                          }
 406  406                  }
 407  407  
 408  408                  if ((grent = getgrnam(ptr)) != NULL)
 409  409                          idtab_append(idt, grent->gr_gid);
 410  410                  else
 411  411                          goto err;
 412  412          }
 413  413  
 414  414          return (0);
 415  415  
 416  416  err:
 417  417          uu_warn(gettext("invalid group name -- %s\n"), ptr);
 418  418          return (-1);
 419  419  }
 420  420  
 421  421  static int
 422  422  parse_ttys(idtab_t *idt, char *arg)
 423  423  {
 424  424          char devpath[MAXPATHLEN];
 425  425          struct stat buf;
 426  426          char *ptr;
 427  427  
 428  428          int seen_console = 0; /* Flag so we only stat syscon and systty once */
 429  429  
 430  430          for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) {
 431  431                  if (strcmp(ptr, "none") == 0) {
 432  432                          idtab_append(idt, (idkey_t)PRNODEV);
 433  433                          continue;
 434  434                  }
 435  435  
 436  436                  if (strcmp(ptr, "console") == 0) {
 437  437                          if (seen_console)
 438  438                                  continue;
 439  439  
 440  440                          if (stat("/dev/syscon", &buf) == 0)
 441  441                                  idtab_append(idt, (idkey_t)buf.st_rdev);
 442  442  
 443  443                          if (stat("/dev/systty", &buf) == 0)
 444  444                                  idtab_append(idt, (idkey_t)buf.st_rdev);
 445  445  
 446  446                          seen_console++;
 447  447                  }
 448  448  
 449  449                  (void) snprintf(devpath, MAXPATHLEN - 1, "/dev/%s", ptr);
 450  450  
 451  451                  if (stat(devpath, &buf) == -1)
 452  452                          goto err;
 453  453  
 454  454                  idtab_append(idt, (idkey_t)buf.st_rdev);
 455  455          }
 456  456  
 457  457          return (0);
 458  458  
 459  459  err:
 460  460          uu_warn(gettext("unknown terminal name -- %s\n"), ptr);
 461  461          return (-1);
 462  462  }
 463  463  
 464  464  static int
 465  465  parse_projects(idtab_t *idt, char *arg)
 466  466  {
 467  467          char *ptr, *next;
 468  468          projid_t projid;
 469  469          idkey_t id;
 470  470  
 471  471          for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) {
 472  472                  if (isdigit(ptr[0])) {
 473  473                          id = strtol(ptr, &next, 10);
 474  474  
 475  475                          if (next != ptr && *next == '\0') {
 476  476                                  idtab_append(idt, id);
 477  477                                  continue;
 478  478                          }
 479  479                  }
 480  480  
 481  481                  if ((projid = getprojidbyname(ptr)) != -1)
 482  482                          idtab_append(idt, projid);
 483  483                  else
 484  484                          goto err;
 485  485          }
 486  486  
 487  487          return (0);
 488  488  
 489  489  err:
 490  490          uu_warn(gettext("invalid project name -- %s\n"), ptr);
 491  491          return (-1);
 492  492  }
 493  493  
 494  494  static int
 495  495  parse_zones(idtab_t *idt, char *arg)
 496  496  {
 497  497          char *ptr;
 498  498          zoneid_t id;
 499  499  
 500  500          for (ptr = strtok(arg, LSEP); ptr != NULL; ptr = strtok(NULL, LSEP)) {
 501  501                  if (zone_get_id(ptr, &id) != 0) {
 502  502                          uu_warn(gettext("invalid zone name -- %s\n"), ptr);
 503  503                          return (-1);
 504  504                  }
 505  505                  idtab_append(idt, id);
 506  506          }
 507  507  
 508  508          return (0);
 509  509  }
 510  510  
 511  511  /*ARGSUSED*/
 512  512  static int
 513  513  opt_euid(char c, char *arg)
 514  514  {
 515  515          return (parse_uids(&g_psexp.ps_euids, arg));
 516  516  }
 517  517  
 518  518  /*ARGSUSED*/
 519  519  static int
 520  520  opt_uid(char c, char *arg)
 521  521  {
 522  522          return (parse_uids(&g_psexp.ps_ruids, arg));
 523  523  }
 524  524  
 525  525  /*ARGSUSED*/
 526  526  static int
 527  527  opt_gid(char c, char *arg)
 528  528  {
 529  529          return (parse_gids(&g_psexp.ps_rgids, arg));
 530  530  }
 531  531  
 532  532  static int
 533  533  opt_ppid(char c, char *arg)
 534  534  {
 535  535          return (parse_ids(&g_psexp.ps_ppids, arg, 10, c, 0));
 536  536  }
 537  537  
 538  538  static int
 539  539  opt_pgrp(char c, char *arg)
 540  540  {
 541  541          return (parse_ids(&g_psexp.ps_pgids, arg, 10, c, getpgrp()));
 542  542  }
 543  543  
 544  544  static int
 545  545  opt_sid(char c, char *arg)
 546  546  {
 547  547          return (parse_ids(&g_psexp.ps_sids, arg, 10, c, getsid(0)));
 548  548  }
 549  549  
 550  550  /*ARGSUSED*/
 551  551  static int
 552  552  opt_term(char c, char *arg)
 553  553  {
 554  554          return (parse_ttys(&g_psexp.ps_ttys, arg));
 555  555  }
 556  556  
 557  557  /*ARGSUSED*/
 558  558  static int
 559  559  opt_projid(char c, char *arg)
 560  560  {
 561  561          return (parse_projects(&g_psexp.ps_projids, arg));
 562  562  }
 563  563  
 564  564  static int
 565  565  opt_taskid(char c, char *arg)
 566  566  {
 567  567          return (parse_ids(&g_psexp.ps_taskids, arg, 10, c, gettaskid()));
 568  568  }
 569  569  
 570  570  /*ARGSUSED*/
 571  571  static int
 572  572  opt_zoneid(char c, char *arg)
 573  573  {
 574  574          return (parse_zones(&g_psexp.ps_zoneids, arg));
 575  575  }
 576  576  
 577  577  static int
 578  578  opt_ctid(char c, char *arg)
 579  579  {
 580  580          return (parse_ids(&g_psexp.ps_ctids, arg, 10, c, getctid()));
 581  581  }
 582  582  
 583  583  static void
 584  584  print_usage(FILE *stream)
 585  585  {
 586  586          if (g_flags & F_KILL)
 587  587                  (void) fprintf(stream, gettext(PKILL_USAGE), g_pname);
 588  588          else
 589  589                  (void) fprintf(stream, gettext(PGREP_USAGE), g_pname);
  
    | 
      ↓ open down ↓ | 
    589 lines elided | 
    
      ↑ open up ↑ | 
  
 590  590  }
 591  591  
 592  592  int
 593  593  main(int argc, char *argv[])
 594  594  {
 595  595          void (*funcp)(psinfo_t *);
 596  596  
 597  597          const char *optstr;
 598  598          optdesc_t *optd;
 599  599          int nmatches, c;
      600 +        const char *zroot;
      601 +        char buf[PATH_MAX];
 600  602  
 601  603          DIR *dirp;
 602  604  
 603  605          (void) setlocale(LC_ALL, "");
 604  606          (void) textdomain(TEXT_DOMAIN);
 605  607  
 606  608          UU_EXIT_FATAL = E_ERROR;
 607  609  
 608  610          g_pname = uu_setpname(argv[0]);
 609  611          g_pid = getpid();
 610  612  
 611  613          psexp_create(&g_psexp);
 612  614  
 613  615          if (strcmp(g_pname, "pkill") == 0) {
 614  616  
 615  617                  if (argc > 1 && argv[1][0] == '-' &&
 616  618                      str2sig(&argv[1][1], &g_signal) == 0) {
 617  619                          argv[1] = argv[0];
 618  620                          argv++;
  
    | 
      ↓ open down ↓ | 
    9 lines elided | 
    
      ↑ open up ↑ | 
  
 619  621                          argc--;
 620  622                  }
 621  623  
 622  624                  optstr = PKILL_OPTS;
 623  625                  g_flags |= F_KILL;
 624  626          } else
 625  627                  optstr = PGREP_OPTS;
 626  628  
 627  629          opterr = 0;
 628  630  
      631 +        zroot = zone_get_nroot();
      632 +        if (zroot != NULL) {
      633 +                (void) snprintf(buf, sizeof (buf), "%s/%s", zroot, g_procdir);
      634 +                g_procdir = buf;
      635 +        }
      636 +
 629  637          while (optind < argc) {
 630  638                  while ((c = getopt(argc, argv, optstr)) != (int)EOF) {
 631  639  
 632  640                          if (c == ':' || c == '?' ||
 633  641                              g_optdtab[c - 'A'].o_opts == 0) {
 634  642                                  if (c == ':') {
 635  643                                          uu_warn(
 636  644                                              gettext("missing argument -- %c\n"),
 637  645                                              optopt);
 638  646                                  } else if (optopt != '?') {
 639  647                                          uu_warn(
 640  648                                              gettext("illegal option -- %c\n"),
 641  649                                              optopt);
 642  650                                  }
 643  651  
 644  652                                  print_usage(stderr);
 645  653                                  return (E_USAGE);
 646  654                          }
 647  655  
 648  656                          optd = &g_optdtab[c - 'A'];
 649  657  
 650  658                          if (optd->o_opts & OPT_SETB)
 651  659                                  *((ushort_t *)optd->o_ptr) |= optd->o_bits;
 652  660  
 653  661                          if (optd->o_opts & OPT_CLRB)
 654  662                                  *((ushort_t *)optd->o_ptr) &= ~optd->o_bits;
 655  663  
 656  664                          if (optd->o_opts & OPT_STR)
 657  665                                  *((char **)optd->o_ptr) = optarg;
 658  666  
 659  667                          if (optd->o_opts & OPT_CRIT)
 660  668                                  g_flags |= F_HAVE_CRIT;
 661  669  
 662  670                          if (optd->o_opts & OPT_FUNC) {
 663  671                                  if (optd->o_func(c, optarg) == -1)
 664  672                                          return (E_USAGE);
 665  673                          }
 666  674                  }
 667  675  
 668  676                  if (optind < argc) {
 669  677                          if (g_psexp.ps_pat != NULL) {
 670  678                                  uu_warn(gettext("illegal argument -- %s\n"),
 671  679                                      argv[optind]);
 672  680                                  print_usage(stderr);
 673  681                                  return (E_USAGE);
 674  682                          }
 675  683  
 676  684                          g_psexp.ps_pat = argv[optind++];
 677  685                          g_flags |= F_HAVE_CRIT;
 678  686                  }
 679  687          }
 680  688  
 681  689          if ((g_flags & F_NEWEST) && (g_flags & F_OLDEST)) {
 682  690                  uu_warn(gettext("-n and -o are mutually exclusive\n"));
 683  691                  print_usage(stderr);
 684  692                  return (E_USAGE);
 685  693          }
 686  694  
 687  695          if ((g_flags & F_HAVE_CRIT) == 0) {
 688  696                  uu_warn(gettext("No matching criteria specified\n"));
 689  697                  print_usage(stderr);
 690  698                  return (E_USAGE);
 691  699          }
 692  700  
 693  701          if (psexp_compile(&g_psexp) == -1) {
 694  702                  psexp_destroy(&g_psexp);
 695  703                  return (E_USAGE);
 696  704          }
 697  705  
 698  706          if ((dirp = open_proc_dir(g_procdir)) == NULL)
 699  707                  return (E_ERROR);
 700  708  
 701  709          if (g_flags & F_KILL)
 702  710                  funcp = kill_proc;
 703  711          else if (g_flags & F_LONG_OUT)
 704  712                  funcp = print_proc_long;
 705  713          else
 706  714                  funcp = print_proc;
 707  715  
 708  716          nmatches = scan_proc_dir(g_procdir, dirp, &g_psexp, funcp);
 709  717  
 710  718          if (g_flags & F_OUTPUT)
 711  719                  (void) fputc('\n', stdout);
 712  720  
 713  721          psexp_destroy(&g_psexp);
 714  722          return (nmatches ? E_MATCH : E_NOMATCH);
 715  723  }
  
    | 
      ↓ open down ↓ | 
    77 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX