17c2fbfb3SApril Chin /***********************************************************************
27c2fbfb3SApril Chin * *
37c2fbfb3SApril Chin * This software is part of the ast package *
4*3e14f97fSRoger A. Faulkner * Copyright (c) 1992-2010 AT&T Intellectual Property *
57c2fbfb3SApril Chin * and is licensed under the *
67c2fbfb3SApril Chin * Common Public License, Version 1.0 *
77c2fbfb3SApril Chin * by AT&T Intellectual Property *
87c2fbfb3SApril Chin * *
97c2fbfb3SApril Chin * A copy of the License is available at *
107c2fbfb3SApril Chin * http://www.opensource.org/licenses/cpl1.0.txt *
117c2fbfb3SApril Chin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
127c2fbfb3SApril Chin * *
137c2fbfb3SApril Chin * Information and Software Systems Research *
147c2fbfb3SApril Chin * AT&T Research *
157c2fbfb3SApril Chin * Florham Park NJ *
167c2fbfb3SApril Chin * *
177c2fbfb3SApril Chin * Glenn Fowler <gsf@research.att.com> *
187c2fbfb3SApril Chin * David Korn <dgk@research.att.com> *
197c2fbfb3SApril Chin * *
207c2fbfb3SApril Chin ***********************************************************************/
217c2fbfb3SApril Chin #pragma prototyped
227c2fbfb3SApril Chin
237c2fbfb3SApril Chin #define FORMAT "PID=%(pid)d PPID=%(ppid)d PGID=%(pgid)d TID=%(tid)d SID=%(sid)d"
247c2fbfb3SApril Chin
257c2fbfb3SApril Chin static const char usage[] =
267c2fbfb3SApril Chin "[-?\n@(#)$Id: pids (AT&T Research) 2008-04-01 $\n]"
277c2fbfb3SApril Chin USAGE_LICENSE
287c2fbfb3SApril Chin "[+NAME?pids - list calling shell process ids]"
297c2fbfb3SApril Chin "[+DESCRIPTION?When invoked as a shell builtin, \bpids\b lists one or "
307c2fbfb3SApril Chin "more of the calling process ids determined by \bgetpid\b(2), "
317c2fbfb3SApril Chin "\bgetppid\b(2), \bgetpgrp\b(2), \btcgetpgrp\b(2) and \bgetsid\b(2). "
327c2fbfb3SApril Chin "Unknown or invalid ids have the value \b-1\b.]"
337c2fbfb3SApril Chin "[f:format?List the ids specified by \aformat\a. \aformat\a follows "
347c2fbfb3SApril Chin "\bprintf\b(3) conventions, except that \bsfio\b(3) inline ids are used "
357c2fbfb3SApril Chin "instead of arguments: "
367c2fbfb3SApril Chin "%[-+]][\awidth\a[.\aprecis\a[.\abase\a]]]]]](\aid\a)\achar\a. The "
377c2fbfb3SApril Chin "supported \aid\as are:]:[format:=" FORMAT "]"
387c2fbfb3SApril Chin "{"
397c2fbfb3SApril Chin "[+pid?The process id.]"
407c2fbfb3SApril Chin "[+pgid?The process group id.]"
417c2fbfb3SApril Chin "[+ppid?The parent process id.]"
427c2fbfb3SApril Chin "[+tid|tty?The controlling terminal id.]"
437c2fbfb3SApril Chin "[+sid?The session id.]"
447c2fbfb3SApril Chin "}"
457c2fbfb3SApril Chin "[+SEE ALSO?\bgetpid\b(2), \bgetppid\b(2), \bgetpgrp\b(2), "
467c2fbfb3SApril Chin "\btcgetpgrp\b(2), \bgetsid\b(2)]"
477c2fbfb3SApril Chin ;
487c2fbfb3SApril Chin
497c2fbfb3SApril Chin #include <cmd.h>
507c2fbfb3SApril Chin #include <ast_tty.h>
517c2fbfb3SApril Chin #include <sfdisc.h>
527c2fbfb3SApril Chin
537c2fbfb3SApril Chin /*
547c2fbfb3SApril Chin * sfkeyprintf() lookup
557c2fbfb3SApril Chin * handle==0 for heading
567c2fbfb3SApril Chin */
577c2fbfb3SApril Chin
587c2fbfb3SApril Chin static int
key(void * handle,Sffmt_t * fp,const char * arg,char ** ps,Sflong_t * pn)597c2fbfb3SApril Chin key(void* handle, Sffmt_t* fp, const char* arg, char** ps, Sflong_t* pn)
607c2fbfb3SApril Chin {
617c2fbfb3SApril Chin register char* s;
627c2fbfb3SApril Chin int fd;
637c2fbfb3SApril Chin long tid;
647c2fbfb3SApril Chin
657c2fbfb3SApril Chin if (!(s = fp->t_str) || streq(s, "pid"))
667c2fbfb3SApril Chin *pn = getpid();
677c2fbfb3SApril Chin else if (streq(s, "pgid"))
687c2fbfb3SApril Chin *pn = getpgid(0);
697c2fbfb3SApril Chin else if (streq(s, "ppid"))
707c2fbfb3SApril Chin *pn = getppid();
717c2fbfb3SApril Chin else if (streq(s, "tid") || streq(s, "tty"))
727c2fbfb3SApril Chin {
737c2fbfb3SApril Chin for (fd = 0; fd < 3; fd++)
747c2fbfb3SApril Chin if ((tid = tcgetpgrp(fd)) >= 0)
757c2fbfb3SApril Chin break;
767c2fbfb3SApril Chin *pn = tid;
777c2fbfb3SApril Chin }
787c2fbfb3SApril Chin else if (streq(s, "sid"))
797c2fbfb3SApril Chin *pn = getsid(0);
807c2fbfb3SApril Chin else if (streq(s, "format"))
817c2fbfb3SApril Chin *ps = (char*)handle;
827c2fbfb3SApril Chin else
837c2fbfb3SApril Chin {
847c2fbfb3SApril Chin error(2, "%s: unknown format identifier", s);
857c2fbfb3SApril Chin return 0;
867c2fbfb3SApril Chin }
877c2fbfb3SApril Chin return 1;
887c2fbfb3SApril Chin }
897c2fbfb3SApril Chin
907c2fbfb3SApril Chin int
b_pids(int argc,char ** argv,void * context)917c2fbfb3SApril Chin b_pids(int argc, char** argv, void* context)
927c2fbfb3SApril Chin {
937c2fbfb3SApril Chin char* format = 0;
947c2fbfb3SApril Chin
957c2fbfb3SApril Chin cmdinit(argc, argv, context, ERROR_CATALOG, 0);
967c2fbfb3SApril Chin for (;;)
977c2fbfb3SApril Chin {
987c2fbfb3SApril Chin switch (optget(argv, usage))
997c2fbfb3SApril Chin {
1007c2fbfb3SApril Chin case 'f':
1017c2fbfb3SApril Chin format = opt_info.arg;
1027c2fbfb3SApril Chin continue;
1037c2fbfb3SApril Chin case '?':
1047c2fbfb3SApril Chin error(ERROR_USAGE|4, "%s", opt_info.arg);
1057c2fbfb3SApril Chin continue;
1067c2fbfb3SApril Chin case ':':
1077c2fbfb3SApril Chin error(2, "%s", opt_info.arg);
1087c2fbfb3SApril Chin continue;
1097c2fbfb3SApril Chin }
1107c2fbfb3SApril Chin break;
1117c2fbfb3SApril Chin }
1127c2fbfb3SApril Chin argv += opt_info.index;
1137c2fbfb3SApril Chin if (error_info.errors || *argv)
1147c2fbfb3SApril Chin error(ERROR_USAGE|4, "%s", optusage(NiL));
1157c2fbfb3SApril Chin if (!format)
1167c2fbfb3SApril Chin format = FORMAT;
1177c2fbfb3SApril Chin sfkeyprintf(sfstdout, format, format, key, NiL);
1187c2fbfb3SApril Chin sfprintf(sfstdout, "\n");
1197c2fbfb3SApril Chin return 0;
1207c2fbfb3SApril Chin }
121