GNU bug report logs - #57387
[PATCH] gnu: Add restartd.

Previous Next

Package: guix-patches;

Reported by: Nicolas Graves <ngraves <at> ngraves.fr>

Date: Wed, 24 Aug 2022 16:01:02 UTC

Severity: normal

Tags: patch

Done: Ludovic Courtès <ludo <at> gnu.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 57387 in the body.
You can then email your comments to 57387 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Wed, 24 Aug 2022 16:01:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Nicolas Graves <ngraves <at> ngraves.fr>:
New bug report received and forwarded. Copy sent to guix-patches <at> gnu.org. (Wed, 24 Aug 2022 16:01:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Nicolas Graves <ngraves <at> ngraves.fr>
To: guix-patches <at> gnu.org
Cc: ngraves <at> ngraves.fr
Subject: [PATCH] gnu: Add restartd.
Date: Wed, 24 Aug 2022 17:59:38 +0200
* gnu/packages/admin.scm (restartd): New variable.
---
 gnu/packages/admin.scm | 67 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/gnu/packages/admin.scm b/gnu/packages/admin.scm
index a4c5189222..17a400bdf6 100644
--- a/gnu/packages/admin.scm
+++ b/gnu/packages/admin.scm
@@ -51,6 +51,7 @@
 ;;; Copyright © 2021 Artyom V. Poptsov <poptsov.artyom <at> gmail.com>
 ;;; Copyright © 2022 Wamm K. D. <jaft.r <at> outlook.com>
 ;;; Copyright © 2022 Roman Riabenko <roman <at> riabenko.com>
+;;; Copyright © 2022 Nicolas Graves <ngraves <at> ngraves.fr>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -5455,6 +5456,72 @@ (define-public fail2ban
 mechanisms if you really want to protect services.")
     (license license:gpl2+)))
 
