1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1992-2012 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Eclipse Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.eclipse.org/org/documents/epl-v10.html * 11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) * 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) 2011-08-27 $\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 = getpgrp(); 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 #if _lib_getsid 80 *pn = getsid(0); 81 #else 82 *pn = -1; 83 #endif 84 else if (streq(s, "format")) 85 *ps = (char*)handle; 86 else 87 { 88 error(2, "%s: unknown format identifier", s); 89 return 0; 90 } 91 return 1; 92 } 93 94 int 95 b_pids(int argc, char** argv, Shbltin_t* context) 96 { 97 char* format = 0; 98 99 cmdinit(argc, argv, context, ERROR_CATALOG, 0); 100 for (;;) 101 { 102 switch (optget(argv, usage)) 103 { 104 case 'f': 105 format = opt_info.arg; 106 continue; 107 case '?': 108 error(ERROR_USAGE|4, "%s", opt_info.arg); 109 break; 110 case ':': 111 error(2, "%s", opt_info.arg); 112 break; 113 } 114 break; 115 } 116 argv += opt_info.index; 117 if (error_info.errors || *argv) 118 error(ERROR_USAGE|4, "%s", optusage(NiL)); 119 if (!format) 120 format = FORMAT; 121 sfkeyprintf(sfstdout, format, format, key, NiL); 122 sfprintf(sfstdout, "\n"); 123 return 0; 124 } 125