[netcf-devel] [PATCH] Use POSIX strerror_r for portability.

Laine Stump laine at laine.org
Fri Dec 21 17:11:37 UTC 2012


On 12/18/2012 01:27 PM, emaste at adaranet.com wrote:
> From: Ed Maste <emaste at adaranet.com>
>
>
> Signed-off-by: Ed Maste <emaste at adaranet.com>
> ---
>  bootstrap.conf    |  1 +
>  src/dutil_posix.c | 36 +++++++++++++++++++-----------------
>  src/internal.h    |  9 +++++++++
>  3 files changed, 29 insertions(+), 17 deletions(-)
>
> diff --git a/bootstrap.conf b/bootstrap.conf
> index 95a84aa..fd1c8f7 100644
> --- a/bootstrap.conf
> +++ b/bootstrap.conf
> @@ -37,6 +37,7 @@ sigprocmask
>  socket
>  spawn
>  stddef
> +strerror_r-posix
>  string
>  sys_ioctl
>  sys_socket
> diff --git a/src/dutil_posix.c b/src/dutil_posix.c
> index 609d7bd..115b2bd 100644
> --- a/src/dutil_posix.c
> +++ b/src/dutil_posix.c
> @@ -76,9 +76,10 @@ exec_program(struct netcf *ncf,
>      /* create a pipe to receive stdout+stderr from child */
>      if (outfd) {
>          if (pipe(pipeout) < 0) {
> +            strerror_r(errno, errbuf, sizeof(errbuf));
>              report_error(ncf, NETCF_EEXEC,
>                           "failed to create pipe while forking for '%s': %s",
> -                         commandline, strerror_r(errno, errbuf, sizeof(errbuf)));
> +                         commandline, errbuf);
>              goto error;
>          }
>          *outfd = pipeout[0];
> @@ -90,24 +91,25 @@ exec_program(struct netcf *ncf,
>       */
>      sigfillset(&newmask);
>      if (pthread_sigmask(SIG_SETMASK, &newmask, &oldmask) != 0) {
> +        strerror_r(errno, errbuf, sizeof(errbuf));
>          report_error(ncf, NETCF_EEXEC,
>                       "failed to set signal mask while forking for '%s': %s",
> -                     commandline, strerror_r(errno, errbuf, sizeof(errbuf)));
> +                     commandline, errbuf);
>          goto error;
>      }
>  
>      *pid = fork();
>  
> -    ERR_THROW(*pid < 0, ncf, EEXEC, "failed to fork for '%s': %s",
> -              commandline, strerror_r(errno, errbuf, sizeof(errbuf)));
> +    ERR_THROW_STRERROR(*pid < 0, ncf, EEXEC, "failed to fork for '%s': %s",
> +                       commandline, errbuf);
>  
>      if (*pid) { /* parent */
>          /* Restore our original signal mask now that the child is
>             safely running */
> -        ERR_THROW(pthread_sigmask(SIG_SETMASK, &oldmask, NULL) != 0,
> -                  ncf, EEXEC,
> -                  "failed to restore signal mask while forking for '%s': %s",
> -                  commandline, strerror_r(errno, errbuf, sizeof(errbuf)));
> +        ERR_THROW_STRERROR(pthread_sigmask(SIG_SETMASK, &oldmask, NULL) != 0,
> +                           ncf, EEXEC,
> +                           "failed to restore signal mask while forking for '%s': %s",
> +                           commandline, errbuf);
>  
>          /* parent doesn't use write side of the pipe */
>          if (pipeout[1] >= 0)
> @@ -208,14 +210,14 @@ int run_program(struct netcf *ncf, const char *const *argv, char **output)
>      ERR_BAIL(ncf);
>  
>      outfile = fdopen(outfd, "r");
> -    ERR_THROW(outfile == NULL, ncf, EEXEC,
> -              "Failed to create file stream for output while executing '%s': %s",
> -              argv_str, strerror_r(errno, errbuf, sizeof(errbuf)));
> +    ERR_THROW_STRERROR(outfile == NULL, ncf, EEXEC,
> +                       "Failed to create file stream for output while executing '%s': %s",
> +                       argv_str, errbuf);
>  
>      *output = fread_file(outfile, &outlen);
> -    ERR_THROW(*output == NULL, ncf, EEXEC,
> -              "Error while reading output from execution of '%s': %s",
> -              argv_str, strerror_r(errno, errbuf, sizeof(errbuf)));
> +    ERR_THROW_STRERROR(*output == NULL, ncf, EEXEC,
> +                       "Error while reading output from execution of '%s': %s",
> +                       argv_str, errbuf);
>  
>      /* finished with the stream. Close it so the child can exit. */
>      fclose(outfile);
> @@ -226,9 +228,9 @@ int run_program(struct netcf *ncf, const char *const *argv, char **output)
>          /* empty loop */
>      }
>  
> -    ERR_THROW(waitret == -1, ncf, EEXEC,
> -              "Failed waiting for completion of '%s': %s",
> -              argv_str, strerror_r(errno, errbuf, sizeof(errbuf)));
> +    ERR_THROW_STRERROR(waitret == -1, ncf, EEXEC,
> +                       "Failed waiting for completion of '%s': %s",
> +                       argv_str, errbuf);
>      ERR_THROW(!WIFEXITED(exitstatus) && WIFSIGNALED(exitstatus), ncf, EEXEC,
>                "'%s' terminated by signal: %d",
>                argv_str, WTERMSIG(exitstatus));
> diff --git a/src/internal.h b/src/internal.h
> index cca7a46..0354fb7 100644
> --- a/src/internal.h
> +++ b/src/internal.h
> @@ -133,6 +133,15 @@
>          }                                            \
>      } while(0)
>  
> +#define ERR_THROW_STRERROR(cond, ncf, err, fmt ...)     \
> +    do {                                                \
> +        if (cond) {                                     \
> +            strerror_r(errno, errbuf, sizeof(errbuf));  \
> +            report_error(ncf, NETCF_##err, ## fmt);     \
> +            goto error;                                 \
> +        }                                               \
> +    } while(0)
> +
>  /* Clear error code and details */
>  #define API_ENTRY(ncf)                          \
>      do {                                        \

I considered making errbuf local to inside "if (cond)" so that we didn't
need to add it to the arg list, but that would have meant two errbufs on
the stack in one place, and I don't want to increase stack usage without
good reason, so I left it as you wrote it.

ACK and pushed.

(note that make won't automatically re-run bootstrap when bootstrap.conf
is touched, so you'll have to do that by hand after pulling this patch.
That should be fixed too, but as a separate patch, and I don't have the
time to look into it right now).


More information about the netcf-devel mailing list