process 1.2.3.0 → 1.3.0.0
raw patch · 8 files changed
+203/−117 lines, 8 filesnew-uploader
Files
- System/Process.hsc +15/−10
- System/Process/Internals.hs +34/−9
- cbits/runProcess.c +21/−0
- changelog.md +6/−0
- configure +107/−97
- include/processFlags.h +3/−0
- process.cabal +1/−1
- test/main.hs +16/−0
System/Process.hsc view
@@ -91,7 +91,6 @@ # include <io.h> /* for _close and _pipe */ # include <fcntl.h> /* for _O_BINARY */ import Control.Exception (onException)-import Foreign.C.Types (CInt(..), CUInt(..)) #else import System.Posix.Process (getProcessGroupIDOf) import qualified System.Posix.IO as Posix@@ -124,7 +123,10 @@ std_err = Inherit, close_fds = False, create_group = False,- delegate_ctlc = False}+ delegate_ctlc = False,+ detach_console = False,+ create_new_console = False,+ new_session = False } -- | Construct a 'CreateProcess' record for passing to 'createProcess', -- representing a command to be passed to the shell.@@ -137,7 +139,10 @@ std_err = Inherit, close_fds = False, create_group = False,- delegate_ctlc = False}+ delegate_ctlc = False,+ detach_console = False,+ create_new_console = False,+ new_session = False } {- | This is the most general way to spawn an external process. The@@ -269,7 +274,7 @@ -- arguments. It does not wait for the program to finish, but returns the -- 'ProcessHandle'. ----- /Since: 1.2.0.0/+-- @since 1.2.0.0 spawnProcess :: FilePath -> [String] -> IO ProcessHandle spawnProcess cmd args = do (_,_,_,p) <- createProcess_ "spawnProcess" (proc cmd args)@@ -278,7 +283,7 @@ -- | Creates a new process to run the specified shell command. -- It does not wait for the program to finish, but returns the 'ProcessHandle'. ----- /Since: 1.2.0.0/+-- @since 1.2.0.0 spawnCommand :: String -> IO ProcessHandle spawnCommand cmd = do (_,_,_,p) <- createProcess_ "spawnCommand" (shell cmd)@@ -297,7 +302,7 @@ -- @callProcess@ will wait (block) until the process has been -- terminated. ----- /Since: 1.2.0.0/+-- @since 1.2.0.0 callProcess :: FilePath -> [String] -> IO () callProcess cmd args = do exit_code <- withCreateProcess_ "callProcess"@@ -315,7 +320,7 @@ -- @callCommand@ will wait (block) until the process has been -- terminated. ----- /Since: 1.2.0.0/+-- @since 1.2.0.0 callCommand :: String -> IO () callCommand cmd = do exit_code <- withCreateProcess_ "callCommand"@@ -425,7 +430,7 @@ -- -- Note that @Handle@s provided for @std_in@ or @std_out@ via the CreateProcess -- record will be ignored.--- /Since: 1.2.3.0/+-- @since 1.2.3.0 readCreateProcess :: CreateProcess@@ -494,7 +499,7 @@ -- Note that @Handle@s provided for @std_in@, @std_out@, or @std_err@ via the CreateProcess -- record will be ignored. ----- /Since: 1.2.3.0/+-- @since 1.2.3.0 readCreateProcessWithExitCode :: CreateProcess -> String -- ^ standard input@@ -929,7 +934,7 @@ -- | Create a pipe for interprocess communication and return a -- @(readEnd, writeEnd)@ `Handle` pair. ----- /Since: 1.2.1.0/+-- @since 1.2.1.0 createPipe :: IO (Handle, Handle) #if !mingw32_HOST_OS createPipe = do
System/Process/Internals.hs view
@@ -177,11 +177,22 @@ std_err :: StdStream, -- ^ How to determine stderr close_fds :: Bool, -- ^ Close all file descriptors except stdin, stdout and stderr in the new process (on Windows, only works if std_in, std_out, and std_err are all Inherit) create_group :: Bool, -- ^ Create a new process group- delegate_ctlc:: Bool -- ^ Delegate control-C handling. Use this for interactive console processes to let them handle control-C themselves (see below for details).+ delegate_ctlc:: Bool, -- ^ Delegate control-C handling. Use this for interactive console processes to let them handle control-C themselves (see below for details). -- -- On Windows this has no effect. --- -- /Since: 1.2.0.0/+ -- @since 1.2.0.0+ detach_console :: Bool, -- ^ Use the windows DETACHED_PROCESS flag when creating the process; does nothing on other platforms.+ --+ -- @since 1.3.0.0+ create_new_console :: Bool, -- ^ Use the windows CREATE_NEW_CONSOLE flag when creating the process; does nothing on other platforms.+ --+ -- Default: @False@+ --+ -- @since 1.3.0.0+ new_session :: Bool -- ^ Use posix setsid to start the new process in a new session; does nothing on other platforms.+ --+ -- @since 1.3.0.0 } data CmdSpec@@ -213,7 +224,7 @@ -- | construct a `ShellCommand` from a string literal ----- /Since: 1.2.1.0/+-- @since 1.2.1.0 instance IsString CmdSpec where fromString = ShellCommand @@ -224,6 +235,7 @@ -- @Handle@ will use the default encoding -- and newline translation mode (just -- like @Handle@s created by @openFile@).+ | NoStream -- ^ No stream handle will be passed -- | This function is almost identical to -- 'System.Process.createProcess'. The only differences are:@@ -237,7 +249,7 @@ -- for some time, and is part of the "System.Process" module since version -- 1.2.1.0. ----- /Since: 1.2.1.0/+-- @since 1.2.1.0 createProcess_ :: String -- ^ function name (for error messages) -> CreateProcess@@ -258,7 +270,10 @@ std_err = mb_stderr, close_fds = mb_close_fds, create_group = mb_create_group,- delegate_ctlc = mb_delegate_ctlc }+ delegate_ctlc = mb_delegate_ctlc,+ detach_console = mb_detach_console,+ create_new_console = mb_create_new_console,+ new_session = mb_new_session } = do let (cmd,args) = commandToProcess cmdsp withFilePathException cmd $@@ -288,7 +303,10 @@ pfdStdInput pfdStdOutput pfdStdError (if mb_delegate_ctlc then 1 else 0) ((if mb_close_fds then RUN_PROCESS_IN_CLOSE_FDS else 0)- .|.(if mb_create_group then RUN_PROCESS_IN_NEW_GROUP else 0))+ .|.(if mb_create_group then RUN_PROCESS_IN_NEW_GROUP else 0)+ .|.(if mb_detach_console then RUN_PROCESS_DETACHED else 0)+ .|.(if mb_create_new_console then RUN_PROCESS_NEW_CONSOLE else 0)+ .|.(if mb_new_session then RUN_PROCESS_NEW_SESSION else 0)) pFailedDoing when (proc_handle == -1) $ do@@ -419,7 +437,10 @@ std_err = mb_stderr, close_fds = mb_close_fds, create_group = mb_create_group,- delegate_ctlc = _ignored }+ delegate_ctlc = _ignored,+ detach_console = mb_detach_console,+ create_new_console = mb_create_new_console,+ new_session = mb_new_session } = do (cmd, cmdline) <- commandToProcess cmdsp withFilePathException cmd $@@ -450,7 +471,10 @@ fdin fdout fderr pfdStdInput pfdStdOutput pfdStdError ((if mb_close_fds then RUN_PROCESS_IN_CLOSE_FDS else 0)- .|.(if mb_create_group then RUN_PROCESS_IN_NEW_GROUP else 0))+ .|.(if mb_create_group then RUN_PROCESS_IN_NEW_GROUP else 0)+ .|.(if mb_detach_console then RUN_PROCESS_DETACHED else 0)+ .|.(if mb_create_new_console then RUN_PROCESS_NEW_CONSOLE else 0)+ .|.(if mb_new_session then RUN_PROCESS_NEW_SESSION else 0)) hndStdInput <- mbPipe mb_stdin pfdStdInput WriteMode hndStdOutput <- mbPipe mb_stdout pfdStdOutput ReadMode@@ -503,6 +527,7 @@ mbFd :: String -> FD -> StdStream -> IO FD mbFd _ _std CreatePipe = return (-1) mbFd _fun std Inherit = return std+mbFd _fn _std NoStream = return (-2) mbFd fun _std (UseHandle hdl) = withHandle fun hdl $ \Handle__{haDevice=dev,..} -> case cast dev of@@ -634,7 +659,7 @@ traditional argument vector argv[0], argv[1], etc. It does this using a complex and arcane set of rules which are described here: - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/progs_12.asp+ https://msdn.microsoft.com/en-us/library/a1y7w461.aspx (if this URL stops working, you might be able to find it by searching for "Parsing C Command-Line Arguments" on MSDN. Also,
cbits/runProcess.c view
@@ -138,6 +138,9 @@ close(forkCommunicationFds[0]); fcntl(forkCommunicationFds[1], F_SETFD, FD_CLOEXEC); + if ((flags & RUN_PROCESS_NEW_SESSION) != 0) {+ setsid();+ } if ((flags & RUN_PROCESS_IN_NEW_GROUP) != 0) { setpgid(0, 0); }@@ -162,6 +165,8 @@ close(fdStdInput[0]); } close(fdStdInput[1]);+ } else if (fdStdIn == -2) {+ close(STDIN_FILENO); } else { dup2(fdStdIn, STDIN_FILENO); }@@ -172,6 +177,8 @@ close(fdStdOutput[1]); } close(fdStdOutput[0]);+ } else if (fdStdOut == -2) {+ close(STDOUT_FILENO); } else { dup2(fdStdOut, STDOUT_FILENO); }@@ -182,6 +189,8 @@ close(fdStdError[1]); } close(fdStdError[0]);+ } else if (fdStdErr == -2) {+ close(STDERR_FILENO); } else { dup2(fdStdErr, STDERR_FILENO); }@@ -481,6 +490,8 @@ if (!mkAnonPipe(&hStdInputRead, TRUE, &hStdInputWrite, FALSE)) goto cleanup_err; sInfo.hStdInput = hStdInputRead;+ } else if (fdStdIn == -2) {+ sInfo.hStdInput = NULL; } else if (fdStdIn == 0) { // Don't duplicate stdin, as console handles cannot be // duplicated and inherited. urg.@@ -501,6 +512,8 @@ if (!mkAnonPipe(&hStdOutputRead, FALSE, &hStdOutputWrite, TRUE)) goto cleanup_err; sInfo.hStdOutput = hStdOutputWrite;+ } else if (fdStdOut == -2) {+ sInfo.hStdOutput = NULL; } else if (fdStdOut == 1) { // Don't duplicate stdout, as console handles cannot be // duplicated and inherited. urg.@@ -521,6 +534,8 @@ if (!mkAnonPipe(&hStdErrorRead, TRUE, &hStdErrorWrite, TRUE)) goto cleanup_err; sInfo.hStdError = hStdErrorWrite;+ } else if (fdStdErr == -2) {+ sInfo.hStdError = NULL; } else if (fdStdErr == 2) { // Don't duplicate stderr, as console handles cannot be // duplicated and inherited. urg.@@ -552,6 +567,12 @@ if ((flags & RUN_PROCESS_IN_NEW_GROUP) != 0) { dwFlags |= CREATE_NEW_PROCESS_GROUP;+ }+ if ((flags & RUN_PROCESS_DETACHED) != 0) {+ dwFlags |= DETACHED_PROCESS;+ }+ if ((flags & RUN_PROCESS_NEW_CONSOLE) != 0) {+ dwFlags |= CREATE_NEW_CONSOLE; } if (!CreateProcess(NULL, cmd, NULL, NULL, inherit, dwFlags, environment, workingDirectory, &sInfo, &pInfo))
changelog.md view
@@ -1,5 +1,11 @@ # Changelog for [`process` package](http://hackage.haskell.org/package/process) +## 1.3.0.0 (unreleased)++* Add `StdStream(NoStream)` to have standard handles closed. [#13](https://github.com/haskell/process/pull/13)+* Support for Windows `DETACHED_PROCESS` and `setsid` [#32](https://github.com/haskell/process/issues/32)+* Support for Windows `CREATE_NEW_CONSOLE` [#38](https://github.com/haskell/process/issues/38)+ ## 1.2.3.0 *March 2015* * [Meaningful error message when exe not found on close\_fds is
configure view
@@ -1,13 +1,11 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles.-# Generated by GNU Autoconf 2.68 for Haskell process package 1.0.+# Generated by GNU Autoconf 2.69 for Haskell process package 1.0. # # Report bugs to <libraries@haskell.org>. # #-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software-# Foundation, Inc.+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation@@ -136,6 +134,31 @@ # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH +# Use a proper internal environment variable to ensure we don't fall+ # into an infinite loop, continuously re-executing ourselves.+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then+ _as_can_reexec=no; export _as_can_reexec;+ # We cannot yet assume a decent shell, so we have to provide a+# neutralization value for shells without unset; and this also+# works around shells that cannot unset nonexistent variables.+# Preserve -v and -x to the replacement shell.+BASH_ENV=/dev/null+ENV=/dev/null+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV+case $- in # ((((+ *v*x* | *x*v* ) as_opts=-vx ;;+ *v* ) as_opts=-v ;;+ *x* ) as_opts=-x ;;+ * ) as_opts= ;;+esac+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}+# Admittedly, this is quite paranoid, since all the known shells bail+# out after a failed `exec'.+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2+as_fn_exit 255+ fi+ # We don't want this to propagate to other subprocesses.+ { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh@@ -169,7 +192,8 @@ else exitcode=1; echo positional parameters were not saved. fi-test x\$exitcode = x0 || exit 1"+test x\$exitcode = x0 || exit 1+test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&@@ -214,21 +238,25 @@ if test "x$CONFIG_SHELL" != x; then :- # We cannot yet assume a decent shell, so we have to provide a- # neutralization value for shells without unset; and this also- # works around shells that cannot unset nonexistent variables.- # Preserve -v and -x to the replacement shell.- BASH_ENV=/dev/null- ENV=/dev/null- (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV- export CONFIG_SHELL- case $- in # ((((- *v*x* | *x*v* ) as_opts=-vx ;;- *v* ) as_opts=-v ;;- *x* ) as_opts=-x ;;- * ) as_opts= ;;- esac- exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}+ export CONFIG_SHELL+ # We cannot yet assume a decent shell, so we have to provide a+# neutralization value for shells without unset; and this also+# works around shells that cannot unset nonexistent variables.+# Preserve -v and -x to the replacement shell.+BASH_ENV=/dev/null+ENV=/dev/null+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV+case $- in # ((((+ *v*x* | *x*v* ) as_opts=-vx ;;+ *v* ) as_opts=-v ;;+ *x* ) as_opts=-x ;;+ * ) as_opts= ;;+esac+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}+# Admittedly, this is quite paranoid, since all the known shells bail+# out after a failed `exec'.+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2+exit 255 fi if test x$as_have_required = xno; then :@@ -331,6 +359,14 @@ } # as_fn_mkdir_p++# as_fn_executable_p FILE+# -----------------------+# Test if FILE is an executable regular file.+as_fn_executable_p ()+{+ test -f "$1" && test -x "$1"+} # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take@@ -452,6 +488,10 @@ chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have+ # already done that, so ensure we don't try to do so again and fall+ # in an infinite loop. This has already happened in practice.+ _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this).@@ -486,16 +526,16 @@ # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.- # In both cases, we have to default to `cp -p'.+ # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||- as_ln_s='cp -p'+ as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else- as_ln_s='cp -p'+ as_ln_s='cp -pR' fi else- as_ln_s='cp -p'+ as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null@@ -507,28 +547,8 @@ as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then- as_test_x='test -x'-else- if ls -dL / >/dev/null 2>&1; then- as_ls_L_option=L- else- as_ls_L_option=- fi- as_test_x='- eval sh -c '\''- if test -d "$1"; then- test -d "$1/.";- else- case $1 in #(- -*)set "./$1";;- esac;- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((- ???[sx]*):;;*)false;;esac;fi- '\'' sh- '-fi-as_executable_p=$as_test_x+as_test_x='test -x'+as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"@@ -1121,8 +1141,6 @@ if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe- $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.- If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi@@ -1355,9 +1373,9 @@ if $ac_init_version; then cat <<\_ACEOF Haskell process package configure 1.0-generated by GNU Autoconf 2.68+generated by GNU Autoconf 2.69 -Copyright (C) 2010 Free Software Foundation, Inc.+Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF@@ -1688,7 +1706,7 @@ test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes ||- $as_test_x conftest$ac_exeext+ test -x conftest$ac_exeext }; then : ac_retval=0 else@@ -1791,7 +1809,8 @@ main () { static int test_array [1 - 2 * !(($2) >= 0)];-test_array [0] = 0+test_array [0] = 0;+return test_array [0]; ; return 0;@@ -1807,7 +1826,8 @@ main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)];-test_array [0] = 0+test_array [0] = 0;+return test_array [0]; ; return 0;@@ -1833,7 +1853,8 @@ main () { static int test_array [1 - 2 * !(($2) < 0)];-test_array [0] = 0+test_array [0] = 0;+return test_array [0]; ; return 0;@@ -1849,7 +1870,8 @@ main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)];-test_array [0] = 0+test_array [0] = 0;+return test_array [0]; ; return 0;@@ -1883,7 +1905,8 @@ main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)];-test_array [0] = 0+test_array [0] = 0;+return test_array [0]; ; return 0;@@ -1956,7 +1979,7 @@ running configure, to aid debugging if configure makes a mistake. It was created by Haskell process package $as_me 1.0, which was-generated by GNU Autoconf 2.68. Invocation command line was+generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2338,7 +2361,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2@@ -2378,7 +2401,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2@@ -2431,7 +2454,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2@@ -2472,7 +2495,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue@@ -2530,7 +2553,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2@@ -2574,7 +2597,7 @@ IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2@@ -3020,8 +3043,7 @@ /* end confdefs.h. */ #include <stdarg.h> #include <stdio.h>-#include <sys/types.h>-#include <sys/stat.h>+struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int);@@ -3262,7 +3284,7 @@ for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"- { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue+ as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in@@ -3328,7 +3350,7 @@ for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"- { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue+ as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in@@ -4192,16 +4214,16 @@ # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.- # In both cases, we have to default to `cp -p'.+ # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||- as_ln_s='cp -p'+ as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else- as_ln_s='cp -p'+ as_ln_s='cp -pR' fi else- as_ln_s='cp -p'+ as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null@@ -4261,29 +4283,17 @@ as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then- as_test_x='test -x'-else- if ls -dL / >/dev/null 2>&1; then- as_ls_L_option=L- else- as_ls_L_option=- fi- as_test_x='- eval sh -c '\''- if test -d "$1"; then- test -d "$1/.";- else- case $1 in #(- -*)set "./$1";;- esac;- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((- ???[sx]*):;;*)false;;esac;fi- '\'' sh- '-fi-as_executable_p=$as_test_x +# as_fn_executable_p FILE+# -----------------------+# Test if FILE is an executable regular file.+as_fn_executable_p ()+{+ test -f "$1" && test -x "$1"+} # as_fn_executable_p+as_test_x='test -x'+as_executable_p=as_fn_executable_p+ # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -4304,7 +4314,7 @@ # values after options handling. ac_log=" This file was extended by Haskell process package $as_me 1.0, which was-generated by GNU Autoconf 2.68. Invocation command line was+generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS@@ -4357,10 +4367,10 @@ ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ Haskell process package config.status 1.0-configured by $0, generated by GNU Autoconf 2.68,+configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" -Copyright (C) 2010 Free Software Foundation, Inc.+Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -4440,7 +4450,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then- set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL'
include/processFlags.h view
@@ -6,3 +6,6 @@ #define RUN_PROCESS_IN_CLOSE_FDS 0x1 #define RUN_PROCESS_IN_NEW_GROUP 0x2+#define RUN_PROCESS_DETACHED 0x4+#define RUN_PROCESS_NEW_SESSION 0x8+#define RUN_PROCESS_NEW_CONSOLE 0x10
process.cabal view
@@ -1,5 +1,5 @@ name: process-version: 1.2.3.0+version: 1.3.0.0 -- NOTE: Don't forget to update ./changelog.md license: BSD3 license-file: LICENSE
test/main.hs view
@@ -1,4 +1,5 @@ import Control.Exception+import System.Exit import System.IO.Error import System.Process @@ -12,3 +13,18 @@ case res of Left True -> return () _ -> error $ show res++ let test name modifier = do+ putStrLn $ "Running test: " ++ name+ (_, _, _, ph) <- createProcess+ $ modifier $ proc "echo" ["hello", "world"]+ ec <- waitForProcess ph+ if ec == ExitSuccess+ then putStrLn $ "Success running: " ++ name+ else error $ "echo returned: " ++ show ec++ test "detach_console" $ \cp -> cp { detach_console = True }+ test "create_new_console" $ \cp -> cp { create_new_console = True }+ test "new_session" $ \cp -> cp { new_session = True }++ putStrLn "Tests passed successfully"