aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--toys/pending/lsof.c85
1 files changed, 33 insertions, 52 deletions
diff --git a/toys/pending/lsof.c b/toys/pending/lsof.c
index 436fdd2a..2852f41f 100644
--- a/toys/pending/lsof.c
+++ b/toys/pending/lsof.c
@@ -8,10 +8,10 @@ config LSOF
bool "lsof"
default n
help
- usage: lsof [-lt] [-p PID1,PID2,...] [NAME]...
+ usage: lsof [-lt] [-p PID1,PID2,...] [FILE...]
- Lists open files. If names are given on the command line, only
- those files will be shown.
+ List all open files belonging to all active processes, or processes using
+ listed FILE(s).
-l list uids numerically
-p for given comma-separated pids only (default all pids)
@@ -25,17 +25,13 @@ GLOBALS(
struct arg_list *p;
struct stat *sought_files;
-
- struct double_list *all_sockets;
- struct double_list *files;
- int last_shown_pid;
- int shown_header;
+ struct double_list *all_sockets, *files;
+ int last_shown_pid, shown_header;
)
struct proc_info {
- char cmd[10];
- int pid;
- char user[12];
+ char cmd[17];
+ int pid, uid;
};
struct file_info {
@@ -43,8 +39,7 @@ struct file_info {
// For output.
struct proc_info pi;
- char* name;
- char fd[8], rw, locks, type[10], device[32], size_off[32], node[32];
+ char *name, fd[8], rw, locks, type[10], device[32], size_off[32], node[32];
// For filtering.
dev_t st_dev;
@@ -78,7 +73,7 @@ static void print_info(void *data)
}
printf("%-9s %5d %10.10s %4s%c%c %7s %18s %9s %10s %s\n",
- fi->pi.cmd, fi->pi.pid, fi->pi.user,
+ fi->pi.cmd, fi->pi.pid, getusername(fi->pi.uid),
fi->fd, fi->rw, fi->locks, fi->type, fi->device, fi->size_off,
fi->node, fi->name);
}
@@ -164,10 +159,8 @@ static void scan_netlink(char *line, int af, char type)
"ENCRYPTFS", "RDMA", "CRYPTO"
};
- if (sscanf(line, "%*p %u %*u %*x %*u %*u %*u %*u %*u %lu", &state, &inode)
- < 2) {
+ if (sscanf(line, "%*p %u %*u %*x %*u %*u %*u %*u %*u %lu", &state, &inode)<2)
return;
- }
struct file_info *fi = add_socket(inode, "netlink");
fi->name =
@@ -388,40 +381,28 @@ static void visit_fds(struct proc_info *pi)
closedir(dir);
}
-static void lsof_pid(int pid)
+static void lsof_pid(int pid, struct stat *st)
{
struct proc_info pi;
- char *line;
struct stat sb;
+ char *s;
+
+ pi.pid = pid;
// Skip nonexistent pids
sprintf(toybuf, "/proc/%d/stat", pid);
- if (!(line = readfile(toybuf, toybuf, sizeof(toybuf)))) return;
-
- // Get COMMAND.
- strcpy(pi.cmd, "?");
- if (line) {
- char *open_paren = strchr(toybuf, '(');
- char *close_paren = strrchr(toybuf, ')');
-
- if (open_paren && close_paren) {
- *close_paren = 0;
- snprintf(pi.cmd, sizeof(pi.cmd), "%s", open_paren + 1);
- }
- }
-
- // We already know PID.
- pi.pid = pid;
+ if (!readfile(toybuf, toybuf, sizeof(toybuf)-1) || !(s = strchr(toybuf, '(')))
+ return;
+ memcpy(pi.cmd, s+1, sizeof(pi.cmd)-1);
+ pi.cmd[sizeof(pi.cmd)-1] = 0;
+ if ((s = strrchr(pi.cmd, ')'))) *s = 0;
// Get USER.
- snprintf(toybuf, sizeof(toybuf), "/proc/%d", pid);
- if (!stat(toybuf, &sb)) {
- struct passwd *pw;
-
- if (!(toys.optflags&FLAG_l) && (pw = getpwuid(sb.st_uid))) {
- snprintf(pi.user, sizeof(pi.user), "%s", pw->pw_name);
- } else snprintf(pi.user, sizeof(pi.user), "%u", (unsigned)sb.st_uid);
+ if (!st) {
+ snprintf(toybuf, sizeof(toybuf), "/proc/%d", pid);
+ if (stat(toybuf, st = &sb)) return;
}
+ pi.uid = st->st_uid;
visit_symlink(&pi, "cwd", "cwd");
visit_symlink(&pi, "rtd", "root");
@@ -435,7 +416,7 @@ static int scan_proc(struct dirtree *node)
int pid;
if (!node->parent) return DIRTREE_RECURSE|DIRTREE_SHUTUP;
- if ((pid = atol(node->name))) lsof_pid(pid);
+ if ((pid = atol(node->name))) lsof_pid(pid, &node->st);
return 0;
}
@@ -443,22 +424,22 @@ static int scan_proc(struct dirtree *node)
void lsof_main(void)
{
struct arg_list *pp;
- int i;
+ int i, pid;
// lsof will only filter on paths it can stat (because it filters by inode).
- TT.sought_files = xmalloc(toys.optc*sizeof(struct stat));
- for (i = 0; i<toys.optc; ++i) xstat(toys.optargs[i], TT.sought_files+i);
+ if (toys.optc) {
+ TT.sought_files = xmalloc(toys.optc*sizeof(struct stat));
+ for (i = 0; i<toys.optc; ++i) xstat(toys.optargs[i], TT.sought_files+i);
+ }
if (!TT.p) dirtree_read("/proc", scan_proc);
else for (pp = TT.p; pp; pp = pp->next) {
char *start, *end, *next = pp->arg;
- int length, pid;
- while ((start = comma_iterate(&next, &length))) {
- pid = strtol(start, &end, 10);
- if (pid<1 || (*end && *end!=','))
- error_exit("bad -p '%.*s'", (int)(end-start), start);
- lsof_pid(pid);
+ while ((start = comma_iterate(&next, &i))) {
+ if ((pid = strtol(start, &end, 10))<1 || (*end && *end!=','))
+ error_msg("bad -p '%.*s'", (int)(end-start), start);
+ lsof_pid(pid, 0);
}
}