File: getproc.c

package info (click to toggle)
procps 1%3A1.2.9-3
  • links: PTS
  • area: main
  • in suites: slink
  • size: 732 kB
  • ctags: 1,324
  • sloc: ansic: 7,125; makefile: 877; sh: 21
file content (167 lines) | stat: -rw-r--r-- 4,301 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#ifndef lint
static char rcsid[] = "$Header: /mnt/devel/CVS/procps/skill/getproc.c,v 1.2 1998/06/23 21:07:21 johnsonm Exp $";
#endif

/*
**  This program may be freely redistributed for noncommercial purposes.
**  This entire comment MUST remain intact.
**
**  Linux support by Chuck Blake (cblake@bbn.com)
**  Copyright 1994 by Jeff Forys (jeff@forys.cranbury.nj.us)
*/

#define	NO_MEXTERN
#include "conf.h"
#undef	NO_MEXTERN

#include <sys/resource.h>	/* for [get|set]priority() */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include "proc/readproc.h"	/* maybe <proc/readproc.h> instead */

extern int MissedProcCnt;

/*
 * Define SigNames, NSig, and TtyDevDir here; they are used by other
 * routines and must be global.  Everyone seems to have their own
 * idea as to what NSIG should be.  Here, `NSig' is the number of
 * signals available, not counting zero.
 */

char *SigMap[] = {
	"0",
	"HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", "BUS", "FPE", "KILL",
	"USR1", "SEGV", "USR2", "PIPE", "ALRM", "TERM", "STKFLT", "CHLD",
	"CONT", "STOP", "TSTP", "TTIN", "TTOU", "IO", "XCPU", "XFSZ", "VTALRM",
	"PROF", "WINCH", "LOST", "PWR", "UNUSED" 
};

int NSig = 31;

#define	SETCMD(dst,src,maxlen) {			\
	extern char *strrchr();				\
	if (maxlen > 0) src[maxlen] = '\0';		\
	dst = (dst = strrchr(src, '/')) ? ++dst: src;	\
}

static char *TtyDevDir = "/dev";

int	Skill;			/* set 1 if running `skill', 0 if `snice' */
int	PrioMin, PrioMax;	/* min and max process priorities */
int	SigPri;			/* signal to send or priority to set */
pid_T	MyPid;			/* pid of this process */
uid_T	MyUid;			/* uid of this process */
char	*ProgName;		/* program name */

/*
 * This is the machine-dependent initialization routine.
 *
 *   - The following global variables must be initialized:
 *     MyPid, MyUid, ProgName, Skill, PrioMin, PrioMax, SigPri
 *   - The working directory will be changed to that which contains the
 *     tty devices (`TtyDevDir'); this makes argument parsing go faster.
 *   - If possible, this routine should raise the priority of this process.
 */

void skill_getpri(int *low, int *high);

void
MdepInit(pname)
	char *pname;
{
	extern char *rindex(), *SysErr();

	MyPid = (pid_T) getpid();
	MyUid = (uid_T) getuid();
	SETCMD(ProgName, pname, 0)

	/*
	 * If we are running as root, raise our priority to better
	 * catch runaway processes.
	 */
	if (MyUid == ROOTUID)
		(void) setpriority(PRIO_PROCESS, MyPid, PRIO_MIN);

	/*
	 * Determine what we are doing to processes we find.  We will
	 * either send them a signal (skill), or renice them (snice).
	 */
	Skill = (strstr(ProgName, "snice") == NULL);

	/*
	 * Set up minimum and maximum process priorities.
	 * Initialize SigPri to either default signal (`skill') or
	 * default priority (`snice').
	 */
	PrioMin = PRIO_MIN;
	PrioMax = PRIO_MAX;
	SigPri = Skill ? SIGTERM : 4;

	/*
	 * chdir to `TtyDevDir' to speed up tty argument parsing.
	 */
	if (chdir(TtyDevDir) < 0) {
		fprintf(stderr, "%s: chdir(%s): %s\n", ProgName, TtyDevDir,
		        SysErr());
		exit(EX_SERR);
	}
}

/*
 * Carry out an action on a particular process.  If this is `skill',
 * then send the process a signal, otherwise this is `snice' so change
 * it's priority.
 *
 * If 0 is returned, the operation was successful, otherwise -1 is
 * returned and `errno' set.
 */
int
MdepAction(pid)
	pid_T pid;
{
	if (Skill)
		return(kill((int)pid, SigPri));
	else
		return(setpriority(PRIO_PROCESS, (int)pid, SigPri));
}

/*
 * Now, set up everything we need to write a GetProc() routine.
 */

#include <fcntl.h>
char *SysErr();

/*
 * GetProc()
 *
 * Fill in and return a `struct ProcInfo' with information about the
 * next process.  If no processes are left, return NULL.
 */
struct ProcInfo *
GetProc()
{
	static struct ProcInfo procinfo;
	static PROCTAB* ptab = NULL;
	static proc_t p;

	/* If this is our first time here call openproc */
	if (!ptab && !(ptab = openproc(PROC_FILLCMD))) {
		fprintf(stderr, "%s: /proc: %s\n", ProgName, SysErr());
		exit(EX_SERR);
	}
	while (readproc(ptab, &p)) {
		procinfo.pi_uid = p.uid;
		procinfo.pi_pid = p.pid;
		procinfo.pi_cmd = p.cmdline ? p.cmdline[0] : p.cmd;
		procinfo.pi_tty = p.tty;
		return &procinfo;
	}
	(void) closeproc(ptab);
	ptab = NULL;
	return (struct ProcInfo*) NULL;
}