[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] Implement open-process and related functions on MinGW
From: |
Mark H Weaver |
Subject: |
Re: [PATCH] Implement open-process and related functions on MinGW |
Date: |
Sat, 22 Feb 2014 09:59:39 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) |
Eli Zaretskii <address@hidden> writes:
> This patch allows the MinGW build of Guile to have the process related
> functions (open-process, kill, waitpid, status:exit-val, etc.).
>
> Implement open-process and related functions on MinGW
>
> * libguile/filesys.c (fsync, link) [__MINGW32__]: Redirect Posix
> functions to their Windows equivalents.
Gnulib has an 'fsync' module that apparently implements it on MinGW.
I think we should use that instead, no?
> (scm_chown, scm_open_fdes, scm_open, scm_close, scm_close_fdes)
> (scm_link, scm_chdir, set_element, fill_select_type)
> (get_element, retrieve_select_type, scm_select, scm_fcntl)
> (scm_fsync, scm_symlink, scm_readlink, scm_copy_file, scm_sendfile)
> (scm_dir_print, scm_dir_free): These functions are no longer
> wholesale ifdef'ed away if HAVE_POSIX is not defined.
As I wrote in my other recent message, I think we should simply
recommend that MinGW builds be done without "--disable-posix", since we
have at least one report that it works now.
> (scm_init_filesys): Don't ifdef away parts of the function when
> HAVE_POSIX is not defined.
>
> diff --git a/libguile/posix.c b/libguile/posix.c
> index 0443f95..69652a3 100644
> --- a/libguile/posix.c
> +++ b/libguile/posix.c
> @@ -85,6 +85,27 @@
> #if HAVE_SYS_WAIT_H
> # include <sys/wait.h>
> #endif
> +#ifdef __MINGW32__
> +# define WEXITSTATUS(stat_val) ((stat_val) & 255)
> +/* Windows reports exit status from fatal exceptions as 0xC0000nnn
> + codes, see winbase.h. We usurp codes above 0xC0000200 for SIGxxx
> + signals. */
> +# define WIFEXITED(stat_val) (((stat_val) & 0xC0000000) == 0)
> +# define WIFSIGNALED(stat_val) (((stat_val) & 0xC0000000) != 0)
> +# define WTERMSIG(stat_val) ((stat_val > 0xC0000200) ? stat_val -
> 0xC0000200 : stat_val)
> +# define WIFSTOPPED(stat_val) (0)
> +# define WSTOPSIG(stat_var) (0)
> +# include <process.h>
> +# define waitpid(p,s,o) _cwait(s, p, WAIT_CHILD)
> +# define HAVE_WAITPID 1
> +# define getuid() (500) /* Local Administrator */
> +# define getgid() (513) /* None */
> +# define setuid(u) (0)
> +# define setgid(g) (0)
> +# define pipe(f) _pipe(f, 0, O_NOINHERIT)
> +# define WIN32_LEAN_AND_MEAN
> +# include <windows.h>
> +#endif
> #ifndef WEXITSTATUS
> # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
> #endif
> @@ -674,6 +695,25 @@ SCM_DEFINE (scm_kill, "kill", 2, 0, 0,
> goto err;
> }
> }
> +#ifdef __MINGW32__
> + else
> + {
> + HANDLE ph = OpenProcess (PROCESS_TERMINATE, 0, scm_to_int (pid));
> + int s = scm_to_int (sig);
> +
> + if (!ph)
> + {
> + errno = EPERM;
> + goto err;
> + }
> + if (!TerminateProcess (ph, 0xC0000200 + s))
> + {
> + errno = EINVAL;
> + goto err;
> + }
> + CloseHandle (ph);
> + }
> +#endif /* __MINGW32__ */
> #endif
> return SCM_UNSPECIFIED;
> }
> @@ -720,6 +760,7 @@ SCM_DEFINE (scm_waitpid, "waitpid", 1, 1, 0,
> {
> int i;
> int status;
> +#ifndef __MINGW32__
> int ioptions;
> if (SCM_UNBNDP (options))
> ioptions = 0;
> @@ -728,6 +769,7 @@ SCM_DEFINE (scm_waitpid, "waitpid", 1, 1, 0,
> /* Flags are interned in scm_init_posix. */
> ioptions = scm_to_int (options);
> }
> +#endif
> SCM_SYSCALL (i = waitpid (scm_to_int (pid), &status, ioptions));
> if (i == -1)
> SCM_SYSERROR;
> @@ -736,7 +778,6 @@ SCM_DEFINE (scm_waitpid, "waitpid", 1, 1, 0,
> #undef FUNC_NAME
> #endif /* HAVE_WAITPID */
>
> -#ifndef __MINGW32__
> SCM_DEFINE (scm_status_exit_val, "status:exit-val", 1, 0, 0,
> (SCM status),
> "Return the exit status value, as would be set if a process\n"
> @@ -787,7 +828,6 @@ SCM_DEFINE (scm_status_stop_sig, "status:stop-sig", 1, 0,
> 0,
> return SCM_BOOL_F;
> }
> #undef FUNC_NAME
> -#endif /* __MINGW32__ */
>
> #ifdef HAVE_GETPPID
> SCM_DEFINE (scm_getppid, "getppid", 0, 0, 0,
> @@ -802,7 +842,6 @@ SCM_DEFINE (scm_getppid, "getppid", 0, 0, 0,
> #endif /* HAVE_GETPPID */
>
>
> -#ifndef __MINGW32__
> SCM_DEFINE (scm_getuid, "getuid", 0, 0, 0,
> (),
> "Return an integer representing the current real user ID.")
> @@ -932,7 +971,6 @@ SCM_DEFINE (scm_setegid, "setegid", 1, 0, 0,
>
> }
> #undef FUNC_NAME
> -#endif
>
>
> #ifdef HAVE_GETPGRP
> @@ -1248,6 +1286,7 @@ SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0,
> return scm_from_int (pid);
> }
> #undef FUNC_NAME
> +#endif /* HAVE_FORK */
>
> /* Since Guile uses threads, we have to be very careful to avoid calling
> functions that are not async-signal-safe in the child. That's why
> @@ -1321,7 +1360,130 @@ scm_open_process (SCM mode, SCM prog, SCM args)
> }
> #endif
>
> +#ifdef HAVE_FORK
> pid = fork ();
> +#elif defined(__MINGW32__)
> + {
> + int save_stdin = -1, save_stdout = -1;
> + int errno_save;
> +
> + if (reading)
> + {
> + save_stdout = dup (1);
> + errno_save = errno;
> + if (save_stdout == -1)
> + {
> + close (c2p[0]);
> + close (c2p[1]);
> + free (exec_file);
> + errno = errno_save;
> + SCM_SYSERROR;
> + }
> + }
> +
> + if (writing)
> + {
> + save_stdin = dup (0);
> + errno_save = errno;
> + if (save_stdin == -1)
> + {
> + if (reading)
> + close (save_stdout);
> + close (p2c[0]);
> + close (p2c[1]);
> + free (exec_file);
> + errno = errno_save;
> + SCM_SYSERROR;
> + }
> + }
> +
> + if (reading)
> + {
> + close (1);
> + if (dup (c2p[1]) != 1)
> + {
> + errno_save = errno;
> + close (save_stdout);
> + close (c2p[0]);
> + close (c2p[1]);
> + if (writing)
> + {
> + close (save_stdin);
> + close (p2c[0]);
> + close (p2c[1]);
> + }
> + errno = errno_save;
> + SCM_SYSERROR;
> + }
> + close (c2p[1]);
> + }
> + if (writing)
> + {
> + close (0);
> + if (dup (p2c[0]) != 0)
> + {
> + errno_save = errno;
> + close (save_stdin);
> + close (p2c[0]);
> + close (p2c[1]);
> + if (reading)
> + {
> + close (save_stdout);
> + close (c2p[0]);
> + close (c2p[1]);
> + }
> + errno = errno_save;
> + SCM_SYSERROR;
> + }
> + close (p2c[0]);
> + }
> +
> + pid = spawnvp (P_NOWAIT, exec_file, exec_argv);
> + errno_save = errno;
> +
> + if (reading)
> + {
> + close (1);
> + if (dup (save_stdout) != 1)
> + {
> + if (writing)
> + close (save_stdin);
> + close (save_stdout);
> + close (p2c[1]);
> + close (c2p[0]);
> + errno = errno_save;
> + SCM_SYSERROR;
> + }
> + close (save_stdout);
> + }
> + if (writing)
> + {
> + close (0);
> + if (dup (save_stdin) != 0)
> + {
> + if (reading)
> + close (save_stdout);
> + close (save_stdin);
> + close (p2c[1]);
> + close (c2p[0]);
> + errno = errno_save;
> + SCM_SYSERROR;
> + }
> + close (save_stdin);
> + }
> +
> + if (pid < 0)
> + errno = errno_save;
> + }
> +#else
> + close (c2p[0]);
> + close (c2p[1]);
> + close (p2c[0]);
> + close (p2c[1]);
> + free (exec_file);
> + errno = ENOSYS;
> + SCM_SYSERROR;
> +#endif /* HAVE_FORK */
>
> if (pid == -1)
> {
> @@ -1330,14 +1492,28 @@ scm_open_process (SCM mode, SCM prog, SCM args)
> if (reading)
> {
> close (c2p[0]);
> +#ifdef HAVE_FORK
> close (c2p[1]);
> +#endif
> }
> if (writing)
> {
> +#ifdef HAVE_FORK
> close (p2c[0]);
> +#endif
> close (p2c[1]);
> }
> errno = errno_save;
> +
> +#ifndef HAVE_FORK
> + /* The exec failed! There is nothing sensible to do. */
> + if (err > 0)
> + {
> + char *msg = strerror (errno);
> + fprintf (fdopen (err, "a"), "In spawnvp of %s: %s\n",
> + exec_file, msg);
> + }
> +#endif
> SCM_SYSERROR;
> }
>
> @@ -1363,7 +1539,8 @@ scm_open_process (SCM mode, SCM prog, SCM args)
> return scm_values
> (scm_list_3 (read_port, write_port, scm_from_int (pid)));
> }
> -
> +
> +#ifdef HAVE_FORK
> /* The child. */
> if (reading)
> close (c2p[0]);
> @@ -1412,16 +1589,16 @@ scm_open_process (SCM mode, SCM prog, SCM args)
> if (err > 0)
> {
> char *msg = strerror (errno);
> - fprintf (fdopen (err, "a"), "In execlp of %s: %s\n",
> + fprintf (fdopen (err, "a"), "In execvp of %s: %s\n",
> exec_file, msg);
> }
>
> _exit (EXIT_FAILURE);
> /* Not reached. */
> return SCM_BOOL_F;
> +#endif /* HAVE_FORK */
> }
> #undef FUNC_NAME
> -#endif /* HAVE_FORK */
>
> #ifdef __MINGW32__
> # include "win32-uname.h"
> @@ -2239,13 +2416,11 @@ SCM_DEFINE (scm_gethostname, "gethostname", 0, 0, 0,
> #endif /* HAVE_GETHOSTNAME */
>
>
> -#ifdef HAVE_FORK
> static void
> scm_init_popen (void)
> {
> scm_c_define_gsubr ("open-process", 2, 0, 1, scm_open_process);
> }
> -#endif
>
> void
> scm_init_posix ()
> @@ -2338,11 +2513,11 @@ scm_init_posix ()
>
> #ifdef HAVE_FORK
> scm_add_feature ("fork");
> +#endif /* HAVE_FORK */
> scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
> "scm_init_popen",
> (scm_t_extension_init_func) scm_init_popen,
> NULL);
> -#endif /* HAVE_FORK */
> }
>
> /*
- Re: [PATCH v2] Improved ^c support for gdb/guile, (continued)
- MinGW patches, Ludovic Courtès, 2014/02/18
- Re: MinGW patches, Eli Zaretskii, 2014/02/18
- [PATCH] Remove unneeded HAVE_POSIX conditionals, Eli Zaretskii, 2014/02/22
- Re: [PATCH] Remove unneeded HAVE_POSIX conditionals, Mark H Weaver, 2014/02/22
- Re: [PATCH] Remove unneeded HAVE_POSIX conditionals, Eli Zaretskii, 2014/02/22
- Re: [PATCH] Remove unneeded HAVE_POSIX conditionals, Ludovic Courtès, 2014/02/26
- [PATCH] Implement open-process and related functions on MinGW, Eli Zaretskii, 2014/02/22
- Re: [PATCH] Implement open-process and related functions on MinGW,
Mark H Weaver <=
- Re: [PATCH] Implement open-process and related functions on MinGW, Eli Zaretskii, 2014/02/22
- Re: [PATCH] Implement open-process and related functions on MinGW, Mark H Weaver, 2014/02/22
- Re: [PATCH] Implement open-process and related functions on MinGW, Eli Zaretskii, 2014/02/22
- Re: [PATCH] Implement open-process and related functions on MinGW, Mark H Weaver, 2014/02/23
- Re: [PATCH] Implement open-process and related functions on MinGW, Eli Zaretskii, 2014/02/23
- Re: [PATCH] Implement open-process and related functions on MinGW, Mark H Weaver, 2014/02/24
- Re: [PATCH] Implement open-process and related functions on MinGW, Eli Zaretskii, 2014/02/24
- Re: [PATCH] Implement open-process and related functions on MinGW, Mark H Weaver, 2014/02/28
- Re: [PATCH] Implement open-process and related functions on MinGW, Eli Zaretskii, 2014/02/28
- Re: [PATCH] Implement open-process and related functions on MinGW, Mark H Weaver, 2014/02/28