diff --git a/psmisc-22.16-timeout.patch b/psmisc-22.16-timeout.patch deleted file mode 100644 index d219df0..0000000 --- a/psmisc-22.16-timeout.patch +++ /dev/null @@ -1,394 +0,0 @@ -diff --git a/ChangeLog b/ChangeLog -index b42a4d7..baba19e 100644 ---- a/ChangeLog -+++ b/ChangeLog -@@ -1,3 +1,10 @@ -+ * Make it possible to use --enable-timeout-stat as well as -+ --enable-timeout-stat=static for a static background process which -+ does the final stat system calls -+ * Do not mix HAVE_TIMEOUT_STAT with WITH_TIMEOUT_STAT -+ * Add timeout.c/timeout.h for static background process which is able -+ to read the file name from pipe, does the stat(2) system call, and -+ writes the result back to a pipe. - * Really add ASCII null at command string in add_proc() of pstree.c - - Changes in 22.16 -diff --git a/configure.ac b/configure.ac -index 0615f5f..9265d82 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -30,12 +30,16 @@ AC_SUBST([SELINUX_LIB]) - # Call fork before all stat calls to stop hanging on NFS mounts - AC_SUBST([WITH_TIMEOUT_STAT]) - AC_ARG_ENABLE([timeout_stat], -- [AS_HELP_STRING([--enable-timeout-stat], [Use a timeout on stat calls])], -+ [AS_HELP_STRING([--enable-timeout-stat], [Use a timeout on stat calls (optional with argument "static" for a static background process)])], - [enable_timeout_stat=$enableval], - [enable_timeout_stat="no"]) - if test "$enable_timeout_stat" = "yes"; then - AC_DEFINE([WITH_TIMEOUT_STAT], [1], [Use timeout on stat calls]) - fi -+if test "$enable_timeout_stat" = "static"; then -+ AC_DEFINE([WITH_TIMEOUT_STAT], [2], [Use timeout on stat calls]) -+fi -+AM_CONDITIONAL([WANT_TIMEOUT_STAT], [test "$enable_timeout_stat" = "static"]) - - # Enable hardened compile and link flags - AC_ARG_ENABLE([harden_flags], -diff --git a/src/Makefile.am b/src/Makefile.am -index d511f24..a28af7d 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -24,6 +24,9 @@ if WANT_PEEKFD_MIPS - endif - - fuser_SOURCES = fuser.c comm.h signals.c signals.h i18n.h fuser.h lists.h -+if WANT_TIMEOUT_STAT -+ fuser_SOURCES += timeout.c timeout.h -+endif - - fuser_LDADD = @LIBINTL@ - -diff --git a/src/fuser.c b/src/fuser.c -index e4081eb..09548ff 100644 ---- a/src/fuser.c -+++ b/src/fuser.c -@@ -111,9 +111,13 @@ static dev_t device(const char *path); - #endif - static char *expandpath(const char *path); - --typedef int (*stat_t)(const char*, struct stat*); - #ifdef WITH_TIMEOUT_STAT -+# if (WITH_TIMEOUT_STAT == 2) -+# include "timeout.h" -+# else -+typedef int (*stat_t)(const char*, struct stat*); - static int timeout(stat_t func, const char *path, struct stat *buf, unsigned int seconds); -+# endif - #else - #define timeout(func,path,buf,dummy) (func)((path),(buf)) - #endif /* WITH_TIMEOUT_STAT */ -@@ -1783,7 +1787,7 @@ scan_swaps(struct names *names_head, struct inode_list *ino_head, - * Execute stat(2) system call with timeout to avoid deadlock - * on network based file systems. - */ --#ifdef HAVE_TIMEOUT_STAT -+#if defined(WITH_TIMEOUT_STAT) && (WITH_TIMEOUT_STAT == 1) - - static sigjmp_buf jenv; - -diff --git a/src/timeout.c b/src/timeout.c -new file mode 100644 -index 0000000..1fe0354 ---- /dev/null -+++ b/src/timeout.c -@@ -0,0 +1,267 @@ -+/* -+ * timout.c Advanced timeout handling for file system calls -+ * to avoid deadlocks on remote file shares. -+ * -+ * Version: 0.1 07-Sep-2011 Fink -+ * -+ * Copyright 2011 Werner Fink, 2011 SUSE LINUX Products GmbH, Germany. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * Author: Werner Fink , 2011 -+ */ -+ -+#ifndef _GNU_SOURCE -+# define _GNU_SOURCE -+#endif -+ -+#ifndef USE_SOCKETPAIR -+# define USE_SOCKETPAIR 1 -+#endif -+ -+#ifdef _FEATURES_H -+# error Include local config.h before any system header file -+#endif -+#include "config.h" /* For _FILE_OFFSET_BITS */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#if USE_SOCKETPAIR -+# include -+# include -+# include -+# ifndef SHUT_RD -+# define SHUT_RD 0 -+# endif -+# ifndef SHUT_WR -+# define SHUT_WR 1 -+# endif -+# undef pipe -+# define pipe(v) (((socketpair(AF_UNIX,SOCK_STREAM,0,v) < 0) || \ -+ (shutdown((v)[1],SHUT_RD) < 0) || (shutdown((v)[0],SHUT_WR) < 0)) ? -1 : 0) -+#endif -+#include -+ -+#include "timeout.h" -+ -+#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) -+# ifndef destructor -+# define destructor __destructor__ -+# endif -+# ifndef constructor -+# define constructor __constructor__ -+# endif -+# ifndef packed -+# define packed __packed__ -+# endif -+# ifndef inline -+# define inline __inline__ -+# endif -+# ifndef unused -+# define unused __unused__ -+# endif -+# ifndef volatile -+# define volatile __volatile__ -+# endif -+#endif -+#ifndef attribute -+# define attribute(attr) __attribute__(attr) -+#endif -+ -+#if defined __GNUC__ -+# undef strcpy -+# define strcpy(d,s) __builtin_strcpy((d),(s)) /* Without boundary check please */ -+#endif -+ -+/* -+ * The structure used for communication between the processes -+ */ -+typedef struct _handle { -+ int errcode; -+ struct stat argument; -+ stat_t function; -+ size_t len; -+ char path[0]; -+} attribute((packed)) handle_t; -+ -+/* -+ * Using a forked process for doing e.g. stat(2) system call as this -+ * allows us to send e.g. SIGKILL to this process if it hangs in `D' -+ * state on a file share due a stalled NFS server. This does not work -+ * with (p)threads as SIGKILL would kill all threads including main. -+ */ -+ -+static volatile pid_t active; -+static int pipes[4] = {-1, -1, -1, -1}; -+static char buf[PATH_MAX + sizeof(handle_t) + 1]; -+ -+static void sigchild(int sig attribute((unused))) -+{ -+ pid_t pid = waitpid(active, NULL, WNOHANG|WUNTRACED); -+ if (pid <= 0) -+ return; -+ if (errno == ECHILD) -+ return; -+ active = 0; -+} -+ -+static void attribute((constructor)) start(void) -+{ -+ sigset_t sigset, oldset; -+ struct sigaction act; -+ ssize_t in; -+ -+ if (pipes[1] >= 0) close(pipes[1]); -+ if (pipes[2] >= 0) close(pipes[2]); -+ -+ if (pipe(&pipes[0])) -+ goto error; -+ if (pipe(&pipes[2])) -+ goto error; -+ -+ memset(&act, 0, sizeof(act)); -+ sigemptyset(&act.sa_mask); -+ act.sa_flags = SA_RESTART; -+ act.sa_handler = sigchild; -+ sigaction(SIGCHLD, &act, 0); -+ -+ if ((active = fork()) < 0) -+ goto error; -+ -+ if (active) { -+ close(pipes[0]); -+ close(pipes[3]); -+ pipes[0] = pipes[3] = -1; -+ return; -+ } -+ -+ sigemptyset(&sigset); -+ sigaddset(&sigset, SIGALRM); -+ sigprocmask(SIG_BLOCK, &sigset, &oldset); -+ -+ act.sa_handler = SIG_DFL; -+ sigaction(SIGCHLD, &act, 0); -+ -+ close(pipes[1]); -+ close(pipes[2]); -+ dup2(pipes[0], STDIN_FILENO); -+ dup2(pipes[3], STDOUT_FILENO); -+ close(pipes[0]); -+ close(pipes[3]); -+ pipes[1] = pipes[2] = -1; -+ pipes[0] = pipes[3] = -1; -+ -+ { -+ handle_t *restrict handle = (void*)&buf[0]; -+ -+ while ((in = read(STDIN_FILENO, handle, sizeof(buf))) > sizeof(handle_t)) { -+ if (handle->function(handle->path, &handle->argument) < 0) -+ handle->errcode = errno; -+ write(STDOUT_FILENO, &handle->errcode, sizeof(handle->errcode)+sizeof(handle->argument)); -+ memset(handle, 0, sizeof(handle_t)); -+ } -+ } -+ sigprocmask(SIG_SETMASK, &oldset, NULL); -+ exit(0); -+error: -+ if (pipes[0] >= 0) close(pipes[0]); -+ if (pipes[1] >= 0) close(pipes[1]); -+ if (pipes[2] >= 0) close(pipes[2]); -+ if (pipes[3] >= 0) close(pipes[3]); -+} -+ -+static void /* attribute((destructor)) */ stop(void) -+{ -+ if (active && waitpid(active, NULL, WNOHANG|WUNTRACED) == 0) -+ kill(active, SIGKILL); -+} -+ -+static sigjmp_buf jenv; -+static void sigjump(int sig attribute((unused))) -+{ -+ siglongjmp(jenv, 1); -+} -+ -+/* -+ * External routine -+ */ -+int timeout(stat_t function, const char *path, struct stat *restrict argument, time_t seconds) -+{ -+ handle_t *restrict handle = (void*)&buf[0]; -+ struct sigaction alrm_act, pipe_act, new_act; -+ sigset_t sigset, oldset; -+ -+ if (active <= 0) /* Oops, last one failed therefore clear status and restart */ -+ start(); -+ -+ memset(handle, 0, sizeof(handle_t)); -+ handle->len = strlen(path) + 1; -+ if (handle->len >= PATH_MAX) { -+ errno = ENAMETOOLONG; -+ goto error; -+ } -+ handle->errcode = 0; -+ handle->argument = *argument; -+ handle->function = function; -+ strcpy(handle->path, path); -+ -+ sigemptyset(&sigset); -+ sigaddset(&sigset, SIGALRM); -+ sigaddset(&sigset, SIGPIPE); -+ sigprocmask(SIG_UNBLOCK, &sigset, &oldset); -+ -+ memset(&new_act, 0, sizeof(new_act)); -+ sigemptyset(&new_act.sa_mask); -+ new_act.sa_flags = SA_RESETHAND; -+ -+ if (sigsetjmp(jenv, 1)) -+ goto timed; -+ -+ new_act.sa_handler = sigjump; -+ sigaction(SIGALRM, &new_act, &alrm_act); -+ sigaction(SIGPIPE, &new_act, &pipe_act); -+ alarm(seconds); -+ -+ write(pipes[1], handle, sizeof(handle_t)+handle->len); -+ read(pipes[2], &handle->errcode, sizeof(handle->errcode)+sizeof(handle->argument)); -+ -+ alarm(0); -+ sigaction(SIGPIPE, &pipe_act, NULL); -+ sigaction(SIGALRM, &alrm_act, NULL); -+ -+ if (handle->errcode) { -+ errno = handle->errcode; -+ goto error; -+ } -+ -+ *argument = handle->argument; -+ sigprocmask(SIG_SETMASK, &oldset, NULL); -+ -+ return 0; -+timed: -+ (void) alarm(0); -+ sigaction(SIGPIPE, &pipe_act, NULL); -+ sigaction(SIGALRM, &alrm_act, NULL); -+ sigprocmask(SIG_SETMASK, &oldset, NULL); -+ stop(); -+ errno = ETIMEDOUT; -+error: -+ return -1; -+} -+ -+/* -+ * End of timeout.c -+ */ -diff --git a/src/timeout.h b/src/timeout.h -new file mode 100644 -index 0000000..546c13b ---- /dev/null -+++ b/src/timeout.h -@@ -0,0 +1,36 @@ -+/* -+ * timout.h Advanced timeout handling for file system calls -+ * to avoid deadlocks on remote file shares. -+ * -+ * Version: 0.1 07-Sep-2011 Fink -+ * -+ * Copyright 2011 Werner Fink, 2011 SUSE LINUX Products GmbH, Germany. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * Author: Werner Fink , 2011 -+ */ -+ -+#ifndef _TIMEOUT_H -+#define _TIMEOUT_H -+ -+#include "config.h" /* For _FILE_OFFSET_BITS */ -+ -+#include -+#include -+#include -+#include -+ -+#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) -+# ifndef restrict -+# define restrict __restrict__ -+# endif -+#endif -+ -+typedef int (*stat_t)(const char *, struct stat *restrict); -+extern int timeout(stat_t, const char *, struct stat *restrict, time_t); -+ -+#endif diff --git a/psmisc-22.16.tar.gz b/psmisc-22.16.tar.gz deleted file mode 100644 index fb6f25a..0000000 --- a/psmisc-22.16.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ae426d7238e5353fdf51b1d313897c2bbed0023e66e5b4af2be9cd03d87a9d01 -size 465138 diff --git a/psmisc-22.20-pstree.patch b/psmisc-22.20-pstree.patch new file mode 100644 index 0000000..f1a3b0f --- /dev/null +++ b/psmisc-22.20-pstree.patch @@ -0,0 +1,38 @@ +--- src/pstree.c ++++ src/pstree.c 2012-12-18 17:06:03.369452415 +0000 +@@ -141,7 +141,11 @@ static char last_char = 0; + static int dumped = 0; /* used by dump_by_user */ + static int charlen = 0; /* length of character */ + ++#ifdef WITH_SELINUX ++static void fix_orphans(security_context_t scontext); ++#else + static void fix_orphans(void); ++#endif + /* + * Allocates additional buffer space for width and more as needed. + * The first call will allocate the first buffer. +@@ -810,7 +814,11 @@ static void read_proc(void) + } + } + (void) closedir(dir); ++#ifdef WITH_SELINUX ++ fix_orphans(scontext); ++#else + fix_orphans(); ++#endif + if (print_args) + free(buffer); + if (empty) { +@@ -819,7 +827,11 @@ static void read_proc(void) + } + } + ++#ifdef WITH_SELINUX ++static void fix_orphans(security_context_t scontext) ++#else + static void fix_orphans(void) ++#endif + { + /* When using kernel 3.3 with hidepid feature enabled on /proc + * then we need fake root pid and gather all the orphan processes diff --git a/psmisc-22.20-upstream.patch b/psmisc-22.20-upstream.patch new file mode 100644 index 0000000..e4f0adb --- /dev/null +++ b/psmisc-22.20-upstream.patch @@ -0,0 +1,861 @@ + ChangeLog | 6 ++ + configure.ac | 11 ++++ + src/fuser.c | 182 +++++++++++++++------------------------------------------ + src/fuser.h | 4 +- + src/lists.h | 132 +++++++++++++++++++++++++++++++++++++++-- + src/timeout.c | 163 ++++++++++++++++++++++++++++++++++++++++++--------- + src/timeout.h | 13 ++++- + 7 files changed, 340 insertions(+), 171 deletions(-) + +diff --git ChangeLog ChangeLog +index 4e3f348..d5cb9ec 100644 +--- ChangeLog ++++ ChangeLog +@@ -1,3 +1,9 @@ ++ * Make usage of linked lists of devices found in ++ /proc/self/mountinfo optional ++ * Make timeout() in timeout.c work with shared mmap to ++ reduce the load due write/read the stat buffers ++ * Add list_sort() to lists.h to be able to sort lists ++ + Changes in 22.20 + ================ + * pstree sorts properly on names Debian #682014 +diff --git configure.ac configure.ac +index 9df639d..cb03ba9 100644 +--- configure.ac ++++ configure.ac +@@ -42,6 +42,17 @@ if test "$enable_timeout_stat" = "static"; then + fi + AM_CONDITIONAL([WANT_TIMEOUT_STAT], [test "$enable_timeout_stat" = "static"]) + ++# Use string search for network based file systems but only if the system ++# has /proc/self/mountinfo ++AC_SUBST([WITH_MOUNTINFO_LIST]) ++AC_ARG_ENABLE([mountinfo_list], ++ [AS_HELP_STRING([--enable-mountinfo-list], [Use the list in /proc/self/mountinfo to replace stat(2) syscall on network file systems shares])], ++ [enable_mountinfo_list="yes"], ++ [enable_mountinfo_list="no"]) ++if test "$enable_mountinfo_list" = "yes" -a -e /proc/self/mountinfo ; then ++ AC_DEFINE([WITH_MOUNTINFO_LIST], [1], [Use list in /proc/self/mountinfo to replace stat calls]) ++fi ++ + # Enable hardened compile and link flags + AC_ARG_ENABLE([harden_flags], + [AS_HELP_STRING([--disable-harden-flags], [disable hardened compilier and linker flags])], +diff --git src/fuser.c src/fuser.c +index 0c773fe..8d04ff5 100644 +--- src/fuser.c ++++ src/fuser.c +@@ -58,6 +58,7 @@ + #include "fuser.h" + #include "signals.h" + #include "i18n.h" ++#include "timeout.h" + + //#define DEBUG 1 + +@@ -104,25 +105,14 @@ static void debug_match_lists(struct names *names_head, + struct device_list *dev_head); + #endif + +-#ifdef _LISTS_H ++#if defined(WITH_MOUNTINFO_LIST) + static void clear_mntinfo(void) __attribute__ ((__destructor__)); + static void init_mntinfo(void) __attribute__ ((__constructor__)); +-static dev_t device(const char *path); ++static int mntstat(const char *path, struct stat *buf); + #endif ++static stat_t thestat = stat; + static char *expandpath(const char *path); + +-#ifdef WITH_TIMEOUT_STAT +-#if (WITH_TIMEOUT_STAT == 2) +-#include "timeout.h" +-#else +-typedef int (*stat_t) (const char *, struct stat *); +-static int timeout(stat_t func, const char *path, struct stat *buf, +- unsigned int seconds); +-#endif +-#else +-#define timeout(func,path,buf,dummy) (func)((path),(buf)) +-#endif /* WITH_TIMEOUT_STAT */ +- + static void usage(const char *errormsg) + { + if (errormsg != NULL) +@@ -191,10 +181,6 @@ scan_procs(struct names *names_head, struct inode_list *ino_head, + struct stat *cwd_stat = NULL; + struct stat *exe_stat = NULL; + struct stat *root_stat = NULL; +-#ifdef _LISTS_H +- char path[256] = "/proc/", *slash; +- ssize_t len; +-#endif + + if (topproc_dent->d_name[0] < '0' || topproc_dent->d_name[0] > '9') /* Not a process */ + continue; +@@ -204,30 +190,12 @@ scan_procs(struct names *names_head, struct inode_list *ino_head, + continue; + uid = getpiduid(pid); + +-#ifdef _LISTS_H +- strcpy(&path[6], topproc_dent->d_name); +- len = strlen(path); +- slash = &path[len]; +- +- *slash = '\0'; +- strcat(slash, "/cwd"); +- cwd_dev = device(path); +- +- *slash = '\0'; +- strcat(slash, "/exe"); +- exe_dev = device(path); +- +- *slash = '\0'; +- strcat(slash, "/root"); +- root_dev = device(path); +-#else + cwd_stat = get_pidstat(pid, "cwd"); + exe_stat = get_pidstat(pid, "exe"); + root_stat = get_pidstat(pid, "root"); + cwd_dev = cwd_stat ? cwd_stat->st_dev : 0; + exe_dev = exe_stat ? exe_stat->st_dev : 0; + root_dev = root_stat ? root_stat->st_dev : 0; +-#endif + + /* Scan the devices */ + for (dev_tmp = dev_head; dev_tmp != NULL; +@@ -463,7 +431,7 @@ add_special_proc(struct names *name_list, const char ptype, const uid_t uid, + } + + int parse_file(struct names *this_name, struct inode_list **ino_list, +- const char opts) ++ const opt_type opts) + { + char *new = expandpath(this_name->filename); + if (new) { +@@ -471,8 +439,7 @@ int parse_file(struct names *this_name, struct inode_list **ino_list, + free(this_name->filename); + this_name->filename = strdup(new); + } +- +- if (timeout(stat, this_name->filename, &(this_name->st), 5) != 0) { ++ if (timeout(thestat, this_name->filename, &(this_name->st), 5) != 0) { + if (errno == ENOENT) + fprintf(stderr, + _("Specified filename %s does not exist.\n"), +@@ -514,7 +481,7 @@ parse_unixsockets(struct names *this_name, struct inode_list **ino_list, + + int + parse_mounts(struct names *this_name, struct device_list **dev_list, +- const char opts) ++ const opt_type opts) + { + dev_t match_device; + +@@ -992,6 +959,10 @@ int main(int argc, char *argv[]) + break; + case 'c': + opts |= OPT_MOUNTS; ++#if defined(WITH_MOUNTINFO_LIST) ++ thestat = mntstat; ++#endif ++ read_proc_mounts(&mounts); + break; + case 'f': + /* ignored */ +@@ -1010,6 +981,9 @@ int main(int argc, char *argv[]) + return 0; + case 'm': + opts |= OPT_MOUNTS; ++#if defined(WITH_MOUNTINFO_LIST) ++ thestat = mntstat; ++#endif + read_proc_mounts(&mounts); + break; + case 'M': +@@ -1378,7 +1352,7 @@ static struct stat *get_pidstat(const pid_t pid, const char *filename) + if ((st = (struct stat *)malloc(sizeof(struct stat))) == NULL) + return NULL; + snprintf(pathname, 256, "/proc/%d/%s", pid, filename); +- if (timeout(stat, pathname, st, 5) != 0) { ++ if (timeout(thestat, pathname, st, 5) != 0) { + free(st); + return NULL; + } +@@ -1410,7 +1384,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, + snprintf(filepath, MAX_PATHNAME, "/proc/%d/%s/%s", + pid, dirname, direntry->d_name); + +- if (timeout(stat, filepath, &st, 5) != 0) { ++ if (timeout(thestat, filepath, &st, 5) != 0) { + if (errno != ENOENT) { + fprintf(stderr, _("Cannot stat file %s: %s\n"), + filepath, strerror(errno)); +@@ -1449,7 +1423,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, + if (thedev != ino_tmp->device) + continue; + if (!st.st_ino +- && timeout(stat, filepath, &st, 5) != 0) { ++ && timeout(thestat, filepath, &st, 5) != 0) { + fprintf(stderr, + _("Cannot stat file %s: %s\n"), + filepath, strerror(errno)); +@@ -1519,7 +1493,7 @@ static uid_t getpiduid(const pid_t pid) + + if (snprintf(pathname, MAX_PATHNAME, "/proc/%d", pid) < 0) + return 0; +- if (timeout(stat, pathname, &st, 5) != 0) ++ if (timeout(thestat, pathname, &st, 5) != 0) + return 0; + return st.st_uid; + } +@@ -1555,7 +1529,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) + path = scanned_path; + if (*scanned_path == '@') + scanned_path++; +- if (timeout(stat, scanned_path, &st, 5) < 0) { ++ if (timeout(thestat, scanned_path, &st, 5) < 0) { + free(path); + continue; + } +@@ -1700,7 +1674,7 @@ scan_knfsd(struct names *names_head, struct inode_list *ino_head, + if ((find_space = strpbrk(line, " \t")) == NULL) + continue; + *find_space = '\0'; +- if (timeout(stat, line, &st, 5) != 0) { ++ if (timeout(thestat, line, &st, 5) != 0) { + continue; + } + /* Scan the devices */ +@@ -1744,7 +1718,7 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head, + if ((find_space = strchr(find_mountp, ' ')) == NULL) + continue; + *find_space = '\0'; +- if (timeout(stat, find_mountp, &st, 5) != 0) { ++ if (timeout(thestat, find_mountp, &st, 5) != 0) { + continue; + } + /* Scan the devices */ +@@ -1791,7 +1765,7 @@ scan_swaps(struct names *names_head, struct inode_list *ino_head, + if (*find_space == '\0') + continue; + } +- if (timeout(stat, line, &st, 5) != 0) { ++ if (timeout(thestat, line, &st, 5) != 0) { + continue; + } + /* Scan the devices */ +@@ -1812,73 +1786,7 @@ scan_swaps(struct names *names_head, struct inode_list *ino_head, + fclose(fp); + } + +-/* +- * Execute stat(2) system call with timeout to avoid deadlock +- * on network based file systems. +- */ +-#if defined(WITH_TIMEOUT_STAT) && (WITH_TIMEOUT_STAT == 1) +- +-static sigjmp_buf jenv; +- +-static void sigalarm(int sig) +-{ +- if (sig == SIGALRM) +- siglongjmp(jenv, 1); +-} +- +-static int +-timeout(stat_t func, const char *path, struct stat *buf, unsigned int seconds) +-{ +- pid_t pid = 0; +- int ret = 0, pipes[4]; +- ssize_t len; +- +- if (pipe(&pipes[0]) < 0) +- goto err; +- switch ((pid = fork())) { +- case -1: +- close(pipes[0]); +- close(pipes[1]); +- goto err; +- case 0: +- (void)signal(SIGALRM, SIG_DFL); +- close(pipes[0]); +- if ((ret = func(path, buf)) == 0) +- do +- len = write(pipes[1], buf, sizeof(struct stat)); +- while (len < 0 && errno == EINTR); +- close(pipes[1]); +- exit(ret); +- default: +- close(pipes[1]); +- if (sigsetjmp(jenv, 1)) { +- (void)alarm(0); +- (void)signal(SIGALRM, SIG_DFL); +- if (waitpid(0, (int *)0, WNOHANG) == 0) +- kill(pid, SIGKILL); +- errno = ETIMEDOUT; +- seconds = 1; +- goto err; +- } +- (void)signal(SIGALRM, sigalarm); +- (void)alarm(seconds); +- if (read(pipes[0], buf, sizeof(struct stat)) == 0) { +- errno = EFAULT; +- ret = -1; +- } +- (void)alarm(0); +- (void)signal(SIGALRM, SIG_DFL); +- close(pipes[0]); +- waitpid(pid, NULL, 0); +- break; +- } +- return ret; +- err: +- return -1; +-} +-#endif /* WITH_TIMEOUT_STAT */ +- +-#ifdef _LISTS_H ++#if defined(WITH_MOUNTINFO_LIST) + /* + * Use /proc/self/mountinfo of modern linux system to determine + * the device numbers of the mount points. Use this to avoid the +@@ -1967,42 +1875,46 @@ static void init_mntinfo(void) + /* + * Determine device of links below /proc/ + */ +-static dev_t device(const char *path) ++static int mntstat(const char *path, struct stat *buf) + { + char name[PATH_MAX + 1]; + const char *use; + ssize_t nlen; + list_t *ptr; + +- if ((nlen = readlink(path, name, PATH_MAX)) < 0) { +- nlen = strlen(path); +- use = &path[0]; +- } else { +- name[nlen] = '\0'; +- use = &name[0]; +- } +- +- if (*use != '/') { /* special file (socket, pipe, inotify) */ +- struct stat st; +- if (timeout(stat, path, &st, 5) != 0) +- return (dev_t) - 1; +- return st.st_dev; ++ if ((use = realpath(path, name)) == NULL || *use != '/') ++ { ++ if (errno == ENOENT) ++ return -1; ++ /* ++ * Could be a special file (socket, pipe, inotify) ++ */ ++ errno = 0; ++ return stat(path, buf); + } + ++ nlen = strlen(use); + list_for_each(ptr, &mntinfo) { + mntinfo_t *mnt = list_entry(ptr, mntinfo_t); + if (nlen < mnt->nlen) + continue; +- if (mnt->nlen == 1) /* root fs is the last entry */ +- return mnt->dev; ++ if (mnt->nlen == 1) { /* root fs is the last entry */ ++ buf->st_dev = mnt->dev; ++ buf->st_ino = 0; ++ return 0; ++ } + if (use[mnt->nlen] != '\0' && use[mnt->nlen] != '/') + continue; +- if (strncmp(use, mnt->mpoint, mnt->nlen) == 0) +- return mnt->dev; ++ if (strncmp(use, mnt->mpoint, mnt->nlen) == 0) { ++ buf->st_dev = mnt->dev; ++ buf->st_ino = 0; ++ return 0; ++ } + } +- return (dev_t) - 1; ++ errno = ENOENT; ++ return -1; + } +-#endif /* _LISTS_H */ ++#endif /* WITH_MOUNTINFO_LIST */ + + /* + * Somehow the realpath(3) glibc function call, nevertheless +diff --git src/fuser.h src/fuser.h +index 242ce19..07488bc 100644 +--- src/fuser.h ++++ src/fuser.h +@@ -86,7 +86,7 @@ struct mount_list { + struct mount_list *next; + }; + +-#if defined (__GNUC__) && defined(__OPTIMIZE__) && !defined (__CYGWIN__) ++#if defined (__GNUC__) && defined(WITH_MOUNTINFO_LIST) + # include "lists.h" + typedef struct mntinfo_s { + list_t this; +@@ -95,6 +95,8 @@ typedef struct mntinfo_s { + size_t nlen; + char *mpoint; + } mntinfo_t; ++#else ++# undef WITH_MOUNTINFO_LIST + #endif + + #define NAMESPACE_FILE 0 +diff --git src/lists.h src/lists.h +index ae8929e..bd371a4 100644 +--- src/lists.h ++++ src/lists.h +@@ -1,10 +1,10 @@ + /* +- * lists.h Simple doubly linked list implementation, +- * based on and . ++ * lists.h Simple doubly linked list implementation, based on ++ * , , and lib/list_sort.c + * +- * Version: 0.1 01-Feb-2011 Fink ++ * Version: 0.2 11-Dec-2012 Fink + * +- * Copyright 2011 Werner Fink, 2005 SUSE LINUX Products GmbH, Germany. ++ * Copyright 2011,2012 Werner Fink, 2005,2012 SUSE LINUX Products GmbH, Germany. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -246,4 +246,128 @@ static inline void move_tail(list_t *restrict entry, list_t *restrict head) + #define np_list_for_each_prev(pos, head) \ + for (pos = (head)->prev; pos != (head); pos = pos->prev) + ++#define MAX_LIST_LENGTH_BITS 20 ++ ++/* ++ * Returns a list organized in an intermediate format suited ++ * to chaining of merge() calls: null-terminated, no reserved or ++ * sentinel head node, "prev" links not maintained. ++ */ ++static inline list_t *merge(int (*cmp)(list_t *a, list_t *b), list_t *a, list_t *b) ++{ ++ list_t head, *tail = &head; ++ while (a && b) { ++ /* if equal, take 'a' -- important for sort stability */ ++ if ((*cmp)(a, b) <= 0) { ++ tail->next = a; ++ a = a->next; ++ } else { ++ tail->next = b; ++ b = b->next; ++ } ++ tail = tail->next; ++ } ++ tail->next = a ? a : b; ++ return head.next; ++} ++ ++/* ++ * Combine final list merge with restoration of standard doubly-linked ++ * list structure. This approach duplicates code from merge(), but ++ * runs faster than the tidier alternatives of either a separate final ++ * prev-link restoration pass, or maintaining the prev links ++ * throughout. ++ */ ++static inline void merge_and_restore_back_links(int (*cmp)(list_t *a, list_t *b), list_t *head, list_t *a, list_t *b) ++{ ++ list_t *tail = head; ++ ++ while (a && b) { ++ /* if equal, take 'a' -- important for sort stability */ ++ if ((*cmp)(a, b) <= 0) { ++ tail->next = a; ++ a->prev = tail; ++ a = a->next; ++ } else { ++ tail->next = b; ++ b->prev = tail; ++ b = b->next; ++ } ++ tail = tail->next; ++ } ++ tail->next = a ? a : b; ++ ++ do { ++ /* ++ * In worst cases this loop may run many iterations. ++ * Continue callbacks to the client even though no ++ * element comparison is needed, so the client's cmp() ++ * routine can invoke cond_resched() periodically. ++ */ ++ (*cmp)(tail->next, tail->next); ++ ++ tail->next->prev = tail; ++ tail = tail->next; ++ } while (tail->next); ++ ++ tail->next = head; ++ head->prev = tail; ++} ++ ++ ++/** ++ * list_sort - sort a list ++ * @head: the list to sort ++ * @cmp: the elements comparison function ++ * ++ * This function implements "merge sort", which has O(nlog(n)) ++ * complexity. ++ * ++ * The comparison function @cmp must return a negative value if @a ++ * should sort before @b, and a positive value if @a should sort after ++ * @b. If @a and @b are equivalent, and their original relative ++ * ordering is to be preserved, @cmp must return 0. ++ */ ++static inline void list_sort(list_t *head, int (*cmp)(list_t *a, list_t *b)) ++{ ++ list_t *part[MAX_LIST_LENGTH_BITS+1]; /* sorted partial lists ++ -- last slot is a sentinel */ ++ size_t lev; /* index into part[] */ ++ size_t max_lev = 0; ++ list_t *list; ++ ++ if (list_empty(head)) ++ return; ++ ++ memset(part, 0, sizeof(part)); ++ ++ head->prev->next = NULL; ++ list = head->next; ++ ++ while (list) { ++ list_t *cur = list; ++ list = list->next; ++ cur->next = NULL; ++ ++ for (lev = 0; part[lev]; lev++) { ++ cur = merge(cmp, part[lev], cur); ++ part[lev] = NULL; ++ } ++ if (lev > max_lev) { ++ /* list passed to list_sort() too long for efficiency */ ++ if (lev >= MAX_LIST_LENGTH_BITS) ++ lev--; ++ max_lev = lev; ++ } ++ part[lev] = cur; ++ } ++ ++ for (lev = 0; lev < max_lev; lev++) { ++ if (part[lev]) ++ list = merge(cmp, part[lev], list); ++ } ++ ++ merge_and_restore_back_links(cmp, head, part[max_lev], list); ++} ++ + #endif /* _LISTS_H */ +diff --git src/timeout.c src/timeout.c +index 1fe0354..ca4a7cd 100644 +--- src/timeout.c ++++ src/timeout.c +@@ -2,9 +2,9 @@ + * timout.c Advanced timeout handling for file system calls + * to avoid deadlocks on remote file shares. + * +- * Version: 0.1 07-Sep-2011 Fink ++ * Version: 0.2 11-Dec-2012 Fink + * +- * Copyright 2011 Werner Fink, 2011 SUSE LINUX Products GmbH, Germany. ++ * Copyright 2011,2012 Werner Fink, 2011,2012 SUSE LINUX Products GmbH, Germany. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -18,26 +18,29 @@ + # define _GNU_SOURCE + #endif + +-#ifndef USE_SOCKETPAIR +-# define USE_SOCKETPAIR 1 +-#endif +- + #ifdef _FEATURES_H + # error Include local config.h before any system header file + #endif +-#include "config.h" /* For _FILE_OFFSET_BITS */ ++#include "config.h" ++ ++#ifndef WITH_TIMEOUT_STAT ++# define WITH_TIMEOUT_STAT 0 ++#endif ++ ++#ifndef USE_SOCKETPAIR ++# define USE_SOCKETPAIR 1 ++#endif + + #include +-#include + #include + #include + #include + #include ++#include + #include + #include + #include + #include +- + #include + #if USE_SOCKETPAIR + # include +@@ -86,6 +89,15 @@ + # define strcpy(d,s) __builtin_strcpy((d),(s)) /* Without boundary check please */ + #endif + ++#if WITH_TIMEOUT_STAT ++static sigjmp_buf jenv; ++static void sigjump(int sig attribute((unused))) ++{ ++ siglongjmp(jenv, 1); ++} ++#endif ++ ++#if WITH_TIMEOUT_STAT == 2 + /* + * The structure used for communication between the processes + */ +@@ -106,7 +118,8 @@ typedef struct _handle { + + static volatile pid_t active; + static int pipes[4] = {-1, -1, -1, -1}; +-static char buf[PATH_MAX + sizeof(handle_t) + 1]; ++static handle_t *restrict handle; ++static const size_t buflen = PATH_MAX+sizeof(handle_t)+1; + + static void sigchild(int sig attribute((unused))) + { +@@ -122,6 +135,7 @@ static void attribute((constructor)) start(void) + { + sigset_t sigset, oldset; + struct sigaction act; ++ char sync[1]; + ssize_t in; + + if (pipes[1] >= 0) close(pipes[1]); +@@ -138,6 +152,12 @@ static void attribute((constructor)) start(void) + act.sa_handler = sigchild; + sigaction(SIGCHLD, &act, 0); + ++ if (!handle) ++ handle = mmap(NULL, buflen, PROT_READ|PROT_WRITE, ++ MAP_ANONYMOUS|MAP_SHARED, -1, 0); ++ if (handle == MAP_FAILED) ++ goto error; ++ + if ((active = fork()) < 0) + goto error; + +@@ -164,16 +184,22 @@ static void attribute((constructor)) start(void) + pipes[1] = pipes[2] = -1; + pipes[0] = pipes[3] = -1; + +- { +- handle_t *restrict handle = (void*)&buf[0]; +- +- while ((in = read(STDIN_FILENO, handle, sizeof(buf))) > sizeof(handle_t)) { +- if (handle->function(handle->path, &handle->argument) < 0) +- handle->errcode = errno; +- write(STDOUT_FILENO, &handle->errcode, sizeof(handle->errcode)+sizeof(handle->argument)); +- memset(handle, 0, sizeof(handle_t)); ++ while ((in = read(STDIN_FILENO, &sync, sizeof(sync))) != 0) { ++ ssize_t out; ++ if (in < 0) { ++ if (errno == EINTR) ++ continue; ++ break; + } ++ if (!handle) ++ break; ++ if (handle->function(handle->path, &handle->argument) < 0) ++ handle->errcode = errno; ++ do ++ out = write(STDOUT_FILENO, &sync, sizeof(sync)); ++ while (out < 0 && errno == EINTR); + } ++ + sigprocmask(SIG_SETMASK, &oldset, NULL); + exit(0); + error: +@@ -181,6 +207,9 @@ error: + if (pipes[1] >= 0) close(pipes[1]); + if (pipes[2] >= 0) close(pipes[2]); + if (pipes[3] >= 0) close(pipes[3]); ++ if (handle && handle != MAP_FAILED) ++ munmap(handle, buflen); ++ handle = NULL; + } + + static void /* attribute((destructor)) */ stop(void) +@@ -189,24 +218,24 @@ static void /* attribute((destructor)) */ stop(void) + kill(active, SIGKILL); + } + +-static sigjmp_buf jenv; +-static void sigjump(int sig attribute((unused))) +-{ +- siglongjmp(jenv, 1); +-} +- + /* + * External routine ++ * ++ * Execute stat(2) system call with timeout to avoid deadlock ++ * on network based file systems. ++ * + */ +-int timeout(stat_t function, const char *path, struct stat *restrict argument, time_t seconds) ++int ++timeout(stat_t function, const char *path, struct stat *restrict argument, time_t seconds) + { +- handle_t *restrict handle = (void*)&buf[0]; + struct sigaction alrm_act, pipe_act, new_act; + sigset_t sigset, oldset; ++ char sync[1] = "x"; + + if (active <= 0) /* Oops, last one failed therefore clear status and restart */ + start(); +- ++ if (!handle) /* No shared memory area */ ++ return function(path, argument); + memset(handle, 0, sizeof(handle_t)); + handle->len = strlen(path) + 1; + if (handle->len >= PATH_MAX) { +@@ -235,8 +264,8 @@ int timeout(stat_t function, const char *path, struct stat *restrict argument, t + sigaction(SIGPIPE, &new_act, &pipe_act); + alarm(seconds); + +- write(pipes[1], handle, sizeof(handle_t)+handle->len); +- read(pipes[2], &handle->errcode, sizeof(handle->errcode)+sizeof(handle->argument)); ++ write(pipes[1], &sync, sizeof(sync)); ++ read(pipes[2], &sync, sizeof(sync)); + + alarm(0); + sigaction(SIGPIPE, &pipe_act, NULL); +@@ -261,6 +290,82 @@ timed: + error: + return -1; + } ++#elif WITH_TIMEOUT_STAT == 1 ++/* ++ * External routine ++ * ++ * Execute stat(2) system call with timeout to avoid deadlock ++ * on network based file systems. ++ * ++ */ ++int ++timeout(stat_t function, const char *path, struct stat *restrict argument, time_t seconds) ++{ ++ struct sigaction alrm_act, pipe_act, new_act; ++ sigset_t sigset, oldset; ++ int ret = 0, pipes[4]; ++ pid_t pid = 0; ++ ssize_t len; ++ ++ if (pipe(&pipes[0]) < 0) ++ goto error; ++ switch ((pid = fork())) { ++ case -1: ++ close(pipes[0]); ++ close(pipes[1]); ++ goto error; ++ case 0: ++ new_act.sa_handler = SIG_DFL; ++ sigaction(SIGALRM, &new_act, NULL); ++ close(pipes[0]); ++ if ((ret = function(path, argument)) == 0) ++ do ++ len = write(pipes[1], argument, sizeof(struct stat)); ++ while (len < 0 && errno == EINTR); ++ close(pipes[1]); ++ exit(ret); ++ default: ++ close(pipes[1]); ++ ++ sigemptyset(&sigset); ++ sigaddset(&sigset, SIGALRM); ++ sigaddset(&sigset, SIGPIPE); ++ sigprocmask(SIG_UNBLOCK, &sigset, &oldset); ++ ++ memset(&new_act, 0, sizeof(new_act)); ++ sigemptyset(&new_act.sa_mask); ++ ++ if (sigsetjmp(jenv, 1)) ++ goto timed; ++ ++ new_act.sa_handler = sigjump; ++ sigaction(SIGALRM, &new_act, &alrm_act); ++ sigaction(SIGPIPE, &new_act, &pipe_act); ++ alarm(seconds); ++ if (read(pipes[0], argument, sizeof(struct stat)) == 0) { ++ errno = EFAULT; ++ ret = -1; ++ } ++ (void)alarm(0); ++ sigaction(SIGPIPE, &pipe_act, NULL); ++ sigaction(SIGALRM, &alrm_act, NULL); ++ ++ close(pipes[0]); ++ waitpid(pid, NULL, 0); ++ break; ++ } ++ return ret; ++timed: ++ (void)alarm(0); ++ sigaction(SIGPIPE, &pipe_act, NULL); ++ sigaction(SIGALRM, &alrm_act, NULL); ++ if (waitpid(0, NULL, WNOHANG) == 0) ++ kill(pid, SIGKILL); ++ errno = ETIMEDOUT; ++error: ++ return -1; ++} ++#endif + + /* + * End of timeout.c +diff --git src/timeout.h src/timeout.h +index 546c13b..f372297 100644 +--- src/timeout.h ++++ src/timeout.h +@@ -17,7 +17,11 @@ + #ifndef _TIMEOUT_H + #define _TIMEOUT_H + +-#include "config.h" /* For _FILE_OFFSET_BITS */ ++#include "config.h" ++ ++#ifndef WITH_TIMEOUT_STAT ++# define WITH_TIMEOUT_STAT 0 ++#endif + + #include + #include +@@ -30,7 +34,12 @@ + # endif + #endif + +-typedef int (*stat_t)(const char *, struct stat *restrict); ++typedef int (*stat_t)(const char *, struct stat *); ++ ++#if WITH_TIMEOUT_STAT > 0 + extern int timeout(stat_t, const char *, struct stat *restrict, time_t); ++#else ++# define timeout(func,path,buf,dummy) (func)((path),(buf)) ++#endif + + #endif diff --git a/psmisc-22.16.dif b/psmisc-22.20.dif similarity index 51% rename from psmisc-22.16.dif rename to psmisc-22.20.dif index 427c38e..bdcfe46 100644 --- a/psmisc-22.16.dif +++ b/psmisc-22.20.dif @@ -1,6 +1,6 @@ --- configure.ac -+++ configure.ac 2010-10-15 09:00:32.915927054 +0000 -@@ -72,7 +72,7 @@ AC_CHECK_MEMBERS([struct user_regs_struc ++++ configure.ac 2010-10-15 09:00:33.000000000 +0000 +@@ -121,7 +121,7 @@ AC_CHECK_MEMBERS([struct user_regs_struc struct user_regs_struct.rdi, struct user_regs_struct.rsi, struct user_regs_struct.rdx], [],[], @@ -10,37 +10,35 @@ AC_CHECK_MEMBERS([struct pt_regs.orig_gpr3, struct pt_regs.gpr], [],[], [#include ]) --- src/fuser.c -+++ src/fuser.c 2011-02-08 16:08:59.823926228 +0000 -@@ -888,7 +888,8 @@ int main(int argc, char *argv[]) - char option_buf[3]; - struct option *optr; ++++ src/fuser.c 2012-12-18 16:52:23.749452207 +0000 +@@ -878,6 +878,7 @@ int main(int argc, char *argv[]) + struct option *optr; char *nsptr; -- int skip_argv; -+ int skip_argv; + int skip_argv; + int seen_file; struct option options[] = { {"all", 0, NULL, 'a'}, -@@ -927,6 +928,7 @@ int main(int argc, char *argv[]) - netdev = find_net_dev(); +@@ -918,6 +919,7 @@ int main(int argc, char *argv[]) fill_unix_cache(&unixsockets); + #endif -+ seen_file = 0; - for (argc_cnt = 1; argc_cnt < argc; argc_cnt++) { - current_argv = argv[argc_cnt]; - if (current_argv[0] == '-') { /* its an option */ -@@ -1056,6 +1058,7 @@ int main(int argc, char *argv[]) ++ seen_file = 0; + for (argc_cnt = 1; argc_cnt < argc; argc_cnt++) { + current_argv = argv[argc_cnt]; + if (current_argv[0] == '-') { /* its an option */ +@@ -1070,6 +1072,7 @@ int main(int argc, char *argv[]) } } this_name->matched_procs = NULL; + seen_file = 1; - if (opts & (OPT_MOUNTS|OPT_ISMOUNTPOINT) + if (opts & (OPT_MOUNTS | OPT_ISMOUNTPOINT) && this_name->name_space != NAMESPACE_FILE) usage(_ -@@ -1103,7 +1106,7 @@ int main(int argc, char *argv[]) +@@ -1126,7 +1129,7 @@ int main(int argc, char *argv[]) names_tail->next = this_name; names_tail = this_name; - } /* for across the argvs */ + } /* for across the argvs */ - if (names_head == NULL) + if (names_head == NULL && !seen_file) usage(_("No process specification given")); diff --git a/psmisc-22.20.tar.gz b/psmisc-22.20.tar.gz new file mode 100644 index 0000000..86b8d54 --- /dev/null +++ b/psmisc-22.20.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b17224e2385f6a799ffebba27eb7870771d42555e86814ef56b6d7e955765514 +size 432501 diff --git a/psmisc.changes b/psmisc.changes index 0c33651..1761621 100644 --- a/psmisc.changes +++ b/psmisc.changes @@ -1,3 +1,31 @@ +------------------------------------------------------------------- +Tue Dec 18 17:16:02 UTC 2012 - werner@suse.de + +- Update to version 22.20 + upstream patch + * Make usage of linked lists of devices found in + /proc/self/mountinfo optional + * Make timeout() in timeout.c work with shared mmap to + reduce the load due write/read the stat buffers + * Add list_sort() to lists.h to be able to sort lists + * pstree sorts properly on names Debian #682014 + * fuser -m regresion fixed SF #3559232, thanks to hanpt + * pstree finds orphaned processes SF#3537508 + * fuser finds unix sockets again SF #3502649 + * pstree finds pid 0 stops looping Debian #687829 + * killall with no args exits again SF #3536526 + * Added AC_CANONICAL_TARGET for target_os Debian #673485 + * sed doesn't have [0-9]+ replace with [0-9][0-9]* + * assert in killall triggered for small lifetimes Debian #628617 + * killall MAX_NAMES off by one Debian #677428 + * Removed remaining parts of pidof + * fuser uses correct timeout_stat define Debian #661723 + * fuser is not compiled on hurd-i386 Debian #673485 + * No TEXTRELS in src/lists built as PIE on x86 + * Fake pstree root for kernels with hidepid turned on + * More fixes for Cygwin SF Patch #3511920 + * pstree can show PGIDs SF Patch #3471056 +- This should fix the bug reported by Madhu + ------------------------------------------------------------------- Tue Mar 13 15:26:37 UTC 2012 - werner@suse.de diff --git a/psmisc.spec b/psmisc.spec index c7b040e..8075aa8 100644 --- a/psmisc.spec +++ b/psmisc.spec @@ -24,18 +24,21 @@ BuildRequires: libselinux-devel BuildRequires: ncurses-devel Url: http://sourceforge.net/projects/psmisc/ PreReq: %fillup_prereq %insserv_prereq -Version: 22.16 +Version: 22.20 Release: 0 Provides: ps:/usr/bin/killall +%if %suse_version > 1020 +Recommends: %{name}-lang = 6.18.00 +%endif Summary: Utilities for managing processes on your system License: GPL-2.0+ Group: System/Monitoring Source: http://sourceforge.net/projects/psmisc/files/psmisc/%{name}-%{version}.tar.gz -Patch0: %name-22.16.dif +Patch0: %name-22.20.dif Patch1: %name-22.12-tigetstr.patch Patch2: %name-22.12-pstree.patch -Patch42: pstree-segfault.patch -Patch43: %name-22.16-timeout.patch +Patch3: %name-22.20-pstree.patch +Patch42: %{name}-%{version}-upstream.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build %define nopeek s390 s390x ia64 %sparc hppa @@ -48,12 +51,20 @@ command sends a specified signal (SIGTERM if nothing is specified) to processes identified by name. The fuser command identifies the PIDs of processes that are using specified files or filesystems. +%package lang +Summary: Languages for package %{name} +Group: System/Localization +Requires: %{name} = %{version} + +%description lang +Provides translations to the package %{name} + %prep %setup -q -%patch42 -p1 -b .to -%patch43 -p1 -b .comm +%patch42 -p0 -b .up %patch1 -p0 -b .tigetstr %patch2 -p0 -b .pstree +%patch3 -p0 -b .se %patch0 -p0 -b .0 %build @@ -67,7 +78,8 @@ sh ./configure --prefix=%{_prefix} --mandir=%{_mandir} \ --disable-rpath \ --with-gnu-ld \ --enable-selinux \ - --enable-timeout-stat + --enable-mountinfo-list \ + --enable-timeout-stat=static make %{?_smp_mflags} CFLAGS="$CFLAGS" "CC=$CC" %install @@ -82,7 +94,7 @@ rm -f $RPM_BUILD_ROOT%{_mandir}/man1/peekfd.1* %clean rm -rf $RPM_BUILD_ROOT -%files -f psmisc.lang +%files %defattr (-,root,root,755) /bin/fuser %{_bindir}/killall @@ -100,4 +112,6 @@ rm -rf $RPM_BUILD_ROOT %{_mandir}/man1/prtstat.1* %{_mandir}/man1/pstree.1* +%files lang -f psmisc.lang + %changelog diff --git a/pstree-segfault.patch b/pstree-segfault.patch deleted file mode 100644 index f80fd95..0000000 --- a/pstree-segfault.patch +++ /dev/null @@ -1,32 +0,0 @@ -diff --git a/ChangeLog b/ChangeLog -index 45f6c04..b42a4d7 100644 ---- a/ChangeLog -+++ b/ChangeLog -@@ -1,3 +1,5 @@ -+ * Really add ASCII null at command string in add_proc() of pstree.c -+ - Changes in 22.16 - ================ - * Use strncpy for COMM_LEN and make it 18 characters to cover brackets -diff --git a/src/pstree.c b/src/pstree.c -index 80cfcec..a6c8f6e 100644 ---- a/src/pstree.c -+++ b/src/pstree.c -@@ -265,7 +265,7 @@ static PROC *new_proc(const char *comm, pid_t pid, uid_t uid) - exit(1); - } - strncpy(new->comm, comm, COMM_LEN+2); -- new->comm[COMM_LEN+1]='\0'; /* make sure nul terminated*/ -+ new->comm[COMM_LEN+1] = '\0'; /* make sure nul terminated*/ - new->pid = pid; - new->uid = uid; - new->flags = 0; -@@ -354,7 +354,7 @@ add_proc(const char *comm, pid_t pid, pid_t ppid, uid_t uid, - #endif /*WITH_SELINUX */ - else { - strncpy(this->comm, comm, COMM_LEN+2); -- this->comm[COMM_LEN+1]; -+ this->comm[COMM_LEN+1] = '\0'; - this->uid = uid; - } - if (args)