run_command(): handle missing command errors more gracefully
commit45c0961c87884a04517b65c0acc6aedeeae2d0c8
authorJeff King <peff@peff.net>
Wed, 28 Jan 2009 07:35:33 +0000 (28 02:35 -0500)
committerJunio C Hamano <gitster@pobox.com>
Wed, 28 Jan 2009 22:08:57 +0000 (28 14:08 -0800)
tree1758b488113a6654b63e8829682f745c7a855fb7
parentf172f334fde49ce29d0afa21749bf85463a2db9a
run_command(): handle missing command errors more gracefully

When run_command() was asked to run a non-existant command, its behavior
varied depending on the platform:

  - on POSIX systems, we would fork, and then after the execvp call
    failed, we could call die(), which prints a message to stderr and
    exits with code 128.

  - on Windows, we do a PATH lookup, realize the program isn't there, and
    then return ERR_RUN_COMMAND_FORK

The goal of this patch is to make it clear to callers that the specific
error was a missing command. To do this, we will return the error code
ERR_RUN_COMMAND_EXEC, which is already defined in run-command.h, checked
for in several places, but never actually gets set.

The new behavior is:

  - on POSIX systems, we exit the forked process with code 127 (the same
    as the shell uses to report missing commands). The parent process
    recognizes this code and returns an EXEC error. The stderr message is
    silenced, since the caller may be speculatively trying to run a
    command. Instead, we use trace_printf so that somebody interested in
    debugging can see the error that occured.

  - on Windows, we check errno, which is already set correctly by
    mingw_spawnvpe, and report an EXEC error instead of a FORK error

Thus it is safe to speculatively run a command:

  int r = run_command_v_opt(argv, 0);
  if (r == -ERR_RUN_COMMAND_EXEC)
  /* oops, it wasn't found; try something else */
  else
  /* we failed for some other reason, error is in r */

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
run-command.c