1N/A/***********************************************************************
1N/A* *
1N/A* This software is part of the ast package *
1N/A* Copyright (c) 1992-2011 AT&T Intellectual Property *
1N/A* and is licensed under the *
1N/A* Common Public License, Version 1.0 *
1N/A* by AT&T Intellectual Property *
1N/A* *
1N/A* A copy of the License is available at *
1N/A* http://www.opensource.org/licenses/cpl1.0.txt *
1N/A* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
1N/A* *
1N/A* Information and Software Systems Research *
1N/A* AT&T Research *
1N/A* Florham Park NJ *
1N/A* *
1N/A* Glenn Fowler <gsf@research.att.com> *
1N/A* David Korn <dgk@research.att.com> *
1N/A* *
1N/A***********************************************************************/
1N/A#pragma prototyped
1N/A
1N/A#define FORMAT "PID=%(pid)d PPID=%(ppid)d PGID=%(pgid)d TID=%(tid)d SID=%(sid)d"
1N/A
1N/Astatic const char usage[] =
1N/A"[-?\n@(#)$Id: pids (AT&T Research) 2008-04-01 $\n]"
1N/AUSAGE_LICENSE
1N/A"[+NAME?pids - list calling shell process ids]"
1N/A"[+DESCRIPTION?When invoked as a shell builtin, \bpids\b lists one or "
1N/A "more of the calling process ids determined by \bgetpid\b(2), "
1N/A "\bgetppid\b(2), \bgetpgrp\b(2), \btcgetpgrp\b(2) and \bgetsid\b(2). "
1N/A "Unknown or invalid ids have the value \b-1\b.]"
1N/A"[f:format?List the ids specified by \aformat\a. \aformat\a follows "
1N/A "\bprintf\b(3) conventions, except that \bsfio\b(3) inline ids are used "
1N/A "instead of arguments: "
1N/A "%[-+]][\awidth\a[.\aprecis\a[.\abase\a]]]]]](\aid\a)\achar\a. The "
1N/A "supported \aid\as are:]:[format:=" FORMAT "]"
1N/A "{"
1N/A "[+pid?The process id.]"
1N/A "[+pgid?The process group id.]"
1N/A "[+ppid?The parent process id.]"
1N/A "[+tid|tty?The controlling terminal id.]"
1N/A "[+sid?The session id.]"
1N/A "}"
1N/A"[+SEE ALSO?\bgetpid\b(2), \bgetppid\b(2), \bgetpgrp\b(2), "
1N/A "\btcgetpgrp\b(2), \bgetsid\b(2)]"
1N/A;
1N/A
1N/A#include <cmd.h>
1N/A#include <ast_tty.h>
1N/A#include <sfdisc.h>
1N/A
1N/A/*
1N/A * sfkeyprintf() lookup
1N/A * handle==0 for heading
1N/A */
1N/A
1N/Astatic int
1N/Akey(void* handle, Sffmt_t* fp, const char* arg, char** ps, Sflong_t* pn)
1N/A{
1N/A register char* s;
1N/A int fd;
1N/A long tid;
1N/A
1N/A if (!(s = fp->t_str) || streq(s, "pid"))
1N/A *pn = getpid();
1N/A else if (streq(s, "pgid"))
1N/A *pn = getpgid(0);
1N/A else if (streq(s, "ppid"))
1N/A *pn = getppid();
1N/A else if (streq(s, "tid") || streq(s, "tty"))
1N/A {
1N/A for (fd = 0; fd < 3; fd++)
1N/A if ((tid = tcgetpgrp(fd)) >= 0)
1N/A break;
1N/A *pn = tid;
1N/A }
1N/A else if (streq(s, "sid"))
1N/A *pn = getsid(0);
1N/A else if (streq(s, "format"))
1N/A *ps = (char*)handle;
1N/A else
1N/A {
1N/A error(2, "%s: unknown format identifier", s);
1N/A return 0;
1N/A }
1N/A return 1;
1N/A}
1N/A
1N/Aint
1N/Ab_pids(int argc, char** argv, void* context)
1N/A{
1N/A char* format = 0;
1N/A
1N/A cmdinit(argc, argv, context, ERROR_CATALOG, 0);
1N/A for (;;)
1N/A {
1N/A switch (optget(argv, usage))
1N/A {
1N/A case 'f':
1N/A format = opt_info.arg;
1N/A continue;
1N/A case '?':
1N/A error(ERROR_USAGE|4, "%s", opt_info.arg);
1N/A break;
1N/A case ':':
1N/A error(2, "%s", opt_info.arg);
1N/A break;
1N/A }
1N/A break;
1N/A }
1N/A argv += opt_info.index;
1N/A if (error_info.errors || *argv)
1N/A error(ERROR_USAGE|4, "%s", optusage(NiL));
1N/A if (!format)
1N/A format = FORMAT;
1N/A sfkeyprintf(sfstdout, format, format, key, NiL);
1N/A sfprintf(sfstdout, "\n");
1N/A return 0;
1N/A}