[texdoc] A question on TL2008

Karl Berry karl at freefriends.org
Fri Sep 5 02:29:09 CEST 2008

    Yes, I think that just s/spawn/execute/ in the last line of the wrapper
    should do the trick.

So can you commit that change when you have a chance?

    Since I assume there is a good reason for not doing this in general,

Well, in theory, yes.  Reinhard posted the details to tex-live.  I know
you've seen it but I will reproduce here since having them in more than
one archive can only help :).

    it could indeed be useful to create a texdoc-specific wrapper for this.

It seems to me that it is a generic problem, and any program which used
the wrapper and then subsequently invoked AR9 (or whatever) on Windows
would fail.  But, I surmise, texdoc is the only one that meets those


From: Reinhard Kotucha <reinhard.kotucha at web.de>
Message-ID: <18620.31670.775017.86121 at zaphod.ms25.net>
Subject: Re: [tex-live] texdoc error


Lua only provides os.execute(), which passes a string to a shell.  Taco
added os.exec() which is supposed to replace the current process by
another one.  It doesn't use a shell but calls the program directly.

One important difference is that if you call a program directly on
Windows, you can use forward slashes in file names because the MS-DOS
API always supported this.  But you'll get into trouble if you use
forward slashes when a command-line interpreter is involved.  The
reason is that forward slashes are treated special by the CLI.  On
UNIX, arguments separated by spaces are passed to the program and the
program is responsible for resolving its arguments, i.e. to find out
which argument is a switch, a file name, or a key-value pair.

On Windows it's not so easy because command-line options are not
delimited by spaces.  I assume that this behavior had been inherited
from VMS.  Please try:


These are all valid commands on Windows.  Sigh!

For exactly this reason we tried to avoid os.execute() and used
os.exec() instead.  What we want to achieve by our wrappers is to
replace one process by an other one in a changed environment.

However, os.exec() behaves different on UNIX and Windows because of
different implementations of the execvpe() system call.  On UNIX it
does what we expect.  It replaces the current process image by another
one and waits until it's finished.  On Windows it creates a new
process and returns immediately.  The newly created process runs in
the background.  If such a process hangs because it's waiting for user
input, all you can do is to invoke the task manager in order to kill

Thus, Taco wrote another function for us, os.spawn().  This function
avoids the CLI and is quite similar to os.exec(), but it waits until
the child process is finished, also on Windows.  And it supports
lists.  At the first glance this was the ultimate solution.

But not on Windows.  Usually, if one program invokes another one, it
passes the arguments as a list with zero-bytes as delimiters and the
other one expects exactly this.  

Obviously, on Windows the argument list you pass to another program is
converted to a string and then converted to a list again.  I don't
understand why, but maybe a CLI is involved here too.

This is what happens:

One program passes 

   foo\0this is a file name with spaces\0bar

to another program.  No problem on UNIX, it's a list containing three
elements, ("foo", "this is a file name with spaces", "bar") separated
by zero-bytes.

On Windows, however, the list is converted to a string:

  "foo this is a file name with spaces bar".

and it's converted back to a list when passed to the child process:


Sigh!  You have to quote file names on Windows even if you pass them
as a zero-byte delimited list to other programs.

With all this said, the wrapper script
(bin/win32/tl-w32-wrapper.texlua) should be comprehensible.  The
function fixwin() is supposed to solve the quoting problem.

More information about the texdoc mailing list