diff --git a/peekfd-m68k.patch b/peekfd-m68k.patch deleted file mode 100644 index 206e69b..0000000 --- a/peekfd-m68k.patch +++ /dev/null @@ -1,64 +0,0 @@ -Index: psmisc-22.20/configure.ac -=================================================================== ---- psmisc-22.20.orig/configure.ac -+++ psmisc-22.20/configure.ac -@@ -128,6 +128,8 @@ AC_CHECK_MEMBERS([struct pt_regs.orig_gp - AC_CHECK_MEMBERS([struct pt_regs.uregs],[],[], [#include ]) - AC_CHECK_MEMBERS([struct pt_regs.regs, - struct pt_regs.cp0_status],[],[], [#include ]) -+AC_CHECK_MEMBERS([struct pt_regs.orig_d0, -+ struct pt_regs.d0],[],[], [#include ]) - - case ${target_os} in - gnu*) -@@ -160,6 +162,9 @@ AM_CONDITIONAL(WANT_PEEKFD_MIPS, - test $build_cpu = mipsel && - test $ac_cv_member_struct_pt_regs_regs = yes && - test $ac_cv_member_struct_pt_regs_cp0_status = yes) -+AM_CONDITIONAL(WANT_PEEKFD_M68K, -+ test $ac_cv_member_struct_pt_regs_orig_d0 = yes && -+ test $ac_cv_member_struct_pt_regs_d0 = yes) - - dnl Checks for library functions. - AC_FUNC_CLOSEDIR_VOID -Index: psmisc-22.20/src/Makefile.am -=================================================================== ---- psmisc-22.20.orig/src/Makefile.am -+++ psmisc-22.20/src/Makefile.am -@@ -29,6 +29,10 @@ if WANT_PEEKFD_MIPS - bin_PROGRAMS += peekfd - AM_CFLAGS += -DMIPS - endif -+if WANT_PEEKFD_M68K -+ bin_PROGRAMS += peekfd -+ AM_CFLAGS += -DM68K -+endif - - fuser_SOURCES = fuser.c comm.h signals.c signals.h i18n.h fuser.h lists.h - if WANT_TIMEOUT_STAT -Index: psmisc-22.20/src/peekfd.c -=================================================================== ---- psmisc-22.20.orig/src/peekfd.c -+++ psmisc-22.20/src/peekfd.c -@@ -76,6 +76,12 @@ - #define REG_PARAM1 regs[4] - #define REG_PARAM2 regs[5] - #define REG_PARAM3 regs[6] -+#elif defined(M68K) -+ #define REG_ORIG_ACCUM orig_d0 -+ #define REG_ACCUM d0 -+ #define REG_PARAM1 d1 -+ #define REG_PARAM2 d2 -+ #define REG_PARAM3 d3 - #endif - - #define MAX_ATTACHED_PIDS 1024 -@@ -270,7 +276,7 @@ int main(int argc, char **argv) - } - - for (i = 0; i < regs.REG_PARAM3; i++) { --#ifdef _BIG_ENDIAN -+#if BYTE_ORDER == BIG_ENDIAN - #if __WORDSIZE == 64 - unsigned int a = bswap_64(ptrace(PTRACE_PEEKTEXT, pid, regs.REG_PARAM2 + i, 0)); - #else diff --git a/psmisc-22.20-pstree.patch b/psmisc-22.20-pstree.patch deleted file mode 100644 index f1a3b0f..0000000 --- a/psmisc-22.20-pstree.patch +++ /dev/null @@ -1,38 +0,0 @@ ---- 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 index e4f0adb..501db88 100644 --- a/psmisc-22.20-upstream.patch +++ b/psmisc-22.20-upstream.patch @@ -18,9 +18,9 @@ index 4e3f348..d5cb9ec 100644 + 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 + Changes in 22.21 ================ - * pstree sorts properly on names Debian #682014 + * Missing comma in fuser(1) added Debian #702391 diff --git configure.ac configure.ac index 9df639d..cb03ba9 100644 --- configure.ac diff --git a/psmisc-22.12-pstree.patch b/psmisc-22.21-pstree.patch similarity index 83% rename from psmisc-22.12-pstree.patch rename to psmisc-22.21-pstree.patch index 19861bb..bf7298a 100644 --- a/psmisc-22.12-pstree.patch +++ b/psmisc-22.21-pstree.patch @@ -1,6 +1,6 @@ --- src/pstree.c -+++ src/pstree.c 2010-07-13 10:27:54.139239142 +0000 -@@ -61,6 +61,7 @@ extern const char *__progname; ++++ src/pstree.c 2014-03-24 15:54:58.905193559 +0000 +@@ -69,6 +69,7 @@ extern const char *__progname; #define UTF_HD "\342\224\254" /* U+252C, Horizontal and down */ #define VT_BEG "\033(0\017" /* use graphic chars */ @@ -8,9 +8,9 @@ #define VT_END "\033(B" /* back to normal char set */ #define VT_V "x" /* see UTF definitions above */ #define VT_VR "t" -@@ -230,6 +231,27 @@ static void out_scontext(security_contex +@@ -397,6 +398,27 @@ static void out_scontext(security_contex + out_string("'"); } - #endif /*WITH_SELINUX */ +/* + * Only affects vt100 line drawing mode: Do not count the strlen of @@ -33,10 +33,10 @@ + } +} + - static void out_newline(void) { -@@ -426,11 +448,12 @@ dump_tree(PROC * current, int level, int + if (last_char && cur_x == output_width) +@@ -605,11 +627,12 @@ dump_tree(PROC * current, int level, int for (lvl = 0; lvl < level; lvl++) { for (i = width[lvl] + 1; i; i--) out_char(' '); @@ -54,7 +54,7 @@ } if (rep < 2) add = 0; -@@ -531,7 +554,7 @@ dump_tree(PROC * current, int level, int +@@ -714,7 +737,7 @@ dump_tree(PROC * current, int level, int } width[level] = comm_len + cur_x - offset + add; if (cur_x >= output_width && trunc) { @@ -63,7 +63,7 @@ out_string("+"); out_newline(); return; -@@ -553,7 +576,7 @@ dump_tree(PROC * current, int level, int +@@ -736,7 +759,7 @@ dump_tree(PROC * current, int level, int } } if (first) { diff --git a/psmisc-22.21-upstream.patch b/psmisc-22.21-upstream.patch new file mode 100644 index 0000000..d70b12b --- /dev/null +++ b/psmisc-22.21-upstream.patch @@ -0,0 +1,838 @@ +--- ChangeLog ++++ ChangeLog 2014-03-24 00:00:00.000000000 +0000 +@@ -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.21 + ================ + * Missing comma in fuser(1) added Debian #702391 +--- configure.ac ++++ configure.ac 2014-03-24 00:00:00.000000000 +0000 +@@ -42,6 +42,17 @@ if test "$enable_timeout_stat" = "static + 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])], +--- src/fuser.c ++++ src/fuser.c 2014-03-24 15:50:46.202235621 +0000 +@@ -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 nam + 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, str + 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, str + 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 + } + + 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, + 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_nam + + int + parse_mounts(struct names *this_name, struct device_list **dev_list, +- const char opts) ++ const opt_type opts) + { + dev_t match_device; + +@@ -1015,6 +982,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 */ +@@ -1033,6 +1004,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': +@@ -1401,7 +1375,7 @@ static struct stat *get_pidstat(const pi + 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; + } +@@ -1433,7 +1407,7 @@ check_dir(const pid_t pid, const char *d + 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 && errno != ENOTDIR) { + fprintf(stderr, _("Cannot stat file %s: %s\n"), + filepath, strerror(errno)); +@@ -1472,7 +1446,7 @@ check_dir(const pid_t pid, const char *d + 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)); +@@ -1542,7 +1516,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; + } +@@ -1578,7 +1552,7 @@ void fill_unix_cache(struct unixsocket_l + 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; + } +@@ -1723,7 +1697,7 @@ scan_knfsd(struct names *names_head, str + 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 */ +@@ -1767,7 +1741,7 @@ scan_mounts(struct names *names_head, st + 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 */ +@@ -1814,7 +1788,7 @@ scan_swaps(struct names *names_head, str + if (*find_space == '\0') + continue; + } +- if (timeout(stat, line, &st, 5) != 0) { ++ if (timeout(thestat, line, &st, 5) != 0) { + continue; + } + /* Scan the devices */ +@@ -1835,73 +1809,7 @@ scan_swaps(struct names *names_head, str + 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 +@@ -1990,42 +1898,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 +--- src/fuser.h ++++ src/fuser.h 2014-03-24 00:00:00.000000000 +0000 +@@ -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 +--- src/lists.h ++++ src/lists.h 2014-03-24 00:00:00.000000000 +0000 +@@ -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 *res + #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 */ +--- src/timeout.c ++++ src/timeout.c 2014-03-24 00:00:00.000000000 +0000 +@@ -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)) sta + { + 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)) sta + 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)) sta + 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)) * + 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 + 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 +--- src/timeout.h ++++ src/timeout.h 2014-03-24 00:00:00.000000000 +0000 +@@ -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.20.dif b/psmisc-22.21.dif similarity index 61% rename from psmisc-22.20.dif rename to psmisc-22.21.dif index bdcfe46..4315a01 100644 --- a/psmisc-22.20.dif +++ b/psmisc-22.21.dif @@ -1,5 +1,14 @@ --- configure.ac +++ configure.ac 2010-10-15 09:00:33.000000000 +0000 +@@ -40,7 +40,7 @@ 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"]) ++AM_CONDITIONAL([WANT_TIMEOUT_STAT], [test "$enable_timeout_stat" != "no"]) + + # Use string search for network based file systems but only if the system + # has /proc/self/mountinfo @@ -121,7 +121,7 @@ AC_CHECK_MEMBERS([struct user_regs_struc struct user_regs_struct.rdi, struct user_regs_struct.rsi, @@ -10,8 +19,8 @@ AC_CHECK_MEMBERS([struct pt_regs.orig_gpr3, struct pt_regs.gpr], [],[], [#include ]) --- src/fuser.c -+++ src/fuser.c 2012-12-18 16:52:23.749452207 +0000 -@@ -878,6 +878,7 @@ int main(int argc, char *argv[]) ++++ src/fuser.c 2014-03-24 15:56:40.134235583 +0000 +@@ -901,6 +901,7 @@ int main(int argc, char *argv[]) struct option *optr; char *nsptr; int skip_argv; @@ -19,7 +28,7 @@ struct option options[] = { {"all", 0, NULL, 'a'}, -@@ -918,6 +919,7 @@ int main(int argc, char *argv[]) +@@ -941,6 +942,7 @@ int main(int argc, char *argv[]) fill_unix_cache(&unixsockets); #endif @@ -27,7 +36,7 @@ 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[]) +@@ -1093,6 +1095,7 @@ int main(int argc, char *argv[]) } } this_name->matched_procs = NULL; @@ -35,7 +44,7 @@ if (opts & (OPT_MOUNTS | OPT_ISMOUNTPOINT) && this_name->name_space != NAMESPACE_FILE) usage(_ -@@ -1126,7 +1129,7 @@ int main(int argc, char *argv[]) +@@ -1144,7 +1147,7 @@ int main(int argc, char *argv[]) names_tail->next = this_name; names_tail = this_name; } /* for across the argvs */ @@ -43,4 +52,4 @@ + if (names_head == NULL && !seen_file) usage(_("No process specification given")); - if (opts & OPT_SILENT) { + /* Check if -M flag was used and if so check mounts */ diff --git a/psmisc-22.21.tar.gz b/psmisc-22.21.tar.gz new file mode 100644 index 0000000..e4911a0 --- /dev/null +++ b/psmisc-22.21.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97323cad619210845b696d7d722c383852b2acb5c49b5b0852c4f29c77a8145a +size 457702 diff --git a/psmisc.changes b/psmisc.changes index a09ef0e..2396d08 100644 --- a/psmisc.changes +++ b/psmisc.changes @@ -1,3 +1,24 @@ +------------------------------------------------------------------- +Mon Mar 24 16:01:51 UTC 2014 - werner@suse.de + +- Update to version 22.21 + * Missing comma in fuser(1) added Debian #702391 + * pstree uses COLUMN env variable Debian #717017 + * pstree shows proper thread names SF Bug#57 + * pstree shows namespace options SF Patch#30 + * killall.1 minor fixes SF Bug#59 + * peekfd for m68k SF Patch#31 + * Fixing some derefefed pointers SF Patch#32 + * Minor typos in man pages SF Bug#61 Bug#60 + * fuser -m and -M flags work either way Debian #606178 +- Remove patch + psmisc-22.20-pstree.patch as now part of upstream + peekfd-m68k.patch as now part of upstream +- Port the patches + psmisc-22.20-upstream.patch which becomes psmisc-22.21-upstream.patch + psmisc-22.20.dif which becomes psmisc-22.21.dif + psmisc-22.12-pstree.patch which becomes psmisc-22.21-pstree.patch + ------------------------------------------------------------------- Wed Oct 23 14:35:46 UTC 2013 - p.drouand@gmail.com diff --git a/psmisc.spec b/psmisc.spec index 9d2eace..ff47a3b 100644 --- a/psmisc.spec +++ b/psmisc.spec @@ -1,7 +1,7 @@ # # spec file for package psmisc # -# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -23,7 +23,7 @@ BuildRequires: glibc-devel BuildRequires: libselinux-devel BuildRequires: ncurses-devel Url: http://sourceforge.net/projects/psmisc/ -Version: 22.20 +Version: 22.21 Release: 0 Provides: ps:/usr/bin/killall Recommends: %{name}-lang @@ -31,12 +31,10 @@ 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.20.dif +Patch0: %name-22.21.dif Patch1: %name-22.12-tigetstr.patch -Patch2: %name-22.12-pstree.patch -Patch3: %name-22.20-pstree.patch -Patch4: peekfd-m68k.patch -Patch42: %{name}-%{version}-upstream.patch +Patch2: %name-22.21-pstree.patch +Patch42: %{name}-22.21-upstream.patch %define nopeek s390 s390x ia64 %sparc hppa aarch64 @@ -55,9 +53,7 @@ processes that are using specified files or filesystems. %patch42 -p0 -b .up %patch1 -p0 -b .tigetstr %patch2 -p0 -b .pstree -%patch3 -p0 -b .se %patch0 -p0 -b .0 -%patch4 -p1 %build autoreconf -fi