Package: expect
Version: 5.43.0-8

In exp_command.c expBusy is called from exp_close to ensure that an
ExpState is connected to /dev/null rather than having simply invalid
fd's.  However, the code forgets that an ExpState has both input and
output fds.  It connects the input fd to /dev/null but neglects the
input fd.

Under some circumstances, this means that expect closes its fds 0 and
1 but only reopens /dev/null for fd 0.  expect then continues without
fd 1 and things start to go wrong.

Additionally, expBusy forgets that not all fds should be marked close
on exec: fds 0-2 should not, because called programs will need them.

The attached patch remedies these problems.

I note while perusing the code that the error handling is atrocious.
Many system calls lack error checking.  I have retained this style in
expBusy to reduce the size of the patch and to avoid having to take on
the herculean task of adding an error check to every syscall in
expect.

Regards,
Ian.

diff -rU10 orig/expect-5.43.0/exp_command.c expect-5.43.0/exp_command.c
--- orig/expect-5.43.0/exp_command.c    2004-08-20 18:18:01.000000000 +0100
+++ expect-5.43.0/exp_command.c 2007-09-04 12:35:06.000000000 +0100
@@ -303,21 +303,29 @@
 static
 void
 expBusy(esPtr)
      ExpState *esPtr;
 {     
   int x = open("/dev/null",0);
   if (x != esPtr->fdin) {
     fcntl(x,F_DUPFD,esPtr->fdin);
     close(x);
   }
-  expCloseOnExec(esPtr->fdin);
+  if (esPtr->fdout != EXP_NOFD &&
+      esPtr->fdout != esPtr->fdin) {
+    fcntl(esPtr->fdin,F_DUPFD,esPtr->fdout);
+  }
+  if (esPtr->fdin > 2)
+    expCloseOnExec(esPtr->fdin);
+  if (esPtr->fdout != EXP_NOFD &&
+      esPtr->fdout > 2)
+    expCloseOnExec(esPtr->fdout);
   esPtr->fdBusy = TRUE;
 }
 
 int
 exp_close(interp,esPtr)
 Tcl_Interp *interp;
 ExpState *esPtr;
 {
     if (0 == expStateCheck(interp,esPtr,1,0,"close")) return TCL_ERROR;
     esPtr->open = FALSE;


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to