[PATCH] pstree: New applet, v2
Tito
farmatito at tiscali.it
Sat Nov 6 13:54:51 UTC 2010
On Saturday 06 November 2010 10:26:45 Lauri Kasanen wrote:
> Hi
>
> v2:
>
> - struct globals
> - removed unneeded if() from maybe_free_buffers
> - use xzalloc instead of xmalloc
> - properly indent out_args
> - xmalloc, sprintf -> xasprintf
> - write the guru ?:?:?: open
>
> $ size procps/pstree.o
> text data bss dec hex filename
> 3053 0 0 3053 bed procps/pstree.o
>
> Sorry 'bout the indent, it wasn't my code in the first place ;)
>
> - Lauri
>
From 48368988a7699655c5f08b3017ff836945568eac Mon Sep 17 00:00:00 2001
From: Lauri Kasanen <curaga at operamail.com>
Date: Thu, 4 Nov 2010 10:29:41 +0200
Subject: [PATCH] pstree: New applet
v2:
- struct globals
- removed unneeded if() from maybe_free_buffers
- use xzalloc instead of xmalloc
- properly indent out_args
- xmalloc, sprintf -> xasprintf
- write the guru ?:?:?: open
Signed-off-by: Lauri Kasanen <curaga at operamail.com>
---
procps/pstree.c | 496 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 496 insertions(+), 0 deletions(-)
create mode 100644 procps/pstree.c
snip
+
+/*
+ * read_proc now uses a similar method as procps for finding the process
+ * name in the /proc filesystem. My thanks to Albert and procps authors.
+ */
+static void read_proc(void)
+{
+ DIR *dir;
+ struct dirent *de;
+ FILE *file;
+ struct stat st;
+ char *path, *comm;
+ char readbuf[BUFSIZ + 1];
+ char *tmpptr;
+ pid_t pid, ppid;
+ int size;
+ int empty;
+
+ dir = xopendir(PROC_BASE);
+ empty = 1;
+ while ((de = readdir(dir)) != NULL)
+ if ((pid = (pid_t) atoi(de->d_name)) != 0) {
+ path = xasprintf("%s/%d/stat", PROC_BASE, pid);
+ if ((file = fopen(path, "r")) != NULL) {
+ empty = 0;
+ sprintf(path, "%s/%d", PROC_BASE, pid);
+ xstat(path, &st);
What happens here if program with PID == pid exits before we do xstat,
seems to me the program run is interrupted (maybe better goto free(path)
or fclose(file) and ignore ? )
+ size = fread(readbuf, 1, BUFSIZ, file);
+ if (ferror(file) == 0) {
+ readbuf[size] = 0;
+ /* commands may have spaces or ) in them.
+ * so don't trust anything from the ( to the last ) */
+ if ((comm = strchr(readbuf, '('))
+ && (tmpptr = strrchr(comm, ')'))) {
+ ++comm;
+ *tmpptr = 0;
+ /* We now have readbuf with pid and cmd, and tmpptr+2
+ * with the rest */
+ if (sscanf(tmpptr + 2, "%*c %d", &ppid) == 1) {
+ DIR *taskdir;
+ struct dirent *dt;
+ char *taskpath = NULL;
+ char *threadname = NULL;
+ int thread;
+
+ taskpath = xasprintf("%s/task", path);
+
+ if ((taskdir = opendir(taskpath)) != 0) {
+ /* if we have this dir, we're on 2.6 */
+ threadname = xasprintf("{%.*s}", COMM_LEN-2, comm);
+ while ((dt = readdir(taskdir)) != NULL) {
+ if ((thread = atoi(dt->d_name)) != 0) {
+ if (thread != pid) {
+ add_proc(threadname, thread, pid, st.st_uid,
+ 1);
+ }
+ }
+ }
+ free(threadname);
+ (void) closedir(taskdir);
+ }
+ free(taskpath);
+ add_proc(comm, pid, ppid, st.st_uid, 0);
+ }
+ }
+ }
+ (void) fclose(file);
+ }
+ free(path);
+ }
+ (void) closedir(dir);
+ if (empty) {
bb_error_msg_and_die()
+ fprintf(stderr, "%s is empty (not mounted ?)\n", PROC_BASE);
+ exit(1);
+ }
+}
+
+
+int pstree_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int pstree_main(int argc, char **argv)
+{
+ struct winsize winsz;
+ pid_t pid = 1;
+ long uid = 0;
+
+ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G)));
+
+ G.sym = (struct sym_t) { " ", "|-", "| ", "`-", "---", "-+-"};
+ G.output_width = 132;
+ G.cur_x = 1;
+
We have get_terminal_width_height() in libbb
+ if (ioctl(1, TIOCGWINSZ, &winsz) >= 0)
+ if (winsz.ws_col)
+ G.output_width = winsz.ws_col;
+
+ if (argc > 2) bb_show_usage();
+ else if (argc == 2) {
+ if (*argv[1] >= '0' && *argv[1] <= '9') {
IIRC we have xatoi in libbb.
+ if (!(pid = (pid_t) atoi(argv[1])))
+ bb_show_usage();
+ } else {
+ uid = xuname2uid(argv[1]);
+ }
+ }
+
+ read_proc();
+ if (!uid)
+ dump_tree(find_proc(pid), 0, 1, 1, 1, 0);
+ else {
+ dump_by_user(find_proc(1), uid);
+ if (!G.dumped) {
bb_error_msg_and_die()
+ fprintf(stderr, "No processes found.\n");
+ return 1;
+ }
+ }
+ maybe_free_buffers();
+
+ return 0;
+}
--
1.7.2.1
Hi,
just my 0,2 cents.
Ciao,
Tito
More information about the busybox
mailing list