fvwm2 causes stdin to be closed when execing within tcl/tk

Peter L. Peres plp-ysDPMY98cNQDDBjDh4tngg at public.gmane.org
Mon Jan 26 16:47:26 UTC 2004


On Sat, 24 Jan 2004, David Tilbrook wrote:

> I have uncovered a bizarre behaviour in RH9.0 fvwm2 and tcl/tk
> that is impossible to debug.
>
> I have a gui that contains many statements of the form:
>
> 	[catch {eval exec ...} ...]
>
> When this gui is invoked via a menu entry in fvwm2, the standard
> input for the program being invoked is not open (i.e., fid 0
> is not open).

That is the correct behavior. You can use pipes or such to connect
something to your command, or you can open fd 0 of the interpreter on a
log file or terminal pty (in tcl). E.g. if no file is open and you open
one in tcl, it will (should) get fd 0 and behave like stdin for most
purposes to all other subsequent code.

> Yet when invoked from an xterm window, even if detached,
> the programs are invoked with a valid fid 0.

A forked child inherits all the file descriptors of the parent.

> The reason that it is impossible to debug is that the environment
> in which the problem occurs is not one that can run gdb or
> even report diagnostics in a useful manner.

Write some tcl code to catch the output of your command. An easy way to
debug is to replace the executable with a simple shell script that dumps
env and argv[] into a temp file in /tmp, then exits. The file will reveal
the user and umask of whoever ran the script and the full environment.

> Given the different behaviours are due to the gui's invocation,
> does anyone have a suggestion as to the cause?

The short answer would be that you are not supposed to run programs that
require terminal io from a daemon.

> My best guess is that somehow that tcl/tk does a:
>
> 	fcntl(0, F_SETFD)
>
> but why only if invoked from fvwm2?

No, it simply does not open stdin if it is not already open.

> What state information that is exported to exec'd children
> could possibly result in such a bizarre behaviour?

None. Exec does not open any fds. Exec inherits the parent's open fd's. If
stdin is not open in the parent then it is not open in the child.

> Any why doesn't crt0 ensure that fids 0,1,&2 are open?

Any program compiled to be runnable both as a daemon and as a terminal
application will have code that either detects that stdin is not connected
to anything, and closes it, or not open it in the first place. F.ex the
isatty() call would fail on stdin if it would not be open. Daemons
specifically close stdin and stdout and stderr in the forked child before
doing anything else. The real story and much more you can find in
R.Stevens' Advanced Programming in the Unix Environment.

Peter
--
The Toronto Linux Users Group.      Meetings: http://tlug.ss.org
TLUG requests: Linux topics, No HTML, wrap text below 80 columns
How to UNSUBSCRIBE: http://tlug.ss.org/subscribe.shtml





More information about the Legacy mailing list