// SYS_symlink 57
// generic
+static void do_readlink(const HChar* path, HChar *buf, SizeT bufsize, SyscallStatus* status, Bool* curproc_file)
+{
+ HChar name[30];
+ VG_(sprintf)(name, "/proc/%d/file", VG_(getpid)());
+ if (ML_(safe_to_deref)(path, 1)
+ && (VG_(strcmp)(path, name) == 0
+ || VG_(strcmp)(path, "/proc/curproc/file") == 0)) {
+ vg_assert(VG_(resolved_exename));
+ Int len = VG_(snprintf)(buf, bufsize, "%s", VG_(resolved_exename));
+ SET_STATUS_Success(len);
+ *curproc_file = True;
+ }
+}
+
// SYS_readlink 58
-// generic
+// ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsiz);
+PRE(sys_readlink)
+{
+ FUSE_COMPATIBLE_MAY_BLOCK();
+ Word saved = SYSNO;
+ Bool curproc_file = False;
+
+ PRINT("sys_readlink ( %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %llu )",
+ ARG1, (char*)(Addr)ARG1, ARG2, (ULong)ARG3);
+ PRE_REG_READ3(long, "readlink",
+ const char *, path, char *, buf, int, bufsiz);
+ PRE_MEM_RASCIIZ( "readlink(path)", ARG1 );
+ PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 );
+
+ if (VG_(have_slash_proc) == True)
+ {
+ /*
+ * Handle the case where readlink is looking at /proc/curproc/file or
+ * /proc/<pid>/file
+ */
+ do_readlink((const HChar *)ARG1, (HChar *)ARG2, (SizeT)ARG3, status, &curproc_file);
+ }
+
+ if (!curproc_file) {
+ /* Normal case */
+ SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, ARG1, ARG2, ARG3));
+ }
+ if (SUCCESS && RES > 0) {
+ POST_MEM_WRITE( ARG2, RES );
+ }
+}
// SYS_execve 59
// generic
static Bool sysctl_kern_proc_pathname(HChar *out, SizeT *len)
{
- // is this stashed somewhere?
- const HChar *exe_name = VG_(find_executable)(VG_(args_the_exename));
+ const HChar *exe_name = VG_(resolved_exename);
if (!VG_(realpath)(exe_name, out)) {
return False;
// size_t bufsize);
PRE(sys_readlinkat)
{
- HChar name[25];
Word saved = SYSNO;
+ Bool curproc_file = False;
PRINT("sys_readlinkat ( %" FMT_REGWORD "u, %#" FMT_REGWORD "x(%s), %#" FMT_REGWORD "x, %llu )", ARG1,ARG2,(char*)ARG2,ARG3,(ULong)ARG4);
PRE_REG_READ4(ssize_t, "readlinkat",
PRE_MEM_RASCIIZ( "readlinkat(path)", ARG2 );
PRE_MEM_WRITE( "readlinkat(buf)", ARG3,ARG4 );
- if (VG_(have_slash_proc) == True) {
+ if (VG_(have_slash_proc) == True && (Int)ARG1 == VKI_AT_FDCWD) {
/*
* Handle the case where readlinkat is looking at /proc/curproc/file or
* /proc/<pid>/file.
*/
- VG_(sprintf)(name, "/proc/%d/file", VG_(getpid)());
- if (ML_(safe_to_deref)((void*)ARG2, 1)
- && (VG_(strcmp)((HChar *)ARG2, name) == 0
- || VG_(strcmp)((HChar *)ARG2, "/proc/curproc/file") == 0)) {
- VG_(sprintf)(name, "/proc/curproc/fd/%d", VG_(cl_exec_fd));
- SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
- ARG3, ARG4));
- return;
- }
+ do_readlink((const HChar *)ARG2, (HChar *)ARG3, (SizeT)ARG4, status, &curproc_file);
+ }
+
+ // @todo PJF there is still the case where fd refers to /proc or /proc/pid
+ // or /proc/curproc and path is relative pid/file, curptoc/file or just file
+
+ if (!curproc_file) {
+ /* Normal case */
+ SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
+ }
+ if (SUCCESS && RES > 0) {
+ POST_MEM_WRITE( ARG3, RES );
}
- /* Normal case */
- SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
}
POST(sys_readlinkat)
BSDX_(__NR_revoke, sys_revoke), // 56
GENX_(__NR_symlink, sys_symlink), // 57
- GENX_(__NR_readlink, sys_readlink), // 58
+ BSDX_(__NR_readlink, sys_readlink), // 58
GENX_(__NR_execve, sys_execve), // 59
GENX_(__NR_umask, sys_umask), // 60