[MLton] Cygwin->Mingw32: patch + future

Wesley W. Terpstra terpstra@gkec.tu-darmstadt.de
Mon, 22 Nov 2004 11:57:57 +0100


--0F1p//8PRICkK4MW
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Fri, Nov 19, 2004 at 07:24:35AM -0800, Stephen Weeks wrote:
> > There were only two issues:
> > 1. With gcc-3.4, the '-b <arch>' must be the first argument.
> > 2. When using cygwin to compile native windows applications via their
> > included mingw compiler, the option to use is '-mno-cygwin' instead.
> > (I don't know why they did this, but there you have it)
> 
> One thing I did change was the condition for using -mno-cygwin.  It is
> now
> 
>   Cygwin = MLton.Platform.OS.host
>   andalso String.hasSubstring (s, {substring = "mingw"})

If I had known the method hasSubstring, I would have done that myself. ;)

> > In general, I think most of the CC-controlling options should be
> > moved into a config file somewhere. 
> 
> As Matthew pointed out, most of them are outside the binary.  And as
> you pointed out, not all of them are.  Unfortunately, I don't see an
> easy way to move the remaining ones out.

In hindsight, I think if there was an option '-target-cc foo "gcc
-mno-cygwin"' that would be enough. However, I think that keeping these
settings in the mlton script is the wrong place. Target compilation
options should be stored in the usr/lib/mlton/target/ directory. If the
mlton script sourced files from there, that would be ideal.

If a -target-cc was added, it must support multiple words (unlike the
current -cc option). The default for a target 'bar' should be
"$(cc) -b bar" where $(cc) is the setting of -cc for 'self'.

I will send a patch with this approach in a bit.

> > I propose to add in MLTON_PROCESS (or maybe MLTON_CHILD?):
> I like your proposal.  Adding your stuff to MLTON_PROCESS seems fine.

I actually ended up adding it to MLTON_CHILD.
The reason was that in basis-extra.mlb the ordering prevents it from
working. A proper implementation similar to system/unix.sml needs the signal
mask stuff which is in signal.sml. But the dependency
signal->thread->exn->process prevents me from putting the code there.

So, I split it apart.

> * What is the NULL iosource for?

To point stdin to /dev/null. (still haven't found an equiv. for windows...)
If you use INHERIT, you can get IO contention races on the shared channels.
If a process doesn't need the parent's stdin/out/errr, it should be possible
to point them to nowhere to prevent problems.

> * What is RedirectionFailure for?

It was supposed to be if it failed to create the PIPE or open the FILE.
Right now I just let the exceptions trickle through. I am not sure what the
best solution is; I am unused to using exceptions for error-handling...

> * It seems like you missed the ability to pass the three iosources
> (stdin, stdout, stderr) to create.

Yes, my current code was already fixed.
However, since I've assimilated your later suggestion the whole interface
looks rather different.

> * I wonder if it makes sense to change the semantics from how the
> Unix module behaves so that, e.g., two calls to textStdinOf return the
> same stream instead of creating a new one (which has no reasonable
> behavior).

Yes! Please!

My patch presently keeps with the tradition (?) of using the system's CRLF
translation.  I added Posix.IO.setbin and Posix.IO.settext (not exposed)
which can change the state. Then I plugged this into posix/io.sml: mkReader,
etc. I note that you used O.binary and O.text to openf for TextIO and BinIO.
I think both these approaches are bad.

They work, BUT: What about stdin?

It seems to me that the SML basis library provides an opportunity to finally
solve the age-old stupid C problem of: is my (already open) stdin/out/err
etc translated or not?

TextIO.stdin and BinIO.stdin should behave as their name suggests
automagically. I propose to remove all the text/binary toggles out of the
SML library and put all MLton filedescs in binary mode. Then add translation
at the level of TextIO. More work to be done in the MLton basis library,
true. However, this will probably be more portable in the long run and
makes several otherwise impossible problems solvable

Make both TextIO.stdin and BinIO.stdin point to the same underlying buffer
and bingo, it finally works the way C should have. If you combine this with
your above suggestion of returning the same stream, one can even guarantee
that reads/writes to the same fd are not order-mangled by the buffers.

I am not including this change in my first patchset for pipes.

> * I don't think the "Of" suffix does anything.  I propose to drop it.

I kept it so it is close to the Unix module's conventions...
However, with every change this becomes less and less like Unix.* 
New function names adopted.

> * I propose to strengthen the use of phantom types.  Right now, all
> they do is prevent is turning the same file descriptor into both a
> binary and a text stream when using {bin,text}Std{err,in,out}Of.  We
> can use them to express whether or not the stream can be extracted.
> Once we do that, we can also drop the option return type.

This sounds really good.
I've taken your suggestion and integrated it.

> Here's a MLtonization of your signature, with my proposed changes.
> 	    val file: string -> 'a isNotPipe t
> 	    val inherit: 'a isNotPipe t
> 	    val lie: 'a isNotPipe t -> 'a isPipe t
> 	    val null: 'a isNotPipe t
> 	    val pipe: 'a isPipe t

Uhm, "lie"?
That sounds like a dangerous option.
What's it for?

After some more thought about this problem I also decided there needs to be
another two features: get the fd of the opened pipe, and be able to pass an
fd in as a source.  The first is needed to pass the fd to C libraries (gtk).
Ths second is needed if you want to build a pipeline of child processes where
the stdin of one child is connected to the stdout of another.

Another modification to the above: When I've been using the ('a, 'b, 'c)
proc method I proposed earlier, I kept getting warnings from MLton about how
it couldn't fully determine the type. This was when I only used the stdout
part of the pipe, and didn't touch stdin/err.

