or if it doesn't exist, we return False. */
Bool VG_(resolve_filename) ( Int fd, HChar* buf, Int n_buf )
{
+# if defined(VGO_linux)
HChar tmp[64];
-
VG_(sprintf)(tmp, "/proc/self/fd/%d", fd);
VG_(memset)(buf, 0, n_buf);
-
if (VG_(readlink)(tmp, buf, n_buf) > 0 && buf[0] == '/')
return True;
else
return False;
+# elif defined(VGO_aix5)
+ I_die_here; /* maybe just return False? */
+ return False;
+# else
+# error "need fd-to-filename for this OS"
+# endif
}
SysRes VG_(open) ( const Char* pathname, Int flags, Int mode )
VG_(message)(Vg_UserMsg, "");
}
-/* If /proc/self/fd doesn't exist for some weird reason (like you've
- got a kernel that doesn't have /proc support compiled in), then we
- need to find out what file descriptors we inherited from our parent
- process the hard way - by checking each fd in turn. */
-
+/* If /proc/self/fd doesn't exist (e.g. you've got a Linux kernel that doesn't
+ have /proc support compiled in, or a non-Linux kernel), then we need to
+ find out what file descriptors we inherited from our parent process the
+ hard way - by checking each fd in turn. */
static
-void do_hacky_preopened(void)
+void init_preopened_fds_without_proc_self_fd(void)
{
struct vki_rlimit lim;
UInt count;
if (VG_(getrlimit) (VKI_RLIMIT_NOFILE, &lim) == -1) {
/* Hmm. getrlimit() failed. Now we're screwed, so just choose
an arbitrarily high number. 1024 happens to be the limit in
- the 2.4 kernels. */
+ the 2.4 Linux kernels. */
count = 1024;
} else {
count = lim.rlim_cur;
}
for (i = 0; i < count; i++)
- if(VG_(fcntl)(i, VKI_F_GETFL, 0) != -1)
- ML_(record_fd_open_nameless)(-1, i);
+ if (VG_(fcntl)(i, VKI_F_GETFL, 0) != -1)
+ ML_(record_fd_open_named)(-1, i);
}
/* Initialize the list of open file descriptors with the file descriptors
void VG_(init_preopened_fds)(void)
{
+// Nb: AIX5 is handled in syswrap-aix5.c.
+#if defined(VGO_linux)
Int ret;
struct vki_dirent d;
SysRes f;
f = VG_(open)("/proc/self/fd", VKI_O_RDONLY, 0);
if (f.isError) {
- do_hacky_preopened();
+ init_preopened_fds_without_proc_self_fd();
return;
}
out:
VG_(close)(f.res);
+
+#else
+# error Unknown OS
+#endif
}
static
PRE(sys_ni_syscall)
{
+ // Nb: AIX5 is handled in syswrap-aix5.c.
PRINT("non-existent syscall! (ni_syscall)");
PRE_REG_READ0(long, "ni_syscall");
SET_STATUS_Failure( VKI_ENOSYS );
#ifndef _FDLEAK_H_
#define _FDLEAK_H_
+#include <stdlib.h>
+#include <stdio.h>
+
+#define DO(op) \
+ ({ \
+ long res = op; \
+ if (res < 0) { \
+ perror(#op); \
+ exit(1); \
+ }; \
+ res; \
+ })
+
/*
* The macro below closes file descriptors inherited from the process
* that forked the current process. Close these file descriptors right
char fileb[24];
char sock[24];
-void
-server (void)
+void server (void)
{
int s, fd1, fd2;
struct sockaddr_un addr;
- fd1 = open(filea, O_RDWR | O_CREAT | O_TRUNC, 0750);
- if(fd1 == -1) {
- perror("open");
- exit(1);
- }
-
- fd2 = open(fileb, O_RDWR | O_CREAT | O_TRUNC, 0750);
- if(fd2 == -1) {
- perror("open");
- exit(1);
- }
-
- s = socket(PF_UNIX, SOCK_STREAM, 0);
- if(s == -1) {
- perror("socket");
- exit(1);
- }
+ fd1 = DO( open(filea, O_RDWR | O_CREAT | O_TRUNC, 0750) );
+ fd2 = DO( open(fileb, O_RDWR | O_CREAT | O_TRUNC, 0750) );
+ s = DO( socket(PF_UNIX, SOCK_STREAM, 0) );
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
sprintf(addr.sun_path, "%s", sock);
- unlink(addr.sun_path);
- if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
- perror("bind");
- exit(1);
- }
-
- if(listen(s, 5) == -1) {
- perror("listen");
- exit(1);
- }
+ unlink(sock);
+ DO( bind(s, (struct sockaddr *)&addr, sizeof(addr)) );
+ DO( listen(s, 5) );
{
int x;
struct iovec iov[1];
memset(&baddr, 0, sizeof(baddr));
- x = accept(s, (struct sockaddr *)&baddr, &baddrsize);
- if(x == -1) {
- perror("accept");
- exit(1);
- }
+ x = DO( accept(s, (struct sockaddr *)&baddr, &baddrsize) );
msg.msg_control = buf;
msg.msg_controllen = sizeof(buf);
msg.msg_iov = iov;
msg.msg_iovlen = 1;
- if(sendmsg(x, &msg, 0) == -1) {
- perror("sendmsg");
- exit(1);
- }
+ DO( sendmsg(x, &msg, 0) );
}
}
-void
-client (void)
+void client (void)
{
int s, fd1 = -1, fd2 = -1, size, count = 0, ret;
struct sockaddr_un addr;
iov[0].iov_len = sizeof(buf);
s = socket(PF_UNIX, SOCK_STREAM, 0);
- if(s == -1) {
+ if (s == -1) {
perror("socket");
exit(1);
}
do {
count++;
ret = connect(s, (struct sockaddr *)&addr, sizeof(addr));
- if(ret == -1) sleep(1);
+ if (ret == -1) sleep(1);
} while (count < 10 && ret == -1);
- if(ret == -1) {
+ if (ret == -1) {
perror("connect");
exit(1);
}
again:
- if((size = recvmsg(s, &msg, 0)) == -1) {
+ if ((size = recvmsg(s, &msg, 0)) == -1) {
if (errno == EINTR)
goto again; /* SIGCHLD from server exiting could interrupt */
perror("recvmsg");
cmsg = CMSG_FIRSTHDR(&msg);
- while(cmsg) {
- if(cmsg->cmsg_level == SOL_SOCKET &&
+ while (cmsg) {
+ if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS &&
cmsg->cmsg_len == CMSG_LEN(sizeof(int) * 2)) {
fd1 = ((int *)CMSG_DATA(cmsg))[0];
cmsg = CMSG_NXTHDR(&msg, cmsg);
}
- if(fd1 != -1) write(fd1, "Yeah 1\n", 8);
- if(fd2 != -1) write(fd2, "Yeah 2\n", 8);
+ if (fd1 != -1) write(fd1, "Yeah 1\n", 8);
+ if (fd2 != -1) write(fd2, "Yeah 2\n", 8);
}
-int
-main (int argc, char **argv)
+int main (int argc, char **argv)
{
int pid, status;
-
-
-
-
-
CLOSE_INHERITED_FDS;
pid = getpid();
sprintf(fileb, "/tmp/data2.%d", pid);
sprintf(sock, "/tmp/sock.%d", pid);
- if((pid = fork()) == 0) {
+ if ((pid = fork()) == 0) {
server();
return 0;
}
wait(&status);
- unlink(filea);
- unlink(fileb);
- unlink(sock);
+ DO( unlink(filea) );
+ DO( unlink(fileb) );
+ DO( unlink(sock) );
return 0;
}
FILE DESCRIPTORS: 7 open at exit.
-Open AF_UNIX socket .: /tmp/sock
+Open AF_UNIX socket ...: /tmp/sock
...
-Open AF_UNIX socket .: /tmp/sock
+Open AF_UNIX socket ...: /tmp/sock
...
-Open file descriptor .: /tmp/data2
+Open file descriptor ...: /tmp/data2
...
-Open file descriptor .: /tmp/data1
+Open file descriptor ...: /tmp/data1
...
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
<inherited from parent>
FILE DESCRIPTORS: 6 open at exit.
-Open file descriptor .: /tmp/data2
+Open file descriptor ...: /tmp/data2
...
-Open file descriptor .: /tmp/data1
+Open file descriptor ...: /tmp/data1
...
-Open AF_UNIX socket .: <unknown>
+Open AF_UNIX socket ...: <unknown>
...
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
<inherited from parent>
#include <stdio.h>
#include <fcntl.h>
#include "fdleak.h"
-int
-main (int argc, char **argv)
+
+int main (int argc, char **argv)
{
char filename[24];
-
-
-
-
-
CLOSE_INHERITED_FDS;
sprintf(filename, "/tmp/file.%d", getpid());
- creat(filename, 0);
- unlink(filename);
+ DO( creat(filename, 0) );
+ DO( unlink(filename) );
return 0;
}
FILE DESCRIPTORS: 4 open at exit.
-Open file descriptor .: /tmp/file
+Open file descriptor ...: /tmp/file
...
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
<inherited from parent>
#include <unistd.h>
#include <fcntl.h>
#include "fdleak.h"
-int
-main (int argc, char **argv)
+
+int main (int argc, char **argv)
{
int s;
-
-
-
-
-
CLOSE_INHERITED_FDS;
- s = open("/dev/null", O_RDONLY);
- dup(s);
+ s = DO( open("/dev/null", O_RDONLY) );
+ DO( dup(s) );
+
return 0;
}
FILE DESCRIPTORS: 5 open at exit.
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
...
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
...
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
<inherited from parent>
#include <unistd.h>
#include <fcntl.h>
#include "fdleak.h"
-int
-main (int argc, char **argv)
+
+int main (int argc, char **argv)
{
int s1;
int s2;
-
-
-
-
-
CLOSE_INHERITED_FDS;
- s1 = open("/dev/null", O_RDONLY);
- s2 = open("/dev/null", O_RDONLY);
+ s1 = DO( open("/dev/null", O_RDONLY) );
+ s2 = DO( open("/dev/null", O_RDONLY) );
+
+ DO( dup2(s1, 20) ); // dup s1 as fd 20
+ DO( dup2(s1, s2) ); // dup s1 as fd s2, which closes existing s2 fd
- dup2(s1, 20);
- dup2(s1, s2);
return 0;
}
FILE DESCRIPTORS: 6 open at exit.
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
...
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
...
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
...
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
<inherited from parent>
#include <stdio.h>
#include <fcntl.h>
#include "fdleak.h"
-int
-main (int argc, char **argv)
+
+int main (int argc, char **argv)
{
int s1;
-
-
-
-
-
CLOSE_INHERITED_FDS;
- s1 = open("/dev/null", O_RDONLY);
- if(fcntl(s1, F_DUPFD, s1) == -1) perror("fcntl");
+ s1 = DO( open("/dev/null", O_RDONLY) );
+ DO( fcntl(s1, F_DUPFD, s1) );
+
return 0;
}
FILE DESCRIPTORS: 5 open at exit.
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
...
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
...
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
<inherited from parent>
#include <stdlib.h>
#include <string.h>
#include "fdleak.h"
-void
-server ()
+
+void server ()
{
int s, x;
struct sockaddr_in baddr;
struct sockaddr_in addr;
- int baddrsize = sizeof(baddr);
+ socklen_t baddrsize = sizeof(baddr);
int one = 1;
- s = socket(PF_INET, SOCK_STREAM, 0);
- if(s == -1) {
- perror("socket");
- exit(1);
- }
+ s = DO( socket(PF_INET, SOCK_STREAM, 0) );
- setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
+ DO( setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int)) );
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = 12321;
- if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
- perror("bind");
- exit(1);
- }
+ DO( bind(s, (struct sockaddr *)&addr, sizeof(addr)) );
- if(listen(s, 5) == -1) {
- perror("listen");
- exit(1);
- }
+ DO( listen(s, 5) );
memset(&baddr, 0, sizeof(baddr));
- x = accept(s, (struct sockaddr *)&baddr, &baddrsize);
- if(x == -1) {
- perror("accept");
- exit(1);
- }
+ x = DO( accept(s, (struct sockaddr *)&baddr, &baddrsize) );
- write(x, "hello", 6);
+ DO( write(x, "hello", 6) );
}
-void
-client ()
+void client ()
{
int s, count = 0, ret;
struct sockaddr_in addr;
char buf[1024];
- s = socket(PF_INET, SOCK_STREAM, 0);
- if(s == -1) {
- perror("socket");
- exit(1);
- }
+ s = DO( socket(PF_INET, SOCK_STREAM, 0) );
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
do {
count++;
ret = connect(s, (struct sockaddr *)&addr, sizeof(addr));
- if(ret == -1) sleep(1);
+ if (ret == -1) sleep(1);
} while (count < 10 && ret == -1);
- if(ret == -1) {
+ if (ret == -1) {
perror("connect");
exit(1);
}
- read(s, buf, sizeof(buf));
+ DO( read(s, buf, sizeof(buf)) );
printf("%s\n", buf);
}
-int
-main (int argc, char **argv)
+int main (int argc, char **argv)
{
int pid, status;
-
-
-
-
-
CLOSE_INHERITED_FDS;
- if((pid = fork()) == 0) {
+ if ((pid = fork()) == 0) {
server();
return 0;
}
Open AF_INET socket 3: 127.0.0.1:... <-> unbound
...
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
<inherited from parent>
Open AF_INET socket 3: 127.0.0.1:... <-> 127.0.0.1:...
...
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
<inherited from parent>
#include <unistd.h>
#include "fdleak.h"
-int
-main (int argc, char **argv)
+int main (int argc, char **argv)
{
-
-
-
CLOSE_INHERITED_FDS;
- open("/dev/null", O_RDONLY);
+ DO( open("/dev/null", O_RDONLY) );
+
return 0;
}
FILE DESCRIPTORS: 4 open at exit.
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
...
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
<inherited from parent>
#include <unistd.h>
#include "fdleak.h"
-int
-main (int argc, char **argv)
+
+int main (int argc, char **argv)
{
int fds[2];
-
-
-
-
-
CLOSE_INHERITED_FDS;
- pipe(fds);
+ DO( pipe(fds) );
+
return 0;
}
FILE DESCRIPTORS: 5 open at exit.
-Open file descriptor .:
+Open file descriptor ...:
...
-Open file descriptor .:
+Open file descriptor ...:
...
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
<inherited from parent>
#include <sys/socket.h>
#include <unistd.h>
#include "fdleak.h"
+#include <sys/errno.h>
-int
-main (int argc, char **argv)
+int main (int argc, char **argv)
{
int fds[2];
-
-
-
CLOSE_INHERITED_FDS;
- socketpair(AF_UNIX, SOCK_STREAM, PF_UNIX, fds);
+ DO( socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fds) );
+
return 0;
}
FILE DESCRIPTORS: 5 open at exit.
-Open AF_UNIX socket .: <unknown>
+Open AF_UNIX socket ...: <unknown>
...
-Open AF_UNIX socket .: <unknown>
+Open AF_UNIX socket ...: <unknown>
...
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: .
+Open file descriptor ...: ...
<inherited from parent>
-Open file descriptor .: /dev/null
+Open file descriptor ...: /dev/null
<inherited from parent>
dir=`dirname $0`
-./filter_stderr |
+./filter_stderr |
-sed s/"^Open AF_UNIX socket [0-9]*: <unknown>/Open AF_UNIX socket .: <unknown>/" |
-sed s/"^Open \(AF_UNIX socket\|file descriptor\) [0-9]*: \/dev\/null/Open \\1 .: \/dev\/null/" |
-sed s/"^Open \(AF_UNIX socket\|file descriptor\) [0-9]*: \/tmp\/\(sock\|data1\|data2\|file\)\.[0-9]*/Open \\1 .: \/tmp\/\\2/" |
-sed s/"^Open file descriptor [0-9]*: .*/Open file descriptor .: ./" |
-sed s/"^Open file descriptor [0-9]*:$/Open file descriptor .:/" |
-sed s/"127.0.0.1:[0-9]*/127.0.0.1:.../g" |
+perl -p -e 's/^Open AF_UNIX socket [0-9]*: <unknown>/Open AF_UNIX socket ...: <unknown>/' |
+perl -p -e 's/^Open (AF_UNIX socket|file descriptor) [0-9]*: \/dev\/null/Open $1 ...: \/dev\/null/' |
+# Nb: on Darwin, /tmp is a symlink to /private/tmp, so sometimes it's
+# necessary to filter out the "/private" part.
+perl -p -e 's/^Open (AF_UNIX socket|file descriptor) [0-9]*: (\/private)?\/tmp\/(sock|data1|data2|file)\.[0-9]*/Open $1 ...: \/tmp\/$3/' |
+perl -p -e 's/^Open file descriptor [0-9]*: .*/Open file descriptor ...: .../' |
+perl -p -e 's/^Open file descriptor [0-9]*:$/Open file descriptor ...:/' |
+perl -p -e 's/127.0.0.1:[0-9]*/127.0.0.1:.../g' |
# Stack traces showing where fds were created have lots of variations:
# different numbers of entries, line numbers or not depending on whether