diff --git a/pidof b/pidof new file mode 100755 index 0000000..5bf33ee --- /dev/null +++ b/pidof @@ -0,0 +1,5 @@ +#!/bin/sh + +[ $0 = /sbin/pidof ] && echo -e "WARNING: pidof has been moved from /sbin to /usr/bin.\n Please, change/remove the hardcoded path." 1>&2 + +/usr/bin/pidof "$@" diff --git a/procps-ng-3.3.8-pidof.patch b/procps-ng-3.3.8-pidof.patch new file mode 100644 index 0000000..7c1b1a4 --- /dev/null +++ b/procps-ng-3.3.8-pidof.patch @@ -0,0 +1,552 @@ +diff --git a/Makefile.am b/Makefile.am +index 3d66d60..7075e67 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -52,6 +52,14 @@ EXTRA_DIST = \ + Documentation/TODO \ + sysctl.conf + ++if BUILD_PIDOF ++usrbin_exec_PROGRAMS += pidof ++dist_man_MANS += pidof.1 ++pidof_SOURCES = pidof.c $(top_srcdir)/lib/fileutils.c ++else ++ EXTRA_DIST += pidof.1 ++endif ++ + if BUILD_KILL + bin_PROGRAMS = kill + dist_man_MANS += kill.1 +diff --git a/pidof.1 b/pidof.1 +new file mode 100644 +index 0000000..f2544c8 +--- /dev/null ++++ b/pidof.1 +@@ -0,0 +1,60 @@ ++'\" -*- coding: UTF-8 -*- ++.\" Copyright (C) 1998 Miquel van Smoorenburg. ++.\" ++.\" 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. ++.\" ++.\" 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 General Public License for more details. ++.\" ++.\" You should have received a copy of the GNU General Public License ++.\" along with this program; if not, write to the Free Software ++.\" Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++.\" ++.TH PIDOF 1 "24 Jul 2013" "" "User Commands" ++.SH NAME ++pidof -- find the process ID of a running program. ++.SH SYNOPSIS ++.B pidof ++.RB [ \-s ] ++.RB [ \-c ] ++.RB [ \-x ] ++.RB [ \-o ++.IR omitpid[,omitpid..] ] ++.RB [ \-o ++.IR omitpid[,omitpid..].. ] ++.B program ++.RB [ program.. ] ++.SH DESCRIPTION ++.B Pidof ++finds the process id's (pids) of the named programs. It prints those ++id's on the standard output. ++.SH OPTIONS ++.IP \-s ++Single shot - this instructs the program to only return one \fIpid\fP. ++.IP \-c ++Only return process ids that are running with the same root directory. ++This option is ignored for non-root users, as they will be unable to check ++the current root directory of processes they do not own. ++.IP \-x ++Scripts too - this causes the program to also return process id's of ++shells running the named scripts. ++.IP "-o \fIomitpid\fP" ++Tells \fIpidof\fP to omit processes with that process id. ++.SH "EXIT STATUS" ++.TP ++.B 0 ++At least one program was found with the requested name. ++.TP ++.B 1 ++No program was found with the requested name. ++ ++.SH SEE ALSO ++.BR pgrep (1), ++.BR pkill (1) ++.SH AUTHOR ++Jaromir Capik +diff --git a/pidof.c b/pidof.c +new file mode 100644 +index 0000000..6cce24c +--- /dev/null ++++ b/pidof.c +@@ -0,0 +1,371 @@ ++/* ++ * pidof.c - Utility for listing pids of running processes ++ * ++ * Copyright (C) 2013 Jaromir Capik ++ * ++ * 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. ++ * ++ * 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 General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include ++#include ++ ++#include "c.h" ++#include "fileutils.h" ++#include "nls.h" ++#include "xalloc.h" ++#include "proc/readproc.h" ++#include "proc/sig.h" ++#include "proc/devname.h" ++#include "proc/sysinfo.h" ++#include "proc/version.h" /* procps_version */ ++ ++ ++#define grow_size(x) (x = x * 5 / 4 + 1024) ++#define safe_free(x) if (x) { free(x); x=NULL; } ++ ++ ++struct el { ++ pid_t pid; ++}; ++ ++struct el *procs = NULL; ++static int proc_count = 0; ++ ++struct el *omitted_procs = NULL; ++static int omit_count = 0; ++ ++static char *program = NULL; ++ ++/* switch flags */ ++static int opt_single_shot = 0; /* -s */ ++static int opt_scripts_too = 0; /* -x */ ++static int opt_rootdir_check = 0; /* -c */ ++ ++static char *pidof_root = NULL; ++ ++static int __attribute__ ((__noreturn__)) usage(int opt) ++{ ++ int err = (opt == '?'); ++ FILE *fp = err ? stderr : stdout; ++ ++ fputs(USAGE_HEADER, fp); ++ fprintf(fp, _(" %s [options] [program [...]]\n"), program_invocation_short_name); ++ fputs(USAGE_OPTIONS, fp); ++ fputs(_(" -s, --single-shot return one PID only\n" ++ " -c, --check-root omit processes with different root\n" ++ " -x scripts too\n" ++ " -o, --omit-pid omit processes with PID\n"), fp); ++ fputs(USAGE_SEPARATOR, fp); ++ fputs(USAGE_HELP, fp); ++ fputs(USAGE_VERSION, fp); ++ fprintf(fp, USAGE_MAN_TAIL("pidof(1)")); ++ ++ exit(fp == stderr ? EXIT_FAILURE : EXIT_SUCCESS); ++} ++ ++ ++static int is_omitted (pid_t pid) ++{ ++ int i; ++ ++ for (i = 0; i < omit_count; i++) { ++ if (pid == omitted_procs[i].pid) return 1; ++ } ++ ++ return 0; ++} ++ ++ ++static char *get_basename (char *filename) ++{ ++ char *pos; ++ char *result; ++ ++ pos = result = filename; ++ while (*pos != '\0') { ++ if (*(pos++) == '/') result = pos; ++ } ++ ++ return result; ++} ++ ++ ++static char *pid_link (pid_t pid, const char *base_name) ++{ ++ char link [PROCPATHLEN]; ++ char *result; ++ int path_alloc_size; ++ int len; ++ ++ snprintf(link, sizeof(link), "/proc/%d/%s", pid, base_name); ++ ++ len = path_alloc_size = 0; ++ result = NULL; ++ do { ++ if (len == path_alloc_size) { ++ grow_size (path_alloc_size); ++ result = (char *) xrealloc (result, path_alloc_size); ++ } ++ ++ if ((len = readlink(link, result, path_alloc_size - 1)) < 0) { ++ len = 0; ++ break; ++ } ++ ++ } while (len == path_alloc_size); ++ ++ result[len] = '\0'; ++ ++ return result; ++} ++ ++ ++static void select_procs (void) ++{ ++ PROCTAB *ptp; ++ proc_t task; ++ int match, root_check_ok; ++ static int size = 0; ++ char *cmd_arg0, *cmd_arg0base; ++ char *cmd_arg1, *cmd_arg1base; ++ char *pos; ++ char *program_base; ++ char *root_link; ++ char *exe_link; ++ char *exe_link_base; ++ ++ /* get the input base name */ ++ program_base = get_basename(program); ++ ++ ptp = openproc (PROC_FILLCOM | PROC_FILLSTAT); ++ ++ exe_link = root_link = NULL; ++ memset(&task, 0, sizeof (task)); ++ while(readproc(ptp, &task)) { ++ ++ if (opt_rootdir_check) { ++ /* get the /proc//root symlink value */ ++ root_link = pid_link(task.XXXID, "root"); ++ match = !strcmp(pidof_root, root_link); ++ safe_free(root_link); ++ ++ if (!match) { /* root check failed */ ++ memset (&task, 0, sizeof (task)); ++ continue; ++ } ++ } ++ ++ if (!is_omitted(task.XXXID) && task.cmdline) { ++ ++ cmd_arg0 = *task.cmdline; ++ ++ /* processes starting with '-' are login shells */ ++ if (*cmd_arg0 == '-') { ++ cmd_arg0++; ++ } ++ ++ /* get the argv0 base name */ ++ cmd_arg0base = get_basename(cmd_arg0); ++ ++ /* get the /proc//exe symlink value */ ++ exe_link = pid_link(task.XXXID, "exe"); ++ ++ /* get the exe_link base name */ ++ exe_link_base = get_basename(exe_link); ++ ++ match = 0; ++ ++ if (!strcmp(program, cmd_arg0base) || ++ !strcmp(program_base, cmd_arg0) || ++ !strcmp(program, cmd_arg0) || ++ ++ !strcmp(program, exe_link_base) || ++ !strcmp(program, exe_link)) ++ { ++ match = 1; ++ ++ } else if (opt_scripts_too && *(task.cmdline+1)) { ++ ++ pos = cmd_arg1base = cmd_arg1 = *(task.cmdline+1); ++ ++ /* get the arg1 base name */ ++ while (*pos != '\0') { ++ if (*(pos++) == '/') cmd_arg1base = pos; ++ } ++ ++ /* if script, then task.cmd = argv1, otherwise task.cmd = argv0 */ ++ if (task.cmd && ++ !strncmp(task.cmd, cmd_arg1base, strlen(task.cmd)) && ++ (!strcmp(program, cmd_arg1base) || ++ !strcmp(program_base, cmd_arg1) || ++ !strcmp(program, cmd_arg1))) ++ { ++ match = 1; ++ } ++ } ++ ++ safe_free(exe_link); ++ ++ if (match) { ++ if (proc_count == size) { ++ grow_size(size); ++ procs = xrealloc(procs, size * (sizeof *procs)); ++ } ++ if (procs) { ++ procs[proc_count++].pid = task.XXXID; ++ } else { ++ xerrx(EXIT_FAILURE, _("internal error")); ++ } ++ } ++ ++ } ++ ++ memset (&task, 0, sizeof (task)); ++ } ++ ++ closeproc (ptp); ++} ++ ++ ++static void add_to_omit_list (char *input_arg) ++{ ++ static int omit_size = 0; ++ ++ char *omit_str; ++ char *endptr; ++ ++ pid_t omit_pid; ++ ++ omit_str = NULL; ++ omit_str = strtok(input_arg, ","); ++ while (omit_str) { ++ ++ omit_pid = strtoul(omit_str, &endptr, 10); ++ ++ if (*endptr == '\0') { ++ if (omit_count == omit_size) { ++ grow_size(omit_size); ++ omitted_procs = xrealloc(omitted_procs, omit_size * sizeof(*omitted_procs)); ++ } ++ if (omitted_procs) { ++ omitted_procs[omit_count++].pid = omit_pid; ++ } else { ++ xerrx(EXIT_FAILURE, _("internal error")); ++ } ++ } else { ++ xwarnx(_("illegal omit pid value (%s)!\n"), omit_str); ++ } ++ ++ omit_str = strtok(NULL, ","); ++ } ++} ++ ++ ++ ++int main (int argc, char **argv) ++{ ++ int opt; ++ signed int i; ++ int found = 0; ++ int first_pid = 1; ++ ++ const char *opts = "scnxmo:?Vh"; ++ ++ static const struct option longopts[] = { ++ {"single-shot", no_argument, NULL, 's'}, ++ {"omit-pid", required_argument, NULL, 'o'}, ++ {"help", no_argument, NULL, 'h'}, ++ {"version", no_argument, NULL, 'V'}, ++ {NULL, 0, NULL, 0} ++ }; ++ ++#ifdef HAVE_PROGRAM_INVOCATION_NAME ++ program_invocation_name = program_invocation_short_name; ++#endif ++ setlocale (LC_ALL, ""); ++ bindtextdomain (PACKAGE, LOCALEDIR); ++ textdomain (PACKAGE); ++ atexit (close_stdout); ++ ++ /* process command-line options */ ++ while ((opt = getopt_long (argc, argv, opts, longopts, NULL)) != -1) { ++ switch (opt) { ++ case 's': ++ opt_single_shot = 1; ++ break; ++ case 'o': ++ add_to_omit_list (optarg); ++ break; ++ case 'x': ++ opt_scripts_too = 1; ++ break; ++ case 'c': ++ if (geteuid() == 0) { ++ opt_rootdir_check = 1; ++ pidof_root = pid_link(getpid(), "root"); ++ } ++ break; ++ case 'V': ++ printf (PROCPS_NG_VERSION); ++ exit (EXIT_SUCCESS); ++ case 'h': ++ case '?': ++ usage (opt); ++ break; ++ /* compatibility-only switches */ ++ case 'n': /* avoiding stat(2) on NFS volumes doesn't make any sense anymore ... */ ++ /* ... as this reworked solution does not use stat(2) at all */ ++ case 'm': /* omitting relatives with argv[0] & argv[1] matching the argv[0] & argv[1] ...*/ ++ /* ... of explicitly omitted PIDs is too 'expensive' and as we don't know */ ++ /* ... wheter it is still needed, we won't re-implement it unless ... */ ++ /* ... somebody gives us a good reason to do so :) */ ++ break; ++ } ++ } ++ ++ /* main loop */ ++ while (argc - optind) { /* for each program */ ++ ++ program = argv[optind++]; ++ ++ select_procs(); /* get the list of matching processes */ ++ ++ if (proc_count) { ++ ++ found = 1; ++ for (i = proc_count - 1; i >= 0; i--) { /* and display their PIDs */ ++ if (first_pid) { ++ first_pid = 0; ++ printf ("%ld", procs[i].pid); ++ } else { ++ printf (" %ld", procs[i].pid); ++ } ++ if (opt_single_shot) break; ++ } ++ ++ proc_count = 0; ++ } ++ } ++ ++ /* final line feed */ ++ if (found) printf("\n"); ++ ++ /* some cleaning */ ++ safe_free(procs); ++ safe_free(omitted_procs); ++ safe_free(pidof_root); ++ ++ return !found; ++} +-- +1.8.3.1 + +diff --git a/pidof.c b/pidof.c +index 6cce24c..a39a4c0 100644 +--- a/pidof.c ++++ b/pidof.c +@@ -26,9 +26,6 @@ + #include "nls.h" + #include "xalloc.h" + #include "proc/readproc.h" +-#include "proc/sig.h" +-#include "proc/devname.h" +-#include "proc/sysinfo.h" + #include "proc/version.h" /* procps_version */ + + +@@ -284,6 +281,7 @@ int main (int argc, char **argv) + const char *opts = "scnxmo:?Vh"; + + static const struct option longopts[] = { ++ {"check-root", no_argument, NULL, 'c'}, + {"single-shot", no_argument, NULL, 's'}, + {"omit-pid", required_argument, NULL, 'o'}, + {"help", no_argument, NULL, 'h'}, +-- +1.8.3.1 + +diff --git a/pidof.1 b/pidof.1 +index f2544c8..f49cd23 100644 +--- a/pidof.1 ++++ b/pidof.1 +@@ -44,7 +44,9 @@ the current root directory of processes they do not own. + Scripts too - this causes the program to also return process id's of + shells running the named scripts. + .IP "-o \fIomitpid\fP" +-Tells \fIpidof\fP to omit processes with that process id. ++Tells \fIpidof\fP to omit processes with that process id. The special ++pid \fB%PPID\fP can be used to name the parent process of the \fIpidof\fP ++program, in other words the calling shell or shell script. + .SH "EXIT STATUS" + .TP + .B 0 +diff --git a/pidof.c b/pidof.c +index a39a4c0..72344e7 100644 +--- a/pidof.c ++++ b/pidof.c +@@ -246,10 +246,15 @@ static void add_to_omit_list (char *input_arg) + pid_t omit_pid; + + omit_str = NULL; +- omit_str = strtok(input_arg, ","); ++ omit_str = strtok(input_arg, ",;:"); + while (omit_str) { + +- omit_pid = strtoul(omit_str, &endptr, 10); ++ if (!strcmp(omit_str,"%PPID")) { /* keeping this %PPID garbage for backward compatibility only */ ++ omit_pid = getppid(); /* ... as it can be replaced with $$ in common shells */ ++ endptr = omit_str + sizeof("%PPID") - 1; ++ } else { ++ omit_pid = strtoul(omit_str, &endptr, 10); ++ } + + if (*endptr == '\0') { + if (omit_count == omit_size) { +@@ -265,7 +270,7 @@ static void add_to_omit_list (char *input_arg) + xwarnx(_("illegal omit pid value (%s)!\n"), omit_str); + } + +- omit_str = strtok(NULL, ","); ++ omit_str = strtok(NULL, ",;:"); + } + } + +diff -Naur procps-ng-3.3.8.orig/configure.ac procps-ng-3.3.8/configure.ac +--- procps-ng-3.3.8.orig/configure.ac 2013-10-16 19:45:54.000000000 +0200 ++++ procps-ng-3.3.8/configure.ac 2013-10-16 19:46:56.057000000 +0200 +@@ -168,6 +168,12 @@ + fi + + # AC_ARG_ENABLEs ++AC_ARG_ENABLE([pidof], ++ AS_HELP_STRING([--disable-pidof], [do not build pidof]), ++ [], [enable_pidof=yes] ++) ++AM_CONDITIONAL(BUILD_PIDOF, test "x$enable_pidof" = xyes) ++ + AC_ARG_ENABLE([kill], + AS_HELP_STRING([--disable-kill], [do not build kill]), + [], enable_kill=yes diff --git a/procps-ng.spec b/procps-ng.spec index 133305b..b2b960c 100644 --- a/procps-ng.spec +++ b/procps-ng.spec @@ -4,12 +4,13 @@ Summary: System and process monitoring utilities Name: procps-ng Version: 3.3.8 -Release: 15%{?dist} +Release: 16%{?dist} License: GPL+ and GPLv2 and GPLv2+ and GPLv3+ and LGPLv2+ Group: Applications/System URL: https://sourceforge.net/projects/procps-ng/ -Source: http://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar.xz +Source0: http://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar.xz +Source1: pidof Patch0: 0001-top-add-the-major-version-to-dlopen-of-libnuma-sonam.patch Patch1: 0002-library-for-atexit-support-fix-fileutils-for-EPIPE.patch @@ -24,6 +25,7 @@ Patch9: procps-add_support_for_linux_namespaces.patch Patch10: pgrep-introduce_support_for_namespaces.patch Patch11: skill-support_namespaces.patch Patch12: procps-fix_the_fatal_make_dist_error_for_nsutils.patch +Patch13: procps-ng-3.3.8-pidof.patch Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig @@ -48,6 +50,12 @@ Obsoletes: procps < 3.2.9-1 Provides: /sbin/sysctl Provides: /bin/ps +# sysvinit removal in Fedora 21 +Conflicts: sysvinit-tools < 0:2.88-14 +Obsoletes: sysvinit-tools > 0:2.88-14 +Provides: /sbin/pidof + + %description The procps package contains a set of system utilities that provide system information. Procps includes ps, free, skill, pkill, pgrep, @@ -95,6 +103,8 @@ System and process monitoring utilities development headers %patch10 -p1 %patch11 -p1 %patch12 -p1 +%patch13 -p1 + %build # The following stuff is needed for git archives only @@ -135,6 +145,8 @@ make DESTDIR=%{buildroot} install mkdir -p %{buildroot}%{_sysconfdir}/sysctl.d +install -pm755 %{SOURCE1} %{buildroot}%{_sbindir} + %post -p /sbin/ldconfig %postun -p /sbin/ldconfig @@ -161,6 +173,9 @@ mkdir -p %{buildroot}%{_sysconfdir}/sysctl.d %{_includedir}/proc %changelog +* Wed Oct 16 2013 Jaromir Capik - 3.3.8-16 +- Introducing pidof (#987064) + * Tue Sep 17 2013 Aristeu Rozanski - 3.3.8-15 - Introduce namespaces support (#1016242)