#include "pub_core_libcassert.h"
#include "pub_core_libcfile.h"
#include "pub_core_libcprint.h" // For VG_(sprintf)()
-#include "pub_core_mallocfree.h"
#include "pub_core_syscall.h"
#include "vki_unistd.h"
/* Given a file descriptor, attempt to deduce its filename. To do
this, we use /proc/self/fd/<FD>. If this doesn't point to a file,
- or if it doesn't exist, we just return NULL. The caller is
- responsible for copying the contents of buf out immediately. */
-static HChar resolve_filename_buf[VKI_PATH_MAX];
-HChar* VG_(resolve_filename_nodup) ( Int fd )
+ or if it doesn't exist, we return False. */
+Bool VG_(resolve_filename) ( Int fd, HChar* buf, Int n_buf )
{
HChar tmp[64];
VG_(sprintf)(tmp, "/proc/self/fd/%d", fd);
- VG_(memset)(resolve_filename_buf, 0, VKI_PATH_MAX);
+ VG_(memset)(buf, 0, n_buf);
- if (VG_(readlink)(tmp, resolve_filename_buf, VKI_PATH_MAX) == -1)
- return NULL;
-
- return (resolve_filename_buf[0] == '/')
- ? resolve_filename_buf
- : NULL;
-}
-
-/* Same as resolve_filename_nodup, except that the result is copied
- into new memory which the caller is responsible for freeing. */
-HChar* VG_(resolve_filename) ( Int fd )
-{
- HChar* transient = VG_(resolve_filename_nodup)(fd);
- return transient
- ? VG_(arena_strdup)(VG_AR_CORE, transient)
- : NULL;
+ if (VG_(readlink)(tmp, buf, VKI_PATH_MAX) > 0 && buf[0] == '/')
+ return True;
+ else
+ return False;
}
/* Returns -1 on failure. */
some such thing) or that we don't know the filename. If the fd is
already open, then we're probably doing a dup2() to an existing fd,
so just overwrite the existing one. */
-void ML_(record_fd_open)(ThreadId tid, Int fd, char *pathname)
+static void record_fd_open_with_given_name(ThreadId tid, Int fd, char *pathname)
{
OpenFd *i;
}
i->fd = fd;
- i->pathname = pathname;
+ i->pathname = VG_(arena_strdup)(VG_AR_CORE, pathname);
i->where = (tid == -1) ? NULL : VG_(record_ExeContext)(tid);
}
+// Record opening of an fd, and find its name.
+static void record_fd_open_named(ThreadId tid, Int fd)
+{
+ static HChar buf[VKI_PATH_MAX];
+ Char* name;
+ if (VG_(resolve_filename)(fd, buf, VKI_PATH_MAX))
+ name = buf;
+ else
+ name = NULL;
+
+ record_fd_open_with_given_name(tid, fd, name);
+}
+
+// Record opening of a nameless fd.
+void ML_(record_fd_open_nameless)(ThreadId tid, Int fd)
+{
+ record_fd_open_with_given_name(tid, fd, NULL);
+}
+
static
Char *unix2name(struct vki_sockaddr_un *sa, UInt len, Char *name)
{
for (i = 0; i < count; i++)
if(VG_(fcntl)(i, VKI_F_GETFL, 0) != -1)
- ML_(record_fd_open)(-1, i, NULL);
+ ML_(record_fd_open_nameless)(-1, i);
}
/* Initialize the list of open file descriptors with the file descriptors
}
while((ret = VG_(getdents)(f, &d, sizeof(d))) != 0) {
- if(ret == -1)
+ if (ret == -1)
goto out;
- if(VG_(strcmp)(d.d_name, ".") && VG_(strcmp)(d.d_name, "..")) {
+ if (VG_(strcmp)(d.d_name, ".") && VG_(strcmp)(d.d_name, "..")) {
int fno = VG_(atoll)(d.d_name);
- if(fno != f)
- if(VG_(clo_track_fds))
- ML_(record_fd_open)(-1, fno, VG_(resolve_filename)(fno));
+ if (fno != f)
+ if (VG_(clo_track_fds))
+ record_fd_open_named(-1, fno);
}
VG_(lseek)(f, d.d_off, VKI_SEEK_SET);
if(VG_(clo_track_fds))
// XXX: must we check the range on these fds with
// VG_(fd_allowed)()?
- ML_(record_fd_open) (tid, fds[i], VG_(resolve_filename)(fds[i]));
+ record_fd_open_named(tid, fds[i]);
}
cm = VKI_CMSG_NXTHDR(msg, cm);
} else {
POST_MEM_WRITE( arg3, 2*sizeof(int) );
if (VG_(clo_track_fds)) {
- ML_(record_fd_open)(tid, fd1, NULL);
- ML_(record_fd_open)(tid, fd2, NULL);
+ ML_(record_fd_open_nameless)(tid, fd1);
+ ML_(record_fd_open_nameless)(tid, fd2);
}
}
return r;
r = VG_(mk_SysRes_Error)( VKI_EMFILE );
} else {
if (VG_(clo_track_fds))
- ML_(record_fd_open)(tid, res.val, NULL);
+ ML_(record_fd_open_nameless)(tid, res.val);
}
return r;
}
buf_and_len_post_check ( tid, res, addr_p, addrlen_p,
"socketcall.accept(addrlen_out)" );
if (VG_(clo_track_fds))
- ML_(record_fd_open)(tid, res.val, NULL);
+ ML_(record_fd_open_nameless)(tid, res.val);
}
return r;
}
SET_STATUS_Failure( VKI_EMFILE );
} else {
if (VG_(clo_track_fds))
- ML_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
+ record_fd_open_named(tid, RES);
}
}
{
vg_assert(SUCCESS);
if (VG_(clo_track_fds))
- ML_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
+ record_fd_open_named(tid, RES);
}
PRE(sys_fchdir)
SET_STATUS_Failure( VKI_EMFILE );
} else {
if (VG_(clo_track_fds))
- ML_(record_fd_open)(tid, RES, VG_(resolve_filename)(RES));
+ record_fd_open_named(tid, RES);
}
}
}
SET_STATUS_Failure( VKI_EMFILE );
} else {
if (VG_(clo_track_fds))
- ML_(record_fd_open)(tid, RES,
- VG_(resolve_filename)(RES));
+ record_fd_open_named(tid, RES);
}
}
}
SET_STATUS_Failure( VKI_EMFILE );
} else {
if (VG_(clo_track_fds))
- ML_(record_fd_open)(tid, RES,
- VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
+ record_fd_open_with_given_name(tid, RES, (Char*)ARG1);
}
}
SET_STATUS_Failure( VKI_EMFILE );
} else {
if (VG_(clo_track_fds))
- ML_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
+ record_fd_open_with_given_name(tid, RES, (Char*)ARG1);
}
}
} else {
POST_MEM_WRITE( ARG1, 2*sizeof(int) );
if (VG_(clo_track_fds)) {
- ML_(record_fd_open)(tid, p[0], NULL);
- ML_(record_fd_open)(tid, p[1], NULL);
+ ML_(record_fd_open_nameless)(tid, p[0]);
+ ML_(record_fd_open_nameless)(tid, p[1]);
}
}
}
SET_STATUS_Failure( VKI_EMFILE );
} else {
if (VG_(clo_track_fds))
- ML_(record_fd_open)(tid, RES, VG_(arena_strdup)(VG_AR_CORE, (Char*)ARG1));
+ record_fd_open_with_given_name(tid, RES, (Char*)ARG1);
}
}