present for Jim

This commit is contained in:
albert
2002-12-03 09:07:59 +00:00
parent 538f249009
commit 7ac9a0e1f5
8 changed files with 100 additions and 38 deletions

View File

@ -386,7 +386,7 @@ select_procs (void)
else if (opt_sid && ! match_numlist (task.session, opt_sid)) else if (opt_sid && ! match_numlist (task.session, opt_sid))
match = 0; match = 0;
else if (opt_term) { else if (opt_term) {
if (task.tty == -1) { if (task.tty == 0) {
match = 0; match = 0;
} else { } else {
char tty[256]; char tty[256];

View File

@ -195,7 +195,7 @@ unsigned dev_to_tty(char *restrict ret, unsigned chop, int dev, int pid, unsigne
char *restrict tmp = buf; char *restrict tmp = buf;
unsigned i = 0; unsigned i = 0;
int c; int c;
if((short)dev == (short)-1) goto fail; if((short)dev == (short)0) goto no_tty;
if(linux_version_code > LINUX_VERSION(2, 5, 0)){ /* didn't get done yet */ if(linux_version_code > LINUX_VERSION(2, 5, 0)){ /* didn't get done yet */
if(link_name(tmp, major(dev), minor(dev), pid, "tty" )) goto abbrev; if(link_name(tmp, major(dev), minor(dev), pid, "tty" )) goto abbrev;
} }
@ -203,7 +203,8 @@ unsigned dev_to_tty(char *restrict ret, unsigned chop, int dev, int pid, unsigne
if( link_name(tmp, major(dev), minor(dev), pid, "fd/2" )) goto abbrev; if( link_name(tmp, major(dev), minor(dev), pid, "fd/2" )) goto abbrev;
if( guess_name(tmp, major(dev), minor(dev) )) goto abbrev; if( guess_name(tmp, major(dev), minor(dev) )) goto abbrev;
if( link_name(tmp, major(dev), minor(dev), pid, "fd/255")) goto abbrev; if( link_name(tmp, major(dev), minor(dev), pid, "fd/255")) goto abbrev;
fail: // fall through if unable to find a device file
no_tty:
strcpy(ret, "?"); strcpy(ret, "?");
return 1; return 1;
abbrev: abbrev:
@ -232,7 +233,7 @@ abbrev:
int tty_to_dev(const char *restrict const name) { int tty_to_dev(const char *restrict const name) {
struct stat sbuf; struct stat sbuf;
static char buf[32]; static char buf[32];
if(stat(name, &sbuf) >= 0) return sbuf.st_rdev; if(name[0]=='/' && stat(name, &sbuf) >= 0) return sbuf.st_rdev;
snprintf(buf,32,"/dev/%s",name); snprintf(buf,32,"/dev/%s",name);
if(stat(buf, &sbuf) >= 0) return sbuf.st_rdev; if(stat(buf, &sbuf) >= 0) return sbuf.st_rdev;
snprintf(buf,32,"/dev/tty%s",name); snprintf(buf,32,"/dev/tty%s",name);

View File

@ -14,6 +14,7 @@
#include "procps.h" #include "procps.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@ -74,19 +75,35 @@ void freeproc(proc_t* p) {
static void status2proc(const char *S, proc_t *restrict P, int fill){ static void status2proc(const char *S, proc_t *restrict P){
char* tmp; char* tmp;
if (fill == 1) { int i;
memset(P->cmd, 0, sizeof P->cmd);
sscanf (S, "Name:\t%15c", P->cmd); // The cmd is escaped, with \\ and \n for backslash and newline.
tmp = strchr(P->cmd,'\n'); // It certainly may contain "VmSize:" and similar crap.
*tmp='\0'; if(unlikely(strncmp("Name:\t",S,6))) fprintf(stderr, "Internal error!\n");
tmp = strstr (S,"State"); S += 6;
sscanf (tmp, "State:\t%c", &P->state); i = 0;
while(i < sizeof P->cmd - 1){
int c = *S++;
if(unlikely(c=='\n')) break;
if(unlikely(c=='\0')) return; // should never happen
if(unlikely(c=='\\')){
c = *S++;
if(c=='\n') break; // should never happen
if(!c) break; // should never happen
if(c=='n') c='\n'; // else we assume it is '\\'
} }
P->cmd[i++] = c;
}
P->cmd[i] = '\0';
tmp = strstr (S,"State:\t");
if(likely((long)tmp)) P->state = tmp[7];
else fprintf(stderr, "Internal error!\n");
tmp = strstr (S,"Pid:"); tmp = strstr (S,"Pid:");
if(tmp) sscanf (tmp, if(likely((long)tmp)) sscanf (tmp,
"Pid:\t%d\n" "Pid:\t%d\n"
"PPid:\t%d\n", "PPid:\t%d\n",
&P->pid, &P->pid,
@ -95,21 +112,21 @@ static void status2proc(const char *S, proc_t *restrict P, int fill){
else fprintf(stderr, "Internal error!\n"); else fprintf(stderr, "Internal error!\n");
tmp = strstr (S,"Uid:"); tmp = strstr (S,"Uid:");
if(tmp) sscanf (tmp, if(likely((long)tmp)) sscanf (tmp,
"Uid:\t%d\t%d\t%d\t%d", "Uid:\t%d\t%d\t%d\t%d",
&P->ruid, &P->euid, &P->suid, &P->fuid &P->ruid, &P->euid, &P->suid, &P->fuid
); );
else fprintf(stderr, "Internal error!\n"); else fprintf(stderr, "Internal error!\n");
tmp = strstr (S,"Gid:"); tmp = strstr (S,"Gid:");
if(tmp) sscanf (tmp, if(likely((long)tmp)) sscanf (tmp,
"Gid:\t%d\t%d\t%d\t%d", "Gid:\t%d\t%d\t%d\t%d",
&P->rgid, &P->egid, &P->sgid, &P->fgid &P->rgid, &P->egid, &P->sgid, &P->fgid
); );
else fprintf(stderr, "Internal error!\n"); else fprintf(stderr, "Internal error!\n");
tmp = strstr (S,"VmSize:"); tmp = strstr (S,"VmSize:");
if(tmp) sscanf (tmp, if(likely((long)tmp)) sscanf (tmp,
"VmSize: %lu kB\n" "VmSize: %lu kB\n"
"VmLck: %lu kB\n" "VmLck: %lu kB\n"
"VmRSS: %lu kB\n" "VmRSS: %lu kB\n"
@ -132,7 +149,7 @@ static void status2proc(const char *S, proc_t *restrict P, int fill){
} }
tmp = strstr (S,"SigPnd:"); tmp = strstr (S,"SigPnd:");
if(tmp) sscanf (tmp, if(likely((long)tmp)) sscanf (tmp,
#ifdef SIGNAL_STRING #ifdef SIGNAL_STRING
"SigPnd: %s SigBlk: %s SigIgn: %s %*s %s", "SigPnd: %s SigBlk: %s SigIgn: %s %*s %s",
P->signal, P->blocked, P->sigignore, P->sigcatch P->signal, P->blocked, P->sigignore, P->sigcatch
@ -153,17 +170,25 @@ static void status2proc(const char *S, proc_t *restrict P, int fill){
*/ */
static void stat2proc(const char* S, proc_t *restrict P) { static void stat2proc(const char* S, proc_t *restrict P) {
int num; int num;
char* tmp = strrchr(S, ')'); /* split into "PID (cmd" and "<rest>" */ char* tmp;
*tmp = '\0'; /* replace trailing ')' with NUL */
/* fill in default values for older kernels */ /* fill in default values for older kernels */
P->exit_signal = SIGCHLD; P->exit_signal = SIGCHLD;
P->processor = 0; P->processor = 0;
P->rtprio = -1; P->rtprio = -1;
P->sched = -1; P->sched = -1;
/* parse these two strings separately, skipping the leading "(". */
memset(P->cmd, 0, sizeof P->cmd); /* clear even though *P xcalloc'd ?! */ P->pid = strtol(S, &tmp, 10);
sscanf(S, "%d (%15c", &P->pid, P->cmd); /* comm[16] in kernel */ S = tmp + 2;
num = sscanf(tmp + 2, /* skip space after ')' too */ tmp = strrchr(S, ')'); // split into "PID (cmd" and "<rest>"
num = tmp - S;
if(unlikely(num > sizeof P->cmd)) num = sizeof P->cmd; // 1 too big
num--; // ditch the ')' character
memcpy(P->cmd, S, num);
P->cmd[num] = '\0';
S = tmp + 2; // skip ") "
num = sscanf(S,
"%c " "%c "
"%d %d %d %d %d " "%d %d %d %d %d "
"%lu %lu %lu %lu %lu " "%lu %lu %lu %lu %lu "
@ -193,10 +218,6 @@ static void stat2proc(const char* S, proc_t *restrict P) {
/* -- Linux 2.2.8 to 2.5.17 end here -- */ /* -- Linux 2.2.8 to 2.5.17 end here -- */
&P->rtprio, &P->sched /* both added to 2.5.18 */ &P->rtprio, &P->sched /* both added to 2.5.18 */
); );
/* fprintf(stderr, "stat2proc converted %d fields.\n",num); */
if (P->tty == 0)
P->tty = -1; /* the old notty val, update elsewhere bef. moving to 0 */
} }
static void statm2proc(const char* s, proc_t *restrict P) { static void statm2proc(const char* s, proc_t *restrict P) {
@ -212,8 +233,10 @@ static int file2str(const char *directory, const char *what, char *ret, int cap)
int fd, num_read; int fd, num_read;
sprintf(filename, "%s/%s", directory, what); sprintf(filename, "%s/%s", directory, what);
if ( (fd = open(filename, O_RDONLY, 0)) == -1 ) return -1; fd = open(filename, O_RDONLY, 0);
if ( (num_read = read(fd, ret, cap - 1)) <= 0 ) num_read = -1; if(unlikely(fd==-1)) return -1;
num_read = read(fd, ret, cap - 1);
if(unlikely(num_read<=0)) num_read = -1;
else ret[num_read] = 0; else ret[num_read] = 0;
close(fd); close(fd);
return num_read; return num_read;
@ -226,7 +249,8 @@ static char** file2strvec(const char* directory, const char* what) {
int align; int align;
sprintf(buf, "%s/%s", directory, what); sprintf(buf, "%s/%s", directory, what);
if ( (fd = open(buf, O_RDONLY, 0) ) == -1 ) return NULL; fd = open(buf, O_RDONLY, 0);
if(fd==-1) return NULL;
/* read whole file into a memory buffer, allocating as we go */ /* read whole file into a memory buffer, allocating as we go */
while ((n = read(fd, buf, sizeof buf - 1)) > 0) { while ((n = read(fd, buf, sizeof buf - 1)) > 0) {
@ -272,6 +296,37 @@ static char** file2strvec(const char* directory, const char* what) {
return ret; return ret;
} }
// warning: interface may change
int read_cmdline(char *restrict const dst, unsigned sz, unsigned pid){
char name[32];
int fd;
int n = 0;
snprintf(name, sizeof name, "/proc/%u/cmdline", pid);
fd = open(name, O_RDONLY);
if(fd==-1) return NULL;
dst[0] = '\0';
for(;;){
ssize_t r = read(fd,dst+n,sz-n);
if(r==-1){
if(errno==EINTR) continue;
break;
}
n += r;
if(n==sz) break; // filled the buffer
if(r==0) break; // EOF
}
if(n){
int i;
if(n==sz) n--;
dst[n] = '\0';
i=n;
while(i--){
int c = dst[i];
if(c<' ' || c>'~') dst[i]=' ';
}
}
return n;
}
/* These are some nice GNU C expression subscope "inline" functions. /* These are some nice GNU C expression subscope "inline" functions.
* The can be used with arbitrary types and evaluate their arguments * The can be used with arbitrary types and evaluate their arguments
@ -361,7 +416,7 @@ next_proc: /* get next PID for consideration */
if (flags & PROC_FILLSTATUS) { /* read, parse /proc/#/status */ if (flags & PROC_FILLSTATUS) { /* read, parse /proc/#/status */
if ((file2str(path, "status", sbuf, sizeof sbuf)) != -1 ){ if ((file2str(path, "status", sbuf, sizeof sbuf)) != -1 ){
status2proc(sbuf, p, 0 /*FIXME*/); status2proc(sbuf, p);
} }
} }
@ -459,7 +514,7 @@ next_proc: /* get next PID for consideration */
/* if (flags & PROC_FILLSTATUS) { */ /* read, parse /proc/#/status */ /* if (flags & PROC_FILLSTATUS) { */ /* read, parse /proc/#/status */
if ((file2str(path, "status", sbuf, sizeof sbuf)) != -1 ){ if ((file2str(path, "status", sbuf, sizeof sbuf)) != -1 ){
status2proc(sbuf, p, 0 /*FIXME*/); status2proc(sbuf, p);
} }
/* }*/ /* }*/
@ -509,7 +564,7 @@ void look_up_our_self(proc_t *p) {
file2str(path, "statm", sbuf, sizeof sbuf); file2str(path, "statm", sbuf, sizeof sbuf);
statm2proc(sbuf, p); /* ignore statm errors here */ statm2proc(sbuf, p); /* ignore statm errors here */
file2str(path, "status", sbuf, sizeof sbuf); file2str(path, "status", sbuf, sizeof sbuf);
status2proc(sbuf, p, 0 /*FIXME*/); status2proc(sbuf, p);
} }

View File

@ -9,6 +9,7 @@
* in the file COPYING * in the file COPYING
*/ */
#include "procps.h"
#define SIGNAL_STRING #define SIGNAL_STRING
@ -174,6 +175,9 @@ extern void closeproc(PROCTAB* PT);
extern proc_t* readproc(PROCTAB* PT, proc_t* return_buf); extern proc_t* readproc(PROCTAB* PT, proc_t* return_buf);
extern proc_t* ps_readproc(PROCTAB* PT, proc_t* return_buf); extern proc_t* ps_readproc(PROCTAB* PT, proc_t* return_buf);
// warning: interface may change
extern int read_cmdline(char *restrict const dst, unsigned sz, unsigned pid);
extern void look_up_our_self(proc_t *p); extern void look_up_our_self(proc_t *p);
/* deallocate space allocated by readproc /* deallocate space allocated by readproc

View File

@ -144,15 +144,15 @@ static const char *parse_tty(char *str, sel_union *ret){
lookup("/dev/pty%s"); lookup("/dev/pty%s");
lookup("/dev/%snsole"); /* "co" means "console", maybe do all VCs too? */ lookup("/dev/%snsole"); /* "co" means "console", maybe do all VCs too? */
if(!strcmp(str,"-")){ /* "-" means no tty (from AIX) */ if(!strcmp(str,"-")){ /* "-" means no tty (from AIX) */
ret->tty = -1; /* processes w/o tty */ ret->tty = 0; /* processes w/o tty */
return 0; return 0;
} }
if(!strcmp(str,"?")){ /* "?" means no tty, which bash eats (Reno BSD?) */ if(!strcmp(str,"?")){ /* "?" means no tty, which bash eats (Reno BSD?) */
ret->tty = -1; /* processes w/o tty */ ret->tty = 0; /* processes w/o tty */
return 0; return 0;
} }
if(!*(str+1) && (stat(str,&sbuf)>=0)){ /* Kludge! Assume bash ate '?'. */ if(!*(str+1) && (stat(str,&sbuf)>=0)){ /* Kludge! Assume bash ate '?'. */
ret->tty = -1; /* processes w/o tty */ ret->tty = 0; /* processes w/o tty */
return 0; return 0;
} }
#undef lookup #undef lookup

View File

@ -239,6 +239,8 @@ D uninterruptible sleep (usually IO)
R runnable (on run queue) R runnable (on run queue)
S sleeping S sleeping
T traced or stopped T traced or stopped
W paging
X dead
Z a defunct ("zombie") process Z a defunct ("zombie") process
For BSD formats and when the "stat" keyword is used, additional For BSD formats and when the "stat" keyword is used, additional

View File

@ -19,7 +19,7 @@
#define session_leader(p) ((p)->session == (p)->pid) #define session_leader(p) ((p)->session == (p)->pid)
#define process_group_leader(p) ((p)->pgid == (p)->pid) #define process_group_leader(p) ((p)->pgid == (p)->pid)
#define without_a_tty(p) ((unsigned short)((p)->tty) == (unsigned short)-1) #define without_a_tty(p) ((unsigned short)((p)->tty) == (unsigned short)0)
#define some_other_user(p) ((p)->euid != cached_euid) #define some_other_user(p) ((p)->euid != cached_euid)
#define running(p) (((p)->state=='R')||((p)->state=='D')) #define running(p) (((p)->state=='R')||((p)->state=='D'))
#define has_our_euid(p) ((unsigned short)((p)->euid) == (unsigned short)cached_euid) #define has_our_euid(p) ((unsigned short)((p)->euid) == (unsigned short)cached_euid)

View File

@ -468,7 +468,7 @@ selection_collection:
case '-': case '-':
case '?': case '?':
num_found++; num_found++;
ENLIST(tty,-1); ENLIST(tty,0);
if(!NEXTARG) break; if(!NEXTARG) break;
} }
} }