[Libguestfs] [PATCH] umask: Use /proc/<PID>/status to read umask in Linux >= 4.7.
Pino Toscano
ptoscano at redhat.com
Mon May 23 08:49:52 UTC 2016
On Saturday 21 May 2016 13:14:40 Richard W.M. Jones wrote:
> Since Linux 4.7, the process umask is available in /proc/<pid>/status.
> See:
> https://github.com/torvalds/linux/commit/3e42979e65dace1f9268dd5440e5ab096b8dee59
>
> Use this value if available, else fall back to the existing codepath
> for Linux <= 4.6 and other Unix.
> ---
Sounds good -- just wondering whether the result of the inspection of
the "status" file should be cached somehow, so following get_umask calls
after the first one will use only the working method.
A couple of notes follow.
> src/umask.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------
> 1 file changed, 78 insertions(+), 8 deletions(-)
>
> diff --git a/src/umask.c b/src/umask.c
> index b8748e8..3f32337 100644
> --- a/src/umask.c
> +++ b/src/umask.c
> @@ -18,12 +18,22 @@
>
> /**
> * Return current umask in a thread-safe way.
> + *
> + * glibc documents, but does not actually implement, a "getumask(3)"
> + * call.
> + *
> + * We use C<Umask> from F</proc/I<PID>/status> for Linux E<ge> 4.7.
> + * For older Linux and other Unix, this file implements an expensive
> + * but thread-safe way to get the current process's umask.
> + *
> + * Thanks to: Josh Stone, Jiri Jaburek, Eric Blake.
> */
>
> #include <config.h>
>
> #include <stdio.h>
> #include <stdlib.h>
> +#include <stdbool.h>
> #include <unistd.h>
> #include <fcntl.h>
> #include <errno.h>
> @@ -35,21 +45,81 @@
> #include "guestfs.h"
> #include "guestfs-internal.h"
>
> +static int get_umask_from_proc (guestfs_h *g);
> +static int get_umask_from_fork (guestfs_h *g);
> +
> /**
> - * glibc documents, but does not actually implement, a L<getumask(3)>
> - * call.
> - *
> - * This function implements an expensive, but thread-safe way to get
> - * the current process's umask.
> - *
> * Returns the current process's umask. On failure, returns C<-1> and
> * sets the error in the guestfs handle.
> - *
> - * Thanks to: Josh Stone, Jiri Jaburek, Eric Blake.
> */
> int
> guestfs_int_getumask (guestfs_h *g)
> {
> + int mask;
> +
> + mask = get_umask_from_proc (g);
> + if (mask == -1)
> + return -1;
> + if (mask >= 0)
> + return mask;
> +
> + return get_umask_from_fork (g);
> +}
> +
> +/**
> + * For Linux E<ge> 4.7 get the umask from F</proc/I<PID>/status>.
> + *
> + * On failure this returns C<-1>. However if we could not open the
> + * F</proc> file or find the C<Umask> entry in it, return C<-2> which
> + * causes the fallback path to run.
> + */
> +static int
> +get_umask_from_proc (guestfs_h *g)
> +{
> + FILE *fp;
There's CLEANUP_FCLOSE, although it discards the error on fclose()
(which could be ignored, anyway?).
> + CLEANUP_FREE char *path = NULL, *line = NULL;
> + size_t allocsize;
This needs to be reset to 0, as documented for getline.
> + ssize_t len;
> + unsigned int mask;
> + bool found = false;
> +
> + path = safe_asprintf (g, "/proc/%d/status", getpid ());
This does not need a new buffer on heap, a short stack buffer like
char path[sizeof ("/proc/%d/status") + sizeof (pid_t) * 3];
should be enough.
> + fp = fopen (path, "r");
> + if (fp == NULL) {
> + if (errno == ENOENT || errno == ENOTDIR)
> + return -2; /* fallback */
> + perrorf (g, "open: %s", path);
> + return -1;
> + }
> +
> + while ((len = getline (&line, &allocsize, fp)) != -1) {
> + if (len > 0 && line[len-1] == '\n')
> + line[--len] = '\0';
> +
> + /* Looking for: "Umask: 0022" */
> + if (sscanf (line, "Umask: %o", &mask) == 1) {
> + found = true;
> + break;
> + }
> + }
> +
> + if (fclose (fp) == -1) {
> + perrorf (g, "close: %s", path);
> + return -1;
> + }
> +
> + if (!found)
> + return -2; /* fallback */
> +
> + return (int) mask;
> +}
> +
> +/**
> + * Fallback method of getting the umask using fork.
> + */
> +static int
> +get_umask_from_fork (guestfs_h *g)
> +{
> pid_t pid;
> int fd[2], r;
> int mask;
>
--
Pino Toscano
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part.
URL: <http://listman.redhat.com/archives/libguestfs/attachments/20160523/11d0ab84/attachment.sig>
More information about the Libguestfs
mailing list