xref: /openbsd/gnu/usr.bin/cvs/lib/dup2.c (revision a6445c1d)
1 /*
2 	dup2 -- 7th Edition UNIX system call emulation for UNIX System V
3 
4 	last edit:	11-Feb-1987	D A Gwyn
5 */
6 
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10 
11 #include	<errno.h>
12 #include	<fcntl.h>
13 
14 extern int	close(), fcntl();
15 
16 int
17 dup2( oldfd, newfd )
18 	int		oldfd;		/* already-open file descriptor */
19 	int		newfd;		/* desired duplicate descriptor */
20 {
21 	register int	ret;		/* for fcntl() return value */
22 	register int	save;		/* for saving entry errno */
23 
24 	if ( oldfd == newfd )
25 		return oldfd;		/* be careful not to close() */
26 
27 	save = errno;			/* save entry errno */
28 	(void) close( newfd );		/* in case newfd is open */
29 	/* (may have just clobbered the original errno value) */
30 
31 	ret = fcntl( oldfd, F_DUPFD, newfd );	/* dupe it */
32 
33 	if ( ret >= 0 )
34 		errno = save;		/* restore entry errno */
35 	else				/* fcntl() returned error */
36 		if ( errno == EINVAL )
37 			errno = EBADF;	/* we think of everything */
38 
39 	return ret;			/* return file descriptor */
40 }
41