On Wed, Apr 25, 2012 at 02:54:07PM -0400, Chet Ramey wrote:
> On 4/25/12 2:04 PM, Greg Wooledge wrote:
> 
> > Maybe it only works on boxes with a very large "open files" resource
> > limit.  Perhaps the hard-coded 255 should be replaced with something
> > involving getrlimit() or similar?
> 
> I see two potential fixes here.  First, try changing the 255 to -1 and
> see what happens.

That broke something pretty badly.

cyclops:/var/tmp/bash/bash-4.2$ cat ~/foo
#!/bin/bash
shopt -s lastpipe
echo hi | read foo
echo "<$foo>"
cyclops:/var/tmp/bash/bash-4.2$ ./bash ~/foo
cyclops:/var/tmp/bash/bash-4.2$ ./bash -c 'shopt -s lastpipe; echo hi | read 
foo; echo "<$foo>"'
<hi>

So it seems to work with -c but not when reading from a file.  I'm guessing
the file descriptor move somehow made bash lose track of the file it was
reading commands from.

The move_to_high_fd part looks happier:

Breakpoint 2, move_to_high_fd (fd=0, check_new=0, maxfd=-1) at general.c:444
444       if (maxfd < 20)
(gdb) n
446           nfds = getdtablesize ();
(gdb) n
447           if (nfds <= 0)
(gdb) n
449           if (nfds > HIGH_FD_MAX)
(gdb) n
455       for (nfds--; check_new && nfds > 3; nfds--)
(gdb) n
459       if (nfds > 3 && fd != nfds && (script_fd = dup2 (fd, nfds)) != -1)
(gdb) n
461           if (check_new == 0 || fd != fileno (stderr))      /* don't close 
stderr */
(gdb) n
462             close (fd);
(gdb) n
463           return (script_fd);
(gdb) print script_fd
$1 = 127
(gdb) n
469     }
(gdb) n

But after that I have no idea what's happening (or failing to happen):

execute_pipeline (command=0x209d2c260, asynchronous=0, pipe_in=-1,
    pipe_out=-1, fds_to_close=0x202b8ca10) at execute_cmd.c:2209
2209          if (lstdin > 0)
(gdb) n
2211              do_piping (prev, pipe_out);
(gdb) n
2212              prev = NO_PIPE;
(gdb) n
2213              add_unwind_protect (restore_stdin, lstdin);
(gdb) n
2214              lastpipe_flag = 1;
(gdb) n
2215              freeze_jobs_list ();
(gdb) n
2216              lastpipe_jid = stop_pipeline (0, (COMMAND *)NULL);    /* XXX 
*/
(gdb) n
2217              add_unwind_protect (lastpipe_cleanup, lastpipe_jid);
f (cmd)
(gdb) n
2220            cmd->flags |= CMD_LASTPIPE;
(gdb) n
2222      if (prev >= 0)
(gdb) n
2226      exec_result = execute_command_internal (cmd, asynchronous, prev, 
pipe_out, fds_to_close);
(gdb) n
2229      if (lstdin > 0)
(gdb) n
2230        restore_stdin (lstdin);
(gdb) n
2233      if (prev >= 0)
(gdb) n
2237      UNBLOCK_CHILD (oset);
(gdb) n
2240      QUIT;
(gdb) n
2242      if (lastpipe_flag)
(gdb) n
2245          append_process (savestring (the_printed_command), 
dollar_dollar_pid, exec_result, lastpipe_jid);
(gdb) n
2247          lstdin = wait_for (lastpid);
(gdb) n
2249          exec_result = job_exit_status (lastpipe_jid);
(gdb) n
2251          unfreeze_jobs_list ();
(gdb) n
2254      discard_unwind_frame ("lastpipe-exec");
(gdb) n
2256      return (exec_result);
(gdb) n
2257    }
(gdb) n
execute_connection (command=0x209d2c260, asynchronous=0, pipe_in=-1, 
    pipe_out=-1, fds_to_close=0x202b8ca10) at execute_cmd.c:2338
2338          if (was_error_trap && ignore_return == 0 && invert == 0 && 
exec_result != EXECUTION_SUCCESS)
(gdb) cont
Continuing.

Program exited normally.
(gdb) 

Reply via email to