X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=fish%2Ffish.c;h=a758810682bea134bd7ed7663b4bb702e2e08745;hp=f31f4ad349588686e6c2f8f950568631e0884ae1;hb=b9a691af0fa468873eda3706a1c797568857785b;hpb=8249460acfc0ab7298d125b4ea29c72729a4582b diff --git a/fish/fish.c b/fish/fish.c index f31f4ad..a758810 100644 --- a/fish/fish.c +++ b/fish/fish.c @@ -40,6 +40,8 @@ #include #include "fish.h" +#include "closeout.h" +#include "progname.h" struct mp { struct mp *next; @@ -87,21 +89,25 @@ launch (guestfs_h *_g) return 0; } -static void -usage (void) +static void __attribute__((noreturn)) +usage (int status) { - fprintf (stderr, - _("guestfish: guest filesystem shell\n" - "guestfish lets you edit virtual machine filesystems\n" + if (status != EXIT_SUCCESS) + fprintf (stderr, _("Try `%s --help' for more information.\n"), + program_name); + else { + fprintf (stdout, + _("%s: guest filesystem shell\n" + "%s lets you edit virtual machine filesystems\n" "Copyright (C) 2009 Red Hat Inc.\n" "Usage:\n" - " guestfish [--options] cmd [: cmd : cmd ...]\n" - " guestfish -i libvirt-domain\n" - " guestfish -i disk-image(s)\n" + " %s [--options] cmd [: cmd : cmd ...]\n" + " %s -i libvirt-domain\n" + " %s -i disk-image(s)\n" "or for interactive use:\n" - " guestfish\n" + " %s\n" "or from a shell script:\n" - " guestfish <mountpoint = p+1; } else - mp->mountpoint = "/"; + mp->mountpoint = bad_cast ("/"); mp->device = optarg; mp->next = mps; mps = mp; @@ -287,21 +318,18 @@ main (int argc, char *argv[]) break; case 'V': - printf ("guestfish %s\n", PACKAGE_VERSION); + printf ("%s %s\n", program_name, PACKAGE_VERSION); exit (0); case 'x': echo_commands = 1; break; - case '?': - usage (); - exit (0); + case HELP_OPTION: + usage (0); default: - fprintf (stderr, _("guestfish: unexpected command line option 0x%x\n"), - c); - exit (1); + usage (1); } } @@ -312,19 +340,25 @@ main (int argc, char *argv[]) if (drvs || mps || remote_control_listen || remote_control || guestfs_get_selinux (g)) { - fprintf (stderr, _("guestfish: cannot use -i option with -a, -m, --listen, --remote or --selinux\n")); + fprintf (stderr, _("%s: cannot use -i option with -a, -m," + " --listen, --remote or --selinux\n"), + program_name); exit (1); } if (optind >= argc) { - fprintf (stderr, _("guestfish -i requires a libvirt domain or path(s) to disk image(s)\n")); + fprintf (stderr, + _("%s: -i requires a libvirt domain or path(s) to disk image(s)\n"), + program_name); exit (1); } strcpy (cmd, "a=`virt-inspector"); while (optind < argc) { - if (strlen (cmd) + strlen (argv[optind]) + strlen (argv[0]) + 60 + if (strlen (cmd) + strlen (argv[optind]) + strlen (real_argv0) + 60 >= sizeof cmd) { - fprintf (stderr, _("guestfish: virt-inspector command too long for fixed-size buffer\n")); + fprintf (stderr, + _("%s: virt-inspector command too long for fixed-size buffer\n"), + program_name); exit (1); } strcat (cmd, " '"); @@ -338,7 +372,7 @@ main (int argc, char *argv[]) else strcat (cmd, " --fish"); - sprintf (&cmd[strlen(cmd)], "` && %s $a", argv[0]); + sprintf (&cmd[strlen(cmd)], "` && %s $a", real_argv0); if (guestfs_get_verbose (g)) strcat (cmd, " -v"); @@ -347,7 +381,7 @@ main (int argc, char *argv[]) if (verbose) fprintf (stderr, - "guestfish -i: running virt-inspector command:\n%s\n", cmd); + "%s -i: running virt-inspector command:\n%s\n", program_name, cmd); r = system (cmd); if (r == -1) { @@ -368,17 +402,23 @@ main (int argc, char *argv[]) /* Remote control? */ if (remote_control_listen && remote_control) { - fprintf (stderr, _("guestfish: cannot use --listen and --remote options at the same time\n")); + fprintf (stderr, + _("%s: cannot use --listen and --remote options at the same time\n"), + program_name); exit (1); } if (remote_control_listen) { if (optind < argc) { - fprintf (stderr, _("guestfish: extra parameters on the command line with --listen flag\n")); + fprintf (stderr, + _("%s: extra parameters on the command line with --listen flag\n"), + program_name); exit (1); } if (file) { - fprintf (stderr, _("guestfish: cannot use --listen and --file options at the same time\n")); + fprintf (stderr, + _("%s: cannot use --listen and --file options at the same time\n"), + program_name); exit (1); } rc_listen (); @@ -517,7 +557,7 @@ script (int prompt) char *cmd; char *p, *pend; char *argv[64]; - int i, len; + int len; int global_exit_on_error = !prompt; int tilde_candidate; @@ -581,7 +621,7 @@ script (int prompt) if (len == 0) continue; cmd = buf; - i = 0; + unsigned int i = 0; if (buf[len] == '\0') { argv[0] = NULL; goto got_command; @@ -602,12 +642,14 @@ script (int prompt) p++; len = strcspn (p, "\""); if (p[len] == '\0') { - fprintf (stderr, _("guestfish: unterminated double quote\n")); + fprintf (stderr, _("%s: unterminated double quote\n"), program_name); if (exit_on_error) exit (1); goto next_command; } if (p[len+1] && (p[len+1] != ' ' && p[len+1] != '\t')) { - fprintf (stderr, _("guestfish: command arguments not separated by whitespace\n")); + fprintf (stderr, + _("%s: command arguments not separated by whitespace\n"), + program_name); if (exit_on_error) exit (1); goto next_command; } @@ -617,12 +659,14 @@ script (int prompt) p++; len = strcspn (p, "'"); if (p[len] == '\0') { - fprintf (stderr, _("guestfish: unterminated single quote\n")); + fprintf (stderr, _("%s: unterminated single quote\n"), program_name); if (exit_on_error) exit (1); goto next_command; } if (p[len+1] && (p[len+1] != ' ' && p[len+1] != '\t')) { - fprintf (stderr, _("guestfish: command arguments not separated by whitespace\n")); + fprintf (stderr, + _("%s: command arguments not separated by whitespace\n"), + program_name); if (exit_on_error) exit (1); goto next_command; } @@ -643,12 +687,15 @@ script (int prompt) pend++; } if (c != 0) { - fprintf (stderr, _("guestfish: unterminated \"[...]\" sequence\n")); + fprintf (stderr, + _("%s: unterminated \"[...]\" sequence\n"), program_name); if (exit_on_error) exit (1); goto next_command; } if (*pend && (*pend != ' ' && *pend != '\t')) { - fprintf (stderr, _("guestfish: command arguments not separated by whitespace\n")); + fprintf (stderr, + _("%s: command arguments not separated by whitespace\n"), + program_name); if (exit_on_error) exit (1); goto next_command; } @@ -667,8 +714,8 @@ script (int prompt) } else pend = &p[len]; } else { - fprintf (stderr, _("guestfish: internal error parsing string at '%s'\n"), - p); + fprintf (stderr, _("%s: internal error parsing string at '%s'\n"), + program_name, p); abort (); } @@ -684,7 +731,7 @@ script (int prompt) } if (i == sizeof argv / sizeof argv[0]) { - fprintf (stderr, _("guestfish: too many arguments\n")); + fprintf (stderr, _("%s: too many arguments\n"), program_name); if (exit_on_error) exit (1); goto next_command; } @@ -713,7 +760,7 @@ cmdline (char *argv[], int optind, int argc) cmd = argv[optind++]; if (strcmp (cmd, ":") == 0) { - fprintf (stderr, _("guestfish: empty command on command line\n")); + fprintf (stderr, _("%s: empty command on command line\n"), program_name); exit (1); } params = &argv[optind]; @@ -750,8 +797,14 @@ issue_command (const char *cmd, char *argv[], const char *pipecmd) if (pipecmd) { int fd[2]; - fflush (stdout); - pipe (fd); + if (fflush (stdout) == EOF) { + perror ("failed to flush standard output"); + return -1; + } + if (pipe (fd) < 0) { + perror ("pipe failed"); + return -1; + } pid = fork (); if (pid == -1) { perror ("fork"); @@ -760,7 +813,10 @@ issue_command (const char *cmd, char *argv[], const char *pipecmd) if (pid == 0) { /* Child process. */ close (fd[1]); - dup2 (fd[0], 0); + if (dup2 (fd[0], 0) < 0) { + perror ("dup2 of stdin failed"); + _exit (1); + } r = system (pipecmd); if (r == -1) { @@ -770,9 +826,16 @@ issue_command (const char *cmd, char *argv[], const char *pipecmd) _exit (WEXITSTATUS (r)); } - stdout_saved_fd = dup (1); + if ((stdout_saved_fd = dup (1)) < 0) { + perror ("failed to dup stdout"); + return -1; + } close (fd[0]); - dup2 (fd[1], 1); + if (dup2 (fd[1], 1) < 0) { + perror ("failed to dup stdout"); + close (stdout_saved_fd); + return -1; + } close (fd[1]); } @@ -823,13 +886,22 @@ issue_command (const char *cmd, char *argv[], const char *pipecmd) /* Always flush stdout after every command, so that messages, results * etc appear immediately. */ - fflush (stdout); + if (fflush (stdout) == EOF) { + perror ("failed to flush standard output"); + return -1; + } if (pipecmd) { close (1); - dup2 (stdout_saved_fd, 1); + if (dup2 (stdout_saved_fd, 1) < 0) { + perror ("failed to dup2 standard output"); + r = -1; + } close (stdout_saved_fd); - waitpid (pid, NULL, 0); + if (waitpid (pid, NULL, 0) < 0) { + perror ("waiting for command to complete"); + r = -1; + } } return r; @@ -974,7 +1046,7 @@ free_strings (char **argv) } int -count_strings (char * const * const argv) +count_strings (char *const *argv) { int c; @@ -984,7 +1056,7 @@ count_strings (char * const * const argv) } void -print_strings (char * const * const argv) +print_strings (char *const *argv) { int argc; @@ -993,7 +1065,7 @@ print_strings (char * const * const argv) } void -print_table (char * const * const argv) +print_table (char *const *argv) { int i; @@ -1092,9 +1164,10 @@ add_history_line (const char *line) } int -xwrite (int fd, const void *buf, size_t len) +xwrite (int fd, const void *v_buf, size_t len) { int r; + const char *buf = v_buf; while (len > 0) { r = write (fd, buf, len);