[Libguestfs] [PATCH libguestfs 2/5] guestfish: write --help to stdout, use gnulib's progname module

Jim Meyering jim at meyering.net
Mon Aug 24 11:51:18 UTC 2009


Jim Meyering wrote:

> Richard W.M. Jones wrote:
>> On Mon, Aug 24, 2009 at 12:21:54PM +0200, Jim Meyering wrote:
>>> +  /* getopt_long uses argv[0], so give it the sanitized name, too.  */
>>> +  argv[0] = bad_cast (program_name);
>>
>> This is wrong.
>>
>> We rely on seeing the original argv[0] later in the code, so that
>> people can run ./fish/guestfish from the source directory and have the
>> appliance path set correctly:
>>
>>   /* If developing, add ./appliance to the path.  Note that libtools
>>    * interferes with this because uninstalled guestfish is a shell
>>    * script that runs the real program with an absolute path.  Detect
>>    * that too.
>>    *
>>    * BUT if LIBGUESTFS_PATH environment variable is already set by
>>    * the user, then don't override it.
>>    */
>>   if (getenv ("LIBGUESTFS_PATH") == NULL &&
>>       argv[0] &&
>>       (argv[0][0] != '/' || strstr (argv[0], "/.libs/lt-") != NULL))
>>     guestfs_set_path (g, "appliance:" GUESTFS_DEFAULT_PATH);
>
> Good catch.  I'll adapt by saving argv[0] just before calling
> getopt_long, setting it as above, and then restoring the original,
> afterwards.

Here's an incremental patch I'll fold onto the one discussed above:

diff --git a/fish/fish.c b/fish/fish.c
index 9f0f8df..547342f 100644
--- a/fish/fish.c
+++ b/fish/fish.c
@@ -139,9 +139,6 @@ main (int argc, char *argv[])
   /* Set global program name that is not polluted with libtool artifacts.  */
   set_program_name (argv[0]);

-  /* getopt_long uses argv[0], so give it the sanitized name, too.  */
-  argv[0] = bad_cast (program_name);
-
   atexit (close_stdout);

   enum { HELP_OPTION = CHAR_MAX + 1 };
@@ -205,6 +202,11 @@ main (int argc, char *argv[])
       (argv[0][0] != '/' || strstr (argv[0], "/.libs/lt-") != NULL))
     guestfs_set_path (g, "appliance:" GUESTFS_DEFAULT_PATH);

+  /* getopt_long uses argv[0], so give it the sanitized name, too.
+     But only temporarily.  */
+  char *argv0 = argv[0];
+  argv[0] = bad_cast (program_name);
+
   for (;;) {
     c = getopt_long (argc, argv, options, long_options, &option_index);
     if (c == -1) break;
@@ -325,6 +327,9 @@ main (int argc, char *argv[])
     }
   }

+  /* Restore original value.  */
+  argv[0] = argv0;
+
   /* Inspector mode invalidates most of the other arguments. */
   if (inspector) {
     char cmd[1024];




More information about the Libguestfs mailing list