Subprocesses (was: [ANNOUNCE] shell-haskell 1.0.0)

Daan Leijen daan@cs.uu.nl
Fri, 9 May 2003 12:51:56 +0200


This is a multi-part message in MIME format.

------=_NextPart_000_00B0_01C31629.C5998A30
Content-Type: multipart/alternative;
	boundary="----=_NextPart_001_00B1_01C31629.C59B10D0"


------=_NextPart_001_00B1_01C31629.C59B10D0
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Sigh, I just realised you need to have the stylesheet
to see the documentation properly --- so here is a new
version with the style sheet inlined.

-- Daan.
  ----- Original Message -----=20
  From: Daan Leijen=20
  To: Simon Marlow ; libraries@haskell.org=20
  Sent: Friday, May 09, 2003 12:45 PM
  Subject: Re: Subprocesses (was: [ANNOUNCE] shell-haskell 1.0.0)


  Hi all,

  I have implemented a generalised library for communicating with child =
processes some
  time ago for windows (but it is easy to implement for unix's too).  I =
believe that
  the interface encompasses all current mechanism around  (system, =
runProcess, popen, launch).

  Basically, it allows one to create pipes in Haskell that can be read =
and written just like
  normal file "Handle"s. Furthermore, you can start a child process that =
can get its stdin, stdout,
  and stderr redirected to one of those pipes. This "runProcess" call is =
basically the same to
  "Posix.runProcess".

  I have attached the documentation and description of the functions to =
this mail in HTML format.
  It also contains an example of a "spawn" function that closely =
resemebles the "launch" function
  of shell-haskell.

  I think that this interface is a good starting point for a discussion =
on the final library interface
  for sub-processes.

  All the best,
    Daan.


  ----- Original Message -----
  From: "Simon Marlow" <simonmar@microsoft.com>
  To: <libraries@haskell.org>
  Sent: Friday, May 09, 2003 12:03 PM
  Subject: Subprocesses (was: [ANNOUNCE] shell-haskell 1.0.0)


  > Libraries people,
  >
  > There are currently two ways to create and communicate with external
  > processes:
  >
  >   - System.Cmd.system  (very basic, doesn't give you access to the
  >     process's output but you can use shell primitives to redirect =
its
  >     input/output).
  >
  >   - Posix.runProcess (can specify Handles for the process's
  > input/output,
  >     but it doesn't create pipes so you can't actually communicate =
with
  >     the subprocess using these Handles.).
  >
  >   - POpen.popen (can specify an input String, and gives you lazy =
output
  >     Strings.  No interactive communication is possible.)
  >
  > Ok, *three* ways.  System.Cmd.system, Posix.runProcess, POpen.popen, =
and
  > shell-haskell.  Er.  *Four* ways.
  >
  > David Sankel's shell-haskell creates pipes for stdin/stdout/stderr, =
and
  > lets you communicate interactively with the sub-process via Handles. =
 It
  > could do with a way to specify the environment and working directory =
of
  > the sub-process (ala POpen and runProcess), but apart from that it =
seems
  > to be the most flexible of the four.  It could be simplified =
slightly by
  > using one Handle rather than two for stdin/stdout.
  >
  > We should think about what functionality we want to provide in the =
core
  > libraries.  My preference would be to go for a full version with =
three
  > pipes (like shell-haskell) and perhaps one or two more specialised
  > versions covering common cases (I don't know what these should be,
  > though).
  >
  > What do people think?
  >
  > Cheers,
  > Simon
  >
  > -----Original Message-----
  > From: haskell-admin@haskell.org [mailto:haskell-admin@haskell.org] =
On
  > Behalf Of David Sankel
  > Sent: 06 May 2003 03:06
  > To: haskell@haskell.org
  > Subject: [ANNOUNCE] shell-haskell 1.0.0
  >
  > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  > shell-haskell 1.0.0
  > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
  >
  >   shell-haskell provides utilities to communicate with
  > other process's via Haskell code.  This library can be
  > used for something as simple as getting the output of
  > another program or as complex as interacting with an
  > interpreter.
  >
  > see
  >
  >   http://www.electronconsulting.com/shell-haskell
  >
  > for details.
  >
  > David J. Sankel
  > _______________________________________________
  > Haskell mailing list
  > Haskell@haskell.org
  > http://www.haskell.org/mailman/listinfo/haskell
  >
  >
  > _______________________________________________
  > Libraries mailing list
  > Libraries@haskell.org
  > http://www.haskell.org/mailman/listinfo/libraries
  >
  >
  >


------=_NextPart_001_00B1_01C31629.C59B10D0
Content-Type: text/html;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2713.1100" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2>Sigh, I just realised you need to have =
the=20
stylesheet</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>to see the documentation properly --- =
so here is a=20
new</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>version with the style sheet =
inlined.</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>-- Daan.</FONT></DIV>
<BLOCKQUOTE=20
style=3D"PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; =
BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
  <DIV style=3D"FONT: 10pt arial">----- Original Message ----- </DIV>
  <DIV=20
  style=3D"BACKGROUND: #e4e4e4; FONT: 10pt arial; font-color: =
black"><B>From:</B>=20
  <A title=3Ddaan@cs.uu.nl href=3D"mailto:daan@cs.uu.nl">Daan Leijen</A> =
</DIV>
  <DIV style=3D"FONT: 10pt arial"><B>To:</B> <A =
title=3Dsimonmar@microsoft.com=20
  href=3D"mailto:simonmar@microsoft.com">Simon Marlow</A> ; <A=20
  title=3Dlibraries@haskell.org=20
  href=3D"mailto:libraries@haskell.org">libraries@haskell.org</A> </DIV>
  <DIV style=3D"FONT: 10pt arial"><B>Sent:</B> Friday, May 09, 2003 =
12:45 PM</DIV>
  <DIV style=3D"FONT: 10pt arial"><B>Subject:</B> Re: Subprocesses (was: =

  [ANNOUNCE] shell-haskell 1.0.0)</DIV>
  <DIV><BR></DIV>Hi all,<BR><BR>I have implemented a generalised library =
for=20
  communicating with child processes some<BR>time ago for windows (but =
it is=20
  easy to implement for unix's too).&nbsp; I believe that<BR>the =
interface=20
  encompasses all current mechanism around&nbsp; (system, runProcess, =
popen,=20
  launch).<BR><BR>Basically, it allows one to create pipes in Haskell =
that can=20
  be read and written just like<BR>normal file "Handle"s. Furthermore, =
you can=20
  start a child process that can get its stdin, stdout,<BR>and stderr =
redirected=20
  to one of those pipes. This "runProcess" call is basically the same=20
  to<BR>"Posix.runProcess".<BR><BR>I have attached the documentation and =

  description of the functions to this mail in HTML format.<BR>It also =
contains=20
  an example of a "spawn" function that closely resemebles the "launch"=20
  function<BR>of shell-haskell.<BR><BR>I think that this interface is a =
good=20
  starting point for a discussion on the final library interface<BR>for=20
  sub-processes.<BR><BR>All the best,<BR>&nbsp; Daan.<BR><BR><BR>----- =
Original=20
  Message -----<BR>From: "Simon Marlow" =
&lt;simonmar@microsoft.com&gt;<BR>To:=20
  &lt;libraries@haskell.org&gt;<BR>Sent: Friday, May 09, 2003 12:03=20
  PM<BR>Subject: Subprocesses (was: [ANNOUNCE] shell-haskell=20
  1.0.0)<BR><BR><BR>&gt; Libraries people,<BR>&gt;<BR>&gt; There are =
currently=20
  two ways to create and communicate with external<BR>&gt;=20
  processes:<BR>&gt;<BR>&gt;&nbsp;&nbsp; - System.Cmd.system&nbsp; (very =
basic,=20
  doesn't give you access to the<BR>&gt;&nbsp;&nbsp;&nbsp;&nbsp; =
process's=20
  output but you can use shell primitives to redirect=20
  its<BR>&gt;&nbsp;&nbsp;&nbsp;&nbsp; =
input/output).<BR>&gt;<BR>&gt;&nbsp;&nbsp;=20
  - Posix.runProcess (can specify Handles for the process's<BR>&gt;=20
  input/output,<BR>&gt;&nbsp;&nbsp;&nbsp;&nbsp; but it doesn't create =
pipes so=20
  you can't actually communicate with<BR>&gt;&nbsp;&nbsp;&nbsp;&nbsp; =
the=20
  subprocess using these Handles.).<BR>&gt;<BR>&gt;&nbsp;&nbsp; - =
POpen.popen=20
  (can specify an input String, and gives you lazy=20
  output<BR>&gt;&nbsp;&nbsp;&nbsp;&nbsp; Strings.&nbsp; No interactive=20
  communication is possible.)<BR>&gt;<BR>&gt; Ok, *three* ways.&nbsp;=20
  System.Cmd.system, Posix.runProcess, POpen.popen, and<BR>&gt;=20
  shell-haskell.&nbsp; Er.&nbsp; *Four* ways.<BR>&gt;<BR>&gt; David =
Sankel's=20
  shell-haskell creates pipes for stdin/stdout/stderr, and<BR>&gt; lets =
you=20
  communicate interactively with the sub-process via Handles.&nbsp; =
It<BR>&gt;=20
  could do with a way to specify the environment and working directory=20
  of<BR>&gt; the sub-process (ala POpen and runProcess), but apart from =
that it=20
  seems<BR>&gt; to be the most flexible of the four.&nbsp; It could be=20
  simplified slightly by<BR>&gt; using one Handle rather than two for=20
  stdin/stdout.<BR>&gt;<BR>&gt; We should think about what functionality =
we want=20
  to provide in the core<BR>&gt; libraries.&nbsp; My preference would be =
to go=20
  for a full version with three<BR>&gt; pipes (like shell-haskell) and =
perhaps=20
  one or two more specialised<BR>&gt; versions covering common cases (I =
don't=20
  know what these should be,<BR>&gt; though).<BR>&gt;<BR>&gt; What do =
people=20
  think?<BR>&gt;<BR>&gt; Cheers,<BR>&gt; Simon<BR>&gt;<BR>&gt; =
-----Original=20
  Message-----<BR>&gt; From: haskell-admin@haskell.org=20
  [mailto:haskell-admin@haskell.org] On<BR>&gt; Behalf Of David =
Sankel<BR>&gt;=20
  Sent: 06 May 2003 03:06<BR>&gt; To: haskell@haskell.org<BR>&gt; =
Subject:=20
  [ANNOUNCE] shell-haskell 1.0.0<BR>&gt;<BR>&gt; =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D<BR>&gt;=20
  shell-haskell 1.0.0<BR>&gt; =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D<BR>&gt;<BR>&gt;=
&nbsp;&nbsp;=20
  shell-haskell provides utilities to communicate with<BR>&gt; other =
process's=20
  via Haskell code.&nbsp; This library can be<BR>&gt; used for something =
as=20
  simple as getting the output of<BR>&gt; another program or as complex =
as=20
  interacting with an<BR>&gt; interpreter.<BR>&gt;<BR>&gt;=20
  see<BR>&gt;<BR>&gt;&nbsp;&nbsp;=20
  http://www.electronconsulting.com/shell-haskell<BR>&gt;<BR>&gt; for=20
  details.<BR>&gt;<BR>&gt; David J. Sankel<BR>&gt;=20
  _______________________________________________<BR>&gt; Haskell =
mailing=20
  list<BR>&gt; Haskell@haskell.org<BR>&gt;=20
  =
http://www.haskell.org/mailman/listinfo/haskell<BR>&gt;<BR>&gt;<BR>&gt;=20
  _______________________________________________<BR>&gt; Libraries =
mailing=20
  list<BR>&gt; Libraries@haskell.org<BR>&gt;=20
  =
http://www.haskell.org/mailman/listinfo/libraries<BR>&gt;<BR>&gt;<BR>&gt;=
<BR></BLOCKQUOTE></BODY></HTML>

------=_NextPart_001_00B1_01C31629.C59B10D0--

------=_NextPart_000_00B0_01C31629.C5998A30
Content-Type: text/html;
	name="RunProcess.html"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="RunProcess.html"

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" =
"http://www.w3.org/TR/html4/loose.dtd">
<!--Rendered using the Haskell Html Library v0.2-->
<HTML
><HEAD
  ><TITLE
    >RunProcess</TITLE
    >
	<style type=3D"text/css">
	TT { font-size: 100% }
LI P { margin: 0pt }

/* -------- Global things --------- */

BODY {=20
  background-color: #ffffff;
  color: #000000;
  font-family: sans-serif;
  }=20

A:link    { color: #0000e0; text-decoration: none }
A:visited { color: #0000a0; text-decoration: none }
A:hover   { background-color: #e0e0ff; text-decoration: none }

TABLE.vanilla {
  width: 100%;
  border-width: 0px;
  /* I can't seem to specify cellspacing or cellpadding properly using =
CSS... */
}

TD {
  border-width: 0px;
}

TABLE.narrow {
  border-width: 0px;
}

TD.s8  {  height: 8px;  }
TD.s15 {  height: 15px; }

SPAN.keyword { text-decoration: underline; }

/* --------- Documentation elements ---------- */

TD.children {
  padding-left: 25px;
  }

TD.synopsis {
  padding: 2px;
  background-color: #f0f0f0;
  font-family: monospace
 }

TD.decl {=20
  padding: 2px;
  background-color: #f0f0f0;=20
  font-family: monospace;
  white-space: nowrap;
  vertical-align: top;
  }

TD.recfield { padding-left: 20px }

TD.doc  {=20
  padding-top: 2px;
  padding-left: 10px;
  }

TD.ndoc  {=20
  padding: 2px;
  }

TD.rdoc  {=20
  padding: 2px;
  padding-left: 10px;
  width: 100%;
  }

TD.body  {=20
  padding-left: 10px
  }

/* ------- Section Headings ------- */

TD.section1 {
  padding-top: 15px;
  font-weight: bold;
  font-size: 150%
  }

TD.section2 {
  padding-top: 10px;
  font-weight: bold;
  font-size: 130%
  }

TD.section3 {
  padding-top: 5px;
  font-weight: bold;
  font-size: 110%
  }

TD.section4 {
  font-weight: bold;
  font-size: 100%
  }

/* -------------- The title bar at the top of the page */

TD.infohead {
  color: #ffffff;
  font-weight: bold;
  padding-right: 10px;
  text-align: left;
}

TD.infoval {
  color: #ffffff;
  padding-right: 10px;
  text-align: left;
}

TD.topbar {
  background-color: #000099;
  padding: 5px;
}

TD.title {
  color: #ffffff;
  padding-left: 10px;
  width: 100%
  }

TD.topbut {
  padding-left: 5px;
  padding-right: 5px;
  border-left-width: 1px;
  border-left-color: #ffffff;
  border-left-style: solid;
  white-space: nowrap;
  }

TD.topbut A:link {
  color: #ffffff
  }

TD.topbut A:visited {
  color: #ffff00
  }

TD.topbut A:hover {
  background-color: #6060ff;
  }

TD.topbut:hover {
  background-color: #6060ff
  }

TD.modulebar {=20
  background-color: #0077dd;
  padding: 5px;
  border-top-width: 1px;
  border-top-color: #ffffff;
  border-top-style: solid;
  }

/* --------- The page footer --------- */

TD.botbar {
  background-color: #000099;
  color: #ffffff;
  padding: 5px
  }
TD.botbar A:link {
  color: #ffffff;
  text-decoration: underline
  }
TD.botbar A:visited {
  color: #ffff00
  }
TD.botbar A:hover {
  background-color: #6060ff
  }

	</style>
	</HEAD
  ><BODY
  ><TABLE CLASS =3D "vanilla" CELLSPACING =3D "0" CELLPADDING =3D "0"
    ><TR
      ><TD CLASS =3D "topbar"
	><TABLE CLASS =3D "vanilla" CELLSPACING =3D "0" CELLPADDING =3D "0"
	  ><TR
	    ><TD
	      ><IMG SRC =3D "haskell_icon.gif" WIDTH =3D "16" HEIGHT =3D "16" =
ALT =3D " "
		></TD
	      ><TD CLASS =3D "title"
	      ></TD
	      ><TD CLASS =3D "topbut"
	      ><A HREF =3D "index.html"
		>Contents</A
		></TD
	      ><TD CLASS =3D "topbut"
	      ><A HREF =3D "doc-index.html"
		>Index</A
		></TD
	      ></TR
	    ></TABLE
	  ></TD
	></TR
      ><TR
      ><TD CLASS =3D "modulebar"
	><TABLE CLASS =3D "vanilla" CELLSPACING =3D "0" CELLPADDING =3D "0"
	  ><TR
	    ><TD
	      ><FONT SIZE =3D "6"
		>Win32RunProcess</FONT
		></TD
	      ><TD ALIGN =3D "right"
	      ><TABLE CLASS =3D "narrow" CELLSPACING =3D "0" CELLPADDING =3D =
"0"
		><TR
		  ><TD CLASS =3D "infohead"
		    >Portability</TD
		    ><TD CLASS =3D "infoval"
		    >  win32</TD
		    ></TR
		  ><TR
		  ><TD CLASS =3D "infohead"
		    >Stability</TD
		    ><TD CLASS =3D "infoval"
		    >  provisional</TD
		    ></TR
		  ><TR
		  ><TD CLASS =3D "infohead"
		    >Maintainer</TD
		    ><TD CLASS =3D "infoval"
		    >  daan@cs.uu.nl</TD
		    ></TR
		  ></TABLE
		></TD
	      ></TR
	    ></TABLE
	  ></TD
	></TR
      ><TR
      ><TD CLASS =3D "s15"
	></TD
	></TR
      ><TR
      ><TD
	><TR
	  ><TD CLASS =3D "section4"
	    ><B
	      >Contents</B
	      ></TD
	    ></TR
	  ><TR
	  ><TD
	    ><DL
	      ><DT
		><A HREF =3D "#1"
		  > Process control</A
		  ></DT
		><DT
		><A HREF =3D "#2"
		  > Pipes</A
		  ></DT
		><DT
		><A HREF =3D "#3"
		  > Data types (<TT
		    >IOModeEx</TT
		    >) </A
		  ></DT
		></DL
	      ></TD
	    ></TR
	  ></TD
	></TR
      ><TR
      ><TD CLASS =3D "s15"
	></TD
	></TR
      ><TR
      ><TD CLASS =3D "section1"
	>Description</TD
	></TR
      ><TR
      ><TD CLASS =3D "doc"
	>    High level primitives for process spawning on windows.
</TD
	></TR
      ><TR
      ><TD CLASS =3D "s15"
	></TD
	></TR
      ><TR
      ><TD CLASS =3D "section1"
	>Synopsis</TD
	></TR
      ><TR
      ><TD CLASS =3D "s15"
	></TD
	></TR
      ><TR
      ><TD CLASS =3D "body"
	><TABLE CLASS =3D "vanilla" CELLSPACING =3D "0" CELLPADDING =3D "0"
	  ><TR
	    ><TD CLASS =3D "decl"
	      ><A HREF =3D "#runProcess"
		>runProcess</A
		> :: FilePath -&gt; [String] -&gt; Maybe [(String, String)] -&gt; =
Maybe FilePath -&gt; Maybe Handle -&gt; Maybe Handle -&gt; Maybe Handle =
-&gt; IO ()</TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "s8"
	      ></TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "decl"
	      ><A HREF =3D "#runProcessEx"
		>runProcessEx</A
		> :: Bool -&gt; FilePath -&gt; [String] -&gt; Maybe [(String, String)] =
-&gt; Maybe FilePath -&gt; Maybe Handle -&gt; Maybe Handle -&gt; Maybe =
Handle -&gt; IO Int</TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "s8"
	      ></TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "decl"
	      ><A HREF =3D "#createPipe"
		>createPipe</A
		> :: IO (Handle, Handle)</TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "s8"
	      ></TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "decl"
	      ><A HREF =3D "#createPipeEx"
		>createPipeEx</A
		> :: IOModeEx -&gt; IO (Handle, Handle)</TD
	      ></TR
	    ></TABLE
	  ></TD
	></TR
      ><TR
      ><TD CLASS =3D "s15"
	></TD
	></TR
      ><TR
      ><TD CLASS =3D "s15"
	></TD
	></TR
      ><TR
      ><TD CLASS =3D "section1"
	><A NAME =3D "1"
	  > Process control</A
	  ></TD
	></TR
      ><TR
      ><TD CLASS =3D "s15"
	></TD
	></TR
      ><TR
      ><TD CLASS =3D "decl"
	><A NAME =3D "runProcess"
	  ></A
	  ><B
	  >runProcess</B
	  ></TD
	></TR
      ><TR
      ><TD CLASS =3D "body"
	><TABLE CLASS =3D "vanilla" CELLSPACING =3D "0" CELLPADDING =3D "0"
	  ><TR
	    ><TD CLASS =3D "decl"
	      >:: FilePath</TD
	      ><TD CLASS =3D "rdoc"
	      > Command</TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "decl"
	      >-&gt; [String]</TD
	      ><TD CLASS =3D "rdoc"
	      > Arguments</TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "decl"
	      >-&gt; Maybe [(String, String)]</TD
	      ><TD CLASS =3D "rdoc"
	      > Environment (Nothing -&gt; Inherited)</TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "decl"
	      >-&gt; Maybe FilePath</TD
	      ><TD CLASS =3D "rdoc"
	      > Working directory (Nothing -&gt; inherited)</TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "decl"
	      >-&gt; Maybe Handle</TD
	      ><TD CLASS =3D "rdoc"
	      > stdin  (Nothing -&gt; inherited)</TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "decl"
	      >-&gt; Maybe Handle</TD
	      ><TD CLASS =3D "rdoc"
	      > stdout (Nothing -&gt; inherited)</TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "decl"
	      >-&gt; Maybe Handle</TD
	      ><TD CLASS =3D "rdoc"
	      > stderr (Nothing -&gt; inherited)</TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "decl"
	      >-&gt; IO ()</TD
	      ><TD CLASS =3D "rdoc"
	      ></TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "ndoc" COLSPAN =3D "2"
	      ><P
		>(<TT
		  >runProcess cmd args env workdir in out err</TT
		  >) runs a command <TT
		  >cmd</TT
		  >. It searches
the application along the current directory, the windows system =
directories and=20
finally the current PATH. The command is run with the arguments <TT
		  >args</TT
		  >. The
child process runs concurrently with the parent process and a call to =
<TT
		  >runProcess</TT
		  >
returns immediately.</P
		><P
		>If the environment <TT
		  >env</TT
		  > is (<TT
		  >Just pairs</TT
		  >),=20
the command is executed with the environment specified by pairs of =
variables and values; otherwise,=20
the command is executed with the current environment. </P
		><P
		>If <TT
		  >workdir</TT
		  > is (<TT
		  >Just dir</TT
		  >), the command is executed=20
with working directory <TT
		  >dir</TT
		  > and otherwise, the command is executed in the current working =
directory. </P
		><P
		>If {<TT
		  >in</TT
		  >,<TT
		  >out</TT
		  >,<TT
		  >err</TT
		  >} is (<TT
		  >Just handle</TT
		  >), the command is executed with=20
<TT
		  >std</TT
		  >{<TT
		  >in</TT
		  >,<TT
		  >out</TT
		  >,<TT
		  >err</TT
		  >} attached to the specified handle;=20
otherwise, <TT
		  >std</TT
		  >{<TT
		  >in</TT
		  >,<TT
		  >out</TT
		  >,<TT
		  >err</TT
		  >} is left unchanged.</P
		><PRE
		> runProcess =3D runProcessEx False
</PRE
		></TD
	      ></TR
	    ></TABLE
	  ></TD
	></TR
      ><TR
      ><TD CLASS =3D "s15"
	></TD
	></TR
      ><TR
      ><TD CLASS =3D "decl"
	><A NAME =3D "runProcessEx"
	  ></A
	  ><B
	  >runProcessEx</B
	  ></TD
	></TR
      ><TR
      ><TD CLASS =3D "body"
	><TABLE CLASS =3D "vanilla" CELLSPACING =3D "0" CELLPADDING =3D "0"
	  ><TR
	    ><TD CLASS =3D "decl"
	      >:: Bool</TD
	      ><TD CLASS =3D "rdoc"
	      > Wait for termination? </TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "decl"
	      >-&gt; FilePath</TD
	      ><TD CLASS =3D "rdoc"
	      > Command</TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "decl"
	      >-&gt; [String]</TD
	      ><TD CLASS =3D "rdoc"
	      > Arguments</TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "decl"
	      >-&gt; Maybe [(String, String)]</TD
	      ><TD CLASS =3D "rdoc"
	      > Environment (Nothing -&gt; Inherited)</TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "decl"
	      >-&gt; Maybe FilePath</TD
	      ><TD CLASS =3D "rdoc"
	      > Working directory (Nothing -&gt; inherited)</TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "decl"
	      >-&gt; Maybe Handle</TD
	      ><TD CLASS =3D "rdoc"
	      > stdin  (Nothing -&gt; inherited)</TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "decl"
	      >-&gt; Maybe Handle</TD
	      ><TD CLASS =3D "rdoc"
	      > stdout (Nothing -&gt; inherited)</TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "decl"
	      >-&gt; Maybe Handle</TD
	      ><TD CLASS =3D "rdoc"
	      > stderr (Nothing -&gt; inherited)</TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "decl"
	      >-&gt; IO Int</TD
	      ><TD CLASS =3D "rdoc"
	      > The exit code (or 0 if wait is False)</TD
	      ></TR
	    ><TR
	    ><TD CLASS =3D "ndoc" COLSPAN =3D "2"
	      ><P
		>(<TT
		  >runProcessEx wait cmd args env workdir in out err</TT
		  >) runs a command <TT
		  >cmd</TT
		  >.
It searches the application along the=20
current directory, the windows system directories and finally the =
current PATH.
The command is run with the arguments <TT
		  >args</TT
		  >. If <TT
		  >wait</TT
		  > is True, the current
process is suspended until the child terminates, otherwise they are run =
concurrently.</P
		><P
		>If the environment <TT
		  >env</TT
		  > is (<TT
		  >Just pairs</TT
		  >),=20
the command is executed with the environment specified by pairs of =
variables and values; otherwise,=20
the command is executed with the current environment. </P
		><P
		>If <TT
		  >workdir</TT
		  > is (<TT
		  >Just dir</TT
		  >), the command is executed=20
with working directory <TT
		  >dir</TT
		  > and otherwise, the command is executed in the current working =
directory. </P
		><P
		>If {<TT
		  >in</TT
		  >,<TT
		  >out</TT
		  >,<TT
		  >err</TT
		  >} is (<TT
		  >Just handle</TT
		  >), the command is executed with=20
<TT
		  >std</TT
		  >{<TT
		  >in</TT
		  >,<TT
		  >out</TT
		  >,<TT
		  >err</TT
		  >} attached to the specified handle;=20
otherwise, <TT
		  >std</TT
		  >{<TT
		  >in</TT
		  >,<TT
		  >out</TT
		  >,<TT
		  >err</TT
		  >} is left unchanged.</P
		><P
		>If <TT
		  >wait</TT
		  > is True, the call to <TT
		  ><A HREF =3D "Win32RunProcess.html#runProcessEx"
		    >runProcessEx</A
		    ></TT
		  > returns after the child process
has terminated with the exit code of the process. If <TT
		  >wait</TT
		  > is false, the
call to <TT
		  ><A HREF =3D "Win32RunProcess.html#runProcessEx"
		    >runProcessEx</A
		    ></TT
		  > returns immediately with an exit code of 0.</P
		><P
		>Here is a short example of running a command <TT
		  >cmd</TT
		  > that gets its input
from a file <TT
		  >foo</TT
		  >. The process is run synchronously.</P
		><PRE
		>     do{ input    &lt;- openFile &quot;foo&quot; ReadMode
       ; exitcode &lt;- runProcessEx True &quot;cmd&quot; [] Nothing =
Nothing (Just input) Nothing Nothing
       ; hClose input
       ; ...
</PRE
		></TD
	      ></TR
	    ></TABLE
	  ></TD
	></TR
      ><TR
      ><TD CLASS =3D "s15"
	></TD
	></TR
      ><TR
      ><TD CLASS =3D "section1"
	><A NAME =3D "2"
	  > Pipes</A
	  ></TD
	></TR
      ><TR
      ><TD CLASS =3D "s15"
	></TD
	></TR
      ><TR
      ><TD CLASS =3D "decl"
	><A NAME =3D "createPipe"
	  ></A
	  ><B
	  >createPipe</B
	  > :: IO (Handle, Handle)</TD
	></TR
      ><TR
      ><TD CLASS =3D "doc"
	><P
	  >=20
(<TT
	    >createPipe</TT
	    >) creates an anonymous <EM
	    >pipe</EM
	    > and returns a pair of=20
handles, the first for reading and the second for writing. Both
pipe ends can be inherited by a child process.</P
	  ><PRE
	  > createPipe  =3D createPipeEx (BinaryMode AppendMode)  =20
</PRE
	  ></TD
	></TR
      ><TR
      ><TD CLASS =3D "s15"
	></TD
	></TR
      ><TR
      ><TD CLASS =3D "decl"
	><A NAME =3D "createPipeEx"
	  ></A
	  ><B
	  >createPipeEx</B
	  > :: IOModeEx -&gt; IO (Handle, Handle)</TD
	></TR
      ><TR
      ><TD CLASS =3D "doc"
	><P
	  >=20
(<TT
	    >createPipeEx modeEx</TT
	    >) creates an anonymous <EM
	    >pipe</EM
	    > and returns a pair of=20
handles, the first for reading and the second for writing.=20
The pipe mode <TT
	    >modeEx</TT
	    > can be:</P
	  ><UL
	  ><LI
	    ><P
	      > <TT
		>TextMode mode</TT
		> -- the pipe is opened in text mode.</P
	      ></LI
	    ><LI
	    ><P
	      > <TT
		>BinaryMode mode</TT
		> -- the pipe is opened in binary mode.</P
	      ></LI
	    ></UL
	  ><P
	  >The <TT
	    >mode</TT
	    > determines if child processes can inherit the pipe handles:</P
	  ><UL
	  ><LI
	    ><P
	      > ReadMode -- The <EM
		>read</EM
		> handle of the pipe is private to this process. </P
	      ></LI
	    ><LI
	    ><P
	      > WriteMode -- The <EM
		>write</EM
		> handle of the pipe is private to this process. </P
	      ></LI
	    ><LI
	    ><P
	      > ReadWriteMode -- Both handles are private to this process.</P
	      ></LI
	    ><LI
	    ><P
	      > AppendMode -- Both handles are available (inheritable) to child =
processes.
      This mode can be used to <EM
		>append</EM
		> (|) two seperate child processes.</P
	      ></LI
	    ></UL
	  ><P
	  >If a broken pipe is read, an end-of-file (<TT
	    ><A HREF =3D "GHC.IOBase.html#EOF"
	      >EOF</A
	      ></TT
	    >)=20
exception is raised. If a broken pipe is written to, an invalid argument =
exception
is raised (<TT
	    ><A HREF =3D "GHC.IOBase.html#InvalidArgument"
	      >InvalidArgument</A
	      ></TT
	    >).</P
	  ><P
	  >Here is a short example that redirects stdin, stdout and stderr of a =
spawned=20
child process to private handles in the parent process.</P
	  ><PRE
	  > spawn :: String -&gt; IO (Handle,Handle,Handle)
 spawn command=20
   =3D do{ (stdinRead,stdinWrite)   &lt;- createPipeEx (TextMode =
WriteMode)
       ; (stdoutRead,stdoutWrite) &lt;- createPipeEx (TextMode ReadMode)
       ; (stderrRead,stderrWrite) &lt;- createPipeEx (TextMode ReadMode)
       ; runProcess command [] Nothing Nothing (Just stdinRead) (Just =
stdoutWrite) (Just stderrWrite)
       ; hClose stdinRead
       ; hClose stdoutWrite
       ; hClose stderrWrite
       ; return (stdinWrite,stdoutRead,stderrRead)
       }
</PRE
	  ></TD
	></TR
      ><TR
      ><TD CLASS =3D "s15"
	></TD
	></TR
      ><TR
      ><TD CLASS =3D "section1"
	><A NAME =3D "3"
	  > Data types (<TT
	    >IOModeEx</TT
	    >) </A
	  ></TD
	></TR
      ><TR
      ><TD CLASS =3D "s15"
	></TD
	></TR
      ><TR
      ><TD CLASS =3D "botbar"
	>Produced by <A HREF =3D "http://www.haskell.org/haddock"
	  >Haddock</A
	  > version 0.4</TD
	></TR
      ></TABLE
    ></BODY
  ></HTML
>

------=_NextPart_000_00B0_01C31629.C5998A30--