10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2013 Gary Mills
  24  *
  25  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  26  * Use is subject to license terms.
  27  */
  28 
  29 /*
  30  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  31  */
  32 
  33 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  34 /*        All Rights Reserved   */
  35 
  36 /*
  37  * ps -- print things about processes.
  38  */
  39 #include <stdio.h>
  40 #include <ctype.h>
  41 #include <string.h>
  42 #include <errno.h>
  43 #include <fcntl.h>
  44 #include <pwd.h>
  45 #include <grp.h>
  46 #include <sys/types.h>
  47 #include <sys/stat.h>
  48 #include <sys/mkdev.h>
  49 #include <unistd.h>
  50 #include <stdlib.h>
 
 
 269 static  size_t  nlgrps = 0;     /* number elements in the list */
 270 
 271 /* Maximum possible lgroup ID value */
 272 #define MAX_LGRP_ID 256
 273 
 274 static  pid_t   *grpid = NULL;  /* for g option */
 275 static  size_t  grpidsz = 0;
 276 static  int     ngrpid = 0;
 277 
 278 static  pid_t   *sessid = NULL; /* for s option */
 279 static  size_t  sessidsz = 0;
 280 static  int     nsessid = 0;
 281 
 282 static  zoneid_t *zoneid = NULL; /* for z option */
 283 static  size_t  zoneidsz = 0;
 284 static  int     nzoneid = 0;
 285 
 286 static  int     kbytes_per_page;
 287 static  int     pidwidth;
 288 
 289 static  char    *procdir = "/proc";     /* standard /proc directory */
 290 
 291 static struct ughead    euid_tbl;       /* table to store selected euid's */
 292 static struct ughead    ruid_tbl;       /* table to store selected real uid's */
 293 static struct ughead    egid_tbl;       /* table to store selected egid's */
 294 static struct ughead    rgid_tbl;       /* table to store selected real gid's */
 295 static prheader_t *lpsinfobuf;          /* buffer to contain lpsinfo */
 296 static size_t   lpbufsize;
 297 
 298 /*
 299  * This constant defines the sentinal number of process IDs below which we
 300  * only examine individual entries in /proc rather than scanning through
 301  * /proc. This optimization is a huge win in the common case.
 302  */
 303 #define PTHRESHOLD      40
 304 
 305 #define UCB_OPTS        "-aceglnrtuvwxSU"
 306 
 307 static  void    usage(void);
 308 static  char    *getarg(char **);
 309 static  char    *parse_format(char *);
 
 
 322 static  int     gconv(struct ughead *);
 323 static  int     ugfind(id_t, struct ughead *);
 324 static  void    prtime(timestruc_t, int, int);
 325 static  void    przom(psinfo_t *);
 326 static  int     namencnt(char *, int, int);
 327 static  char    *err_string(int);
 328 static  int     print_proc(char *pname);
 329 static  time_t  delta_secs(const timestruc_t *);
 330 static  int     str2id(const char *, pid_t *, long, long);
 331 static  int     str2uid(const char *,  uid_t *, unsigned long, unsigned long);
 332 static  void    *Realloc(void *, size_t);
 333 static  int     pidcmp(const void *p1, const void *p2);
 334 
 335 extern  int     ucbmain(int, char **);
 336 static  int     stdmain(int, char **);
 337 
 338 int
 339 main(int argc, char **argv)
 340 {
 341         const char *me;
 342 
 343         /*
 344          * The original two ps'es are linked in a single binary;
 345          * their main()s are renamed to stdmain for /usr/bin/ps and
 346          * ucbmain for /usr/ucb/ps.
 347          * We try to figure out which instance of ps the user wants to run.
 348          * Traditionally, the UCB variant doesn't require the flag argument
 349          * start with a "-".  If the first argument doesn't start with a
 350          * "-", we call "ucbmain".
 351          * If there's a first argument and it starts with a "-", we check
 352          * whether any of the options isn't acceptable to "ucbmain"; in that
 353          * case we run "stdmain".
 354          * If we can't tell from the options which main to call, we check
 355          * the binary we are running.  We default to "stdmain" but
 356          * any mention in the executable name of "ucb" causes us to call
 357          * ucbmain.
 358          */
 359         if (argv[1] != NULL) {
 360                 if (argv[1][0] != '-')
 361                         return (ucbmain(argc, argv));
 362                 else if (argv[1][strspn(argv[1], UCB_OPTS)] != '\0')
 363                         return (stdmain(argc, argv));
 
 | 
 
 
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2013 Gary Mills
  24  *
  25  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  26  * Use is subject to license terms.
  27  */
  28 
  29 /*
  30  * Copyright 2015 Joyent, Inc.
  31  */
  32 
  33 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  34 /*        All Rights Reserved   */
  35 
  36 /*
  37  * ps -- print things about processes.
  38  */
  39 #include <stdio.h>
  40 #include <ctype.h>
  41 #include <string.h>
  42 #include <errno.h>
  43 #include <fcntl.h>
  44 #include <pwd.h>
  45 #include <grp.h>
  46 #include <sys/types.h>
  47 #include <sys/stat.h>
  48 #include <sys/mkdev.h>
  49 #include <unistd.h>
  50 #include <stdlib.h>
 
 
 269 static  size_t  nlgrps = 0;     /* number elements in the list */
 270 
 271 /* Maximum possible lgroup ID value */
 272 #define MAX_LGRP_ID 256
 273 
 274 static  pid_t   *grpid = NULL;  /* for g option */
 275 static  size_t  grpidsz = 0;
 276 static  int     ngrpid = 0;
 277 
 278 static  pid_t   *sessid = NULL; /* for s option */
 279 static  size_t  sessidsz = 0;
 280 static  int     nsessid = 0;
 281 
 282 static  zoneid_t *zoneid = NULL; /* for z option */
 283 static  size_t  zoneidsz = 0;
 284 static  int     nzoneid = 0;
 285 
 286 static  int     kbytes_per_page;
 287 static  int     pidwidth;
 288 
 289 static  char    procdir[MAXPATHLEN];    /* standard /proc directory */
 290 
 291 static struct ughead    euid_tbl;       /* table to store selected euid's */
 292 static struct ughead    ruid_tbl;       /* table to store selected real uid's */
 293 static struct ughead    egid_tbl;       /* table to store selected egid's */
 294 static struct ughead    rgid_tbl;       /* table to store selected real gid's */
 295 static prheader_t *lpsinfobuf;          /* buffer to contain lpsinfo */
 296 static size_t   lpbufsize;
 297 
 298 /*
 299  * This constant defines the sentinal number of process IDs below which we
 300  * only examine individual entries in /proc rather than scanning through
 301  * /proc. This optimization is a huge win in the common case.
 302  */
 303 #define PTHRESHOLD      40
 304 
 305 #define UCB_OPTS        "-aceglnrtuvwxSU"
 306 
 307 static  void    usage(void);
 308 static  char    *getarg(char **);
 309 static  char    *parse_format(char *);
 
 
 322 static  int     gconv(struct ughead *);
 323 static  int     ugfind(id_t, struct ughead *);
 324 static  void    prtime(timestruc_t, int, int);
 325 static  void    przom(psinfo_t *);
 326 static  int     namencnt(char *, int, int);
 327 static  char    *err_string(int);
 328 static  int     print_proc(char *pname);
 329 static  time_t  delta_secs(const timestruc_t *);
 330 static  int     str2id(const char *, pid_t *, long, long);
 331 static  int     str2uid(const char *,  uid_t *, unsigned long, unsigned long);
 332 static  void    *Realloc(void *, size_t);
 333 static  int     pidcmp(const void *p1, const void *p2);
 334 
 335 extern  int     ucbmain(int, char **);
 336 static  int     stdmain(int, char **);
 337 
 338 int
 339 main(int argc, char **argv)
 340 {
 341         const char *me;
 342         const char *zroot = zone_get_nroot();
 343 
 344         /*
 345          * If this is a branded zone, the native procfs may mounted in a
 346          * non-standard location.  Apply such a path prefix if it exists.
 347          */
 348         (void) snprintf(procdir, sizeof (procdir), "%s/proc", zroot != NULL ?
 349             zroot : "");
 350 
 351         /*
 352          * The original two ps'es are linked in a single binary;
 353          * their main()s are renamed to stdmain for /usr/bin/ps and
 354          * ucbmain for /usr/ucb/ps.
 355          * We try to figure out which instance of ps the user wants to run.
 356          * Traditionally, the UCB variant doesn't require the flag argument
 357          * start with a "-".  If the first argument doesn't start with a
 358          * "-", we call "ucbmain".
 359          * If there's a first argument and it starts with a "-", we check
 360          * whether any of the options isn't acceptable to "ucbmain"; in that
 361          * case we run "stdmain".
 362          * If we can't tell from the options which main to call, we check
 363          * the binary we are running.  We default to "stdmain" but
 364          * any mention in the executable name of "ucb" causes us to call
 365          * ucbmain.
 366          */
 367         if (argv[1] != NULL) {
 368                 if (argv[1][0] != '-')
 369                         return (ucbmain(argc, argv));
 370                 else if (argv[1][strspn(argv[1], UCB_OPTS)] != '\0')
 371                         return (stdmain(argc, argv));
 
 |