diff --git a/.gitignore b/.gitignore index 3a3ea6e..3be968b 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,5 @@ configure libtool stamp-* *-stamp +src/zzuf +test/zzcat diff --git a/configure.ac b/configure.ac index 4e9e47b..405c96c 100644 --- a/configure.ac +++ b/configure.ac @@ -29,7 +29,7 @@ AC_SUBST(DLL_LDFLAGS) AC_CHECK_HEADERS(windows.h winsock2.h io.h process.h unistd.h inttypes.h stdint.h getopt.h libc.h malloc.h dlfcn.h regex.h sys/socket.h netinet/in.h sys/uio.h aio.h sys/mman.h sys/wait.h sys/resource.h sys/time.h endian.h) AC_CHECK_FUNCS(setenv waitpid setrlimit gettimeofday fork kill pipe _pipe) -AC_CHECK_FUNCS(open64 lseek64 mmap64 fopen64 fseeko _IO_getc getline getdelim __getdelim fgetln __srefill map_fd memalign posix_memalign aio_read accept bind connect socket readv pread recv recvfrom recvmsg mmap valloc sigaction getpagesize) +AC_CHECK_FUNCS(open64 lseek64 mmap64 fopen64 dup dup2 fseeko _IO_getc getline getdelim __getdelim fgetln __srefill map_fd memalign posix_memalign aio_read accept bind connect socket readv pread recv recvfrom recvmsg mmap valloc sigaction getpagesize) AC_CHECK_TYPES(sighandler_t, [], [], [#define _GNU_SOURCE diff --git a/doc/zzuf.1 b/doc/zzuf.1 index c3a4fda..4fc574a 100644 --- a/doc/zzuf.1 +++ b/doc/zzuf.1 @@ -409,9 +409,10 @@ allocations, \fBzzuf\fR diverts and reimplements the following functions, which can be private libc symbols, too: .TP Unix file descriptor handling: -\fBopen\fR(), \fBlseek\fR(), \fBread\fR(), \fBreadv\fR(), \fBpread\fR(), -\fBaccept\fR(), \fBsocket\fR(), \fBrecv\fR(), \fBrecvfrom\fR(), \fBrecvmsg\fR(), -\fBaio_read\fR(), \fBaio_return\fR(), \fBclose\fR() +\fBopen\fR(), \fBdup\fR(), \fBdup2\fR(), \fBlseek\fR(), \fBread\fR(), +\fBreadv\fR(), \fBpread\fR(), \fBaccept\fR(), \fBsocket\fR(), \fBrecv\fR(), +\fBrecvfrom\fR(), \fBrecvmsg\fR(), \fBaio_read\fR(), \fBaio_return\fR(), +\fBclose\fR() .TP Standard IO streams: \fBfopen\fR(), \fBfreopen\fR(), \fBfseek\fR(), \fBfseeko\fR(), \fBrewind\fR(), diff --git a/src/lib-fd.c b/src/lib-fd.c index 7230620..2ef9329 100644 --- a/src/lib-fd.c +++ b/src/lib-fd.c @@ -81,6 +81,12 @@ static int (*ORIG(open)) (const char *file, int oflag, ...); #if defined HAVE_OPEN64 static int (*ORIG(open64)) (const char *file, int oflag, ...); #endif +#if defined HAVE_DUP +static int (*ORIG(dup)) (int oldfd); +#endif +#if defined HAVE_DUP2 +static int (*ORIG(dup2)) (int oldfd, int newfd); +#endif #if defined HAVE_ACCEPT static int (*ORIG(accept)) (int sockfd, struct sockaddr *addr, SOCKLEN_T *addrlen); @@ -171,6 +177,53 @@ int NEW(open64)(const char *file, int oflag, ...) } #endif +#if defined HAVE_DUP +int NEW(dup)(int oldfd) +{ + int ret; + + LOADSYM(dup); + ret = ORIG(dup)(oldfd); + if(!_zz_ready || _zz_islocked(-1) || !_zz_iswatched(oldfd) + || !_zz_isactive(oldfd)) + return ret; + + if(ret >= 0) + { + debug("%s(%i) = %i", __func__, oldfd, ret); + _zz_register(ret); + } + + return ret; +} +#endif + +#if defined HAVE_DUP2 +int NEW(dup2)(int oldfd, int newfd) +{ + int ret; + + LOADSYM(dup2); + ret = ORIG(dup2)(oldfd, newfd); + if(!_zz_ready || _zz_islocked(-1) || !_zz_iswatched(oldfd) + || !_zz_isactive(oldfd)) + return ret; + + if(ret >= 0) + { + /* We must close newfd if it was open, but only if oldfd != newfd + * and if dup2() suceeded. */ + if(oldfd != newfd && _zz_iswatched(newfd) && _zz_isactive(newfd)) + _zz_unregister(newfd); + + debug("%s(%i, %i) = %i", __func__, oldfd, newfd, ret); + _zz_register(ret); + } + + return ret; +} +#endif + #if defined HAVE_ACCEPT int NEW(accept)(int sockfd, struct sockaddr *addr, SOCKLEN_T *addrlen) {