X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=daemon%2Fguestfsd.c;h=5938846eb9ec283ad1d8512c06f036c0564c4f5f;hb=830a2d29d9b3f13bef2455c9446eb4eadb444ca7;hp=81305246016b16baef68487a054ee77a08efac88;hpb=866ec00d1f8bc40042795b66ceec12608bb1f9e8;p=libguestfs.git diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c index 8130524..5938846 100644 --- a/daemon/guestfsd.c +++ b/daemon/guestfsd.c @@ -60,6 +60,11 @@ static char *read_cmdline (void); # define MAX(a,b) ((a)>(b)?(a):(b)) #endif +/* Not the end of the world if this open flag is not defined. */ +#ifndef O_CLOEXEC +# define O_CLOEXEC 0 +#endif + /* If root device is an ext2 filesystem, this is the major and minor. * This is so we can ignore this device from the point of view of the * user, eg. in guestfs_list_devices and many other places. @@ -137,6 +142,8 @@ main (int argc, char *argv[]) int dont_fork = 0; char *cmdline; + ignore_value (chdir ("/")); + if (winsock_init () == -1) error (EXIT_FAILURE, 0, "winsock initialization failed"); @@ -237,7 +244,8 @@ main (int argc, char *argv[]) #endif /* Connect to virtio-serial channel. */ - int sock = open ("/dev/virtio-ports/org.libguestfs.channel.0", O_RDWR); + int sock = open ("/dev/virtio-ports/org.libguestfs.channel.0", + O_RDWR | O_CLOEXEC); if (sock == -1) { fprintf (stderr, "\n" @@ -252,6 +260,7 @@ main (int argc, char *argv[]) "output to the libguestfs developers, either in a bug report\n" "or on the libguestfs redhat com mailing list.\n" "\n"); + perror ("/dev/virtio-ports/org.libguestfs.channel.0"); exit (EXIT_FAILURE); } @@ -264,8 +273,10 @@ main (int argc, char *argv[]) xdrmem_create (&xdr, lenbuf, sizeof lenbuf, XDR_ENCODE); xdr_u_int (&xdr, &len); - if (xwrite (sock, lenbuf, sizeof lenbuf) == -1) + if (xwrite (sock, lenbuf, sizeof lenbuf) == -1) { + perror ("xwrite"); exit (EXIT_FAILURE); + } xdr_destroy (&xdr); @@ -433,6 +444,7 @@ add_string (char ***argv, int *size, int *alloc, const char *str) if (new_str == NULL) { reply_with_perror ("strdup"); free_strings (*argv); + return -1; } } else new_str = NULL; @@ -683,6 +695,7 @@ commandrvf (char **stdoutput, char **stderror, int flags, } if (pid == 0) { /* Child process running the command. */ + signal (SIGPIPE, SIG_DFL); close (0); if (flag_copy_stdin) { dup2 (stdin_fd[0], 0); @@ -690,7 +703,7 @@ commandrvf (char **stdoutput, char **stderror, int flags, close (stdin_fd[1]); } else { /* Set stdin to /dev/null (ignore failure) */ - open ("/dev/null", O_RDONLY); + ignore_value (open ("/dev/null", O_RDONLY)); } close (so_fd[0]); close (se_fd[0]); @@ -771,13 +784,29 @@ commandrvf (char **stdoutput, char **stderror, int flags, quit = 0; while (quit < 2) { + again: rset2 = rset; r = select (MAX (so_fd[0], se_fd[0]) + 1, &rset2, NULL, NULL, NULL); if (r == -1) { + if (errno == EINTR) + goto again; + perror ("select"); quit: - if (stdoutput) free (*stdoutput); - if (stderror) free (*stderror); + if (stdoutput) { + free (*stdoutput); + *stdoutput = NULL; + } + if (stderror) { + free (*stderror); + /* Need to return non-NULL *stderror here since most callers + * will try to print and then free the err string. + * Unfortunately recovery from strdup failure here is not + * possible. + */ + *stderror = strdup ("error running external command, " + "see debug output for details"); + } close (so_fd[0]); close (se_fd[0]); waitpid (pid, NULL, 0); @@ -968,7 +997,8 @@ trim (char *str) } /* printf helper function so we can use %Q ("quoted") and %R to print - * shell-quoted strings. See HACKING file for more details. + * shell-quoted strings. See guestfs(3)/EXTENDING LIBGUESTFS for more + * details. */ static int print_shell_quote (FILE *stream,