1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1992-2008 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <gsf@research.att.com> * 18 * David Korn <dgk@research.att.com> * 19 * * 20 ***********************************************************************/ 21 #pragma prototyped 22 23 #define FORMAT "PID=%(pid)d PPID=%(ppid)d PGID=%(pgid)d TID=%(tid)d SID=%(sid)d" 24 25 static const char usage[] = 26 "[-?\n@(#)$Id: pids (AT&T Research) 2008-04-01 $\n]" 27 USAGE_LICENSE 28 "[+NAME?pids - list calling shell process ids]" 29 "[+DESCRIPTION?When invoked as a shell builtin, \bpids\b lists one or " 30 "more of the calling process ids determined by \bgetpid\b(2), " 31 "\bgetppid\b(2), \bgetpgrp\b(2), \btcgetpgrp\b(2) and \bgetsid\b(2). " 32 "Unknown or invalid ids have the value \b-1\b.]" 33 "[f:format?List the ids specified by \aformat\a. \aformat\a follows " 34 "\bprintf\b(3) conventions, except that \bsfio\b(3) inline ids are used " 35 "instead of arguments: " 36 "%[-+]][\awidth\a[.\aprecis\a[.\abase\a]]]]]](\aid\a)\achar\a. The " 37 "supported \aid\as are:]:[format:=" FORMAT "]" 38 "{" 39 "[+pid?The process id.]" 40 "[+pgid?The process group id.]" 41 "[+ppid?The parent process id.]" 42 "[+tid|tty?The controlling terminal id.]" 43 "[+sid?The session id.]" 44 "}" 45 "[+SEE ALSO?\bgetpid\b(2), \bgetppid\b(2), \bgetpgrp\b(2), " 46 "\btcgetpgrp\b(2), \bgetsid\b(2)]" 47 ; 48 49 #include <cmd.h> 50 #include <ast_tty.h> 51 #include <sfdisc.h> 52 53 /* 54 * sfkeyprintf() lookup 55 * handle==0 for heading 56 */ 57 58 static int 59 key(void* handle, Sffmt_t* fp, const char* arg, char** ps, Sflong_t* pn) 60 { 61 register char* s; 62 int fd; 63 long tid; 64 65 if (!(s = fp->t_str) || streq(s, "pid")) 66 *pn = getpid(); 67 else if (streq(s, "pgid")) 68 *pn = getpgid(0); 69 else if (streq(s, "ppid")) 70 *pn = getppid(); 71 else if (streq(s, "tid") || streq(s, "tty")) 72 { 73 for (fd = 0; fd < 3; fd++) 74 if ((tid = tcgetpgrp(fd)) >= 0) 75 break; 76 *pn = tid; 77 } 78 else if (streq(s, "sid")) 79 *pn = getsid(0); 80 else if (streq(s, "format")) 81 *ps = (char*)handle; 82 else 83 { 84 error(2, "%s: unknown format identifier", s); 85 return 0; 86 } 87 return 1; 88 } 89 90 int 91 b_pids(int argc, char** argv, void* context) 92 { 93 char* format = 0; 94 95 cmdinit(argc, argv, context, ERROR_CATALOG, 0); 96 for (;;) 97 { 98 switch (optget(argv, usage)) 99 { 100 case 'f': 101 format = opt_info.arg; 102 continue; 103 case '?': 104 error(ERROR_USAGE|4, "%s", opt_info.arg); 105 continue; 106 case ':': 107 error(2, "%s", opt_info.arg); 108 continue; 109 } 110 break; 111 } 112 argv += opt_info.index; 113 if (error_info.errors || *argv) 114 error(ERROR_USAGE|4, "%s", optusage(NiL)); 115 if (!format) 116 format = FORMAT; 117 sfkeyprintf(sfstdout, format, format, key, NiL); 118 sfprintf(sfstdout, "\n"); 119 return 0; 120 } 121