execve(), passing file descriptors?

execve(), passing file descriptors?

Post by Mark H. Woo » Mon, 04 Jun 2001 10:56:46



I need to run *part* of standard input through compress, after
inspecting the remainder.  (It's for a weird newsfeed -- boring
details on request.)  While I could pipe it through a subprocess,
that's a rather complicated dance, and I thought there ought to be a
way to pass the properly-positioned file descriptor to compress.  It
sure *looks* as though I should be able to do something like this:

      flags = fcntl(fileno(stdin),F_GETFD);
      flags &= !FD_CLOEXEC;
      fcntl(fileno(stdin),F_SETFD,flags);

      flags = fcntl(fileno(stdout),F_GETFD);
      flags &= !FD_CLOEXEC;
      fcntl(fileno(stdout),F_SETFD,flags);

      if (execlp(DECOMPRESSOR,DECOMPRESSOR,"-d",NULL))
        perror("execlp");

but although compress is launched successfully, it complains about
unexpected end of input.  strace shows the first read() returning
zero.  What did I miss?

(The kernel is Linux 2.2.17, libc is GNU libc 2.2.3 .)

--

Make a good day.

 
 
 

execve(), passing file descriptors?

Post by Andrew Giert » Mon, 04 Jun 2001 12:02:50


 Mark> I need to run *part* of standard input through compress, after
 Mark> inspecting the remainder.  (It's for a weird newsfeed -- boring
 Mark> details on request.)  While I could pipe it through a
 Mark> subprocess, that's a rather complicated dance, and I thought
 Mark> there ought to be a way to pass the properly-positioned file
 Mark> descriptor to compress.  It sure *looks* as though I should be
 Mark> able to do something like this:

 Mark>       flags = fcntl(fileno(stdin),F_GETFD);
 Mark>       flags &= !FD_CLOEXEC;
 Mark>       fcntl(fileno(stdin),F_SETFD,flags);

 Mark>       flags = fcntl(fileno(stdout),F_GETFD);
 Mark>       flags &= !FD_CLOEXEC;
 Mark>       fcntl(fileno(stdout),F_SETFD,flags);

you shouldn't need to do any of that. FD_CLOEXEC will not be set on
stdin or stdout (unless your program did so itself, which is
perverse).

However, if you've used any of the stdio functions to read from stdin,
then it will almost certainly be positioned incorrectly for your
purposes. (The stdio functions will read more data than expected.)  If
stdin is a pipe (and therefore not seekable), then you'll basically
have to avoid using any stdio functions on it at all; if it's a plain
file, then you should call lseek (not fseek) before the exec to get
the positioning correct.

--
Andrew.

comp.unix.programmer FAQ: see <URL: http://www.erlenstar.demon.co.uk/unix/>
                           or <URL: http://www.whitefang.com/unix/>

 
 
 

execve(), passing file descriptors?

Post by Mark H. Woo » Tue, 05 Jun 2001 20:04:04


[snip]

Quote:> However, if you've used any of the stdio functions to read from stdin,
> then it will almost certainly be positioned incorrectly for your
> purposes. (The stdio functions will read more data than expected.)

Duuh, of course that's the problem.  Thank you.  The revised code is
working well.

--

Make a good day.

 
 
 

1. Maintaining file descriptor attributes across execve()

How can I maintain a file descriptor's attributes across an execve()?
The problem I am having is that when I turn i/o buffering off using
setvbuf() in the child process, buffering ends up being restored in
the exec'd program.  For example, look at the FILE* structures for the
child process before and after the execve():

Before execve():
{
  _cnt = 0;
  _ptr = 0xcef08 "";
  _base = 0xcef08 "";
  _bufsiz = 0;
  _flag = 153;
  _file = 0 '\000';
  _smallbuf = 0 '\000';

After execve():
{
  _cnt = 0;
  _ptr = 0x101ea " child stdin\n";
  _base = 0x101e8 "1\n child stdin\n";
  _bufsiz = 4096;
  _flag = 9;
  _file = 0 '\000';
  _smallbuf = 0 '\000';

The man page for execve() says that open file descriptors are not effected
by the call.  Obviously this is not quite true.

Any ideas on how I can maintain the unbuffered attribute?

Thanks,
Scott Stark

2. Sparc 10 and ISDN

3. Passing file descriptors using recvmsg and sendmsg questions

4. How to install Soundblaster PCI64

5. Passing file descriptors across processes

6. fdisk

7. Passing File Descriptor

8. Findfont Problem when printing

9. Passing file descriptors between processes

10. passing file descriptors in AIX

11. passing file descriptors under Linux

12. Passing open file descriptors

13. passing file descriptors