[net.unix-wizards] dup2 simulator

lmc@denelcor.UUCP (Lyle McElhaney) (03/08/84)

I am attempting to port the uucp contained in 4.2 over to a system 3,
and I've found the old faithful dup2 system call in gwd.c. Is there a
general purpose work-around under system 3 calls to simulate dup2's
function?

Thanks for the help.
-- 
		Lyle McElhaney
		(hao,brl-bmd,nbires,csu-cs,scgvaxd)!denelcor!lmc

guy@rlgvax.UUCP (Guy Harris) (03/10/84)

This question comes up periodically (how to simulate the old V7 "dup2"
system call under USG UNIX (System III, System V, etc.)), so here's the
trick.

"dup2" is sort of an early version of "fcntl(F_DUPFD)".  The main
difference is that it closes the file descriptor to be dup'ed to before
duping it, so that it guarantees (assuming no errors) that the resulting
file descriptor will, indeed, be the one asked for.

So:

/*
 * From DUP(2), 4.1BSD manual:
 *
 * "fildes" is a file descriptor referring to an open file, and "fildes2"
 * is a non-negative integer less than the maximum value allowed for file
 * descriptors (approximately 19).  "Dup2" causes "fildes2" to refer to the
 * same file as "fildes".  If "fildes2" already referred to an open file,
 * it is closed first.
 */
#include <fcntl.h>

int
dup2(fildes, fildes2)
int fildes;
int fildes2;
{
#ifdef PARANOID
	/*
	 * To be completely technically correct, if "fildes" is not a valid
	 * file descriptor, "dup2" fails *without* closing "fildes2".  So
	 * we can check if we really want to be paranoid.
	 *
	 * We do this check by doing an "fstat" on "fildes" into a "stat"
	 * buffer, and if the "fstat" returns -1 with "errno" set to EBADF,
	 * we bail out immediately, returning -1.
	 */
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
	extern int errno;
	struct stat statb;

	if (fstat(fildes, &statb) < 0 && errno == EBADF)
		return(-1);
#endif
	if (close(fildes2) < 0)
		return(-1);
	return(fcntl(fildes, F_DUPFD, fildes2));
}

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

gwyn%brl-vld@sri-unix.UUCP (03/12/84)

From:      Doug Gwyn (VLD/VMB) <gwyn@brl-vld>

Your dup(2) emulation incorrectly returns an error indication if
fildes2 is not open.  The close(fildes2) return value should not
be tested:
	(void)close(fildes2);

gwyn%brl-vld@sri-unix.UUCP (03/12/84)

From:      Doug Gwyn (VLD/VMB) <gwyn@brl-vld>

Your dup2() emulation incorrectly returns an error indication if
fildes2 is not open.  The close() return value should be ignored:
	(void)close(fildes2);