FreeBSD -F and -L options (but -L may be useless) with sucky error messages
This commit is contained in:
parent
93ed75edc9
commit
6baa2fd34e
72
pgrep.c
72
pgrep.c
@ -19,6 +19,8 @@
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
@ -53,17 +55,20 @@ static int opt_newest = 0;
|
||||
static int opt_negate = 0;
|
||||
static int opt_exact = 0;
|
||||
static int opt_signal = SIGTERM;
|
||||
static int opt_flock = 0;
|
||||
static int opt_case = 0;
|
||||
|
||||
static const char *opt_delim = "\n";
|
||||
static union el *opt_pgrp = NULL;
|
||||
static union el *opt_rgid = NULL;
|
||||
static union el *opt_pid = NULL;
|
||||
static union el *opt_ppid = NULL;
|
||||
static union el *opt_sid = NULL;
|
||||
static union el *opt_term = NULL;
|
||||
static union el *opt_euid = NULL;
|
||||
static union el *opt_ruid = NULL;
|
||||
static char *opt_pattern = NULL;
|
||||
static char *opt_pidfile = NULL;
|
||||
|
||||
|
||||
static int usage (int opt) NORETURN;
|
||||
@ -141,6 +146,44 @@ static int strict_atol (const char *restrict str, long *restrict value)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#include <sys/file.h>
|
||||
|
||||
static union el *read_pidfile(void)
|
||||
{
|
||||
char buf[12];
|
||||
int fd;
|
||||
struct stat sbuf;
|
||||
char *endp;
|
||||
int pid;
|
||||
union el *list = NULL;
|
||||
|
||||
fd = open(opt_pidfile, O_RDONLY|O_NOCTTY|O_NONBLOCK);
|
||||
if(fd<0)
|
||||
goto out;
|
||||
if(fstat(fd,&sbuf) || !S_ISREG(sbuf.st_mode) || sbuf.st_size<1)
|
||||
goto out;
|
||||
if(opt_flock){ // Not that Linux uses this? Maybe fcntl is used?
|
||||
// an errno==EWOULDBLOCK means we accept the PID
|
||||
if(!flock(fd, LOCK_SH|LOCK_NB)) // success is bad
|
||||
goto out;
|
||||
if(errno != EWOULDBLOCK)
|
||||
goto out;
|
||||
}
|
||||
memset(buf,'\0',sizeof buf);
|
||||
buf[read(fd,buf+1,sizeof buf-2)] = '\0';
|
||||
pid = strtoul(buf+1,&endp,10);
|
||||
if(endp<=buf+1 || pid<1 || pid>0x7fffffff)
|
||||
goto out;
|
||||
if(*endp && !isspace(*endp))
|
||||
goto out;
|
||||
list = malloc(2 * sizeof *list);
|
||||
list[0].num = 1;
|
||||
list[1].num = pid;
|
||||
out:
|
||||
close(fd);
|
||||
return list;
|
||||
}
|
||||
|
||||
static int conv_uid (const char *restrict name, union el *restrict e)
|
||||
{
|
||||
struct passwd *pwd;
|
||||
@ -368,6 +411,8 @@ static union el * select_procs (int *num)
|
||||
match = 0;
|
||||
else if (opt_ppid && ! match_numlist (task.ppid, opt_ppid))
|
||||
match = 0;
|
||||
else if (opt_pid && ! match_numlist (task.tgid, opt_pid))
|
||||
match = 0;
|
||||
else if (opt_pgrp && ! match_numlist (task.pgrp, opt_pgrp))
|
||||
match = 0;
|
||||
else if (opt_euid && ! match_numlist (task.euid, opt_euid))
|
||||
@ -484,14 +529,16 @@ static void parse_opts (int argc, char **argv)
|
||||
strcat (opts, "ld:");
|
||||
}
|
||||
|
||||
strcat (opts, "fnovxP:g:s:u:U:G:t:?V");
|
||||
strcat (opts, "LF:fnovxP:g:s:u:U:G:t:?V");
|
||||
|
||||
while ((opt = getopt (argc, argv, opts)) != -1) {
|
||||
switch (opt) {
|
||||
// case 'D': // FreeBSD: print info about non-matches for debugging
|
||||
// break;
|
||||
// case 'F': // FreeBSD: the arg is a file containing a PID to match
|
||||
// break;
|
||||
case 'F': // FreeBSD: the arg is a file containing a PID to match
|
||||
opt_pidfile = strdup (optarg);
|
||||
++criteria_count;
|
||||
break;
|
||||
case 'G': // Solaris: match rgid/rgroup
|
||||
opt_rgid = split_list (optarg, conv_gid);
|
||||
if (opt_rgid == NULL)
|
||||
@ -502,8 +549,9 @@ static void parse_opts (int argc, char **argv)
|
||||
// break;
|
||||
// case 'J': // Solaris: match by project ID (name or number)
|
||||
// break;
|
||||
// case 'L': // FreeBSD: fail if pidfile (see -F) not locked with flock()
|
||||
// break;
|
||||
case 'L': // FreeBSD: fail if pidfile (see -F) not locked with flock()
|
||||
opt_flock++;
|
||||
break;
|
||||
// case 'M': // FreeBSD: specify core (OS crash dump) file
|
||||
// break;
|
||||
// case 'N': // FreeBSD: specify alternate namelist file (for us, System.map -- but we don't need it)
|
||||
@ -596,6 +644,20 @@ static void parse_opts (int argc, char **argv)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(opt_flock && !opt_pidfile){
|
||||
fprintf(stderr, "%s: -L without -F makes no sense\n",progname);
|
||||
usage(0);
|
||||
}
|
||||
|
||||
if(opt_pidfile){
|
||||
opt_pid = read_pidfile();
|
||||
if(!opt_pid){
|
||||
fprintf(stderr, "%s: pidfile not valid\n",progname);
|
||||
usage(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (argc - optind == 1)
|
||||
opt_pattern = argv[optind];
|
||||
else if (argc - optind > 1)
|
||||
|
Loading…
Reference in New Issue
Block a user