On 04/14/2016 03:59 AM, Richard W.M. Jones wrote: > The current implementation of getumask involves writing a file with > mode 0777 and then testing what mode was created by the kernel. This > doesn't work properly if the user set a per-mount umask (or fmask/ > dmask). > > This alternative method was suggested by Josh Stone. By forking, we > can use the thread-unsafe method (calling umask) and pass the result > back over a pipe. > > This change also fixes another problem: mode_t is unsigned, so cannot > be used to return an error indication (ie. -1). Return a plain int > instead. > > Thanks: Josh Stone, Jiri Jaburek, Eric Blake. > ---
> +guestfs_int_getumask (guestfs_h *g) > +{ > + if (pid == 0) { > + /* The child process must ONLY call async-safe functions. */ > + close (fd[0]); > + > + /* umask can't fail. */ > + mask = umask (0); > + > + if (write (fd[1], &mask, sizeof mask) != sizeof mask) > + _exit (EXIT_FAILURE); > + if (close (fd[1]) == -1) > + _exit (EXIT_FAILURE); > + > + _exit (EXIT_SUCCESS); Yay - the child looks good now. > + } > + > + /* Parent. */ > + close (fd[1]); > + > + /* Read the umask. */ > + if (read (fd[0], &mask, sizeof mask) != sizeof mask) { > + perrorf (g, "read"); > + close (fd[0]); > + return -1; Oops - this strands a child process. You have to reap the child, even if the read() failed. > + } > + close (fd[0]); > + > + again: > + if (waitpid (pid, &status, 0) == -1) { > + if (errno == EINTR) goto again; > + perrorf (g, "waitpid"); > + return -1; > + } > + else if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) { > + guestfs_int_external_command_failed (g, status, "umask", NULL); > + return -1; > + } Getting closer. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs