/proc code for the 3B15
Stephen J. Friedl
friedl at vsi.COM
Sat Oct 22 14:17:22 AEST 1988
Hi folks,
I've had numerous requests for this code that uses the
/proc filesystem for the 3B15, but I've had numerous bounces
as well - I hope nobody objects to this posting. It runs on
the 3B15 with System V Release 3.1 (or later), compile and
run it, no special system permissions required.
Have fun, and please send me feedback and other /proc
utilities; I'll be a repository for these.
Steve
#----------------- cut here for pstop.c -----------------------
#ident "%W%"
/*
* pstop.c / pstart.c
*
* written by : Stephen J. Friedl
* V-Systems, Inc.
* +1 714 545 6442
* friedl at vsi.com
*
* *NOTE* this program is in the public domain, and may
* be used by anybody for any purpose whatsoever. Please
* pass it around, and enjoy.
*
* This program starts and stops processes from running.
* argv[0] determines the start/stop operation, and the only
* arg is a Pid.
*
* The general idea is to open the /proc slot for this guy,
* extract the current state, and issue the appropriate ioctl()
* instruction to stop (PIOCSTOP) or start (PIOCRUN) the process.
*
* This program must be linked to "pstart" and "pstop", and
* it does not need to be setuid or setgid (it will only
* operate on the current user's processes).
*
* This program checks most kinds of errors and does the
* right thing.
*
* BEGIN-MAKE
pstop : pstop.c
${CC} -o $@ pstop.c
ln pstop pstart
* END-MAKE
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <varargs.h>
#include <sys/types.h>
#include <sys/fs/prioctl.h>
/*
* values to exit()
*/
#ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# define EXIT_FAILURE 1
#endif
/*
* general handy macros
*/
#define pr (void)printf
#define spr (void)sprintf
#define fpr (void)fprintf
#define se stderr
#define STOPPING 1 /* stop the process */
#define STARTING 2 /* start the process */
static int operation = 0; /* what we're doing here... */
static int Pid = 0; /* PID we're looking at */
static char *ProgName = NULL; /* program name (argv[0]) */
static void die();
static void pid_die();
static char *tailpath();
main(argc, argv)
int argc;
char *argv[];
{
struct prpsinfo psinfo; /* ps(1) information */
struct prstatus prstat; /* process status information */
char buf[50], /* buffer for the /proc/##### filename */
*cmdname; /* tail end of the command name */
int proc_fd; /* fildes of the process */
ProgName = argv[0];
if (argc == 1)
die("usage: %s pid", ProgName);
/*
* determine whether we are stopping or starting
*/
cmdname = tailpath(argv[0]);
if (strcmp(cmdname, "pstop") == 0)
operation = STOPPING;
else if (strcmp(cmdname, "pstart") == 0)
operation = STARTING;
else
die("cmdname must be pstop or pstart");
Pid = atoi(argv[1]);
/*
* now that we have the process ID, open the PID file.
* If we can't open it, find out why so we can print
* some kind of reasonable error message.
*
* note that the process must be opened in r/w mode
* to be able to stop or start it...
*/
spr(buf, "/proc/%05d", Pid);
if (proc_fd = open(buf, O_RDWR), proc_fd < 0)
{
switch (errno)
{
case EPERM:
case EACCES:
pid_die("Permission denied");
/*NOTREACHED*/
case ENOENT:
pid_die("No such process");
/*NOTREACHED*/
default:
pid_die("cannot open (errno = %d)", errno);
/*NOTREACHED*/
}
}
/*
* now get PS information about the command so we can see it.
*/
if (ioctl(proc_fd, PIOCPSINFO, &psinfo) < 0)
pid_die("cannot get ps info (errno = %d)", errno);
/*
* now grab the status to see if we're already stopped.
*/
if (ioctl(proc_fd, PIOCSTATUS, &prstat) < 0)
pid_die("cannot get process status (errno = %d)", errno);
if (operation == STOPPING)
{
if (prstat.pr_state == PR_STOP)
pid_die("already stopped");
if (ioctl(proc_fd, PIOCSTOP, 0) < 0)
pid_die("cannot stop process (errno = %d)", errno);
fpr(se, "%s: PID %05d: stopped\n", ProgName, Pid);
}
else
{
if (prstat.pr_state == PR_RUN)
pid_die("already running");
if (ioctl(proc_fd, PIOCRUN, 0) < 0)
pid_die("cannot restart process (errno = %d)", errno);
fpr(se, "%s: PID %05d: restarted\n", ProgName, Pid);
}
exit(EXIT_SUCCESS);
/*NOTREACHED*/
}
/*
* die()
*
* Given a printf-style arg list, print a message (including
* the program name) and exit.
*/
/*VARARGS*/
static void
die(va_alist)
va_dcl
{
va_list args;
char *format;
fpr(stderr, "%s: ", ProgName);
va_start(args);
format = va_arg(args, char *);
(void)vfprintf(stderr, format, args);
va_end(args);
(void)fputc('\n', stderr);
exit(EXIT_FAILURE);
}
/*
* pid_die()
*
* Given a printf-style arg list, print a message (including
* the program name and process ID) and exit.
*
* This is just like die but with the extra PID argument.
*/
/*VARARGS*/
static void
pid_die(va_alist)
va_dcl
{
va_list args;
char *format;
fpr(stderr, "%s: PID %05d: ", ProgName, Pid);
va_start(args);
format = va_arg(args, char *);
(void)vfprintf(stderr, format, args);
va_end(args);
(void)fputc('\n', stderr);
exit(EXIT_FAILURE);
}
/*
* tailpath()
*
* Given a full pathname, return a pointer to the tail end of it.
*/
static char *
tailpath(fullpath)
char *fullpath;
{
char *p;
if (p = strrchr(fullpath, '/'))
return(p+1);
else
return(fullpath);
}
#----------------- cut here for pstop.c -----------------------
--
Steve Friedl V-Systems, Inc. +1 714 545 6442 3B2-kind-of-guy
friedl at vsi.com {backbones}!vsi.com!friedl attmail!vsi!friedl
---------Nancy Reagan on the Three Stooges: "Just say Moe"---------
More information about the Comp.sys.att
mailing list