This problem is fixed by your approach if "'a isNotPipe" -> "isNotPipe"
 -- that way there's no open-ended types left for MLton to complain about.
In fact, if there are open-ended types left, then it is a bug in your code
because you haven't grabbed the open handle! See child.sig attached.

I've also attached a simple example (which works under cygwin+mingw) that
uses this new interface. 

The only 'unsafe' part of my new interface is that you can pass the stdout
of one process into the stdin of more than one process. This gives an
exception. I think it is impossible to prevent this with the type system
though, right?

> > Also, by using the mlton_create_process syscall, there would no longer
> > be a need for the spawn syscall. I would remove it in favour of the more
> > powerful syscall and change the spawn code to use it instead.
> 
> Sounds good.

Actually, after reading your comments about cygwin I've opted to keep it.
The reason: cygwin + CreateProcess doesn't appear possible.

I think this is because _open_osfhandle is not compatible with the cygwin
filedesc abstraction. Therefore, you have no way of getting the HANDLE for
the startup info. If you know of a way let me know!

To keep cygwin on the level of mingw, I've switched cygwin to using fork()
and mmap(). For me, it appears to work (I have the newest cygwin). The
change to enable cygwin+fork() is currently part of my patchset.

> > Has the "path handling to get CM files to build properly" been fixed?
> No.

I'll look into this after I get pipes, ipv6, and multicast working. ;)

I've attached the current signature for your approval.
The attached (lightly tested) patch includes the implementation.
Please do not apply the patch yet; I want to clean-up several things.

I intend to figure out how to run the regression tests today.
However, I only have access to cygwin, mingw32, and linux.

-- 
Wesley W. Terpstra

--0F1p//8PRICkK4MW
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="child.sig"

signature MLTON_CHILD =
   sig
      type pid
      type signal
      
      (* Process handle *)
      type ('stdin, 'stdout, 'stderr) t
      type ('use, 'dir) param
      type ('use, 'dir) child
      
      (* is the io 'dir input or output *)
      type input
      type output
      
      (* to what use can the stdio channel be put *)
      type none
      type chain
      
      val fromPipe: ('use, 'dir) param
      val fromNull: (none, 'dir) param
      val fromSelf: (none, 'dir) param
      val fromFile: string -> (none, 'dir) param
      
      (* from{Child,FD} close their parameter when create is called.
       * therefore they may only be used once!
       *)
      val fromChild:(chain, 'dir) child -> (none, 'dir) param
      (* Not necessarily available on all systems; may raise an exception *)
      val fromFD: Posix.FileSys.file_desc -> (none, 'dir) param
      
      val create: {
        path: string, 
        args: string list, 
        env: string list option, 
        stdin:  ('stdin,   input) param,
        stdout: ('stdout, output) param,
        stderr: ('stderr, output) param 
        } -> (('stdin,  output) child, 
              ('stdout,  input) child,
              ('stderr,  input) child) t
      
      val reap: (('stdin,  output) child, 
                 ('stdout,  input) child,
                 ('stderr,  input) child) t -> OS.Process.status
      val kill: (('stdin,  output) child, 
                 ('stdout,  input) child,
                 ('stderr,  input) child) t * signal -> unit
      
      val getStdin:  (('a, output) child, 'b, 'c) t -> ('a, output) child
      val getStdout: ('a, ('b,  input) child, 'c) t -> ('b, input)  child
      val getStderr: ('a, 'b, ('c,  input) child) t -> ('c, input)  child
      
      val toTextIOin:  (TextIO.instream,  input)  child -> TextIO.instream
      val toTextIOout: (TextIO.outstream, output) child -> TextIO.outstream
      val toBinIOin:   ( BinIO.instream,  input)  child ->  BinIO.instream
      val toBinIOout:  ( BinIO.outstream, output) child ->  BinIO.outstream
      
      (* not necessarily available on all systems; may raise an exception *)
      val toFD: (Posix.FileSys.file_desc, 'dir) child -> Posix.FileSys.file_desc
   end

--0F1p//8PRICkK4MW
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="w32unix.diff.gz"
Content-Transfer-Encoding: base64

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
AZTg6jjFjAAA

--0F1p//8PRICkK4MW
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="foo.sml"

fun suck i =
  case TextIO.inputLine i of
    SOME x => (print ("x: " ^ x); suck i)
  | NONE => ()

val p = Unix.execute ("e:\\windows\\foo.exe", [ "adasd", "zzz", "rtyurt" ])
val _ = print "Launching foo\n"
val (i, _) = Unix.streamsOf p
val _ = print "Sucking stream\n"
val _ = suck i
val _ = print "Done sucking\n"
val _ = Unix.reap p
val _ = print "Reaped\n"

open MLton.Child

val p = create {
  path="e:\\windows\\foo.exe",
  args=[ "-l", "/tmp" ],
  env=NONE,
  stdin =fromNull,
  stdout=fromPipe,
  stderr=fromSelf }

val q = create {
  path="e:\\msys\\1.0\\bin\\grep.exe",
  args=[ "--", "2" ],
  env=NONE,
  stdin =fromChild (getStdout p),
  stdout=fromPipe,
  stderr=fromSelf }

val _ = print "Sucking stream\n"
val _ = suck (toTextIOin (getStdout q))
val _ = print "Done sucking\n"
val _ = reap p (* Posix.Signal.term *)
val _ = print "Reaped\n"
val _ = reap q (* Posix.Signal.term *)
val _ = print "Reaped\n"

--0F1p//8PRICkK4MW--