+(define-public restartd
+  (let* ((commit "7044125ac55056f2663536f7137170edf92ebd75")
+         (revision "1.1"))
+    (package
+      (name "restartd")
+      (version (git-version "0.2.3" revision commit))
+      (source
+       (origin
+         (method git-fetch)
+         (uri (git-reference
+               (url "https://github.com/ajraymond/restartd")
+               (commit commit)))
+         (file-name (git-file-name name version))
+         (sha256
+          (base32
+           "1m1np00b4zvvwx63gzysbi38i5vj1jsjvh2s0p9czl6dzyz582z0"))
+         (patches
+          (list
+           ;; Fix segfault when run as normal user
+           (origin
+             (method url-fetch)
+             (uri
+              (string-append "https://patch-diff.githubusercontent.com/raw"
+                             "/ajraymond/restartd/pull/6.patch"))
+             (sha256
+              (base32
+               "1cqhy6fngvql9ynacrf4f2nc7mzypvdbab5nil96qlclfvb3far8")))
+           ;; Fix compilation with gcc-10+
+           (origin
+             (method url-fetch)
+             (uri
+              (string-append "https://patch-diff.githubusercontent.com/raw"
+                             "/ajraymond/restartd/pull/7.patch"))
+             (sha256
+              (base32
+               "0fk33af8sgrgxibmkyjlv3j8jikgbp4mkj84yamvhv38ic6x2rw6")))))))
+      (build-system gnu-build-system)
+      (arguments
+       (list
+        #:tests? #f ; no tests
+        #:phases
+        #~(modify-phases %standard-phases
+            (add-after 'unpack 'ensure-compilation
+              (lambda _
+                (substitute* "Makefile"
+                  (("CC \\?= gcc") "CC = gcc"))))
+            (delete  'configure)
+            (replace 'install
+              (lambda _
+                (install-file "restartd.conf" (string-append #$output "/etc"))
+                (install-file "restartd" (string-append #$output "/sbin"))
+                (install-file "restartd.8"
+                              (string-append #$output "/share/man/man8"))
+                (mkdir-p (string-append #$output "/share/man/fr/man8"))
+                (copy-file
+                 "restartd.fr.8"
+                 (string-append #$output "/share/man/fr/man8/restartd.8")))))))
+      (home-page "https://launchpad.net/debian/+source/restartd")
+      (synopsis "Daemon for restarting processes")
+      (description "This package provides a daemon for checking running and not
+running processes.  It reads the /proc directory every n seconds and does a
+POSIX regexp on the process names.  You can execute a script or a program if
+the process is or is not running.  The daemon can only be called by the root
+user, but can use @code{sudo -u user} in the process called if needed.")
+      (license license:gpl2))))
+
 (define-public rex
   (package
     (name "rex")
-- 
2.37.2


<#secure method=pgpmime mode=sign>

-- 
Best regards,
Nicolas Graves




Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Wed, 24 Aug 2022 18:10:01 GMT) Full text and rfc822 format available.

Message #8 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Maxime Devos <maximedevos <at> telenet.be>
To: Nicolas Graves <ngraves <at> ngraves.fr>, 57387 <at> debbugs.gnu.org
Subject: Re: [bug#57387] [PATCH] gnu: Add restartd.
Date: Wed, 24 Aug 2022 20:09:07 +0200
[Message part 1 (text/plain, inline)]
On 24-08-2022 17:59, Nicolas Graves via Guix-patches via wrote:

> +         (revision "1.1"))

"1.1" -> "1" ('revision' must be a string with a number, as expected by 
https://issues.guix.gnu.org/53144).

Also, why is an unreleased version used? I assume because of lack of 
activity upstream, but a comment would have been useful.

> +                (substitute* "Makefile"
> +                  (("CC \\?= gcc") "CC = gcc"))))
For cross-compilation, use (cc-for-target)

According to Debian, the home-page is 
<https://github.com/ajraymond/restartd>.

Looking at some source files, it appears to be gpl2-or-later, not gpl2-only.

In restartd.c, it is missing error checking for 'fopen', 'malloc' and 
'strdup'.

in config.c, it is missing error checking for 'malloc'  (and for printf 
on stderr, but there isn't much that can be odone in that case). Also 
printf on stdout, though less important.

On the patches: IIUC, in case additional commits are added to the PR, 
the patch is updated appropriately, so these patches are volatile. Even 
if that doesn't happen, the patch generation algorithm could change 
later. As such, copying these into gnu/packages/patches + search-pathes 
is recommended

> You can execute a script or a program if the process is or is not running.
Maybe: 'The daemon runs an user-provided script based once a program 
starts running or stops running.' That seems a little clearer English to 
me ('it is running or not running' is always true, and scripts / 
programs can be run, but it's not a claim about restartd).

Greetings,
Maxime.

[OpenPGP_0x49E3EE22191725EE.asc (application/pgp-keys, attachment)]
[OpenPGP_signature (application/pgp-signature, attachment)]

Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Wed, 24 Aug 2022 18:15:03 GMT) Full text and rfc822 format available.

Message #11 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: "(" <paren <at> disroot.org>
To: "Maxime Devos" <maximedevos <at> telenet.be>, "Nicolas Graves"
 <ngraves <at> ngraves.fr>, <57387 <at> debbugs.gnu.org>
Subject: Re: [bug#57387] [PATCH] gnu: Add restartd.
Date: Wed, 24 Aug 2022 19:14:51 +0100
On Wed Aug 24, 2022 at 7:09 PM BST, Maxime Devos wrote:
> > +                (substitute* "Makefile"
> > +                  (("CC \\?= gcc") "CC = gcc"))))
> For cross-compilation, use (cc-for-target)

Also, you can replace this substitution with make-flags:

  #:make-flags
  #~(list (string-append "CC=" #$(cc-for-target)))

    -- (




Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Thu, 25 Aug 2022 09:15:03 GMT) Full text and rfc822 format available.

Message #14 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Nicolas Graves <ngraves <at> ngraves.fr>
To: 57387 <at> debbugs.gnu.org
Subject: [PATCH] gnu: Add restartd.
Date: Thu, 25 Aug 2022 11:14:53 +0200
* gnu/packages/admin.scm (restartd): New variable.
---
 gnu/packages/admin.scm                        | 53 +++++++++++++++++++
 .../patches/restartd-fix-compilation.patch    | 53 +++++++++++++++++++
 .../restartd-fix-segfault-normal-user.patch   | 45 ++++++++++++++++
 3 files changed, 151 insertions(+)
 create mode 100644 gnu/packages/patches/restartd-fix-compilation.patch
 create mode 100644 gnu/packages/patches/restartd-fix-segfault-normal-user.patch

diff --git a/gnu/packages/admin.scm b/gnu/packages/admin.scm
index a4c5189222..17ebd5fd7b 100644
--- a/gnu/packages/admin.scm
+++ b/gnu/packages/admin.scm
@@ -51,6 +51,7 @@
 ;;; Copyright © 2021 Artyom V. Poptsov <poptsov.artyom <at> gmail.com>
 ;;; Copyright © 2022 Wamm K. D. <jaft.r <at> outlook.com>
 ;;; Copyright © 2022 Roman Riabenko <roman <at> riabenko.com>
+;;; Copyright © 2022 Nicolas Graves <ngraves <at> ngraves.fr>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -5455,6 +5456,58 @@ (define-public fail2ban
 mechanisms if you really want to protect services.")
     (license license:gpl2+)))

+(define-public restartd
+  (let* ((commit "7044125ac55056f2663536f7137170edf92ebd75")
+         ;; Version is 0.2.4 in the version file in the repo
+         ;; but not in github tags.
+         ;; It is released as 0.2.3-1.1 for other distributions.
+         ;; Probably because of the lack of activity upstream.
+         (revision "1"))
+    (package
+      (name "restartd")
+      (version (git-version "0.2.3" revision commit))
+      (source
+       (origin
+         (method git-fetch)
+         (uri (git-reference
+               (url "https://github.com/ajraymond/restartd")
+               (commit commit)))
+         (file-name (git-file-name name version))
+         (sha256
+          (base32
+           "1m1np00b4zvvwx63gzysbi38i5vj1jsjvh2s0p9czl6dzyz582z0"))
+         (patches
+          (search-patches "restartd-fix-segfault-normal-user.patch"
+                          "restartd-fix-compilation.patch"))))
+      (build-system gnu-build-system)
+      (arguments
+       (list
+        #:tests? #f ; no tests
+        #:make-flags
+        #~(list (string-append "CC=" #$(cc-for-target)))
+        #:phases
+        #~(modify-phases %standard-phases
+            (delete  'configure)
+            (replace 'install
+              (lambda _
+                (install-file "restartd.conf" (string-append #$output "/etc"))
+                (install-file "restartd" (string-append #$output "/sbin"))
+                (install-file "restartd.8"
+                              (string-append #$output "/share/man/man8"))
+                (mkdir-p (string-append #$output "/share/man/fr/man8"))
+                (copy-file
+                 "restartd.fr.8"
+                 (string-append #$output "/share/man/fr/man8/restartd.8")))))))
+      (home-page "https://launchpad.net/debian/+source/restartd")
+      (synopsis "Daemon for restarting processes")
+      (description "This package provides a daemon for checking running and not
+running processes.  It reads the /proc directory every n seconds and does a
+POSIX regexp on the process names.  The daemon runs an user-provided script
+when it detects a program in the running processes, or an alternate script if
+it doesn't detect the program.  The daemon can only be called by the root
+user, but can use @code{sudo -u user} in the process called if needed.")
+      (license license:gpl2+))))
+
 (define-public rex
   (package
     (name "rex")
diff --git a/gnu/packages/patches/restartd-fix-compilation.patch b/gnu/packages/patches/restartd-fix-compilation.patch
new file mode 100644
index 0000000000..a380205675
--- /dev/null
+++ b/gnu/packages/patches/restartd-fix-compilation.patch
@@ -0,0 +1,53 @@
+From 84edc2042bb0a82e65bd4d165b706519886b4075 Mon Sep 17 00:00:00 2001
+From: Sudip Mukherjee <sudipm.mukherjee <at> gmail.com>
+Date: Mon, 10 Aug 2020 19:39:30 +0100
+Subject: [PATCH] Fix build with gcc-10
+
+Bug: https://bugs.debian.org/957761
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee <at> gmail.com>
+---
+ config.h   | 12 ++++++------
+ restartd.c |  7 +++++++
+ 2 files changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/config.h b/config.h
+index fabaa2b..a79b28e 100644
+--- a/config.h
++++ b/config.h
+@@ -25,12 +25,12 @@
+
+ #define DEFAULT_CONFIG "/etc/restartd.conf"
+
+-int debug;
+-int config_process_number;
+-int check_interval;
+-int foreground;
+-struct config_process_type *config_process;
+-char *config_file;
++extern int debug;
++extern int config_process_number;
++extern int check_interval;
++extern int foreground;
++extern struct config_process_type *config_process;
++extern char *config_file;
+
+ typedef struct config_process_type {
+   char name[64];
+diff --git a/restartd.c b/restartd.c
+index 2aa720c..617b298 100644
+--- a/restartd.c
++++ b/restartd.c
+@@ -35,6 +35,13 @@
+
+ #include "config.h"
+
++int debug;
++int config_process_number;
++int check_interval;
++int foreground;
++struct config_process_type *config_process;
++char *config_file;
++
+ /* SIGTERM & SIGHUP handler */
+ void got_signal(int sig)
+ {
diff --git a/gnu/packages/patches/restartd-fix-segfault-normal-user.patch b/gnu/packages/patches/restartd-fix-segfault-normal-user.patch
new file mode 100644
index 0000000000..5c28c3b2ad
--- /dev/null
+++ b/gnu/packages/patches/restartd-fix-segfault-normal-user.patch
@@ -0,0 +1,45 @@
+From 67d7308ba52d2c605d0175c14c34ff09c9d322fb Mon Sep 17 00:00:00 2001
+From: Yin Kangkai <yinkangkai <at> xiaomi.com>
+Date: Sat, 1 Oct 2016 13:52:58 +0800
+Subject: [PATCH] Fix segfault when run as normal user
+
+Also exit immediately when "restartd -h"
+---
+ restartd.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/restartd.c b/restartd.c
+index 2aa720c..1d46fe1 100644
+--- a/restartd.c
++++ b/restartd.c
+@@ -118,6 +118,7 @@ int main(int argc, char *argv[])
+                     "  -i <interval_sec>: the check interval in second\n"
+                     "  -l               : list configuration options\n"
+                     "  -h               : help\n\n", VERSION);
++	    exit(0);
+         }
+     }
+
+@@ -187,6 +188,10 @@ int main(int argc, char *argv[])
+         }
+
+         out_proc = fopen("/var/run/restartd.pid", "wt");
++	if (!out_proc) {
++		syslog(LOG_ERR, "Failed to open /var/run/restartd.pid");
++		return -1;
++	}
+         fprintf(out_proc, "%d", getpid());
+         fclose(out_proc);
+
+@@ -244,9 +249,9 @@ int main(int argc, char *argv[])
+                if (strlen(config_process[i].processes) > 0) {
+                    if (strlen(config_process[i].running) > 0) {
+                        strcpy(config_process[i].status, "running");
+-                       syslog(LOG_INFO, "%s is running, executing '%s'",
++                       /* syslog(LOG_INFO, "%s is running, executing '%s'",
+                               config_process[i].name,
+-                              config_process[i].running);
++                              config_process[i].running); */
+                        system(config_process[i].running);
+                     } else {
+                         strcpy(config_process[i].status, "running");
--
2.37.2




Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Thu, 25 Aug 2022 09:17:02 GMT) Full text and rfc822 format available.

Message #17 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Nicolas Graves <ngraves <at> ngraves.fr>
To: 57387 <at> debbugs.gnu.org
Subject: [PATCH] gnu: Add restartd.
Date: Thu, 25 Aug 2022 11:16:48 +0200
Made suggested changes, rephrased the description.
But I never learned C and am not at ease for adding checks in C source
code, sorry.

-- 
Best regards,
Nicolas Graves




Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Thu, 25 Aug 2022 10:35:02 GMT) Full text and rfc822 format available.

Message #20 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Maxime Devos <maximedevos <at> telenet.be>
To: Nicolas Graves <ngraves <at> ngraves.fr>, 57387 <at> debbugs.gnu.org
Subject: Re: [bug#57387] [PATCH] gnu: Add restartd.
Date: Thu, 25 Aug 2022 12:34:01 +0200
[Message part 1 (text/plain, inline)]
On 25-08-2022 11:16, Nicolas Graves via Guix-patches via wrote:
> Made suggested changes, rephrased the description.
> But I never learned C and am not at ease for adding checks in C source
> code, sorry.
>
I'll give it a try myself ...
[OpenPGP_0x49E3EE22191725EE.asc (application/pgp-keys, attachment)]
[OpenPGP_signature (application/pgp-signature, attachment)]

Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Thu, 25 Aug 2022 11:34:02 GMT) Full text and rfc822 format available.

Message #23 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Maxime Devos <maximedevos <at> telenet.be>
To: Nicolas Graves <ngraves <at> ngraves.fr>, 57387 <at> debbugs.gnu.org
Subject: Re: [bug#57387] [PATCH] gnu: Add restartd.
Date: Thu, 25 Aug 2022 13:33:01 +0200
[Message part 1 (text/plain, inline)]
On 25-08-2022 11:16, Nicolas Graves via Guix-patches via wrote:
> Made suggested changes, rephrased the description.
> But I never learned C and am not at ease for adding checks in C source
> code, sorry.
>
I have made a PR at <https://github.com/ajraymond/restartd/pull/8> 
<https://github.com/ajraymond/restartd/pull/8> adding some error checking.

Greetings,
Maxime.

[Message part 2 (text/html, inline)]
[OpenPGP_0x49E3EE22191725EE.asc (application/pgp-keys, attachment)]
[OpenPGP_signature (application/pgp-signature, attachment)]

Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Fri, 26 Aug 2022 07:33:02 GMT) Full text and rfc822 format available.

Message #26 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Nicolas Graves <ngraves <at> ngraves.fr>
To: 57387 <at> debbugs.gnu.org 
Subject: [PATCH] gnu: Add restartd.
Date: Fri, 26 Aug 2022 09:32:00 +0200
* gnu/packages/admin.scm (restartd): New variable.
---
 gnu/packages/admin.scm                        |  54 ++++
 ...td-add-error-handling-for-robustness.patch | 232 ++++++++++++++++++
 .../patches/restartd-fix-compilation.patch    |  53 ++++
 3 files changed, 339 insertions(+)
 create mode 100644 gnu/packages/patches/restartd-add-error-handling-for-robustness.patch
 create mode 100644 gnu/packages/patches/restartd-fix-compilation.patch

diff --git a/gnu/packages/admin.scm b/gnu/packages/admin.scm
index a4c5189222..57de594bee 100644
--- a/gnu/packages/admin.scm
+++ b/gnu/packages/admin.scm
@@ -51,6 +51,7 @@
 ;;; Copyright © 2021 Artyom V. Poptsov <poptsov.artyom <at> gmail.com>
 ;;; Copyright © 2022 Wamm K. D. <jaft.r <at> outlook.com>
 ;;; Copyright © 2022 Roman Riabenko <roman <at> riabenko.com>
+;;; Copyright © 2022 Nicolas Graves <ngraves <at> ngraves.fr>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -5455,6 +5456,59 @@ (define-public fail2ban
 mechanisms if you really want to protect services.")
     (license license:gpl2+)))

+(define-public restartd
+  (let* ((commit "7044125ac55056f2663536f7137170edf92ebd75")
+         ;; Version is 0.2.4 in the version file in the repo
+         ;; but not in github tags.
+         ;; It is released as 0.2.3-1.1 for other distributions.
+         ;; Probably because of the lack of activity upstream.
+         (revision "1"))
+    (package
+      (name "restartd")
+      (version (git-version "0.2.3" revision commit))
+      (source
+       (origin
+         (method git-fetch)
+         (uri (git-reference
+               (url "https://github.com/ajraymond/restartd")
+               (commit commit)))
+         (file-name (git-file-name name version))
+         (sha256
+          (base32
+           "1m1np00b4zvvwx63gzysbi38i5vj1jsjvh2s0p9czl6dzyz582z0"))
+         (patches
+          (search-patches
+           "restartd-fix-compilation.patch"
+           "restartd-add-error-handling-for-robustness.patch"))))
+      (build-system gnu-build-system)
+      (arguments
+       (list
+        #:tests? #f ; no tests
+        #:make-flags
+        #~(list (string-append "CC=" #$(cc-for-target)))
+        #:phases
+        #~(modify-phases %standard-phases
+            (delete  'configure)
+            (replace 'install
+              (lambda _
+                (install-file "restartd.conf" (string-append #$output "/etc"))
+                (install-file "restartd" (string-append #$output "/sbin"))
+                (install-file "restartd.8"
+                              (string-append #$output "/share/man/man8"))
+                (mkdir-p (string-append #$output "/share/man/fr/man8"))
+                (copy-file
+                 "restartd.fr.8"
+                 (string-append #$output "/share/man/fr/man8/restartd.8")))))))
+      (home-page "https://launchpad.net/debian/+source/restartd")
+      (synopsis "Daemon for restarting processes")
+      (description "This package provides a daemon for checking running and not
+running processes.  It reads the /proc directory every n seconds and does a
+POSIX regexp on the process names.  The daemon runs an user-provided script
+when it detects a program in the running processes, or an alternate script if
+it doesn't detect the program.  The daemon can only be called by the root
+user, but can use @code{sudo -u user} in the process called if needed.")
+      (license license:gpl2+))))
+
 (define-public rex
   (package
     (name "rex")
diff --git a/gnu/packages/patches/restartd-add-error-handling-for-robustness.patch b/gnu/packages/patches/restartd-add-error-handling-for-robustness.patch
new file mode 100644
index 0000000000..f0abcf1dac
--- /dev/null
+++ b/gnu/packages/patches/restartd-add-error-handling-for-robustness.patch
@@ -0,0 +1,232 @@
+From ec606eb15091ff8ffa672500413128c29814f8ad Mon Sep 17 00:00:00 2001
+From: Yin Kangkai <yinkangkai <at> xiaomi.com>, Maxime Devos <maximedevos <at> telenet.be>
+Date: Thu, 25 Aug 2022 14:29:25 +0200
+Subject: [PATCH] Add some error handling for robustness.
+
+This makes the code a little more robust. What if /var/run does not
+exist, or we do not have permission to open
+/var/run/restartd.pid (EPERM?) due to SELinux misconfiguration?
+This patch also avoids segmentation fault when run from non-root user.
+---
+ config.c   | 19 ++++++++++----
+ config.h   |  2 ++
+ restartd.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++--------
+ 3 files changed, 79 insertions(+), 15 deletions(-)
+
+diff --git a/config.c b/config.c
+index f307b8a..94907e3 100644
+--- a/config.c
++++ b/config.c
+@@ -57,7 +57,11 @@ int read_config(void)
+     config_process_number = 0;
+
+     line1 = (char *) malloc(MAX_LINE_LENGTH);
++    if (!line1)
++      oom_failure();
+     line2 = (char *) malloc(MAX_LINE_LENGTH);
++    if (!line2)
++      oom_failure();
+
+     if ((config_fd = fopen(config_file, "rt")) == NULL) {
+         fprintf(stderr, "Error at opening config file: %s\n", config_file);
+@@ -155,11 +159,16 @@ void dump_config(void) {
+     int i;
+
+     for(i=0; i<config_process_number; i++) {
+-        printf("ID=%d\n  name=%s\n  regexp=%s\n  running=%s\n  not_running=%s\n", i,
+-            config_process[i].name,
+-            config_process[i].regexp,
+-            config_process[i].running,
+-            config_process[i].not_running);
++      if (printf("ID=%d\n  name=%s\n  regexp=%s\n  running=%s\n  not_running=%s\n", i,
++		 config_process[i].name,
++		 config_process[i].regexp,
++		 config_process[i].running,
++		 config_process[i].not_running) < 0) {
++	/* Maybe stdout points to a file and a file system quotum was exceeded? */
++	fprintf(stderr, "Failed to dump the configuration. Exiting.\n");
++	syslog(LOG_ERR, "Failed to dump the configuration. Exiting.");
++	exit(1);
++      }
+     }
+
+ }
+diff --git a/config.h b/config.h
+index fabaa2b..b5a134a 100644
+--- a/config.h
++++ b/config.h
+@@ -1,6 +1,7 @@
+ /* restartd - Process checker and/or restarter daemon
+  * Copyright (C) 2000-2002 Tibor Koleszar <oldw <at> debian.org>
+  * Copyright (C) 2006 Aurélien GÉRÔME <ag <at> roxor.cx>
++ * Copyright (C) 2022 Maxime Devos <maximedevos <at> telenet.be>
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+@@ -43,5 +44,6 @@ typedef struct config_process_type {
+
+ int read_config(/* char *config_file */);
+ void dump_config(void);
++void oom_failure(void);
+
+ #endif /* RESTARTD_CONFIG_H */
+diff --git a/restartd.c b/restartd.c
+index 2aa720c..df0a6eb 100644
+--- a/restartd.c
++++ b/restartd.c
+@@ -1,6 +1,8 @@
+ /* restartd - Process checker and/or restarter daemon
+  * Copyright (C) 2000-2002 Tibor Koleszar <oldw <at> debian.org>
+  * Copyright (C) 2006 Aurélien GÉRÔME <ag <at> roxor.cx>
++ * Copyright (C) 2016 Yin Kangkai <yinkangkai <at> xiaomi.com>
++ * Copyright (C) 2022 Maxime Devos <maximedevos <at> telenet.be>
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+@@ -52,6 +54,17 @@ void got_signal(int sig)
+     }
+ }
+
++/* Ignoring out-of-memory failures is risky on systems without virtual memory
++   where additionally at address 0 there is actually something important
++   mapped. Additionally, while often on Linux the OOM killer will kill processes
++   where an OOM happens, this is not always the case and there exist other systems
++   without an OOM killer (e.g. the Hurd). */
++void oom_failure()
++{
++  syslog(LOG_ERR, "Failed to allocate memory. Exiting.");
++  exit(1);
++}
++
+ int main(int argc, char *argv[])
+ {
+     DIR *procdir_id;
+@@ -75,15 +88,21 @@ int main(int argc, char *argv[])
+
+     /* Options */
+     config_file = strdup(DEFAULT_CONFIG);
++    if (!config_file)
++      oom_failure();
++
+     list_only = 0;
+
+     for(i = 0; i < argc; i++) {
+         if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")) {
+             config_file = strdup(argv[i + 1]);
++	    if (!config_file)
++	      oom_failure();
+         }
+         if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
+             printf("restard %s - Copyright 2000-2002 Tibor Koleszar <oldw <at> debian.org>\n"
+-                   "                Copyright 2006 Aurélien GÉRÔME <ag <at> roxor.cx>\n",
++                   "                Copyright 2006 Aurélien GÉRÔME <ag <at> roxor.cx>\n"
++                   "                Copyright 2022 Maxime Devos <maximedevos <at> telenet.be>\n",
+                    VERSION);
+             exit(0);
+         }
+@@ -118,10 +137,13 @@ int main(int argc, char *argv[])
+                     "  -i <interval_sec>: the check interval in second\n"
+                     "  -l               : list configuration options\n"
+                     "  -h               : help\n\n", VERSION);
++	    exit(0);
+         }
+     }
+
+     config_process = malloc(sizeof(struct config_process_type) * 128);
++    if (!config_process)
++      oom_failure();
+
+     read_config();
+     if (list_only) {
+@@ -133,9 +155,17 @@ int main(int argc, char *argv[])
+            config_process_number);
+
+     procdir_dirent = malloc(sizeof(struct dirent));
++    if (!procdir_dirent)
++      oom_failure();
+     proc_cmdline_str = (char *) malloc(1024);
++    if (!proc_cmdline_str)
++      oom_failure();
+     proc_cmdline_name = (char *) malloc(1024);
++    if (!proc_cmdline_name)
++      oom_failure();
+     regc = malloc(1024);
++    if (!regc)
++      oom_failure();
+
+     /* Catch signals */
+     signal(SIGTERM, got_signal);
+@@ -187,8 +217,18 @@ int main(int argc, char *argv[])
+         }
+
+         out_proc = fopen("/var/run/restartd.pid", "wt");
+-        fprintf(out_proc, "%d", getpid());
+-        fclose(out_proc);
++	if (!out_proc) {
++	  syslog(LOG_ERR, "Failed to open /var/run/restartd.pid");
++	  return -1;
++	}
++        if (fprintf(out_proc, "%d", getpid()) < 0) {
++	  syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting.");
++	  return -1;
++	}
++        if (fclose(out_proc) < 0) { /* errors can happen when flushing the buffer */
++	  syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting.");
++	  return -1;
++	}
+
+         while(1) {
+             if ((procdir_id = opendir("/proc")) == NULL) {
+@@ -237,16 +277,23 @@ int main(int argc, char *argv[])
+            now = time(NULL);
+
+            out_proc = fopen("/var/run/restartd", "wt");
++	   if (!out_proc) {
++	     syslog(LOG_ERR, "Failed to open /var/run/restartd");
++	     return -1;
++	   }
+
+-           fprintf(out_proc, "%s\n", ctime(&now));
++           if (fprintf(out_proc, "%s\n", ctime(&now)) < 0) {
++	     syslog(LOG_ERR, "Failed to write to /var/run/restartd. Exiting.");
++	     return -1;
++	   }
+
+            for(i=0; i<config_process_number; i++) {
+                if (strlen(config_process[i].processes) > 0) {
+                    if (strlen(config_process[i].running) > 0) {
+                        strcpy(config_process[i].status, "running");
+-                       syslog(LOG_INFO, "%s is running, executing '%s'",
++                       /* syslog(LOG_INFO, "%s is running, executing '%s'",
+                               config_process[i].name,
+-                              config_process[i].running);
++                              config_process[i].running); */
+                        system(config_process[i].running);
+                     } else {
+                         strcpy(config_process[i].status, "running");
+@@ -267,12 +314,18 @@ int main(int argc, char *argv[])
+                     strcpy(config_process[i].status, "not running");
+                 }
+
+-                fprintf(out_proc, "%-12s %-12s      %s\n",
+-                        config_process[i].name, config_process[i].status,
+-                        config_process[i].processes);
++		if (fprintf(out_proc, "%-12s %-12s      %s\n",
++			    config_process[i].name, config_process[i].status,
++			    config_process[i].processes) < 0) {
++		  syslog(LOG_ERR, "Failed to write to /var/run/restartd. Exiting.");
++		  return -1;
++		}
+             }
+
+-            fclose(out_proc);
++	    if (fclose(out_proc) < 0) {
++	      syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting.");
++	      return -1;
++	    }
+
+             sleep(check_interval);
+         }
+--
+2.37.2
+
diff --git a/gnu/packages/patches/restartd-fix-compilation.patch b/gnu/packages/patches/restartd-fix-compilation.patch
new file mode 100644
index 0000000000..a380205675
--- /dev/null
+++ b/gnu/packages/patches/restartd-fix-compilation.patch
@@ -0,0 +1,53 @@
+From 84edc2042bb0a82e65bd4d165b706519886b4075 Mon Sep 17 00:00:00 2001
+From: Sudip Mukherjee <sudipm.mukherjee <at> gmail.com>
+Date: Mon, 10 Aug 2020 19:39:30 +0100
+Subject: [PATCH] Fix build with gcc-10
+
+Bug: https://bugs.debian.org/957761
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee <at> gmail.com>
+---
+ config.h   | 12 ++++++------
+ restartd.c |  7 +++++++
+ 2 files changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/config.h b/config.h
+index fabaa2b..a79b28e 100644
+--- a/config.h
++++ b/config.h
+@@ -25,12 +25,12 @@
+
+ #define DEFAULT_CONFIG "/etc/restartd.conf"
+
+-int debug;
+-int config_process_number;
+-int check_interval;
+-int foreground;
+-struct config_process_type *config_process;
+-char *config_file;
++extern int debug;
++extern int config_process_number;
++extern int check_interval;
++extern int foreground;
++extern struct config_process_type *config_process;
++extern char *config_file;
+
+ typedef struct config_process_type {
+   char name[64];
+diff --git a/restartd.c b/restartd.c
+index 2aa720c..617b298 100644
+--- a/restartd.c
++++ b/restartd.c
+@@ -35,6 +35,13 @@
+
+ #include "config.h"
+
++int debug;
++int config_process_number;
++int check_interval;
++int foreground;
++struct config_process_type *config_process;
++char *config_file;
++
+ /* SIGTERM & SIGHUP handler */
+ void got_signal(int sig)
+ {
--
2.37.2


<#secure method=pgpmime mode=sign>

--
Best regards,
Nicolas Graves




Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Fri, 26 Aug 2022 14:04:01 GMT) Full text and rfc822 format available.

Message #29 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Maxime Devos <maximedevos <at> telenet.be>
To: Nicolas Graves <ngraves <at> ngraves.fr>, 57387 <at> debbugs.gnu.org
Subject: Re: [bug#57387] [PATCH] gnu: Add restartd.
Date: Fri, 26 Aug 2022 16:03:41 +0200
[Message part 1 (text/plain, inline)]
On 26-08-2022 09:32, Nicolas Graves via Guix-patches via wrote:

> [...]
> +         (patches
> +          (search-patches
> +           "restartd-fix-compilation.patch"
> +           "restartd-add-error-handling-for-robustness.patch"))))
> [...]
>   (define-public rex
>     (package
>       (name "rex")
> diff --git a/gnu/packages/patches/restartd-add-error-handling-for-robustness.patch b/gnu/packages/patches/restartd-add-error-handling-for-robustness.patch
> new file mode 100644
> index 0000000000..f0abcf1dac
> --- /dev/null
> +++ b/gnu/packages/patches/restartd-add-error-handling-for-robustness.patch
> @@ -0,0 +1,232 @@
> +From ec606eb15091ff8ffa672500413128c29814f8ad Mon Sep 17 00:00:00 2001
> +From: Yin Kangkai <yinkangkai <at> xiaomi.com>, Maxime Devos <maximedevos <at> telenet.be>
A bit of a nitpick, but Yin Kagkai was not involved in this patch, I 
wrote it myself ...
> +Date: Thu, 25 Aug 2022 14:29:25 +0200
> +Subject: [PATCH] Add some error handling for robustness.
> +
> +This makes the code a little more robust. What if /var/run does not
> +exist, or we do not have permission to open
> +/var/run/restartd.pid (EPERM?) due to SELinux misconfiguration?
> +This patch also avoids segmentation fault when run from non-root user.
> +---
> +[..]
> +            for(i=0; i<config_process_number; i++) {
> +                if (strlen(config_process[i].processes) > 0) {
> +                    if (strlen(config_process[i].running) > 0) {
> +                        strcpy(config_process[i].status, "running");
> +-                       syslog(LOG_INFO, "%s is running, executing '%s'",
> ++                       /* syslog(LOG_INFO, "%s is running, executing '%s'",
> +                               config_process[i].name,
> +-                              config_process[i].running);
> ++                              config_process[i].running); */

... the commenting syslog thing was an unrelated patch, maybe various 
commits were squashed?

When I tried out the patch, I added a local copy of 
https://patch-diff.githubusercontent.com/raw/ajraymond/restartd/pull/8.patch 
to the list of patches and "guix build" succeeded, there was no need to 
squash things.

Greetings,
Maaxime.


[OpenPGP_0x49E3EE22191725EE.asc (application/pgp-keys, attachment)]
[OpenPGP_signature (application/pgp-signature, attachment)]

Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Fri, 26 Aug 2022 16:58:02 GMT) Full text and rfc822 format available.

Message #32 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Nicolas Graves <ngraves <at> ngraves.fr>
To: Maxime Devos <maximedevos <at> telenet.be>, 57387 <at> debbugs.gnu.org
Subject: Re: [bug#57387] [PATCH] gnu: Add restartd.
Date: Fri, 26 Aug 2022 18:57:43 +0200
> A bit of a nitpick, but Yin Kagkai was not involved in this patch, I
> wrote it myself ...
> ... the commenting syslog thing was an unrelated patch, maybe various
> commits were squashed?

Sorry, I should have explained.
Applying both pull requests 6 and 8 failed because 3 lines were common
to both.

I resolved that by merging both and recreating a new patch, thus giving
credit to both authors. Is that OK ?

-- 
Best regards,
Nicolas Graves




Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Fri, 26 Aug 2022 19:08:01 GMT) Full text and rfc822 format available.

Message #35 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Maxime Devos <maximedevos <at> telenet.be>
To: Nicolas Graves <ngraves <at> ngraves.fr>, 57387 <at> debbugs.gnu.org
Subject: Re: [bug#57387] [PATCH] gnu: Add restartd.
Date: Fri, 26 Aug 2022 21:07:03 +0200
[Message part 1 (text/plain, inline)]
On 26-08-2022 18:57, Nicolas Graves wrote:

>> A bit of a nitpick, but Yin Kagkai was not involved in this patch, I
>> wrote it myself ...
>> ... the commenting syslog thing was an unrelated patch, maybe various
>> commits were squashed?
> Sorry, I should have explained.
> Applying both pull requests 6 and 8 failed because 3 lines were common
> to both.
Hm, I didn't encounter that, maybe I accidentally removed one of the 
pre-existing patches or even removed my own patch.
> I resolved that by merging both and recreating a new patch, thus giving
> credit to both authors. Is that OK ?

OK, but some commit messages are getting lost, maybe add a link to the 
two upstream PRs to make clear it's a combination of multiple 
independent -- Yin Kangkai did some presumably useful things, but it's 
not adding error handling unlike what the current patch message and file 
name implies.

Greetings,
Maxime.

[Message part 2 (text/html, inline)]
[OpenPGP_0x49E3EE22191725EE.asc (application/pgp-keys, attachment)]
[OpenPGP_signature (application/pgp-signature, attachment)]

Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Fri, 26 Aug 2022 22:17:02 GMT) Full text and rfc822 format available.

Message #38 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Nicolas Graves <ngraves <at> ngraves.fr>
To: 57387 <at> debbugs.gnu.org 
Subject: [PATCH] gnu: Add restartd.
Date: Sat, 27 Aug 2022 00:16:41 +0200
* gnu/packages/admin.scm (restartd): New variable.
---
 gnu/packages/admin.scm                        |  54 ++++
 ...td-add-error-handling-for-robustness.patch | 242 ++++++++++++++++++
 .../patches/restartd-fix-compilation.patch    |  53 ++++
 3 files changed, 349 insertions(+)
 create mode 100644 gnu/packages/patches/restartd-add-error-handling-for-robustness.patch
 create mode 100644 gnu/packages/patches/restartd-fix-compilation.patch

diff --git a/gnu/packages/admin.scm b/gnu/packages/admin.scm
index a4c5189222..57de594bee 100644
--- a/gnu/packages/admin.scm
+++ b/gnu/packages/admin.scm
@@ -51,6 +51,7 @@
 ;;; Copyright © 2021 Artyom V. Poptsov <poptsov.artyom <at> gmail.com>
 ;;; Copyright © 2022 Wamm K. D. <jaft.r <at> outlook.com>
 ;;; Copyright © 2022 Roman Riabenko <roman <at> riabenko.com>
+;;; Copyright © 2022 Nicolas Graves <ngraves <at> ngraves.fr>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -5455,6 +5456,59 @@ (define-public fail2ban
 mechanisms if you really want to protect services.")
     (license license:gpl2+)))

+(define-public restartd
+  (let* ((commit "7044125ac55056f2663536f7137170edf92ebd75")
+         ;; Version is 0.2.4 in the version file in the repo
+         ;; but not in github tags.
+         ;; It is released as 0.2.3-1.1 for other distributions.
+         ;; Probably because of the lack of activity upstream.
+         (revision "1"))
+    (package
+      (name "restartd")
+      (version (git-version "0.2.3" revision commit))
+      (source
+       (origin
+         (method git-fetch)
+         (uri (git-reference
+               (url "https://github.com/ajraymond/restartd")
+               (commit commit)))
+         (file-name (git-file-name name version))
+         (sha256
+          (base32
+           "1m1np00b4zvvwx63gzysbi38i5vj1jsjvh2s0p9czl6dzyz582z0"))
+         (patches
+          (search-patches
+           "restartd-fix-compilation.patch"
+           "restartd-add-error-handling-for-robustness.patch"))))
+      (build-system gnu-build-system)
+      (arguments
+       (list
+        #:tests? #f ; no tests
+        #:make-flags
+        #~(list (string-append "CC=" #$(cc-for-target)))
+        #:phases
+        #~(modify-phases %standard-phases
+            (delete  'configure)
+            (replace 'install
+              (lambda _
+                (install-file "restartd.conf" (string-append #$output "/etc"))
+                (install-file "restartd" (string-append #$output "/sbin"))
+                (install-file "restartd.8"
+                              (string-append #$output "/share/man/man8"))
+                (mkdir-p (string-append #$output "/share/man/fr/man8"))
+                (copy-file
+                 "restartd.fr.8"
+                 (string-append #$output "/share/man/fr/man8/restartd.8")))))))
+      (home-page "https://launchpad.net/debian/+source/restartd")
+      (synopsis "Daemon for restarting processes")
+      (description "This package provides a daemon for checking running and not
+running processes.  It reads the /proc directory every n seconds and does a
+POSIX regexp on the process names.  The daemon runs an user-provided script
+when it detects a program in the running processes, or an alternate script if
+it doesn't detect the program.  The daemon can only be called by the root
+user, but can use @code{sudo -u user} in the process called if needed.")
+      (license license:gpl2+))))
+
 (define-public rex
   (package
     (name "rex")
diff --git a/gnu/packages/patches/restartd-add-error-handling-for-robustness.patch b/gnu/packages/patches/restartd-add-error-handling-for-robustness.patch
new file mode 100644
index 0000000000..33f5f06555
--- /dev/null
+++ b/gnu/packages/patches/restartd-add-error-handling-for-robustness.patch
@@ -0,0 +1,242 @@
+From ec606eb15091ff8ffa672500413128c29814f8ad Mon Sep 17 00:00:00 2001
+From: Maxime Devos <maximedevos <at> telenet.be>, Yin Kangkai <yinkangkai <at> xiaomi.com>
+Date: Thu, 25 Aug 2022 14:29:25 +0200
+Subject: [PATCH] Add some error handling for robustness.
+
+This patch is a merge of two pull requests for the restartd project.
+
+Maxime Devos <maximedevos <at> telenet.be>
+https://github.com/ajraymond/restartd/pull/8
+
+This makes the code a little more robust. What if /var/run does not
+exist, or we do not have permission to open
+/var/run/restartd.pid (EPERM?) due to SELinux misconfiguration?
+
+Yin Kangkai <yinkangkai <at> xiaomi.com>
+https://github.com/ajraymond/restartd/pull/6
+
+This patch also avoids segmentation fault when run from non-root user.
+
+---
+ config.c   | 19 ++++++++++----
+ config.h   |  2 ++
+ restartd.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++--------
+ 3 files changed, 79 insertions(+), 15 deletions(-)
+
+diff --git a/config.c b/config.c
+index f307b8a..94907e3 100644
+--- a/config.c
++++ b/config.c
+@@ -57,7 +57,11 @@ int read_config(void)
+     config_process_number = 0;
+
+     line1 = (char *) malloc(MAX_LINE_LENGTH);
++    if (!line1)
++      oom_failure();
+     line2 = (char *) malloc(MAX_LINE_LENGTH);
++    if (!line2)
++      oom_failure();
+
+     if ((config_fd = fopen(config_file, "rt")) == NULL) {
+         fprintf(stderr, "Error at opening config file: %s\n", config_file);
+@@ -155,11 +159,16 @@ void dump_config(void) {
+     int i;
+
+     for(i=0; i<config_process_number; i++) {
+-        printf("ID=%d\n  name=%s\n  regexp=%s\n  running=%s\n  not_running=%s\n", i,
+-            config_process[i].name,
+-            config_process[i].regexp,
+-            config_process[i].running,
+-            config_process[i].not_running);
++      if (printf("ID=%d\n  name=%s\n  regexp=%s\n  running=%s\n  not_running=%s\n", i,
++		 config_process[i].name,
++		 config_process[i].regexp,
++		 config_process[i].running,
++		 config_process[i].not_running) < 0) {
++	/* Maybe stdout points to a file and a file system quotum was exceeded? */
++	fprintf(stderr, "Failed to dump the configuration. Exiting.\n");
++	syslog(LOG_ERR, "Failed to dump the configuration. Exiting.");
++	exit(1);
++      }
+     }
+
+ }
+diff --git a/config.h b/config.h
+index fabaa2b..b5a134a 100644
+--- a/config.h
++++ b/config.h
+@@ -1,6 +1,7 @@
+ /* restartd - Process checker and/or restarter daemon
+  * Copyright (C) 2000-2002 Tibor Koleszar <oldw <at> debian.org>
+  * Copyright (C) 2006 Aurélien GÉRÔME <ag <at> roxor.cx>
++ * Copyright (C) 2022 Maxime Devos <maximedevos <at> telenet.be>
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+@@ -43,5 +44,6 @@ typedef struct config_process_type {
+
+ int read_config(/* char *config_file */);
+ void dump_config(void);
++void oom_failure(void);
+
+ #endif /* RESTARTD_CONFIG_H */
+diff --git a/restartd.c b/restartd.c
+index 2aa720c..df0a6eb 100644
+--- a/restartd.c
++++ b/restartd.c
+@@ -1,6 +1,8 @@
+ /* restartd - Process checker and/or restarter daemon
+  * Copyright (C) 2000-2002 Tibor Koleszar <oldw <at> debian.org>
+  * Copyright (C) 2006 Aurélien GÉRÔME <ag <at> roxor.cx>
++ * Copyright (C) 2016 Yin Kangkai <yinkangkai <at> xiaomi.com>
++ * Copyright (C) 2022 Maxime Devos <maximedevos <at> telenet.be>
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+@@ -52,6 +54,17 @@ void got_signal(int sig)
+     }
+ }
+
++/* Ignoring out-of-memory failures is risky on systems without virtual memory
++   where additionally at address 0 there is actually something important
++   mapped. Additionally, while often on Linux the OOM killer will kill processes
++   where an OOM happens, this is not always the case and there exist other systems
++   without an OOM killer (e.g. the Hurd). */
++void oom_failure()
++{
++  syslog(LOG_ERR, "Failed to allocate memory. Exiting.");
++  exit(1);
++}
++
+ int main(int argc, char *argv[])
+ {
+     DIR *procdir_id;
+@@ -75,15 +88,21 @@ int main(int argc, char *argv[])
+
+     /* Options */
+     config_file = strdup(DEFAULT_CONFIG);
++    if (!config_file)
++      oom_failure();
++
+     list_only = 0;
+
+     for(i = 0; i < argc; i++) {
+         if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")) {
+             config_file = strdup(argv[i + 1]);
++	    if (!config_file)
++	      oom_failure();
+         }
+         if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
+             printf("restard %s - Copyright 2000-2002 Tibor Koleszar <oldw <at> debian.org>\n"
+-                   "                Copyright 2006 Aurélien GÉRÔME <ag <at> roxor.cx>\n",
++                   "                Copyright 2006 Aurélien GÉRÔME <ag <at> roxor.cx>\n"
++                   "                Copyright 2022 Maxime Devos <maximedevos <at> telenet.be>\n",
+                    VERSION);
+             exit(0);
+         }
+@@ -118,10 +137,13 @@ int main(int argc, char *argv[])
+                     "  -i <interval_sec>: the check interval in second\n"
+                     "  -l               : list configuration options\n"
+                     "  -h               : help\n\n", VERSION);
++	    exit(0);
+         }
+     }
+
+     config_process = malloc(sizeof(struct config_process_type) * 128);
++    if (!config_process)
++      oom_failure();
+
+     read_config();
+     if (list_only) {
+@@ -133,9 +155,17 @@ int main(int argc, char *argv[])
+            config_process_number);
+
+     procdir_dirent = malloc(sizeof(struct dirent));
++    if (!procdir_dirent)
++      oom_failure();
+     proc_cmdline_str = (char *) malloc(1024);
++    if (!proc_cmdline_str)
++      oom_failure();
+     proc_cmdline_name = (char *) malloc(1024);
++    if (!proc_cmdline_name)
++      oom_failure();
+     regc = malloc(1024);
++    if (!regc)
++      oom_failure();
+
+     /* Catch signals */
+     signal(SIGTERM, got_signal);
+@@ -187,8 +217,18 @@ int main(int argc, char *argv[])
+         }
+
+         out_proc = fopen("/var/run/restartd.pid", "wt");
+-        fprintf(out_proc, "%d", getpid());
+-        fclose(out_proc);
++	if (!out_proc) {
++	  syslog(LOG_ERR, "Failed to open /var/run/restartd.pid");
++	  return -1;
++	}
++        if (fprintf(out_proc, "%d", getpid()) < 0) {
++	  syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting.");
++	  return -1;
++	}
++        if (fclose(out_proc) < 0) { /* errors can happen when flushing the buffer */
++	  syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting.");
++	  return -1;
++	}
+
+         while(1) {
+             if ((procdir_id = opendir("/proc")) == NULL) {
+@@ -237,16 +277,23 @@ int main(int argc, char *argv[])
+            now = time(NULL);
+
+            out_proc = fopen("/var/run/restartd", "wt");
++	   if (!out_proc) {
++	     syslog(LOG_ERR, "Failed to open /var/run/restartd");
++	     return -1;
++	   }
+
+-           fprintf(out_proc, "%s\n", ctime(&now));
++           if (fprintf(out_proc, "%s\n", ctime(&now)) < 0) {
++	     syslog(LOG_ERR, "Failed to write to /var/run/restartd. Exiting.");
++	     return -1;
++	   }
+
+            for(i=0; i<config_process_number; i++) {
+                if (strlen(config_process[i].processes) > 0) {
+                    if (strlen(config_process[i].running) > 0) {
+                        strcpy(config_process[i].status, "running");
+-                       syslog(LOG_INFO, "%s is running, executing '%s'",
++                       /* syslog(LOG_INFO, "%s is running, executing '%s'",
+                               config_process[i].name,
+-                              config_process[i].running);
++                              config_process[i].running); */
+                        system(config_process[i].running);
+                     } else {
+                         strcpy(config_process[i].status, "running");
+@@ -267,12 +314,18 @@ int main(int argc, char *argv[])
+                     strcpy(config_process[i].status, "not running");
+                 }
+
+-                fprintf(out_proc, "%-12s %-12s      %s\n",
+-                        config_process[i].name, config_process[i].status,
+-                        config_process[i].processes);
++		if (fprintf(out_proc, "%-12s %-12s      %s\n",
++			    config_process[i].name, config_process[i].status,
++			    config_process[i].processes) < 0) {
++		  syslog(LOG_ERR, "Failed to write to /var/run/restartd. Exiting.");
++		  return -1;
++		}
+             }
+
+-            fclose(out_proc);
++	    if (fclose(out_proc) < 0) {
++	      syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting.");
++	      return -1;
++	    }
+
+             sleep(check_interval);
+         }
+--
+2.37.2
+
diff --git a/gnu/packages/patches/restartd-fix-compilation.patch b/gnu/packages/patches/restartd-fix-compilation.patch
new file mode 100644
index 0000000000..a380205675
--- /dev/null
+++ b/gnu/packages/patches/restartd-fix-compilation.patch
@@ -0,0 +1,53 @@
+From 84edc2042bb0a82e65bd4d165b706519886b4075 Mon Sep 17 00:00:00 2001
+From: Sudip Mukherjee <sudipm.mukherjee <at> gmail.com>
+Date: Mon, 10 Aug 2020 19:39:30 +0100
+Subject: [PATCH] Fix build with gcc-10
+
+Bug: https://bugs.debian.org/957761
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee <at> gmail.com>
+---
+ config.h   | 12 ++++++------
+ restartd.c |  7 +++++++
+ 2 files changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/config.h b/config.h
+index fabaa2b..a79b28e 100644
+--- a/config.h
++++ b/config.h
+@@ -25,12 +25,12 @@
+
+ #define DEFAULT_CONFIG "/etc/restartd.conf"
+
+-int debug;
+-int config_process_number;
+-int check_interval;
+-int foreground;
+-struct config_process_type *config_process;
+-char *config_file;
++extern int debug;
++extern int config_process_number;
++extern int check_interval;
++extern int foreground;
++extern struct config_process_type *config_process;
++extern char *config_file;
+
+ typedef struct config_process_type {
+   char name[64];
+diff --git a/restartd.c b/restartd.c
+index 2aa720c..617b298 100644
+--- a/restartd.c
++++ b/restartd.c
+@@ -35,6 +35,13 @@
+
+ #include "config.h"
+
++int debug;
++int config_process_number;
++int check_interval;
++int foreground;
++struct config_process_type *config_process;
++char *config_file;
++
+ /* SIGTERM & SIGHUP handler */
+ void got_signal(int sig)
+ {
--
2.37.2

--
Best regards,
Nicolas Graves




Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Sun, 28 Aug 2022 17:40:01 GMT) Full text and rfc822 format available.

Message #41 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Maxime Devos <maximedevos <at> telenet.be>
To: Nicolas Graves <ngraves <at> ngraves.fr>, 57387 <at> debbugs.gnu.org
Subject: Re: [bug#57387] [PATCH] gnu: Add restartd.
Date: Sun, 28 Aug 2022 19:38:56 +0200
[Message part 1 (text/plain, inline)]
This merge seems ok to me.

Thanks,
Maxime (not a committer)
[OpenPGP_0x49E3EE22191725EE.asc (application/pgp-keys, attachment)]
[OpenPGP_signature (application/pgp-signature, attachment)]

Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Sun, 11 Sep 2022 14:55:02 GMT) Full text and rfc822 format available.

Message #44 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Mathieu Othacehe <othacehe <at> gnu.org>
To: Nicolas Graves <ngraves <at> ngraves.fr>
Cc: 57387 <at> debbugs.gnu.org
Subject: Re: bug#57387: [PATCH] gnu: Add restartd.
Date: Sun, 11 Sep 2022 16:53:49 +0200
Hello,

> * gnu/packages/admin.scm (restartd): New variable.

I have the following error when trying to build the package:

--8<---------------cut here---------------start------------->8---
2 out of 8 hunks FAILED -- saving rejects to file restartd.c.rej
source is at 'restartd-0.2.3-1.7044125-checkout'
applying '/gnu/store/gayczr3cvcxlqafxz9pclk6b8jhxhl75-restartd-fix-compilation.patch'...
applying '/gnu/store/d1sllhia0ninbfrq9agw2272dwm1v103-restartd-add-error-handling-for-robustness.patch'...
Backtrace:
           5 (primitive-load "/gnu/store/skbm6f65x56bhq5sd8w7fys5q49…")
In ice-9/eval.scm:
    619:8  4 (_ #(#(#<directory (guile-user) 7ffff3fd7c80> "res…") #))
In ice-9/boot-9.scm:
    142:2  3 (dynamic-wind #<procedure 7ffff3f862c0 at ice-9/eval.s…> …)
In ice-9/eval.scm:
    619:8  2 (_ #(#(#<directory (guile-user) 7ffff3fd7c80>)))
In srfi/srfi-1.scm:
    634:9  1 (for-each #<procedure apply-patch (a)> _)
In guix/build/utils.scm:
    762:6  0 (invoke "/gnu/store/z39hnrwds1dgcbpfgj8dnv2cngjb2xbl-p…" …)

guix/build/utils.scm:762:6: In procedure invoke:
ERROR:
  1. &invoke-error:
      program: "/gnu/store/z39hnrwds1dgcbpfgj8dnv2cngjb2xbl-patch-2.7.6/bin/patch"
      arguments: ("--force" "--no-backup-if-mismatch" "-p1" "--input" "/gnu/store/d1sllhia0ninbfrq9agw2272dwm1v103-restartd-add-error-handling-for-robustness.patch")
      exit-status: 1
      term-signal: #f
      stop-signal: #f
--8<---------------cut here---------------end--------------->8---

Mathieu




Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Sun, 11 Sep 2022 18:14:01 GMT) Full text and rfc822 format available.

Message #47 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Nicolas Graves <ngraves <at> ngraves.fr>
To: Mathieu Othacehe <othacehe <at> gnu.org>
Cc: 57387 <at> debbugs.gnu.org
Subject: Re: bug#57387: [PATCH] gnu: Add restartd.
Date: Sun, 11 Sep 2022 20:13:14 +0200
On 2022-09-11 16:53, Mathieu Othacehe wrote:
> I have the following error when trying to build the package:
>
> --8<---------------cut here---------------start------------->8---
> 2 out of 8 hunks FAILED -- saving rejects to file restartd.c.rej

I can't reproduce, don't have the error when compiling again with
--check. Can you provide contents of restartd.c.rej?

Thanks!

Nicolas

-- 
Best regards,
Nicolas Graves




Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Mon, 12 Sep 2022 07:37:01 GMT) Full text and rfc822 format available.

Message #50 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Mathieu Othacehe <othacehe <at> gnu.org>
To: Nicolas Graves <ngraves <at> ngraves.fr>
Cc: 57387 <at> debbugs.gnu.org
Subject: Re: bug#57387: [PATCH] gnu: Add restartd.
Date: Mon, 12 Sep 2022 09:36:13 +0200
[Message part 1 (text/plain, inline)]
Hello,

> I can't reproduce, don't have the error when compiling again with
> --check. Can you provide contents of restartd.c.rej?

Please find it attached.

Mathieu
[restartd.c.rej (application/octet-stream, attachment)]

Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Tue, 13 Sep 2022 09:06:02 GMT) Full text and rfc822 format available.

Message #53 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Nicolas Graves <ngraves <at> ngraves.fr>
To: Mathieu Othacehe <othacehe <at> gnu.org>
Cc: 57387 <at> debbugs.gnu.org
Subject: Re: bug#57387: [PATCH] gnu: Add restartd.
Date: Tue, 13 Sep 2022 10:45:54 +0200
> Please find it attached.
Thanks!

I don't understand why there should be a reject, just by looking at the
patches, I don't see why these hunks would collide.

I don't have a clue on how to fix this. I'll merge both locally
and regenerating a single patch that by definition can't collide.

-- 
Best regards,
Nicolas Graves




Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Wed, 14 Sep 2022 07:49:02 GMT) Full text and rfc822 format available.

Message #56 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Mathieu Othacehe <othacehe <at> gnu.org>
To: Nicolas Graves <ngraves <at> ngraves.fr>
Cc: 57387 <at> debbugs.gnu.org
Subject: Re: bug#57387: [PATCH] gnu: Add restartd.
Date: Wed, 14 Sep 2022 09:48:04 +0200
Hello Nicolas,

>  ...td-add-error-handling-for-robustness.patch | 242 ++++++++++++++++++
>  .../patches/restartd-fix-compilation.patch    |  53 ++++

Both patches also need to be added to the dist_patch_DATA variable of
gnu/local.mk.

Thanks,

Mathieu




Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Thu, 29 Sep 2022 13:15:01 GMT) Full text and rfc822 format available.

Message #59 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Nicolas Graves <ngraves <at> ngraves.fr>
To: 57387 <at> debbugs.gnu.org
Cc: othacehe <at> gnu.org, maximedevos <at> telenet.be
Subject: Re: [PATCH] gnu: Add restartd.
Date: Thu, 29 Sep 2022 15:14:35 +0200
* gnu/packages/admin.scm (restartd): New variable.
---
 gnu/packages/admin.scm                        |  51 +++
 .../patches/restartd-update-robust.patch      | 295 ++++++++++++++++++
 2 files changed, 346 insertions(+)
 create mode 100644 gnu/packages/patches/restartd-update-robust.patch

diff --git a/gnu/packages/admin.scm b/gnu/packages/admin.scm
index 1a213adfdd..c696384211 100644
--- a/gnu/packages/admin.scm
+++ b/gnu/packages/admin.scm
@@ -53,6 +53,7 @@
 ;;; Copyright © 2022 Roman Riabenko <roman <at> riabenko.com>
 ;;; Copyright © 2022 Petr Hodina <phodina <at> protonmail.com>
 ;;; Copyright © 2022 Andreas Rammhold <andreas <at> rammhold.de>
+;;; Copyright © 2022 Nicolas Graves <ngraves <at> ngraves.fr>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -5489,6 +5490,56 @@ (define-public fail2ban
 mechanisms if you really want to protect services.")
     (license license:gpl2+)))
 
+(define-public restartd
+  (let* ((commit "7044125ac55056f2663536f7137170edf92ebd75")
+         ;; Version is 0.2.4 in the version file in the repo
+         ;; but not in github tags.
+         ;; It is released as 0.2.3-1.1 for other distributions.
+         ;; Probably because of the lack of activity upstream.
+         (revision "1"))
+    (package
+      (name "restartd")
+      (version (git-version "0.2.3" revision commit))
+      (source
+       (origin
+         (method git-fetch)
+         (uri (git-reference
+               (url "https://github.com/ajraymond/restartd")
+               (commit commit)))
+         (file-name (git-file-name name version))
+         (sha256
+          (base32
+           "1m1np00b4zvvwx63gzysbi38i5vj1jsjvh2s0p9czl6dzyz582z0"))
+         (patches (search-patches "restartd-update-robust.patch"))))
+      (build-system gnu-build-system)
+      (arguments
+       (list
+        #:tests? #f ; no tests
+        #:make-flags
+        #~(list (string-append "CC=" #$(cc-for-target)))
+        #:phases
+        #~(modify-phases %standard-phases
+            (delete  'configure)
+            (replace 'install
+              (lambda _
+                (install-file "restartd.conf" (string-append #$output "/etc"))
+                (install-file "restartd" (string-append #$output "/sbin"))
+                (install-file "restartd.8"
+                              (string-append #$output "/share/man/man8"))
+                (mkdir-p (string-append #$output "/share/man/fr/man8"))
+                (copy-file
+                 "restartd.fr.8"
+                 (string-append #$output "/share/man/fr/man8/restartd.8")))))))
+      (home-page "https://launchpad.net/debian/+source/restartd")
+      (synopsis "Daemon for restarting processes")
+      (description "This package provides a daemon for checking running and not
+running processes.  It reads the /proc directory every n seconds and does a
+POSIX regexp on the process names.  The daemon runs an user-provided script
+when it detects a program in the running processes, or an alternate script if
+it doesn't detect the program.  The daemon can only be called by the root
+user, but can use @code{sudo -u user} in the process called if needed.")
+      (license license:gpl2+))))
+
 (define-public rex
   (package
     (name "rex")
diff --git a/gnu/packages/patches/restartd-update-robust.patch b/gnu/packages/patches/restartd-update-robust.patch
new file mode 100644
index 0000000000..d279ebd8ff
--- /dev/null
+++ b/gnu/packages/patches/restartd-update-robust.patch
@@ -0,0 +1,295 @@
+From 01cd2d15a9bf1109e0e71b3e31b835d63dcf9cd8 Mon Sep 17 00:00:00 2001
+From: Maxime Devos <maximedevos <at> telenet.be>, Yin Kangkai <yinkangkai <at> xiaomi.com>, Sudip Mukherjee <sudipm.mukherjee <at> gmail.com>
+Subject: [PATCH]
+
+Fix segfault when run as normal user
+
+Also exit immediately when "restartd -h"
+Signed-off-by: Yin Kangkai <yinkangkai <at> xiaomi.com>
+
+Fix build with gcc-10
+
+Bug: https://bugs.debian.org/957761
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee <at> gmail.com>
+
+Handle memory allocation failures.
+
+This makes the code a little more robust.
+Signed-off-by: Maxime Devos <maximedevos <at> telenet.be>
+
+Handle fopen failures.
+
+This makes the code a little more robust. What if /var/run does not
+exist, or we do not have permission to open
+/var/run/restartd.pid (EPERM?) due to SELinux misconfiguration?
+Signed-off-by: Maxime Devos <maximedevos <at> telenet.be>
+
+Handle printf and fprintf failures.
+
+This makes the code a little more robust. What if the write was
+refused to the underlying device being removed?
+
+The --help, debug and stderr printfs were ignored because there error
+handling does not appear important to me.
+Signed-off-by: Maxime Devos <maximedevos <at> telenet.be>
+
+Handle fclose failures when writing.
+
+This makes the code a little more robust. What if a quotum is exceeded?
+Signed-off-by: Maxime Devos <maximedevos <at> telenet.be>
+---
+ config.c   | 19 +++++++++----
+ config.h   | 14 ++++++----
+ restartd.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++-------
+ 3 files changed, 92 insertions(+), 21 deletions(-)
+
+diff --git a/config.c b/config.c
+index f307b8a..5cc0271 100644
+--- a/config.c
++++ b/config.c
+@@ -57,7 +57,11 @@ int read_config(void)
+     config_process_number = 0;
+ 
+     line1 = (char *) malloc(MAX_LINE_LENGTH);
++    if (!line1)
++      oom_failure();
+     line2 = (char *) malloc(MAX_LINE_LENGTH);
++    if (!line2)
++      oom_failure();
+ 
+     if ((config_fd = fopen(config_file, "rt")) == NULL) {
+         fprintf(stderr, "Error at opening config file: %s\n", config_file);
+@@ -155,11 +159,16 @@ void dump_config(void) {
+     int i;
+ 
+     for(i=0; i<config_process_number; i++) {
+-        printf("ID=%d\n  name=%s\n  regexp=%s\n  running=%s\n  not_running=%s\n", i,
+-            config_process[i].name,
+-            config_process[i].regexp,
+-            config_process[i].running,
+-            config_process[i].not_running);
++      if (printf("ID=%d\n  name=%s\n  regexp=%s\n  running=%s\n  not_running=%s\n", i,
++                 config_process[i].name,
++                 config_process[i].regexp,
++                 config_process[i].running,
++                 config_process[i].not_running) < 0) {
++        /* Maybe stdout points to a file and a file system quotum was exceeded? */
++        fprintf(stderr, "Failed to dump the configuration. Exiting.\n");
++        syslog(LOG_ERR, "Failed to dump the configuration. Exiting.");
++        exit(1);
++      }
+     }
+ 
+ }
+diff --git a/config.h b/config.h
+index fabaa2b..2ba1cbe 100644
+--- a/config.h
++++ b/config.h
+@@ -1,6 +1,7 @@
+ /* restartd - Process checker and/or restarter daemon
+  * Copyright (C) 2000-2002 Tibor Koleszar <oldw <at> debian.org>
+  * Copyright (C) 2006 Aurélien GÉRÔME <ag <at> roxor.cx>
++ * Copyright (C) 2022 Maxime Devos <maximedevos <at> telenet.be>
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+@@ -25,12 +26,12 @@
+ 
+ #define DEFAULT_CONFIG "/etc/restartd.conf"
+ 
+-int debug;
+-int config_process_number;
+-int check_interval;
+-int foreground;
+-struct config_process_type *config_process;
+-char *config_file;
++extern int debug;
++extern int config_process_number;
++extern int check_interval;
++extern int foreground;
++extern struct config_process_type *config_process;
++extern char *config_file;
+ 
+ typedef struct config_process_type {
+   char name[64];
+@@ -43,5 +44,6 @@ typedef struct config_process_type {
+ 
+ int read_config(/* char *config_file */);
+ void dump_config(void);
++void oom_failure(void);
+ 
+ #endif /* RESTARTD_CONFIG_H */
+diff --git a/restartd.c b/restartd.c
+index 2aa720c..aa74334 100644
+--- a/restartd.c
++++ b/restartd.c
+@@ -1,6 +1,7 @@
+ /* restartd - Process checker and/or restarter daemon
+  * Copyright (C) 2000-2002 Tibor Koleszar <oldw <at> debian.org>
+  * Copyright (C) 2006 Aurélien GÉRÔME <ag <at> roxor.cx>
++ * Copyright (C) 2022 Maxime Devos <maximedevos <at> telenet.be>
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+@@ -35,6 +36,13 @@
+ 
+ #include "config.h"
+ 
++int debug;
++int config_process_number;
++int check_interval;
++int foreground;
++struct config_process_type *config_process;
++char *config_file;
++
+ /* SIGTERM & SIGHUP handler */
+ void got_signal(int sig)
+ {
+@@ -52,6 +60,17 @@ void got_signal(int sig)
+     }
+ }
+ 
++/* Ignoring out-of-memory failures is risky on systems without virtual memory
++   where additionally at address 0 there is actually something important
++   mapped. Additionally, while often on Linux the OOM killer will kill processes
++   where an OOM happens, this is not always the case and there exist other systems
++   without an OOM killer (e.g. the Hurd). */
++void oom_failure()
++{
++  syslog(LOG_ERR, "Failed to allocate memory. Exiting.");
++  exit(1);
++}
++
+ int main(int argc, char *argv[])
+ {
+     DIR *procdir_id;
+@@ -75,15 +94,21 @@ int main(int argc, char *argv[])
+ 
+     /* Options */
+     config_file = strdup(DEFAULT_CONFIG);
++    if (!config_file)
++      oom_failure();
++
+     list_only = 0;
+ 
+     for(i = 0; i < argc; i++) {
+         if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")) {
+             config_file = strdup(argv[i + 1]);
++	    if (!config_file)
++	      oom_failure();
+         }
+         if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
+             printf("restard %s - Copyright 2000-2002 Tibor Koleszar <oldw <at> debian.org>\n"
+-                   "                Copyright 2006 Aurélien GÉRÔME <ag <at> roxor.cx>\n",
++                   "                Copyright 2006 Aurélien GÉRÔME <ag <at> roxor.cx>\n"
++                   "                Copyright 2022 Maxime Devos <maximedevos <at> telenet.be>\n",
+                    VERSION);
+             exit(0);
+         }
+@@ -118,10 +143,13 @@ int main(int argc, char *argv[])
+                     "  -i <interval_sec>: the check interval in second\n"
+                     "  -l               : list configuration options\n"
+                     "  -h               : help\n\n", VERSION);
++	    exit(0);
+         }
+     }
+ 
+     config_process = malloc(sizeof(struct config_process_type) * 128);
++    if (!config_process)
++      oom_failure();
+   
+     read_config();
+     if (list_only) {
+@@ -133,9 +161,17 @@ int main(int argc, char *argv[])
+            config_process_number);
+   
+     procdir_dirent = malloc(sizeof(struct dirent));
++    if (!procdir_dirent)
++      oom_failure();
+     proc_cmdline_str = (char *) malloc(1024);
++    if (!proc_cmdline_str)
++      oom_failure();
+     proc_cmdline_name = (char *) malloc(1024);
++    if (!proc_cmdline_name)
++      oom_failure();
+     regc = malloc(1024);
++    if (!regc)
++      oom_failure();
+   
+     /* Catch signals */
+     signal(SIGTERM, got_signal);
+@@ -187,8 +223,19 @@ int main(int argc, char *argv[])
+         }
+ 
+         out_proc = fopen("/var/run/restartd.pid", "wt");
+-        fprintf(out_proc, "%d", getpid());
+-        fclose(out_proc);
++	if (!out_proc) {
++		syslog(LOG_ERR, "Failed to open /var/run/restartd.pid");
++		return -1;
++	}
++        if (fprintf(out_proc, "%d", getpid()) < 0) {
++          syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting.");
++          return -1;
++        }
++        if (fclose(out_proc) < 0) { /* errors can happen when flushing the buffer */
++          syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting.");
++          return -1;
++        }
++
+ 
+         while(1) {
+             if ((procdir_id = opendir("/proc")) == NULL) {
+@@ -237,16 +284,23 @@ int main(int argc, char *argv[])
+            now = time(NULL);
+ 
+            out_proc = fopen("/var/run/restartd", "wt");
++           if (!out_proc) {
++             syslog(LOG_ERR, "Failed to open /var/run/restartd.pid");
++             return -1;
++           }
+ 
+-           fprintf(out_proc, "%s\n", ctime(&now));
++           if (fprintf(out_proc, "%s\n", ctime(&now)) < 0) {
++             syslog(LOG_ERR, "Failed to write to /var/run/restartd. Exiting.");
++             return -1;
++           }
+ 
+            for(i=0; i<config_process_number; i++) {
+                if (strlen(config_process[i].processes) > 0) {
+                    if (strlen(config_process[i].running) > 0) {
+                        strcpy(config_process[i].status, "running");
+-                       syslog(LOG_INFO, "%s is running, executing '%s'",
++                       /* syslog(LOG_INFO, "%s is running, executing '%s'",
+                               config_process[i].name,
+-                              config_process[i].running);
++                              config_process[i].running); */
+                        system(config_process[i].running);
+                     } else {
+                         strcpy(config_process[i].status, "running");
+@@ -267,12 +321,18 @@ int main(int argc, char *argv[])
+                     strcpy(config_process[i].status, "not running");
+                 }
+ 
+-                fprintf(out_proc, "%-12s %-12s      %s\n",
+-                        config_process[i].name, config_process[i].status,
+-                        config_process[i].processes);
++                if (fprintf(out_proc, "%-12s %-12s      %s\n",
++                            config_process[i].name, config_process[i].status,
++                            config_process[i].processes) < 0) {
++                  syslog(LOG_ERR, "Failed to write to /var/run/restartd. Exiting.");
++                  return -1;
++                }
+             }
+ 
+-            fclose(out_proc);
++            if (fclose(out_proc) < 0) {
++              syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting.");
++              return -1;
++            }
+ 
+             sleep(check_interval);
+         }
+-- 
+2.37.3
+

-- 
Best regards,
Nicolas Graves




Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Sat, 03 Feb 2024 13:38:02 GMT) Full text and rfc822 format available.

Message #62 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Nicolas Graves <ngraves <at> ngraves.fr>
To: 57387 <at> debbugs.gnu.org
Cc: maximedevos <at> telenet.be, ngraves <at> ngraves.fr, othacehe <at> gnu.org
Subject: [PATCH v2] gnu: Add restartd.
Date: Sat,  3 Feb 2024 14:36:01 +0100
* gnu/packages/admin.scm (restartd): New variable.
---
 gnu/packages/admin.scm                        |  51 +++
 .../patches/restartd-update-robust.patch      | 295 ++++++++++++++++++
 2 files changed, 346 insertions(+)
 create mode 100644 gnu/packages/patches/restartd-update-robust.patch

diff --git a/gnu/packages/admin.scm b/gnu/packages/admin.scm
index fcf05992d8..6940638c75 100644
--- a/gnu/packages/admin.scm
+++ b/gnu/packages/admin.scm
@@ -62,6 +62,7 @@
 ;;; Copyright © 2023 Bruno Victal <mirai <at> makinata.eu>
 ;;; Copyright © 2023 Tobias Kortkamp <tobias.kortkamp <at> gmail.com>
 ;;; Copyright © 2023 Jaeme Sifat <jaeme <at> runbox.com>
+;;; Copyright © 2023 Nicolas Graves <ngraves <at> ngraves.fr>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -5814,6 +5815,56 @@ (define-public fail2ban
 mechanisms if you really want to protect services.")
     (license license:gpl2+)))
 
+(define-public restartd
+  (let* ((commit "7044125ac55056f2663536f7137170edf92ebd75")
+         ;; Version is 0.2.4 in the version file in the repo
+         ;; but not in github tags.
+         ;; It is released as 0.2.3-1.1 for other distributions.
+         ;; Probably because of the lack of activity upstream.
+         (revision "1"))
+    (package
+      (name "restartd")
+      (version (git-version "0.2.3" revision commit))
+      (source
+       (origin
+         (method git-fetch)
+         (uri (git-reference
+               (url "https://github.com/ajraymond/restartd")
+               (commit commit)))
+         (file-name (git-file-name name version))
+         (sha256
+          (base32
+           "1m1np00b4zvvwx63gzysbi38i5vj1jsjvh2s0p9czl6dzyz582z0"))
+         (patches (search-patches "restartd-update-robust.patch"))))
+      (build-system gnu-build-system)
+      (arguments
+       (list
+        #:tests? #f ; no tests
+        #:make-flags
+        #~(list (string-append "CC=" #$(cc-for-target)))
+        #:phases
+        #~(modify-phases %standard-phases
+            (delete  'configure)
+            (replace 'install
+              (lambda _
+                (install-file "restartd.conf" (string-append #$output "/etc"))
+                (install-file "restartd" (string-append #$output "/sbin"))
+                (install-file "restartd.8"
+                              (string-append #$output "/share/man/man8"))
+                (mkdir-p (string-append #$output "/share/man/fr/man8"))
+                (copy-file
+                 "restartd.fr.8"
+                 (string-append #$output "/share/man/fr/man8/restartd.8")))))))
+      (home-page "https://launchpad.net/debian/+source/restartd")
+      (synopsis "Daemon for restarting processes")
+      (description "This package provides a daemon for checking running and not
+running processes.  It reads the /proc directory every n seconds and does a
+POSIX regexp on the process names.  The daemon runs an user-provided script
+when it detects a program in the running processes, or an alternate script if
+it doesn't detect the program.  The daemon can only be called by the root
+user, but can use @code{sudo -u user} in the process called if needed.")
+      (license license:gpl2+))))
+
 (define-public rex
   (package
     (name "rex")
diff --git a/gnu/packages/patches/restartd-update-robust.patch b/gnu/packages/patches/restartd-update-robust.patch
new file mode 100644
index 0000000000..d279ebd8ff
--- /dev/null
+++ b/gnu/packages/patches/restartd-update-robust.patch
@@ -0,0 +1,295 @@
+From 01cd2d15a9bf1109e0e71b3e31b835d63dcf9cd8 Mon Sep 17 00:00:00 2001
+From: Maxime Devos <maximedevos <at> telenet.be>, Yin Kangkai <yinkangkai <at> xiaomi.com>, Sudip Mukherjee <sudipm.mukherjee <at> gmail.com>
+Subject: [PATCH]
+
+Fix segfault when run as normal user
+
+Also exit immediately when "restartd -h"
+Signed-off-by: Yin Kangkai <yinkangkai <at> xiaomi.com>
+
+Fix build with gcc-10
+
+Bug: https://bugs.debian.org/957761
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee <at> gmail.com>
+
+Handle memory allocation failures.
+
+This makes the code a little more robust.
+Signed-off-by: Maxime Devos <maximedevos <at> telenet.be>
+
+Handle fopen failures.
+
+This makes the code a little more robust. What if /var/run does not
+exist, or we do not have permission to open
+/var/run/restartd.pid (EPERM?) due to SELinux misconfiguration?
+Signed-off-by: Maxime Devos <maximedevos <at> telenet.be>
+
+Handle printf and fprintf failures.
+
+This makes the code a little more robust. What if the write was
+refused to the underlying device being removed?
+
+The --help, debug and stderr printfs were ignored because there error
+handling does not appear important to me.
+Signed-off-by: Maxime Devos <maximedevos <at> telenet.be>
+
+Handle fclose failures when writing.
+
+This makes the code a little more robust. What if a quotum is exceeded?
+Signed-off-by: Maxime Devos <maximedevos <at> telenet.be>
+---
+ config.c   | 19 +++++++++----
+ config.h   | 14 ++++++----
+ restartd.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++-------
+ 3 files changed, 92 insertions(+), 21 deletions(-)
+
+diff --git a/config.c b/config.c
+index f307b8a..5cc0271 100644
+--- a/config.c
++++ b/config.c
+@@ -57,7 +57,11 @@ int read_config(void)
+     config_process_number = 0;
+ 
+     line1 = (char *) malloc(MAX_LINE_LENGTH);
++    if (!line1)
++      oom_failure();
+     line2 = (char *) malloc(MAX_LINE_LENGTH);
++    if (!line2)
++      oom_failure();
+ 
+     if ((config_fd = fopen(config_file, "rt")) == NULL) {
+         fprintf(stderr, "Error at opening config file: %s\n", config_file);
+@@ -155,11 +159,16 @@ void dump_config(void) {
+     int i;
+ 
+     for(i=0; i<config_process_number; i++) {
+-        printf("ID=%d\n  name=%s\n  regexp=%s\n  running=%s\n  not_running=%s\n", i,
+-            config_process[i].name,
+-            config_process[i].regexp,
+-            config_process[i].running,
+-            config_process[i].not_running);
++      if (printf("ID=%d\n  name=%s\n  regexp=%s\n  running=%s\n  not_running=%s\n", i,
++                 config_process[i].name,
++                 config_process[i].regexp,
++                 config_process[i].running,
++                 config_process[i].not_running) < 0) {
++        /* Maybe stdout points to a file and a file system quotum was exceeded? */
++        fprintf(stderr, "Failed to dump the configuration. Exiting.\n");
++        syslog(LOG_ERR, "Failed to dump the configuration. Exiting.");
++        exit(1);
++      }
+     }
+ 
+ }
+diff --git a/config.h b/config.h
+index fabaa2b..2ba1cbe 100644
+--- a/config.h
++++ b/config.h
+@@ -1,6 +1,7 @@
+ /* restartd - Process checker and/or restarter daemon
+  * Copyright (C) 2000-2002 Tibor Koleszar <oldw <at> debian.org>
+  * Copyright (C) 2006 Aurélien GÉRÔME <ag <at> roxor.cx>
++ * Copyright (C) 2022 Maxime Devos <maximedevos <at> telenet.be>
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+@@ -25,12 +26,12 @@
+ 
+ #define DEFAULT_CONFIG "/etc/restartd.conf"
+ 
+-int debug;
+-int config_process_number;
+-int check_interval;
+-int foreground;
+-struct config_process_type *config_process;
+-char *config_file;
++extern int debug;
++extern int config_process_number;
++extern int check_interval;
++extern int foreground;
++extern struct config_process_type *config_process;
++extern char *config_file;
+ 
+ typedef struct config_process_type {
+   char name[64];
+@@ -43,5 +44,6 @@ typedef struct config_process_type {
+ 
+ int read_config(/* char *config_file */);
+ void dump_config(void);
++void oom_failure(void);
+ 
+ #endif /* RESTARTD_CONFIG_H */
+diff --git a/restartd.c b/restartd.c
+index 2aa720c..aa74334 100644
+--- a/restartd.c
++++ b/restartd.c
+@@ -1,6 +1,7 @@
+ /* restartd - Process checker and/or restarter daemon
+  * Copyright (C) 2000-2002 Tibor Koleszar <oldw <at> debian.org>
+  * Copyright (C) 2006 Aurélien GÉRÔME <ag <at> roxor.cx>
++ * Copyright (C) 2022 Maxime Devos <maximedevos <at> telenet.be>
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+@@ -35,6 +36,13 @@
+ 
+ #include "config.h"
+ 
++int debug;
++int config_process_number;
++int check_interval;
++int foreground;
++struct config_process_type *config_process;
++char *config_file;
++
+ /* SIGTERM & SIGHUP handler */
+ void got_signal(int sig)
+ {
+@@ -52,6 +60,17 @@ void got_signal(int sig)
+     }
+ }
+ 
++/* Ignoring out-of-memory failures is risky on systems without virtual memory
++   where additionally at address 0 there is actually something important
++   mapped. Additionally, while often on Linux the OOM killer will kill processes
++   where an OOM happens, this is not always the case and there exist other systems
++   without an OOM killer (e.g. the Hurd). */
++void oom_failure()
++{
++  syslog(LOG_ERR, "Failed to allocate memory. Exiting.");
++  exit(1);
++}
++
+ int main(int argc, char *argv[])
+ {
+     DIR *procdir_id;
+@@ -75,15 +94,21 @@ int main(int argc, char *argv[])
+ 
+     /* Options */
+     config_file = strdup(DEFAULT_CONFIG);
++    if (!config_file)
++      oom_failure();
++
+     list_only = 0;
+ 
+     for(i = 0; i < argc; i++) {
+         if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")) {
+             config_file = strdup(argv[i + 1]);
++	    if (!config_file)
++	      oom_failure();
+         }
+         if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
+             printf("restard %s - Copyright 2000-2002 Tibor Koleszar <oldw <at> debian.org>\n"
+-                   "                Copyright 2006 Aurélien GÉRÔME <ag <at> roxor.cx>\n",
++                   "                Copyright 2006 Aurélien GÉRÔME <ag <at> roxor.cx>\n"
++                   "                Copyright 2022 Maxime Devos <maximedevos <at> telenet.be>\n",
+                    VERSION);
+             exit(0);
+         }
+@@ -118,10 +143,13 @@ int main(int argc, char *argv[])
+                     "  -i <interval_sec>: the check interval in second\n"
+                     "  -l               : list configuration options\n"
+                     "  -h               : help\n\n", VERSION);
++	    exit(0);
+         }
+     }
+ 
+     config_process = malloc(sizeof(struct config_process_type) * 128);
++    if (!config_process)
++      oom_failure();
+   
+     read_config();
+     if (list_only) {
+@@ -133,9 +161,17 @@ int main(int argc, char *argv[])
+            config_process_number);
+   
+     procdir_dirent = malloc(sizeof(struct dirent));
++    if (!procdir_dirent)
++      oom_failure();
+     proc_cmdline_str = (char *) malloc(1024);
++    if (!proc_cmdline_str)
++      oom_failure();
+     proc_cmdline_name = (char *) malloc(1024);
++    if (!proc_cmdline_name)
++      oom_failure();
+     regc = malloc(1024);
++    if (!regc)
++      oom_failure();
+   
+     /* Catch signals */
+     signal(SIGTERM, got_signal);
+@@ -187,8 +223,19 @@ int main(int argc, char *argv[])
+         }
+ 
+         out_proc = fopen("/var/run/restartd.pid", "wt");
+-        fprintf(out_proc, "%d", getpid());
+-        fclose(out_proc);
++	if (!out_proc) {
++		syslog(LOG_ERR, "Failed to open /var/run/restartd.pid");
++		return -1;
++	}
++        if (fprintf(out_proc, "%d", getpid()) < 0) {
++          syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting.");
++          return -1;
++        }
++        if (fclose(out_proc) < 0) { /* errors can happen when flushing the buffer */
++          syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting.");
++          return -1;
++        }
++
+ 
+         while(1) {
+             if ((procdir_id = opendir("/proc")) == NULL) {
+@@ -237,16 +284,23 @@ int main(int argc, char *argv[])
+            now = time(NULL);
+ 
+            out_proc = fopen("/var/run/restartd", "wt");
++           if (!out_proc) {
++             syslog(LOG_ERR, "Failed to open /var/run/restartd.pid");
++             return -1;
++           }
+ 
+-           fprintf(out_proc, "%s\n", ctime(&now));
++           if (fprintf(out_proc, "%s\n", ctime(&now)) < 0) {
++             syslog(LOG_ERR, "Failed to write to /var/run/restartd. Exiting.");
++             return -1;
++           }
+ 
+            for(i=0; i<config_process_number; i++) {
+                if (strlen(config_process[i].processes) > 0) {
+                    if (strlen(config_process[i].running) > 0) {
+                        strcpy(config_process[i].status, "running");
+-                       syslog(LOG_INFO, "%s is running, executing '%s'",
++                       /* syslog(LOG_INFO, "%s is running, executing '%s'",
+                               config_process[i].name,
+-                              config_process[i].running);
++                              config_process[i].running); */
+                        system(config_process[i].running);
+                     } else {
+                         strcpy(config_process[i].status, "running");
+@@ -267,12 +321,18 @@ int main(int argc, char *argv[])
+                     strcpy(config_process[i].status, "not running");
+                 }
+ 
+-                fprintf(out_proc, "%-12s %-12s      %s\n",
+-                        config_process[i].name, config_process[i].status,
+-                        config_process[i].processes);
++                if (fprintf(out_proc, "%-12s %-12s      %s\n",
++                            config_process[i].name, config_process[i].status,
++                            config_process[i].processes) < 0) {
++                  syslog(LOG_ERR, "Failed to write to /var/run/restartd. Exiting.");
++                  return -1;
++                }
+             }
+ 
+-            fclose(out_proc);
++            if (fclose(out_proc) < 0) {
++              syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting.");
++              return -1;
++            }
+ 
+             sleep(check_interval);
+         }
+-- 
+2.37.3
+
-- 
2.41.0





Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Sat, 03 Feb 2024 14:07:01 GMT) Full text and rfc822 format available.

Message #65 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Nicolas Graves <ngraves <at> ngraves.fr>
To: 57387 <at> debbugs.gnu.org
Cc: maximedevos <at> telenet.be, ngraves <at> ngraves.fr, othacehe <at> gnu.org
Subject: [PATCH v3] gnu: Add restartd.
Date: Sat,  3 Feb 2024 15:06:17 +0100
* gnu/packages/admin.scm (restartd): New variable.
* gnu/packages/patches/restartd-update-robust.patch: Add file.
* gnu/local.mk: Register gnu/packages/patches/restartd-update-robust.patch.

Change-Id: I38b9b70e97b64f006a86d7618a75f1ec3ed8b034
---
 gnu/local.mk                                  |   1 +
 gnu/packages/admin.scm                        |  51 +++
 .../patches/restartd-update-robust.patch      | 295 ++++++++++++++++++
 3 files changed, 347 insertions(+)
 create mode 100644 gnu/packages/patches/restartd-update-robust.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index fbdb285695..6e4c3b277b 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1981,6 +1981,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/racket-rktio-bin-sh.patch		\
   %D%/packages/patches/racket-zuo-bin-sh.patch			\
   %D%/packages/patches/remake-impure-dirs.patch			\
+  %D%/packages/patches/restartd-update-robust.patch             \
   %D%/packages/patches/restic-0.9.6-fix-tests-for-go1.15.patch	\
   %D%/packages/patches/rng-tools-revert-build-randstat.patch	\
   %D%/packages/patches/rocclr-5.6.0-enable-gfx800.patch		\
diff --git a/gnu/packages/admin.scm b/gnu/packages/admin.scm
index fcf05992d8..6940638c75 100644
--- a/gnu/packages/admin.scm
+++ b/gnu/packages/admin.scm
@@ -62,6 +62,7 @@
 ;;; Copyright © 2023 Bruno Victal <mirai <at> makinata.eu>
 ;;; Copyright © 2023 Tobias Kortkamp <tobias.kortkamp <at> gmail.com>
 ;;; Copyright © 2023 Jaeme Sifat <jaeme <at> runbox.com>
+;;; Copyright © 2023 Nicolas Graves <ngraves <at> ngraves.fr>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -5814,6 +5815,56 @@ (define-public fail2ban
 mechanisms if you really want to protect services.")
     (license license:gpl2+)))
 
+(define-public restartd
+  (let* ((commit "7044125ac55056f2663536f7137170edf92ebd75")
+         ;; Version is 0.2.4 in the version file in the repo
+         ;; but not in github tags.
+         ;; It is released as 0.2.3-1.1 for other distributions.
+         ;; Probably because of the lack of activity upstream.
+         (revision "1"))
+    (package
+      (name "restartd")
+      (version (git-version "0.2.3" revision commit))
+      (source
+       (origin
+         (method git-fetch)
+         (uri (git-reference
+               (url "https://github.com/ajraymond/restartd")
+               (commit commit)))
+         (file-name (git-file-name name version))
+         (sha256
+          (base32
+           "1m1np00b4zvvwx63gzysbi38i5vj1jsjvh2s0p9czl6dzyz582z0"))
+         (patches (search-patches "restartd-update-robust.patch"))))
+      (build-system gnu-build-system)
+      (arguments
+       (list
+        #:tests? #f ; no tests
+        #:make-flags
+        #~(list (string-append "CC=" #$(cc-for-target)))
+        #:phases
+        #~(modify-phases %standard-phases
+            (delete  'configure)
+            (replace 'install
+              (lambda _
+                (install-file "restartd.conf" (string-append #$output "/etc"))
+                (install-file "restartd" (string-append #$output "/sbin"))
+                (install-file "restartd.8"
+                              (string-append #$output "/share/man/man8"))
+                (mkdir-p (string-append #$output "/share/man/fr/man8"))
+                (copy-file
+                 "restartd.fr.8"
+                 (string-append #$output "/share/man/fr/man8/restartd.8")))))))
+      (home-page "https://launchpad.net/debian/+source/restartd")
+      (synopsis "Daemon for restarting processes")
+      (description "This package provides a daemon for checking running and not
+running processes.  It reads the /proc directory every n seconds and does a
+POSIX regexp on the process names.  The daemon runs an user-provided script
+when it detects a program in the running processes, or an alternate script if
+it doesn't detect the program.  The daemon can only be called by the root
+user, but can use @code{sudo -u user} in the process called if needed.")
+      (license license:gpl2+))))
+
 (define-public rex
   (package
     (name "rex")
diff --git a/gnu/packages/patches/restartd-update-robust.patch b/gnu/packages/patches/restartd-update-robust.patch
new file mode 100644
index 0000000000..d279ebd8ff
--- /dev/null
+++ b/gnu/packages/patches/restartd-update-robust.patch
@@ -0,0 +1,295 @@
+From 01cd2d15a9bf1109e0e71b3e31b835d63dcf9cd8 Mon Sep 17 00:00:00 2001
+From: Maxime Devos <maximedevos <at> telenet.be>, Yin Kangkai <yinkangkai <at> xiaomi.com>, Sudip Mukherjee <sudipm.mukherjee <at> gmail.com>
+Subject: [PATCH]
+
+Fix segfault when run as normal user
+
+Also exit immediately when "restartd -h"
+Signed-off-by: Yin Kangkai <yinkangkai <at> xiaomi.com>
+
+Fix build with gcc-10
+
+Bug: https://bugs.debian.org/957761
+Signed-off-by: Sudip Mukherjee <sudipm.mukherjee <at> gmail.com>
+
+Handle memory allocation failures.
+
+This makes the code a little more robust.
+Signed-off-by: Maxime Devos <maximedevos <at> telenet.be>
+
+Handle fopen failures.
+
+This makes the code a little more robust. What if /var/run does not
+exist, or we do not have permission to open
+/var/run/restartd.pid (EPERM?) due to SELinux misconfiguration?
+Signed-off-by: Maxime Devos <maximedevos <at> telenet.be>
+
+Handle printf and fprintf failures.
+
+This makes the code a little more robust. What if the write was
+refused to the underlying device being removed?
+
+The --help, debug and stderr printfs were ignored because there error
+handling does not appear important to me.
+Signed-off-by: Maxime Devos <maximedevos <at> telenet.be>
+
+Handle fclose failures when writing.
+
+This makes the code a little more robust. What if a quotum is exceeded?
+Signed-off-by: Maxime Devos <maximedevos <at> telenet.be>
+---
+ config.c   | 19 +++++++++----
+ config.h   | 14 ++++++----
+ restartd.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++-------
+ 3 files changed, 92 insertions(+), 21 deletions(-)
+
+diff --git a/config.c b/config.c
+index f307b8a..5cc0271 100644
+--- a/config.c
++++ b/config.c
+@@ -57,7 +57,11 @@ int read_config(void)
+     config_process_number = 0;
+ 
+     line1 = (char *) malloc(MAX_LINE_LENGTH);
++    if (!line1)
++      oom_failure();
+     line2 = (char *) malloc(MAX_LINE_LENGTH);
++    if (!line2)
++      oom_failure();
+ 
+     if ((config_fd = fopen(config_file, "rt")) == NULL) {
+         fprintf(stderr, "Error at opening config file: %s\n", config_file);
+@@ -155,11 +159,16 @@ void dump_config(void) {
+     int i;
+ 
+     for(i=0; i<config_process_number; i++) {
+-        printf("ID=%d\n  name=%s\n  regexp=%s\n  running=%s\n  not_running=%s\n", i,
+-            config_process[i].name,
+-            config_process[i].regexp,
+-            config_process[i].running,
+-            config_process[i].not_running);
++      if (printf("ID=%d\n  name=%s\n  regexp=%s\n  running=%s\n  not_running=%s\n", i,
++                 config_process[i].name,
++                 config_process[i].regexp,
++                 config_process[i].running,
++                 config_process[i].not_running) < 0) {
++        /* Maybe stdout points to a file and a file system quotum was exceeded? */
++        fprintf(stderr, "Failed to dump the configuration. Exiting.\n");
++        syslog(LOG_ERR, "Failed to dump the configuration. Exiting.");
++        exit(1);
++      }
+     }
+ 
+ }
+diff --git a/config.h b/config.h
+index fabaa2b..2ba1cbe 100644
+--- a/config.h
++++ b/config.h
+@@ -1,6 +1,7 @@
+ /* restartd - Process checker and/or restarter daemon
+  * Copyright (C) 2000-2002 Tibor Koleszar <oldw <at> debian.org>
+  * Copyright (C) 2006 Aurélien GÉRÔME <ag <at> roxor.cx>
++ * Copyright (C) 2022 Maxime Devos <maximedevos <at> telenet.be>
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+@@ -25,12 +26,12 @@
+ 
+ #define DEFAULT_CONFIG "/etc/restartd.conf"
+ 
+-int debug;
+-int config_process_number;
+-int check_interval;
+-int foreground;
+-struct config_process_type *config_process;
+-char *config_file;
++extern int debug;
++extern int config_process_number;
++extern int check_interval;
++extern int foreground;
++extern struct config_process_type *config_process;
++extern char *config_file;
+ 
+ typedef struct config_process_type {
+   char name[64];
+@@ -43,5 +44,6 @@ typedef struct config_process_type {
+ 
+ int read_config(/* char *config_file */);
+ void dump_config(void);
++void oom_failure(void);
+ 
+ #endif /* RESTARTD_CONFIG_H */
+diff --git a/restartd.c b/restartd.c
+index 2aa720c..aa74334 100644
+--- a/restartd.c
++++ b/restartd.c
+@@ -1,6 +1,7 @@
+ /* restartd - Process checker and/or restarter daemon
+  * Copyright (C) 2000-2002 Tibor Koleszar <oldw <at> debian.org>
+  * Copyright (C) 2006 Aurélien GÉRÔME <ag <at> roxor.cx>
++ * Copyright (C) 2022 Maxime Devos <maximedevos <at> telenet.be>
+  *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public License
+@@ -35,6 +36,13 @@
+ 
+ #include "config.h"
+ 
++int debug;
++int config_process_number;
++int check_interval;
++int foreground;
++struct config_process_type *config_process;
++char *config_file;
++
+ /* SIGTERM & SIGHUP handler */
+ void got_signal(int sig)
+ {
+@@ -52,6 +60,17 @@ void got_signal(int sig)
+     }
+ }
+ 
++/* Ignoring out-of-memory failures is risky on systems without virtual memory
++   where additionally at address 0 there is actually something important
++   mapped. Additionally, while often on Linux the OOM killer will kill processes
++   where an OOM happens, this is not always the case and there exist other systems
++   without an OOM killer (e.g. the Hurd). */
++void oom_failure()
++{
++  syslog(LOG_ERR, "Failed to allocate memory. Exiting.");
++  exit(1);
++}
++
+ int main(int argc, char *argv[])
+ {
+     DIR *procdir_id;
+@@ -75,15 +94,21 @@ int main(int argc, char *argv[])
+ 
+     /* Options */
+     config_file = strdup(DEFAULT_CONFIG);
++    if (!config_file)
++      oom_failure();
++
+     list_only = 0;
+ 
+     for(i = 0; i < argc; i++) {
+         if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")) {
+             config_file = strdup(argv[i + 1]);
++	    if (!config_file)
++	      oom_failure();
+         }
+         if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
+             printf("restard %s - Copyright 2000-2002 Tibor Koleszar <oldw <at> debian.org>\n"
+-                   "                Copyright 2006 Aurélien GÉRÔME <ag <at> roxor.cx>\n",
++                   "                Copyright 2006 Aurélien GÉRÔME <ag <at> roxor.cx>\n"
++                   "                Copyright 2022 Maxime Devos <maximedevos <at> telenet.be>\n",
+                    VERSION);
+             exit(0);
+         }
+@@ -118,10 +143,13 @@ int main(int argc, char *argv[])
+                     "  -i <interval_sec>: the check interval in second\n"
+                     "  -l               : list configuration options\n"
+                     "  -h               : help\n\n", VERSION);
++	    exit(0);
+         }
+     }
+ 
+     config_process = malloc(sizeof(struct config_process_type) * 128);
++    if (!config_process)
++      oom_failure();
+   
+     read_config();
+     if (list_only) {
+@@ -133,9 +161,17 @@ int main(int argc, char *argv[])
+            config_process_number);
+   
+     procdir_dirent = malloc(sizeof(struct dirent));
++    if (!procdir_dirent)
++      oom_failure();
+     proc_cmdline_str = (char *) malloc(1024);
++    if (!proc_cmdline_str)
++      oom_failure();
+     proc_cmdline_name = (char *) malloc(1024);
++    if (!proc_cmdline_name)
++      oom_failure();
+     regc = malloc(1024);
++    if (!regc)
++      oom_failure();
+   
+     /* Catch signals */
+     signal(SIGTERM, got_signal);
+@@ -187,8 +223,19 @@ int main(int argc, char *argv[])
+         }
+ 
+         out_proc = fopen("/var/run/restartd.pid", "wt");
+-        fprintf(out_proc, "%d", getpid());
+-        fclose(out_proc);
++	if (!out_proc) {
++		syslog(LOG_ERR, "Failed to open /var/run/restartd.pid");
++		return -1;
++	}
++        if (fprintf(out_proc, "%d", getpid()) < 0) {
++          syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting.");
++          return -1;
++        }
++        if (fclose(out_proc) < 0) { /* errors can happen when flushing the buffer */
++          syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting.");
++          return -1;
++        }
++
+ 
+         while(1) {
+             if ((procdir_id = opendir("/proc")) == NULL) {
+@@ -237,16 +284,23 @@ int main(int argc, char *argv[])
+            now = time(NULL);
+ 
+            out_proc = fopen("/var/run/restartd", "wt");
++           if (!out_proc) {
++             syslog(LOG_ERR, "Failed to open /var/run/restartd.pid");
++             return -1;
++           }
+ 
+-           fprintf(out_proc, "%s\n", ctime(&now));
++           if (fprintf(out_proc, "%s\n", ctime(&now)) < 0) {
++             syslog(LOG_ERR, "Failed to write to /var/run/restartd. Exiting.");
++             return -1;
++           }
+ 
+            for(i=0; i<config_process_number; i++) {
+                if (strlen(config_process[i].processes) > 0) {
+                    if (strlen(config_process[i].running) > 0) {
+                        strcpy(config_process[i].status, "running");
+-                       syslog(LOG_INFO, "%s is running, executing '%s'",
++                       /* syslog(LOG_INFO, "%s is running, executing '%s'",
+                               config_process[i].name,
+-                              config_process[i].running);
++                              config_process[i].running); */
+                        system(config_process[i].running);
+                     } else {
+                         strcpy(config_process[i].status, "running");
+@@ -267,12 +321,18 @@ int main(int argc, char *argv[])
+                     strcpy(config_process[i].status, "not running");
+                 }
+ 
+-                fprintf(out_proc, "%-12s %-12s      %s\n",
+-                        config_process[i].name, config_process[i].status,
+-                        config_process[i].processes);
++                if (fprintf(out_proc, "%-12s %-12s      %s\n",
++                            config_process[i].name, config_process[i].status,
++                            config_process[i].processes) < 0) {
++                  syslog(LOG_ERR, "Failed to write to /var/run/restartd. Exiting.");
++                  return -1;
++                }
+             }
+ 
+-            fclose(out_proc);
++            if (fclose(out_proc) < 0) {
++              syslog(LOG_ERR, "Failed to write to /var/run/restartd.pid. Exiting.");
++              return -1;
++            }
+ 
+             sleep(check_interval);
+         }
+-- 
+2.37.3
+
-- 
2.41.0





Information forwarded to guix-patches <at> gnu.org:
bug#57387; Package guix-patches. (Sat, 03 Feb 2024 14:08:02 GMT) Full text and rfc822 format available.

Message #68 received at 57387 <at> debbugs.gnu.org (full text, mbox):

From: Nicolas Graves <ngraves <at> ngraves.fr>
To: Mathieu Othacehe <othacehe <at> gnu.org>
Cc: 57387 <at> debbugs.gnu.org
Subject: Re: [bug#57387] [PATCH] gnu: Add restartd.
Date: Sat, 03 Feb 2024 15:07:35 +0100
Hi Mathieu,

Done in a rebased v3, you can ignore the v2. Sorry for the time it took.

Nicolas

On 2022-09-14 09:48, Mathieu Othacehe wrote:

> Hello Nicolas,
>
>>  ...td-add-error-handling-for-robustness.patch | 242 ++++++++++++++++++
>>  .../patches/restartd-fix-compilation.patch    |  53 ++++
>
> Both patches also need to be added to the dist_patch_DATA variable of
> gnu/local.mk.
>
> Thanks,
>
> Mathieu
>
>
>

-- 
Best regards,
Nicolas Graves




Reply sent to Ludovic Courtès <ludo <at> gnu.org>:
You have taken responsibility. (Sun, 18 Feb 2024 14:56:01 GMT) Full text and rfc822 format available.

Notification sent to Nicolas Graves <ngraves <at> ngraves.fr>:
bug acknowledged by developer. (Sun, 18 Feb 2024 14:56:02 GMT) Full text and rfc822 format available.

Message #73 received at 57387-done <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Nicolas Graves <ngraves <at> ngraves.fr>
Cc: othacehe <at> gnu.org, 57387-done <at> debbugs.gnu.org
Subject: Re: [bug#57387] [PATCH v3] gnu: Add restartd.
Date: Sun, 18 Feb 2024 15:54:51 +0100
[Message part 1 (text/plain, inline)]
Nicolas Graves <ngraves <at> ngraves.fr> skribis:

> * gnu/packages/admin.scm (restartd): New variable.
> * gnu/packages/patches/restartd-update-robust.patch: Add file.
> * gnu/local.mk: Register gnu/packages/patches/restartd-update-robust.patch.
>
> Change-Id: I38b9b70e97b64f006a86d7618a75f1ec3ed8b034

Applied with the changes below, thanks!

Ludo’.

[Message part 2 (text/x-patch, inline)]
diff --git a/gnu/packages/admin.scm b/gnu/packages/admin.scm
index 9f51427297..47c82e9678 100644
--- a/gnu/packages/admin.scm
+++ b/gnu/packages/admin.scm
@@ -5886,12 +5886,13 @@ (define-public restartd
                  (string-append #$output "/share/man/fr/man8/restartd.8")))))))
       (home-page "https://launchpad.net/debian/+source/restartd")
       (synopsis "Daemon for restarting processes")
-      (description "This package provides a daemon for checking running and not
-running processes.  It reads the /proc directory every n seconds and does a
-POSIX regexp on the process names.  The daemon runs an user-provided script
-when it detects a program in the running processes, or an alternate script if
-it doesn't detect the program.  The daemon can only be called by the root
-user, but can use @code{sudo -u user} in the process called if needed.")
+      (description "This package provides a daemon for checking running and
+not running processes.  It reads the @file{/proc} directory every @var{n}
+seconds and does a POSIX regexp on the process names.  The daemon runs a
+user-provided script when it detects a program in the running processes, or an
+alternate script if it doesn't detect the program.  The daemon can only be
+called by the root user, but can use @command{sudo -u user} in the process
+called if needed.")
       (license license:gpl2+))))
 
 (define-public rex

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Mon, 18 Mar 2024 11:24:13 GMT) Full text and rfc822 format available.

This bug report was last modified 1 year and 90 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.