[comp.lang.perl] dup2

rbj@uunet.uu.net (Root Boy Jim) (02/08/91)

--text follows this line--

In article <1991Feb8.002436.21328@usenet.ins.cwru.edu> chet@po.CWRU.Edu writes:
>Doug Schmidt writes:
>
>>	I'm curious, is it possible to implement the dup2() system
>>call using only routines available in the standard C library and other
>>existing system calls?
>
>When you really get down to it.  the kernel is going to have to do the
>nitty-gritty duplication for you, otherwise it gets tricky.  If you have
>an fcntl(..., F_DUPFD, ...), it's straightforward. 
>
>Here's how we do it in bash:

Hmmmm. The two left feet don't know what the right hand is doing.
Go check your emacs sources, src/sysdep.c. It's trivial once you
realize the recursive solution.

First, the one from emacs: OOPS! It doesn't work! And I feel
really stupid cuz I sent it to Larry Wall.
Oh well, I just tested this:

dup2(old,new)
{
	register int fd, ret;
	close(new);
	fd = dup(old);
	if (fd == -1) return(-1);
	if (fd == new) return(new);
	ret = dup2(old,new);
	close(fd);
	return(ret);
}

If you want to try it out, here's a driver program:

main(c,v) char **v;
{
	int a,b;
	(c > 2) || (printf("usage: %s srcfd dstfd\n",v[0]), exit(1));  
        a = atoi(v[1]); b = atoi(v[2]);
        printf("dup2(%d,%d) = %d\n",a,b,dup2(a,b)), exit(0);
}
-- 

	Root Boy Jim Cottrell <rbj@uunet.uu.net>
	I got a head full of ideas
	They're driving me insane

rbj@uunet.UU.NET (Root Boy Jim) (02/08/91)

In article <1991Feb8.002436.21328@usenet.ins.cwru.edu> chet@po.CWRU.Edu writes:
>Doug Schmidt writes:
>
>>	I'm curious, is it possible to implement the dup2() system
>>call using only routines available in the standard C library and other
>>existing system calls?
>
>When you really get down to it.  the kernel is going to have to do the
>nitty-gritty duplication for you, otherwise it gets tricky.  If you have
>an fcntl(..., F_DUPFD, ...), it's straightforward. 
>
>Here's how we do it in bash:

[You may see this twice. Sorry if you do]

Well, a clear case of two left feet not knowing what the right hand is
doing. The solution is trivial once you grasp the recursive nature of it.

I was gonna tell y'all to look in ~emacs/src/sysdep.c, but the
version there is broken! I feel like a fool, as I sent it off to
Larry Wall. Dup and dup2 can fail, altho people treat it as if it can't.
I just debugged the following routine. Appended is a test driver.

dup2(old,new)
{
#ifdef F_DUPFD
	close(new);
	return(fcntl(old, F_DUPFD, new));
#else
        register int fd, ret;
        close(new);
        fd = dup(old);
        if (fd == -1) return(-1);
        if (fd == new) return(new);
        ret = dup2(old,new);
        close(fd);
        return(ret);
#endif
}

main(c,v) char *v[];
{
        register int a,b;
        (c > 2) || (printf("usage: %s srcfd dstfd\n",v[0]),exit(1));
        a = atoi(v[1]); b = atoi(v[2]);
        printf("dup2(%d,%d) = %d\n",a,b,dup2(a,b));
}
-- 

	Root Boy Jim Cottrell <rbj@uunet.uu.net>
	I got a head full of ideas
	They're driving me insane