On Tue, 2011-05-03 at 14:58 +0200, Karel Zak wrote: > On Tue, May 03, 2011 at 09:50:41AM -0300, Davidlohr Bueso wrote: ... > PATH_MAX (... although GNU/Hurd guys hate it, because they follow > the universe and the universe is unlimited in space:-) ... > yes, but without err()/warn(), proc_get_next_tid() has to return -1 > on errors. > Here is v2 of the procutils file with the suggested changes. Once we are all set with this, I will resend the chrt patch, along with other schedutil changes. From: Davidlohr Bueso <dave@xxxxxxx> Date: Tue, 3 May 2011 15:52:00 -0300 Subject: [PATCH] procutils: general purpose procfs parsing utilities We include the following functions as a first approach: - proc_open_tasks(): allocate resources and setup basic data - proc_next_tid(): iterate over the thread group - proc_close_tasks(): free used resources Signed-off-by: Davidlohr Bueso <dave@xxxxxxx> --- include/procutils.h | 12 +++++ lib/Makefile.am | 3 +- lib/procutils.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+), 1 deletions(-) create mode 100644 include/procutils.h create mode 100644 lib/procutils.c diff --git a/include/procutils.h b/include/procutils.h new file mode 100644 index 0000000..0af296b --- /dev/null +++ b/include/procutils.h @@ -0,0 +1,12 @@ +#ifndef UTIL_LINUX_PROCUTILS +#define UTIL_LINUX_PROCUTILS + +struct proc_tasks { + DIR *dir; +}; + +struct proc_tasks *proc_open_tasks(pid_t pid); +void proc_close_tasks(struct proc_tasks *tasks); +int proc_next_tid(struct proc_tasks *tasks, pid_t *tid); + +#endif diff --git a/lib/Makefile.am b/lib/Makefile.am index 2b64459..7d966ff 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -3,7 +3,7 @@ include $(top_srcdir)/config/include-Makefile.am AM_CPPFLAGS += -DTEST_PROGRAM noinst_PROGRAMS = test_blkdev test_ismounted test_wholedisk test_mangle \ - test_tt test_canonicalize test_at test_strutils + test_tt test_canonicalize test_at test_strutils test_procutils if LINUX if HAVE_CPU_SET_T noinst_PROGRAMS += test_cpuset @@ -16,6 +16,7 @@ test_wholedisk_SOURCES = wholedisk.c test_mangle_SOURCES = mangle.c test_at_SOURCES = at.c test_strutils_SOURCES = strutils.c +test_procutils_SOURCES = procutils.c if LINUX test_cpuset_SOURCES = cpuset.c endif diff --git a/lib/procutils.c b/lib/procutils.c new file mode 100644 index 0000000..c40b779 --- /dev/null +++ b/lib/procutils.c @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2011 Davidlohr Bueso <dave@xxxxxxx> + * + * procutils.c: General purpose procfs parsing utilities + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library Public License for more details. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <sys/types.h> +#include <dirent.h> + +#include "procutils.h" + +/* + * @pid: process ID for which we want to obtain the threads group + * + * Returns: newly allocated tasks structure + */ +struct proc_tasks *proc_open_tasks(pid_t pid) +{ + struct proc_tasks *tasks; + char path[PATH_MAX]; + + sprintf(path, "/proc/%d/task/", pid); + + tasks = malloc(sizeof(struct proc_tasks)); + if (!tasks) + return NULL; + + tasks->dir = opendir(path); + if (!tasks->dir) + return NULL; + + return tasks; +} + +/* + * @tasks: allocated tasks structure + * + * Returns: nothing + */ +void proc_close_tasks(struct proc_tasks *tasks) +{ + if (tasks->dir) { + closedir(tasks->dir); + free(tasks); + } +} + +/* + * @tasks: allocated task structure + * @tid: [output] one of the thread IDs belonging to the thread group + * If when an error occurs, it is set to 0. + * + * Returns: 0 on success, -1 on failure or no more threads + */ +int proc_next_tid(struct proc_tasks *tasks, pid_t *tid) +{ + struct dirent *d; + + d = readdir(tasks->dir); + if (!d) /* no more listings or error */ + goto err; + + /* When we strtol "." or "..", *tid will be 0 */ + *tid = (pid_t) strtol(d->d_name, (char **)NULL, 10); + if (errno) + goto err; + + return 0; +err: + *tid = 0; + return -1; +} + +#ifdef TEST_PROGRAM +int main(int argc, char *argv[]) +{ + int i = 0; + pid_t tid, pid; + struct proc_tasks *ts; + + if (argc != 2) { + fprintf(stderr, "usage: %s <pid>\n", argv[0]); + exit(EXIT_FAILURE); + } + + pid = strtol(argv[1], (char **) NULL, 10); + ts = proc_open_tasks(pid); + + printf("%d: ", pid); + while (proc_next_tid(ts, &tid) == 0) + if (tid) + printf("%d ", tid); + printf("\n"); + + proc_close_tasks(ts); + return EXIT_SUCCESS; +} +#endif /* TEST_PROGRAM */ -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe util-linux" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html