Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1a 12/4/83; site rlgvax.UUCP Path: utzoo!watmath!clyde!burl!ulysses!harpo!seismo!rlgvax!guy From: guy@rlgvax.UUCP (Guy Harris) Newsgroups: net.unix-wizards,net.unix Subject: Re: dup2 simulator Message-ID: <1796@rlgvax.UUCP> Date: Fri, 9-Mar-84 21:55:38 EST Article-I.D.: rlgvax.1796 Posted: Fri Mar 9 21:55:38 1984 Date-Received: Sat, 10-Mar-84 14:18:23 EST References: <351@denelcor.UUCP> Organization: CCI Office Systems Group, Reston, VA Lines: 53 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. */ #includeint 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 #include #include 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