mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-19 23:28:54 +02:00
gspawn: Make error codes on Windows more specific
A slightly modified patch originally written by Morten Welinder <terra@gnome.org> to make the error codes returned by g_spawn_*() functions more specific when on Windows. They are already this specific on Linux. Add a unit test for the ENOENT case. https://gitlab.gnome.org/GNOME/glib/issues/303 Signed-off-by: Philip Withnall <withnall@endlessm.com>
This commit is contained in:
@@ -352,7 +352,12 @@ main (int ignored_argc, char **ignored_argv)
|
|||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
|
|
||||||
if (handle == -1 && saved_errno != 0)
|
if (handle == -1 && saved_errno != 0)
|
||||||
write_err_and_exit (child_err_report_fd, CHILD_SPAWN_FAILED);
|
{
|
||||||
|
int ec = (saved_errno == ENOENT)
|
||||||
|
? CHILD_SPAWN_NOENT
|
||||||
|
: CHILD_SPAWN_FAILED;
|
||||||
|
write_err_and_exit (child_err_report_fd, ec);
|
||||||
|
}
|
||||||
|
|
||||||
write (child_err_report_fd, &no_error, sizeof (no_error));
|
write (child_err_report_fd, &no_error, sizeof (no_error));
|
||||||
write (child_err_report_fd, &handle, sizeof (handle));
|
write (child_err_report_fd, &handle, sizeof (handle));
|
||||||
|
@@ -46,6 +46,7 @@
|
|||||||
#include "glib-private.h"
|
#include "glib-private.h"
|
||||||
#include "gprintfint.h"
|
#include "gprintfint.h"
|
||||||
#include "glibintl.h"
|
#include "glibintl.h"
|
||||||
|
#include "gspawn-private.h"
|
||||||
#include "gthread.h"
|
#include "gthread.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -86,6 +87,7 @@ enum
|
|||||||
CHILD_NO_ERROR,
|
CHILD_NO_ERROR,
|
||||||
CHILD_CHDIR_FAILED,
|
CHILD_CHDIR_FAILED,
|
||||||
CHILD_SPAWN_FAILED,
|
CHILD_SPAWN_FAILED,
|
||||||
|
CHILD_SPAWN_NOENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -374,6 +376,11 @@ set_child_error (gintptr report[2],
|
|||||||
_("Failed to execute child process (%s)"),
|
_("Failed to execute child process (%s)"),
|
||||||
g_strerror (report[1]));
|
g_strerror (report[1]));
|
||||||
break;
|
break;
|
||||||
|
case CHILD_SPAWN_NOENT:
|
||||||
|
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT,
|
||||||
|
_("Failed to execute child process (%s)"),
|
||||||
|
g_strerror (report[1]));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
@@ -489,7 +496,7 @@ do_spawn_directly (gint *exit_status,
|
|||||||
|
|
||||||
if (rc == -1 && errsv != 0)
|
if (rc == -1 && errsv != 0)
|
||||||
{
|
{
|
||||||
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
|
g_set_error (error, G_SPAWN_ERROR, _g_spawn_exec_err_to_g_error (errsv),
|
||||||
_("Failed to execute child process (%s)"),
|
_("Failed to execute child process (%s)"),
|
||||||
g_strerror (errsv));
|
g_strerror (errsv));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@@ -200,6 +200,28 @@ test_spawn_script (void)
|
|||||||
g_ptr_array_free (argv, TRUE);
|
g_ptr_array_free (argv, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test that spawning a non-existent executable returns %G_SPAWN_ERROR_NOENT. */
|
||||||
|
static void
|
||||||
|
test_spawn_nonexistent (void)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
GPtrArray *argv = NULL;
|
||||||
|
gchar *stdout_str = NULL;
|
||||||
|
gint exit_status = -1;
|
||||||
|
|
||||||
|
argv = g_ptr_array_new ();
|
||||||
|
g_ptr_array_add (argv, "this does not exist");
|
||||||
|
g_ptr_array_add (argv, NULL);
|
||||||
|
|
||||||
|
g_spawn_sync (NULL, (char**) argv->pdata, NULL, 0, NULL, NULL, &stdout_str,
|
||||||
|
NULL, &exit_status, &error);
|
||||||
|
g_assert_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT);
|
||||||
|
g_assert_null (stdout_str);
|
||||||
|
g_assert_cmpint (exit_status, ==, -1);
|
||||||
|
|
||||||
|
g_ptr_array_free (argv, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc,
|
main (int argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
@@ -230,6 +252,7 @@ main (int argc,
|
|||||||
g_test_add_func ("/gthread/spawn-single-sync", test_spawn_sync);
|
g_test_add_func ("/gthread/spawn-single-sync", test_spawn_sync);
|
||||||
g_test_add_func ("/gthread/spawn-single-async", test_spawn_async);
|
g_test_add_func ("/gthread/spawn-single-async", test_spawn_async);
|
||||||
g_test_add_func ("/gthread/spawn-script", test_spawn_script);
|
g_test_add_func ("/gthread/spawn-script", test_spawn_script);
|
||||||
|
g_test_add_func ("/gthread/spawn/nonexistent", test_spawn_nonexistent);
|
||||||
|
|
||||||
ret = g_test_run();
|
ret = g_test_run();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user