commit 19ad2b015ae751d6c30475deaf6c17cb9aa8e0f9 Author: Arkadiusz Miśkiewicz <ar...@maven.pl> Date: Thu Oct 5 19:51:09 2023 +0200
Up to 4.0.4 procps-FILLBUG_backport.patch | 13 +- procps-missing-symbol.patch | 10 - procps-pl.po-update.patch | 5 +- procps.spec | 47 ++- systemd-glob.patch | 857 ------------------------------------------ 5 files changed, 32 insertions(+), 900 deletions(-) --- diff --git a/procps.spec b/procps.spec index 92fdb47..9cefa1f 100644 --- a/procps.spec +++ b/procps.spec @@ -21,23 +21,22 @@ Summary(pl.UTF-8): Narzędzia do monitorowania procesów Summary(pt_BR.UTF-8): Utilitários de monitoração de processos Summary(tr.UTF-8): Süreç izleme araçları Name: procps -Version: 3.3.17 -Release: 2 +Version: 4.0.4 +Release: 1 Epoch: 1 License: GPL v2+ Group: Applications/System Source0: http://downloads.sourceforge.net/procps-ng/%{name}-ng-%{version}.tar.xz -# Source0-md5: d60613e88c2f442ebd462b5a75313d56 +# Source0-md5: 2f747fc7df8ccf402d03e375c565cf96 Source1: %{name}-non-english-man-pages.tar.bz2 # Source1-md5: 60d24720b76c10553ed4abf68b76e079 Source2: top.desktop Source3: top.png # Source3-md5: 5f0133b3c18000116ca48381eecc07af Source4: XConsole.sh -Patch0: %{name}-missing-symbol.patch + Patch1: %{name}-FILLBUG_backport.patch Patch2: %{name}-pl.po-update.patch -Patch3: systemd-glob.patch URL: https://gitlab.com/procps-ng/procps BuildRequires: autoconf >= 2.69 BuildRequires: automake >= 1:1.11 @@ -146,11 +145,10 @@ Static version of libproc library. Statyczna wersja biblioteki libproc. %prep -%setup -q -%patch0 -p1 +%setup -q -n %{name}-ng-%{version} + %patch1 -p1 %patch2 -p1 -%patch3 -p1 %{__sed} -i -e "s#usrbin_execdir=.*#usrbin_execdir='\${bindir}'#g" configure.ac @@ -197,16 +195,16 @@ ln -f $RPM_BUILD_ROOT%{_bindir}/{snice,skill} %endif install -d $RPM_BUILD_ROOT/%{_lib} -%{__mv} $RPM_BUILD_ROOT{%{_libdir}/libprocps.so.*,/%{_lib}} -ln -sf /%{_lib}/$(basename $RPM_BUILD_ROOT/%{_lib}/libprocps.so.*.*.*) \ - $RPM_BUILD_ROOT%{_libdir}/libprocps.so +%{__mv} $RPM_BUILD_ROOT{%{_libdir}/libproc2.so.*,/%{_lib}} +ln -sf /%{_lib}/$(basename $RPM_BUILD_ROOT/%{_lib}/libproc2.so.*.*.*) \ + $RPM_BUILD_ROOT%{_libdir}/libproc2.so cp -p %{SOURCE2} $RPM_BUILD_ROOT%{_desktopdir} cp -p %{SOURCE3} $RPM_BUILD_ROOT%{_pixmapsdir} install -p %{SOURCE4} $RPM_BUILD_ROOT%{_bindir}/XConsole # obsoleted by pkg-config -%{__rm} $RPM_BUILD_ROOT%{_libdir}/libprocps.la +%{__rm} $RPM_BUILD_ROOT%{_libdir}/libproc2.la # packaged as doc %{__rm} -r $RPM_BUILD_ROOT%{_docdir}/procps-ng @@ -224,9 +222,9 @@ rm -rf $RPM_BUILD_ROOT %files -f procps-ng.lang %defattr(644,root,root,755) -%doc AUTHORS Documentation/{FAQ,TODO,bugs.md} NEWS -%attr(755,root,root) /%{_lib}/libprocps.so.*.* -%ghost %attr(755,root,root) /%{_lib}/libprocps.so.8 +%doc AUTHORS doc/{FAQ,TODO,bugs.md} NEWS +%attr(755,root,root) /%{_lib}/libproc2.so.*.* +%ghost %attr(755,root,root) /%{_lib}/libproc2.so.0 %attr(755,root,root) /bin/ps %if %{with pidof} %attr(755,root,root) /bin/pidof @@ -237,7 +235,7 @@ rm -rf $RPM_BUILD_ROOT %attr(755,root,root) %{_bindir}/pgrep %attr(755,root,root) %{_bindir}/pkill %attr(755,root,root) %{_bindir}/pmap -%attr(755,root,root) %{_bindir}/pwait +%attr(755,root,root) %{_bindir}/pidwait %attr(755,root,root) %{_bindir}/pwdx %attr(755,root,root) %{_bindir}/skill %attr(755,root,root) %{_bindir}/slabtop @@ -257,9 +255,8 @@ rm -rf $RPM_BUILD_ROOT %{_mandir}/man1/pgrep.1* %{_mandir}/man1/pkill.1* %{_mandir}/man1/pmap.1* -%{_mandir}/man1/procps.1* %{_mandir}/man1/ps.1* -%{_mandir}/man1/pwait.1* +%{_mandir}/man1/pidwait.1* %{_mandir}/man1/pwdx.1* %{_mandir}/man1/skill.1* %{_mandir}/man1/slabtop.1* @@ -289,13 +286,13 @@ rm -rf $RPM_BUILD_ROOT %files devel %defattr(644,root,root,755) -%attr(755,root,root) %{_libdir}/libprocps.so -%{_includedir}/proc -%{_pkgconfigdir}/libprocps.pc -%{_mandir}/man3/openproc.3* -%{_mandir}/man3/readproc.3* -%{_mandir}/man3/readproctab.3* +%attr(755,root,root) %{_libdir}/libproc2.so +%{_includedir}/libproc2 +%{_pkgconfigdir}/libproc2.pc +%{_mandir}/man3/procps.3* +%{_mandir}/man3/procps_misc.3* +%{_mandir}/man3/procps_pids.3* %files static %defattr(644,root,root,755) -%{_libdir}/libprocps.a +%{_libdir}/libproc2.a diff --git a/procps-FILLBUG_backport.patch b/procps-FILLBUG_backport.patch index 71aad4f..eaf136d 100644 --- a/procps-FILLBUG_backport.patch +++ b/procps-FILLBUG_backport.patch @@ -1,12 +1,13 @@ ---- procps-procps/proc/readproc.h~ 2011-09-12 14:18:23.000000000 +0200 -+++ procps-procps/proc/readproc.h 2011-09-15 12:38:14.976931632 +0200 -@@ -250,6 +250,9 @@ +--- a/library/include/readproc.h~ 2011-09-12 14:18:23.000000000 +0200 ++++ b/library/include/readproc.h 2011-09-15 12:38:14.976931632 +0200 +@@ -241,6 +241,9 @@ // argument is the length of the list (currently only used for lists of user // id's since uid_t supports no convenient termination sentinel.) +// for compatibility with procps 2.0.7 +#define PROC_FILLBUG 0x007f /* No idea what we need */ + - #define PROC_FILLMEM 0x0001 // read statm - #define PROC_FILLCOM 0x0002 // alloc and fill in `cmdline' - #define PROC_FILLENV 0x0004 // alloc and fill in `environ' + #define PROC_FILLMEM 0x00000001 // read statm + #define PROC_FILLARG 0x00000002 // alloc and fill in `cmdline' vectors + #define PROC_FILLENV 0x00000004 // alloc and fill in `environ' vectors + diff --git a/procps-missing-symbol.patch b/procps-missing-symbol.patch deleted file mode 100644 index 7bbf1a0..0000000 --- a/procps-missing-symbol.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- procps-3.3.3/proc/libprocps.sym~ 2012-05-20 06:39:52.000000000 +0200 -+++ procps-3.3.3/proc/libprocps.sym 2012-11-13 14:58:42.195856948 +0100 -@@ -49,6 +49,7 @@ - readproctab2; - readproctab3; - readproctab; -+ freeproc; - readtask; - signal_name_to_number; - signal_number_to_name; diff --git a/procps-pl.po-update.patch b/procps-pl.po-update.patch index d822f3f..4efa369 100644 --- a/procps-pl.po-update.patch +++ b/procps-pl.po-update.patch @@ -1,7 +1,7 @@ diff -urNp -x '*.orig' procps-3.3.17.org/po/pl.po procps-3.3.17/po/pl.po --- procps-3.3.17.org/po/pl.po 2021-02-09 11:11:25.000000000 +0100 +++ procps-3.3.17/po/pl.po 2021-04-25 19:52:34.958750126 +0200 -@@ -285,8 +285,8 @@ msgid "" +@@ -401,8 +401,8 @@ " --ns <PID> match the processes that belong to the same\n" " namespace as <pid>\n" msgstr "" @@ -10,5 +10,6 @@ diff -urNp -x '*.orig' procps-3.3.17.org/po/pl.po procps-3.3.17/po/pl.po +" --ns <PID> dopasowanie procesów należących do tej samej\n" +" przestrzeni nazw, co <PID>\n" - #: pgrep.c:164 + #: src/pgrep.c:199 msgid "" + diff --git a/systemd-glob.patch b/systemd-glob.patch deleted file mode 100644 index 2aa6a98..0000000 --- a/systemd-glob.patch +++ /dev/null @@ -1,857 +0,0 @@ -commit 474847ed35dda5fd4c33a717d8cc7c4d17b90232 -Author: Craig Small <csm...@dropbear.xyz> -Date: Mon Sep 13 22:07:37 2021 +1000 - - sysctl: Support systemd glob patterns - - systemd-sysctl handles glob patterns along with overrides and - exceptions. Now the procps sysctl does it too. - - The return value for sysctl is consistently either 0 or 1. - - Added tests to check sysctl functions. - - References: - procps-ng/procps#191 - - Signed-off-by: Craig Small <csm...@dropbear.xyz> - -diff --git a/sysctl.c b/sysctl.c -index bbca0b9..d26cd11 100644 ---- a/sysctl.c -+++ b/sysctl.c -@@ -17,6 +17,7 @@ - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * -+ * Part of this code comes from systemd, especially sysctl.c - * Changelog: - * v1.01: - * - added -p <preload> to preload values from a file -@@ -40,6 +41,7 @@ - #include <sys/stat.h> - #include <sys/types.h> - #include <unistd.h> -+#include <ctype.h> - - #include "c.h" - #include "fileutils.h" -@@ -66,12 +68,34 @@ static bool PrintName; - static bool PrintNewline; - static bool IgnoreError; - static bool Quiet; -+static bool DryRun; - static char *pattern; - - #define LINELEN 4096 - static char *iobuf; - static size_t iolen = LINELEN; - -+typedef struct SysctlSetting { -+ char *key; -+ char *path; -+ char *value; -+ bool ignore_failure; -+ bool glob_exclude; -+ struct SysctlSetting *next; -+} SysctlSetting; -+ -+typedef struct SettingList { -+ struct SysctlSetting *head; -+ struct SysctlSetting *tail; -+} SettingList; -+ -+#define GLOB_CHARS "*?[" -+static inline bool string_is_glob(const char *p) -+{ -+ return !!strpbrk(p, GLOB_CHARS); -+} -+ -+ - /* Function prototypes. */ - static int pattern_match(const char *string, const char *pat); - static int DisplayAll(const char *restrict const path); -@@ -100,6 +124,81 @@ static void slashdot(char *restrict p, char old, char new) - } - } - -+static void setting_free(SysctlSetting *s) { -+ if (!s) -+ return; -+ -+ free(s->key); -+ free(s->path); -+ free(s->value); -+ free(s); -+} -+ -+static SysctlSetting *setting_new( -+ const char *key, -+ const char *value, -+ bool ignore_failure, -+ bool glob_exclude) { -+ -+ SysctlSetting *s = NULL; -+ char *path = NULL; -+ int proc_len; -+ -+ proc_len = strlen(PROC_PATH); -+ /* used to open the file */ -+ path = xmalloc(strlen(key) + proc_len + 2); -+ strcpy(path, PROC_PATH); -+ if (key[0] == '-') -+ strcat(path + proc_len, key+1); -+ else -+ strcat(path + proc_len, key); -+ /* change . to / */ -+ slashdot(path + proc_len, '.', '/'); -+ -+ s = xmalloc(sizeof(SysctlSetting)); -+ -+ *s = (SysctlSetting) { -+ .key = strdup(key), -+ .path = path, -+ .value = value? strdup(value): NULL, -+ .ignore_failure = ignore_failure, -+ .glob_exclude = glob_exclude, -+ .next = NULL, -+ }; -+ -+ return s; -+} -+ -+static void settinglist_add(SettingList *l, SysctlSetting *s) { -+ SysctlSetting *old_tail; -+ -+ if (!l) -+ return; -+ -+ if (l->head == NULL) -+ l->head = s; -+ -+ if (l->tail != NULL) { -+ old_tail = l->tail; -+ old_tail->next = s; -+ } -+ l->tail = s; -+} -+ -+static SysctlSetting *settinglist_findpath(const SettingList *l, const char *path) { -+ SysctlSetting *node; -+ -+ for (node=l->head; node != NULL; node = node->next) { -+ if (strcmp(node->path, path) == 0) -+ return node; -+ } -+ return NULL; -+} -+ -+/* Function prototypes. */ -+static int pattern_match(const char *string, const char *pat); -+static int DisplayAll(const char *restrict const path); -+ - /* - * Display the usage format - */ -@@ -115,6 +214,7 @@ static void __attribute__ ((__noreturn__)) - fputs(_(" -A alias of -a\n"), out); - fputs(_(" -X alias of -a\n"), out); - fputs(_(" --deprecated include deprecated parameters to listing\n"), out); -+ fputs(_(" --dry-run Print the key and values but do not write\n"), out); - fputs(_(" -b, --binary print value without new line\n"), out); - fputs(_(" -e, --ignore ignore unknown variables errors\n"), out); - fputs(_(" -N, --names print variable names without values\n"), out); -@@ -137,6 +237,39 @@ static void __attribute__ ((__noreturn__)) - exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS); - } - -+/* -+ * Strip left/leading side of a string -+ */ -+static char *lstrip(char *line) -+{ -+ char *start; -+ -+ if (!line || !*line) -+ return line; -+ -+ start = line; -+ while(isspace(*start)) start++; -+ -+ return start; -+} -+ -+/* -+ * Strip right/trailing side of a string -+ * by placing a \0 -+ */ -+static void rstrip(char *line) -+{ -+ char *end; -+ -+ if (!line || !*line) -+ return; -+ -+ end = line + strlen(line) - 1; -+ while(end > line && isspace(*end)) end--; -+ -+ end[1] = '\0'; -+} -+ - /* - * Strip the leading and trailing spaces from a string - */ -@@ -166,7 +299,7 @@ static char *StripLeadingAndTrailingSpaces(char *oneline) - */ - static int ReadSetting(const char *restrict const name) - { -- int rc = 0; -+ int rc = EXIT_SUCCESS; - char *restrict tmpname; - char *restrict outname; - ssize_t rlen; -@@ -198,7 +331,7 @@ static int ReadSetting(const char *restrict const name) - if (stat(tmpname, &ts) < 0) { - if (!IgnoreError) { - xwarn(_("cannot stat %s"), tmpname); -- rc = -1; -+ rc = EXIT_FAILURE; - } - goto out; - } -@@ -215,7 +348,7 @@ static int ReadSetting(const char *restrict const name) - } - - if (pattern && !pattern_match(outname, pattern)) { -- rc = 0; -+ rc = EXIT_SUCCESS; - goto out; - } - -@@ -231,19 +364,19 @@ static int ReadSetting(const char *restrict const name) - case ENOENT: - if (!IgnoreError) { - xwarnx(_("\"%s\" is an unknown key"), outname); -- rc = -1; -+ rc = EXIT_FAILURE; - } - break; - case EACCES: - xwarnx(_("permission denied on key '%s'"), outname); -- rc = -1; -+ rc = EXIT_FAILURE; - break; - case EIO: /* Ignore stable_secret below /proc/sys/net/ipv6/conf */ -- rc = -1; -+ rc = EXIT_FAILURE; - break; - default: - xwarn(_("reading key \"%s\""), outname); -- rc = -1; -+ rc = EXIT_FAILURE; - break; - } - } else { -@@ -279,7 +412,7 @@ static int ReadSetting(const char *restrict const name) - case EACCES: - xwarnx(_("permission denied on key '%s'"), - outname); -- rc = -1; -+ rc = EXIT_FAILURE; - break; - case EISDIR: { - size_t len; -@@ -291,11 +424,11 @@ static int ReadSetting(const char *restrict const name) - goto out; - } - case EIO: /* Ignore stable_secret below /proc/sys/net/ipv6/conf */ -- rc = -1; -+ rc = EXIT_FAILURE; - break; - default: - xwarnx(_("reading key \"%s\""), outname); -- rc = -1; -+ rc = EXIT_FAILURE; - case 0: - break; - } -@@ -323,7 +456,7 @@ static int is_deprecated(char *filename) - */ - static int DisplayAll(const char *restrict const path) - { -- int rc = 0; -+ int rc = EXIT_SUCCESS; - int rc2; - DIR *restrict dp; - struct dirent *restrict de; -@@ -333,7 +466,7 @@ static int DisplayAll(const char *restrict const path) - - if (!dp) { - xwarnx(_("unable to open directory \"%s\""), path); -- rc = -1; -+ rc = EXIT_FAILURE; - } else { - readdir(dp); /* skip . */ - readdir(dp); /* skip .. */ -@@ -369,130 +502,183 @@ static int DisplayAll(const char *restrict const path) - /* - * Write a sysctl setting - */ --static int WriteSetting(const char *setting) --{ -- int rc = 0; -- const char *name = setting; -- const char *value; -- const char *equals; -- char *tmpname; -- char *outname; -- char *last_dot; -- bool ignore_failure; -- -- FILE *fp; -+static int WriteSetting( -+ const char *key, -+ const char *path, -+ const char *value, -+ const bool ignore_failure) { -+ -+ int rc = EXIT_SUCCESS; -+ FILE *fp; - struct stat ts; - -- if (!name) -- /* probably don't want to display this err */ -- return 0; -- -- equals = strchr(setting, '='); -- -- if (!equals) { -- xwarnx(_("\"%s\" must be of the form name=value"), -- setting); -- return -1; -- } -- -- /* point to the value in name=value */ -- value = equals + 1; -- -- if (!*name || name == equals) { -- xwarnx(_("malformed setting \"%s\""), setting); -- return -2; -- } -- -- ignore_failure = name[0] == '-'; -- if (ignore_failure) -- name++; -- -- /* used to open the file */ -- tmpname = xmalloc(equals - name + 1 + strlen(PROC_PATH)); -- strcpy(tmpname, PROC_PATH); -- strncat(tmpname, name, (int) (equals - name)); -- tmpname[equals - name + strlen(PROC_PATH)] = 0; -- /* change . to / */ -- slashdot(tmpname + strlen(PROC_PATH), '.', '/'); -+ if (!key || !path) -+ return rc; - -- /* used to display the output */ -- outname = xmalloc(equals - name + 1); -- strncpy(outname, name, (int) (equals - name)); -- outname[equals - name] = 0; -- /* change / to . */ -- slashdot(outname, '/', '.'); -- last_dot = strrchr(outname, '.'); -- if (last_dot != NULL && is_deprecated(last_dot + 1)) { -- xwarnx(_("%s is deprecated, value not set"), outname); -- goto out; -- } -- -- if (stat(tmpname, &ts) < 0) { -+ if (stat(path, &ts) < 0) { - if (!IgnoreError) { -- xwarn(_("cannot stat %s"), tmpname); -- rc = -1; -+ xwarn(_("cannot stat %s"), path); -+ rc = EXIT_FAILURE; - } -- goto out; -+ return rc; - } - - if ((ts.st_mode & S_IWUSR) == 0) { -- xwarn(_("setting key \"%s\""), outname); -- goto out; -+ xwarn(_("setting key \"%s\""), key); -+ return rc; - } - - if (S_ISDIR(ts.st_mode)) { -- xwarn(_("setting key \"%s\""), outname); -- goto out; -+ xwarn(_("setting key \"%s\""), key); -+ return rc; - } - -- fp = fprocopen(tmpname, "w"); -- -- if (!fp) { -- switch (errno) { -- case ENOENT: -- if (!IgnoreError) { -- xwarnx(_("\"%s\" is an unknown key%s"), outname, (ignore_failure?_(", ignoring"):"")); -+ if (!DryRun) { -+ if ((fp = fprocopen(path, "w")) == NULL) { -+ switch (errno) { -+ case ENOENT: -+ if (!IgnoreError) { -+ xwarnx(_("\"%s\" is an unknown key%s"), -+ key, (ignore_failure?_(", ignoring"):"")); - if (!ignore_failure) -- rc = -1; -+ rc = EXIT_FAILURE; - } - break; -- case EPERM: -- case EROFS: -- case EACCES: -- xwarnx(_("permission denied on key \"%s\"%s"), outname, (ignore_failure?_(", ignoring"):"")); -- break; -- default: -- xwarn(_("setting key \"%s\"%s"), outname, (ignore_failure?_(", ignoring"):"")); -- break; -- } -- if (!ignore_failure && errno != ENOENT) -- rc = -1; -- } else { -- rc = fprintf(fp, "%s\n", value); -- if (0 < rc) -- rc = 0; -- if (close_stream(fp) != 0) -- xwarn(_("setting key \"%s\""), outname); -- else if (rc == 0 && !Quiet) { -- if (NameOnly) { -- fprintf(stdout, "%s\n", outname); -- } else { -- if (PrintName) { -- fprintf(stdout, "%s = %s\n", -- outname, value); -- } else { -- if (PrintNewline) -- fprintf(stdout, "%s\n", value); -- else -- fprintf(stdout, "%s", value); -- } -- } -- } -- } -- out: -- free(tmpname); -- free(outname); -- return rc; -+ case EPERM: -+ case EROFS: -+ case EACCES: -+ xwarnx(_("permission denied on key \"%s\"%s"), -+ key, (ignore_failure?_(", ignoring"):"")); -+ break; -+ default: -+ xwarn(_("setting key \"%s\"%s"), -+ key, (ignore_failure?_(", ignoring"):"")); -+ break; -+ } -+ if (!ignore_failure && errno != ENOENT) -+ rc = EXIT_FAILURE; -+ } else { -+ if (0 < fprintf(fp, "%s\n", value)) -+ rc = EXIT_SUCCESS; -+ if (close_stream(fp) != 0) { -+ xwarn(_("setting key \"%s\""), path); -+ return rc; -+ } -+ } -+ } -+ if ((rc == EXIT_SUCCESS && !Quiet) || DryRun) { -+ if (NameOnly) { -+ printf("%s\n", value); -+ } else { -+ if (PrintName) { -+ printf("%s = %s\n", path, value); -+ } else { -+ if (PrintNewline) -+ printf("%s\n", value); -+ else -+ printf("%s", value); -+ } -+ } -+ } -+ return rc; -+} -+ -+/* -+ * parse each configuration line, there are multiple ways of specifying -+ * a key/value here: -+ * -+ * key = value simple setting -+ * -key = value ignore errors -+ * key.pattern.*.with.glob = value set keys that match glob -+ * -key.pattern.exclude.with.glob dont set this value -+ * key.pattern.override.with.glob = value set this glob match to value -+ * -+ */ -+ -+static SysctlSetting *parse_setting_line( -+ const char *path, -+ const int linenum, -+ char *line) -+{ -+ SysctlSetting *s; -+ char *key; -+ char *value; -+ bool glob_exclude = FALSE; -+ bool ignore_failure = FALSE; -+ -+ key = lstrip(line); -+ if (strlen(key) < 2) -+ return NULL; -+ -+ /* skip over comments */ -+ if (key[0] == '#' || key[0] == ';') -+ return NULL; -+ -+ if (pattern && !pattern_match(key, pattern)) -+ return NULL; -+ -+ value = strchr(key, '='); -+ if (value == NULL) { -+ if (key[0] == '-') { -+ glob_exclude = TRUE; -+ key++; -+ value = NULL; -+ rstrip(key); -+ } else { -+ xwarnx(_("%s(%d): invalid syntax, continuing..."), -+ path, linenum); -+ return NULL; -+ } -+ } else { -+ value[0]='\0'; -+ if (key[0] == '-') { -+ ignore_failure = TRUE; -+ key++; -+ } -+ value++; // skip over = -+ value=lstrip(value); -+ rstrip(value); -+ rstrip(key); -+ } -+ return setting_new(key, value, ignore_failure, glob_exclude); -+} -+ -+/* Go through the setting list, expand and sort out -+ * setting globs and actually write the settings out -+ */ -+static int write_setting_list(const SettingList *sl) -+{ -+ SysctlSetting *node; -+ int rc = EXIT_SUCCESS; -+ -+ for (node=sl->head; node != NULL; node=node->next) { -+ if (node->glob_exclude) -+ continue; -+ -+ if (string_is_glob(node->path)) { -+ char *gl_path; -+ glob_t globbuf; -+ int i; -+ -+ if (glob(node->path, 0, NULL, &globbuf) != 0) -+ continue; -+ -+ for(i=0; i < globbuf.gl_pathc; i++) { -+ if (settinglist_findpath(sl, globbuf.gl_pathv[i])) -+ continue; // override or exclude -+ -+ rc |= WriteSetting(node->key, globbuf.gl_pathv[i], node->value, -+ node->ignore_failure); -+ } -+ } else { -+ rc |= WriteSetting(node->key, node->path, node->value, -+ node->ignore_failure); -+ } -+ -+ -+ } -+ -+ return rc; - } - - static int pattern_match(const char *string, const char *pat) -@@ -513,12 +699,12 @@ static int pattern_match(const char *string, const char *pat) - * Preload the sysctl's from the conf file. We parse the file and then - * reform it (strip out whitespace). - */ --static int Preload(const char *restrict const filename) -+static int Preload(SettingList *setlist, const char *restrict const filename) - { - FILE *fp; - char *t; - int n = 0; -- int rc = 0; -+ int rc = EXIT_SUCCESS; - ssize_t rlen; - char *name, *value; - glob_t globbuf; -@@ -547,62 +733,26 @@ static int Preload(const char *restrict const filename) - ? stdin : fopen(globbuf.gl_pathv[j], "r"); - if (!fp) { - xwarn(_("cannot open \"%s\""), globbuf.gl_pathv[j]); -- rc = -1; -- goto out; -+ return EXIT_FAILURE; - } - - while ((rlen = getline(&iobuf, &iolen, fp)) > 0) { - size_t offset; -+ SysctlSetting *setting; - - n++; - - if (rlen < 2) - continue; - -- t = StripLeadingAndTrailingSpaces(iobuf); -- if (strlen(t) < 2) -- continue; -- -- if (*t == '#' || *t == ';') -- continue; -- -- name = strtok(t, "="); -- if (!name || !*name) { -- xwarnx(_("%s(%d): invalid syntax, continuing..."), -- globbuf.gl_pathv[j], n); -- continue; -- } -- -- StripLeadingAndTrailingSpaces(name); -- -- if (pattern && !pattern_match(name, pattern)) -- continue; -- -- offset = strlen(name); -- memmove(&iobuf[0], name, offset); -- iobuf[offset++] = '='; -- -- value = strtok(NULL, "\n\r"); -- if (!value || !*value) { -- xwarnx(_("%s(%d): invalid syntax, continuing..."), -- globbuf.gl_pathv[j], n); -- continue; -- } -- -- while ((*value == ' ' || *value == '\t') && *value != 0) -- value++; -- -- /* should NameOnly affect this? */ -- memmove(&iobuf[offset], value, strlen(value)); -- offset += strlen(value); -- iobuf[offset] = '\0'; -- -- rc |= WriteSetting(iobuf); -+ if ( (setting = parse_setting_line(globbuf.gl_pathv[j], n, iobuf)) -+ == NULL) -+ continue; -+ settinglist_add(setlist, setting); - } - - fclose(fp); - } --out: - return rc; - } - -@@ -618,7 +768,7 @@ static int sortpairs(const void *A, const void *B) - return strcmp(a->name, b->name); - } - --static int PreloadSystem(void) -+static int PreloadSystem(SettingList *setlist) - { - unsigned di, i; - const char *dirs[] = { -@@ -630,7 +780,7 @@ static int PreloadSystem(void) - }; - struct pair **cfgs = NULL; - unsigned ncfgs = 0; -- int rc = 0; -+ int rc = EXIT_SUCCESS; - struct stat ts; - enum { nprealloc = 16 }; - -@@ -688,14 +838,14 @@ static int PreloadSystem(void) - for (i = 0; i < ncfgs; ++i) { - if (!Quiet) - printf(_("* Applying %s ...\n"), cfgs[i]->value); -- rc |= Preload(cfgs[i]->value); -+ rc |= Preload(setlist, cfgs[i]->value); - } - - - if (stat(DEFAULT_PRELOAD, &ts) == 0 && S_ISREG(ts.st_mode)) { - if (!Quiet) - printf(_("* Applying %s ...\n"), DEFAULT_PRELOAD); -- rc |= Preload(DEFAULT_PRELOAD); -+ rc |= Preload(setlist, DEFAULT_PRELOAD); - } - - /* cleaning */ -@@ -717,15 +867,19 @@ int main(int argc, char *argv[]) - bool preloadfileOpt = false; - int ReturnCode = 0; - int c; -+ int rc; - const char *preloadfile = NULL; -+ SettingList *setlist; - - enum { - DEPRECATED_OPTION = CHAR_MAX + 1, -- SYSTEM_OPTION -+ SYSTEM_OPTION, -+ DRYRUN_OPTION - }; - static const struct option longopts[] = { - {"all", no_argument, NULL, 'a'}, - {"deprecated", no_argument, NULL, DEPRECATED_OPTION}, -+ {"dry-run", no_argument, NULL, DRYRUN_OPTION}, - {"binary", no_argument, NULL, 'b'}, - {"ignore", no_argument, NULL, 'e'}, - {"names", no_argument, NULL, 'N'}, -@@ -753,6 +907,10 @@ int main(int argc, char *argv[]) - IgnoreError = false; - Quiet = false; - IgnoreDeprecated = true; -+ DryRun = false; -+ setlist = xmalloc(sizeof(SettingList)); -+ setlist->head = NULL; -+ setlist->tail = NULL; - - if (argc < 2) - Usage(stderr); -@@ -805,7 +963,12 @@ int main(int argc, char *argv[]) - break; - case SYSTEM_OPTION: - IgnoreError = true; -- return PreloadSystem(); -+ rc |= PreloadSystem(setlist); -+ rc |= write_setting_list(setlist); -+ return rc; -+ case DRYRUN_OPTION: -+ DryRun = true; -+ break; - case 'r': - pattern = xstrdup(optarg); - break; -@@ -833,15 +996,16 @@ int main(int argc, char *argv[]) - int ret = EXIT_SUCCESS, i; - if (!preloadfile) { - if (!argc) { -- ret |= Preload(DEFAULT_PRELOAD); -+ ret |= Preload(setlist, DEFAULT_PRELOAD); - } - } else { - /* This happens when -pfile option is - * used without space. */ -- ret |= Preload(preloadfile); -+ ret |= Preload(setlist, preloadfile); - } - for (i = 0; i < argc; i++) -- ret |= Preload(argv[i]); -+ ret |= Preload(setlist, argv[i]); -+ ret |= write_setting_list(setlist); - return ret; - } - -@@ -855,9 +1019,14 @@ int main(int argc, char *argv[]) - program_invocation_short_name); - - for ( ; *argv; argv++) { -- if (WriteMode || strchr(*argv, '=')) -- ReturnCode += WriteSetting(*argv); -- else -+ if (WriteMode || strchr(*argv, '=')) { -+ SysctlSetting *s; -+ if ( (s = parse_setting_line("command line", 0, *argv)) != NULL) -+ ReturnCode |= WriteSetting(s->key, s->path, s->value, -+ s->ignore_failure); -+ else -+ ReturnCode |= EXIT_FAILURE; -+ } else - ReturnCode += ReadSetting(*argv); - } - return ReturnCode; -diff --git a/testsuite/config/unix.exp b/testsuite/config/unix.exp -index 4156c3b..ecdc0bf 100644 ---- a/testsuite/config/unix.exp -+++ b/testsuite/config/unix.exp -@@ -136,6 +136,15 @@ proc expect_table_dsc { test match_header match_item } { - #} - } - -+proc expect_spawn_retval { test retval } { -+ foreach {pid spawnid os_error_flag value} [wait] break -+ -+ if {$value == $retval} { -+ return -+ } -+ fail "$test (exit value)" -+} -+ - proc make_pipeproc { } { - global pipeproc_pid pipeproc_spawnid topdir - -diff --git a/testsuite/sysctl.test/sysctl_write.exp b/testsuite/sysctl.test/sysctl_write.exp -new file mode 100644 -index 0000000..5a74dec ---- /dev/null -+++ b/testsuite/sysctl.test/sysctl_write.exp -@@ -0,0 +1,29 @@ -+ -+set sysctl ${topdir}sysctl -+ -+set test "sysctl write from command line" -+spawn $sysctl --dry-run kernel.hostname=procps-test -+expect_pass "$test" "/proc/sys/kernel/hostname = procps-test" -+ -+set test "sysctl write from configuration file" -+spawn $sysctl --dry-run -f ${topdir}testsuite/sysctl_glob_test.conf -+expect_pass "$test" "/proc/sys/fs/protected_fifos = 2\\s+/proc/sys/fs/protected_symlinks = 2\\s+/proc/sys/fs/protected_hardlinks = 1" -+ -+set hostname_file "/proc/sys/kernel/hostname" -+if {[file exists ${hostname_file}]} { -+ if {[file writable ${hostname_file}]} { -+ unsupported "sysctl write: hostname file is writable" -+ } else { -+ set test "sysctl write unwritable file" -+ spawn $sysctl -q kernel.hostname=procpstest -+ expect_pass "$test" "sysctl: permission denied on key \"kernel.hostname\"\\s*$" -+ expect_spawn_retval "$test" 1 -+ -+ set test "sysctl write unwritable file ignored" -+ spawn $sysctl -q -- -kernel.hostname=procpstest -+ expect_pass "$test" "sysctl: permission denied on key \"kernel.hostname\", ignoring\\s*$" -+ expect_spawn_retval "$test" 0 -+ } -+} else { -+ unsupported "sysctl write: hostname file doe not exist" -+} -diff --git a/testsuite/sysctl_glob_test.conf b/testsuite/sysctl_glob_test.conf -new file mode 100644 -index 0000000..45ae904 ---- /dev/null -+++ b/testsuite/sysctl_glob_test.conf -@@ -0,0 +1,6 @@ -+# -+# Test configuration for for glob in sysctl -+# -+fs.protected_* = 2 -+fs.protected_hardlinks = 1 -+-fs.protected_regular ================================================================ ---- gitweb: http://git.pld-linux.org/gitweb.cgi/packages/procps.git/commitdiff/19ad2b015ae751d6c30475deaf6c17cb9aa8e0f9 _______________________________________________ pld-cvs-commit mailing list pld-cvs-commit@lists.pld-linux.org http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit