lkml.org 
[lkml]   [1998]   [Jun]   [30]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
/
DateTue, 30 Jun 1998 12:24:42 -0700 (PDT)
FromDean Gaudet <>
SubjectRe: extended file handles
On Tue, 30 Jun 1998, MOLNAR Ingo wrote:

>  [mingo@hal ce]$ ./ce
>  fd(3,3) open(..,..|O_CLOSEXEC) feature works!
> 
> wondering wether the libc & standards guys like this approach though.

Cool :)  You may want call it O_CLOEXEC -- which sounds closer to the
FD_CLOEXEC that solaris defines for fcntl(F_SETFD).

If you support O_CLOEXEC with fcntl() as well, then a single system call
can be used to turn the result of accept()/socket()/socketpair()/pipe()
into a non-blocking, non-inherited socket.

Here's another idea which solves almost all the problems, without any
need for O_CLOEXEC.

    pid_t clonefd(void *sp, unsigned long flags,
		  const int *fd_split, size_t n_fd);

where:
    sp and flags are as in clone()

    fd_split is an array of file descriptors that describe exactly
        which descriptors the child will keep... there's various
	different ways to do this.  If it's not listed in this array
	it will be closed in the child.
    n_fd is the number of descriptors in fd_split

    the result is similar to clone

fd_split has various possible semantics, I'm not sure of the best,
all may be possible with more flags:

- assume that the parent has used pipe() or open() to set up a few
  descriptors for the child and plans to turn them into 0, 1, and 2
  in the child.  So copy fd_split[n] to the nth descriptor in the
  child, and close each in the parent.  i.e.:

    int childin[2];
    int childout[2];
    int childerr[2];
    int fd_split[3];

    pipe(childin);
    pipe(childout);
    pipe(childerr);
    fd_split[0] = childin[0];
    fd_split[1] = childout[1];
    fd_split[2] = childerr[1];
    if (clonefd(NULL, CLONE_FS|CLONE_SIGHAND|CLONE_VM, fd_split, 3)) {
	/* in parent, childin[0], childout[1], and childerr[1] are
	 * no longer open
	 */
    }
    else {
	/* in child, the only open descriptors are 0, 1, 2 */
	exec(something);
    }
    (this one is the best for apache and shells)

- assume that the parent is trying to share an open fd with the child
  (i.e. a log file).  In this case copy fd_split[n] to the nth
  descriptor in the child and leave them open in the parent.  So the
  parent would have to explicitly call close() on the descriptors it
  didn't intend to share.

     (dunno, what's it good for?  You can simulate it with the first
     and a few extra dup()s)

- copy fd_split to the child without renumbering -- so if
  fd_split[0] == 34, then the child has descriptor 34 open.  Works with
  either of the above two semantics.

clonefd() is essentially an extension to clone() to tune it for spawning
new programs.  With it there's almost no reason for XFDs... the
remaining reason is to get away from POSIX' "lowest available
descriptor" semantic...  which is easy for open(), but still a pain
for socket()/accept()/etc.

Dean


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu

\
 
 \ /
  Last update: 2005-03-22 12:43    [W:4.693 / U:0.180 seconds]
©2003-2008 Jasper Spaans