Re: rsync exit code and error cleanup

2021-05-14 Thread Sebastian Benoit
Claudio Jeker(cje...@diehard.n-r-g.com) on 2021.05.07 12:16:26 +0200:
> Currently our rsync does not follow the exit codes from rsync. Also the
> error handling is complex because ERR() and ERRX() are not terminating the
> process.
> 
> This diff tries to start cleaning up the mess a bit. Introduce some exit
> codes to use and apply them in places where it is obvious.
> 
> The rsync server process should normally communicate errors back via the
> rsync socket but there are some errors where this will most probably fail
> as well. A good example are memory failures.
> 
> I used ERR_IPC as a kind of catchall for any system error that pops up
> (fork, socketpair but also pledge, unveil).
> 
> The goal is to reduce the amount of ERR(), ERRX() and ERRX1() from rsync.
> This should simplify the code base.
> 
> I also synced the mkpath() call with the one from mkdir and handle the
> error now outside of the call. Again I think the result is cleaner.
> 
> OK?

ok benno

> -- 
> :wq Claudio
> 
> Index: client.c
> ===
> RCS file: /cvs/src/usr.bin/rsync/client.c,v
> retrieving revision 1.15
> diff -u -p -r1.15 client.c
> --- client.c  8 May 2019 20:00:25 -   1.15
> +++ client.c  7 May 2021 08:29:10 -
> @@ -43,7 +43,7 @@ rsync_client(const struct opts *opts, in
>  
>   if (pledge("stdio unix rpath wpath cpath dpath fattr chown getpw 
> unveil",
>   NULL) == -1)
> - err(1, "pledge");
> + err(ERR_IPC, "pledge");
>  
>   memset(&sess, 0, sizeof(struct sess));
>   sess.opts = opts;
> Index: extern.h
> ===
> RCS file: /cvs/src/usr.bin/rsync/extern.h,v
> retrieving revision 1.36
> diff -u -p -r1.36 extern.h
> --- extern.h  31 Mar 2021 19:45:16 -  1.36
> +++ extern.h  7 May 2021 08:22:32 -
> @@ -42,6 +42,19 @@
>  #define  CSUM_LENGTH_PHASE2 (16)
>  
>  /*
> + * Rsync error codes.
> + */
> +#define ERR_SYNTAX   1
> +#define ERR_PROTOCOL 2
> +#define ERR_SOCK_IO  10
> +#define ERR_FILE_IO  11
> +#define ERR_WIREPROTO12
> +#define ERR_IPC  14  /* catchall for any kind of syscall 
> error */
> +#define ERR_TERMIMATED   16
> +#define ERR_WAITPID  21
> +#define ERR_NOMEM22
> +
> +/*
>   * Use this for --timeout.
>   * All poll events will use it and catch time-outs.
>   */
> Index: fargs.c
> ===
> RCS file: /cvs/src/usr.bin/rsync/fargs.c,v
> retrieving revision 1.17
> diff -u -p -r1.17 fargs.c
> --- fargs.c   8 May 2019 20:00:25 -   1.17
> +++ fargs.c   7 May 2021 08:19:29 -
> @@ -17,6 +17,7 @@
>  #include 
>  
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -51,7 +52,7 @@ fargs_cmdline(struct sess *sess, const s
>   if (sess->opts->ssh_prog) {
>   ap = strdup(sess->opts->ssh_prog);
>   if (ap == NULL)
> - goto out;
> + err(ERR_NOMEM, NULL);
>  
>   while ((arg = strsep(&ap, " \t")) != NULL) {
>   if (arg[0] == '\0') {
> @@ -127,8 +128,4 @@ fargs_cmdline(struct sess *sess, const s
>   addargs(&args, "%s", f->sink);
>  
>   return args.list;
> -out:
> - freeargs(&args);
> - ERR("calloc");
> - return NULL;
>  }
> Index: main.c
> ===
> RCS file: /cvs/src/usr.bin/rsync/main.c,v
> retrieving revision 1.53
> diff -u -p -r1.53 main.c
> --- main.c31 Mar 2021 19:45:16 -  1.53
> +++ main.c7 May 2021 08:30:18 -
> @@ -83,18 +83,18 @@ fargs_parse(size_t argc, char *argv[], s
>   /* Allocations. */
>  
>   if ((f = calloc(1, sizeof(struct fargs))) == NULL)
> - err(1, "calloc");
> + err(ERR_NOMEM, NULL);
>  
>   f->sourcesz = argc - 1;
>   if ((f->sources = calloc(f->sourcesz, sizeof(char *))) == NULL)
> - err(1, "calloc");
> + err(ERR_NOMEM, NULL);
>  
>   for (i = 0; i < argc - 1; i++)
>   if ((f->sources[i] = strdup(argv[i])) == NULL)
> - err(1, "strdup");
> + err(ERR_NOMEM, NULL);
>  
>   if ((f->sink = strdup(argv[i])) == NULL)
> - err(1, "strdup");
> + err(ERR_NOMEM, NULL);
>  
>   /*
>* Test files for its locality.
> @@ -109,15 +109,16 @@ fargs_parse(size_t argc, char *argv[], s
>   if (fargs_is_remote(f->sink)) {
>   f->mode = FARGS_SENDER;
>   if ((f->host = strdup(f->sink)) == NULL)
> - err(1, "strdup");
> + err(ERR_NOMEM, NULL);
>   }
>  
>   if (fargs_is_remote(f->sources[0])) {
>   if (f->host != NULL)
> - errx(1, "both source and destination cannot be remote 
> files");
> + 

rsync exit code and error cleanup

2021-05-07 Thread Claudio Jeker
Currently our rsync does not follow the exit codes from rsync. Also the
error handling is complex because ERR() and ERRX() are not terminating the
process.

This diff tries to start cleaning up the mess a bit. Introduce some exit
codes to use and apply them in places where it is obvious.

The rsync server process should normally communicate errors back via the
rsync socket but there are some errors where this will most probably fail
as well. A good example are memory failures.

I used ERR_IPC as a kind of catchall for any system error that pops up
(fork, socketpair but also pledge, unveil).

The goal is to reduce the amount of ERR(), ERRX() and ERRX1() from rsync.
This should simplify the code base.

I also synced the mkpath() call with the one from mkdir and handle the
error now outside of the call. Again I think the result is cleaner.

OK?
-- 
:wq Claudio

Index: client.c
===
RCS file: /cvs/src/usr.bin/rsync/client.c,v
retrieving revision 1.15
diff -u -p -r1.15 client.c
--- client.c8 May 2019 20:00:25 -   1.15
+++ client.c7 May 2021 08:29:10 -
@@ -43,7 +43,7 @@ rsync_client(const struct opts *opts, in
 
if (pledge("stdio unix rpath wpath cpath dpath fattr chown getpw 
unveil",
NULL) == -1)
-   err(1, "pledge");
+   err(ERR_IPC, "pledge");
 
memset(&sess, 0, sizeof(struct sess));
sess.opts = opts;
Index: extern.h
===
RCS file: /cvs/src/usr.bin/rsync/extern.h,v
retrieving revision 1.36
diff -u -p -r1.36 extern.h
--- extern.h31 Mar 2021 19:45:16 -  1.36
+++ extern.h7 May 2021 08:22:32 -
@@ -42,6 +42,19 @@
 #defineCSUM_LENGTH_PHASE2 (16)
 
 /*
+ * Rsync error codes.
+ */
+#define ERR_SYNTAX 1
+#define ERR_PROTOCOL   2
+#define ERR_SOCK_IO10
+#define ERR_FILE_IO11
+#define ERR_WIREPROTO  12
+#define ERR_IPC14  /* catchall for any kind of syscall 
error */
+#define ERR_TERMIMATED 16
+#define ERR_WAITPID21
+#define ERR_NOMEM  22
+
+/*
  * Use this for --timeout.
  * All poll events will use it and catch time-outs.
  */
Index: fargs.c
===
RCS file: /cvs/src/usr.bin/rsync/fargs.c,v
retrieving revision 1.17
diff -u -p -r1.17 fargs.c
--- fargs.c 8 May 2019 20:00:25 -   1.17
+++ fargs.c 7 May 2021 08:19:29 -
@@ -17,6 +17,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -51,7 +52,7 @@ fargs_cmdline(struct sess *sess, const s
if (sess->opts->ssh_prog) {
ap = strdup(sess->opts->ssh_prog);
if (ap == NULL)
-   goto out;
+   err(ERR_NOMEM, NULL);
 
while ((arg = strsep(&ap, " \t")) != NULL) {
if (arg[0] == '\0') {
@@ -127,8 +128,4 @@ fargs_cmdline(struct sess *sess, const s
addargs(&args, "%s", f->sink);
 
return args.list;
-out:
-   freeargs(&args);
-   ERR("calloc");
-   return NULL;
 }
Index: main.c
===
RCS file: /cvs/src/usr.bin/rsync/main.c,v
retrieving revision 1.53
diff -u -p -r1.53 main.c
--- main.c  31 Mar 2021 19:45:16 -  1.53
+++ main.c  7 May 2021 08:30:18 -
@@ -83,18 +83,18 @@ fargs_parse(size_t argc, char *argv[], s
/* Allocations. */
 
if ((f = calloc(1, sizeof(struct fargs))) == NULL)
-   err(1, "calloc");
+   err(ERR_NOMEM, NULL);
 
f->sourcesz = argc - 1;
if ((f->sources = calloc(f->sourcesz, sizeof(char *))) == NULL)
-   err(1, "calloc");
+   err(ERR_NOMEM, NULL);
 
for (i = 0; i < argc - 1; i++)
if ((f->sources[i] = strdup(argv[i])) == NULL)
-   err(1, "strdup");
+   err(ERR_NOMEM, NULL);
 
if ((f->sink = strdup(argv[i])) == NULL)
-   err(1, "strdup");
+   err(ERR_NOMEM, NULL);
 
/*
 * Test files for its locality.
@@ -109,15 +109,16 @@ fargs_parse(size_t argc, char *argv[], s
if (fargs_is_remote(f->sink)) {
f->mode = FARGS_SENDER;
if ((f->host = strdup(f->sink)) == NULL)
-   err(1, "strdup");
+   err(ERR_NOMEM, NULL);
}
 
if (fargs_is_remote(f->sources[0])) {
if (f->host != NULL)
-   errx(1, "both source and destination cannot be remote 
files");
+   errx(ERR_SYNTAX, "both source and destination "
+   "cannot be remote files");
f->mode = FARGS_RECEIVER;
if ((f->host = strdup(f->sources[0])) == NULL)
-   err(1, "strdup");