Add support for it in the syswrap machinery and test it more thoroughly.
n-i-bz
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15545
CFLAGS="$save_CFLAGS"
+# Solaris-specific check determining if /proc/self/cmdline
+# or /proc/<pid>/cmdline is supported.
+#
+# C-level symbol: SOLARIS_PROC_CMDLINE
+# Automake-level symbol: SOLARIS_PROC_CMDLINE
+#
+AC_CHECK_FILE([/proc/self/cmdline],
+[
+solaris_proc_cmdline=yes
+AC_DEFINE([SOLARIS_PROC_CMDLINE], 1,
+ [Define to 1 if you have /proc/self/cmdline.])
+], [
+solaris_proc_cmdline=no
+])
+AM_CONDITIONAL(SOLARIS_PROC_CMDLINE, test x$solaris_proc_cmdline = xyes)
+
+
# Solaris-specific check determining default platform for the Valgrind launcher.
# Used in case the launcher cannot select platform by looking at the client
# image (for example because the executable is a shell script).
else
AM_CONDITIONAL(SOLARIS_SUN_STUDIO_AS, false)
AM_CONDITIONAL(SOLARIS_XPG_SYMBOLS_PRESENT, false)
+AM_CONDITIONAL(SOLARIS_PROC_CMDLINE, false)
AM_CONDITIONAL(SOLARIS_OLD_SYSCALLS, false)
AM_CONDITIONAL(SOLARIS_LWP_SIGQUEUE_SYSCALL, false)
AM_CONDITIONAL(SOLARIS_LWP_SIGQUEUE_SYSCALL_TAKES_PID, false)
HChar buf2[VG_(mkstemp_fullname_bufsz)(sizeof buf - 1)];
Int fd, r;
-#if defined(VGO_linux)
- /* Fake /proc/<pid>/cmdline only on Linux. */
+#if defined(VGO_linux) || defined(SOLARIS_PROC_CMDLINE)
+ /* Fake /proc/<pid>/cmdline only on Linux and Solaris if supported. */
HChar nul[1];
const HChar* exename;
}
/* Don't bother to seek the file back to the start; instead do
- it every time a copy of it is given out (by PRE(sys_open)).
- That is probably more robust across fork() etc. */
+ it every time a copy of it is given out (by PRE(sys_open) or
+ PRE(sys_openat)). That is probably more robust across fork() etc. */
/* Now delete it, but hang on to the fd. */
r = VG_(unlink)( buf2 );
VG_(err_config_error)("Can't delete client cmdline file in %s\n", buf2);
VG_(cl_cmdline_fd) = fd;
-#endif // defined(VGO_linux)
+#endif // defined(VGO_linux) || defined(SOLARIS_PROC_CMDLINE)
/* Fake /proc/<pid>/auxv on both Linux and Solaris. */
VG_(debugLog)(1, "main", "Create fake /proc/<pid>/auxv\n");
if (!VG_STREQ(filename, name) && !VG_STREQ(filename, "/proc/self/psinfo"))
return False;
- /* use original arguments to open or openat */
+ /* Use original arguments to open() or openat(). */
SysRes sres;
#if defined(SOLARIS_OLD_SYSCALLS)
if (use_openat)
return True;
}
+#if defined(SOLARIS_PROC_CMDLINE)
+/* Handles the case where the open is of /proc/self/cmdline or
+ /proc/<pid>/cmdline. Just give it a copy of VG_(cl_cmdline_fd) for the
+ fake file we cooked up at startup (in m_main). Also, seek the
+ cloned fd back to the start. */
+static Bool handle_cmdline_open(SyscallStatus *status, const HChar *filename)
+{
+ if (!ML_(safe_to_deref)((const void *) filename, 1))
+ return False;
+
+ HChar name[VKI_PATH_MAX]; // large enough
+ VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
+
+ if (!VG_STREQ(filename, name) && !VG_STREQ(filename, "/proc/self/cmdline"))
+ return False;
+
+ SysRes sres = VG_(dup)(VG_(cl_cmdline_fd));
+ SET_STATUS_from_SysRes(sres);
+ if (!sr_isError(sres)) {
+ OffT off = VG_(lseek)(sr_Res(sres), 0, VKI_SEEK_SET);
+ if (off < 0)
+ SET_STATUS_Failure(VKI_EMFILE);
+ }
+
+ return True;
+}
+#endif /* SOLARIS_PROC_CMDLINE */
+
+
#if defined(SOLARIS_OLD_SYSCALLS)
PRE(sys_open)
{
return;
}
- if (ML_(handle_auxv_open)(status, (const HChar*)ARG2, ARG3))
+ if (ML_(handle_auxv_open)(status, (const HChar *) ARG2, ARG3))
return;
- if (handle_psinfo_open(status, True /*use_openat*/, (const HChar*)ARG2,
+ if (handle_psinfo_open(status, True /*use_openat*/, (const HChar *) ARG2,
fd, ARG3, ARG4))
return;
+#if defined(SOLARIS_PROC_CMDLINE)
+ if (handle_cmdline_open(status, (const HChar *) ARG2))
+ return;
+#endif /* SOLARIS_PROC_CMDLINE */
+
*flags |= SfMayBlock;
}
"entity_name->rpr_answertype)", r->rpr_answertype);
}
break;
- #if (SOLARIS_REPCACHE_PROTOCOL_VERSION >= 25)
+#if (SOLARIS_REPCACHE_PROTOCOL_VERSION >= 25)
case VKI_REP_PROTOCOL_ENTITY_GET_ROOT:
{
struct vki_rep_protocol_entity_root *r =
"entity_root->rpr_outid)", r->rpr_outid);
}
break;
- #endif /* SOLARIS_REPCACHE_PROTOCOL_VERSION >= 25 */
+#endif /* SOLARIS_REPCACHE_PROTOCOL_VERSION >= 25 */
case VKI_REP_PROTOCOL_ENTITY_GET:
{
struct vki_rep_protocol_entity_get *r =
-prereq: [ $(uname) != Linux ]
+# For Linux, there is 'procfs-linux'.
+# For Solaris, there is Solaris-specific 'solaris/proc-cmdline-exe'.
+#
+prereq: ! ../../tests/os_test linux && ! ../../tests/os_test solaris
prog: procfs-cmdline-exe
stderr_filter: filter_stderr
proc_aout.stderr.exp proc_aout.stdout.exp proc_aout.vgtest \
proc_auxv.stderr.exp proc_auxv.stdout.exp proc_auxv.vgtest \
proc_auxv_multiple.stderr.exp proc_auxv_multiple.stdout.exp proc_auxv_multiple.vgtest \
+ proc-cmdline-exe.stderr.exp-with-cmdline proc-cmdline-exe.stderr.exp-without-cmdline \
+ proc-cmdline-exe.vgtest \
proc_psinfo.stderr.exp proc_psinfo.stdout.exp proc_psinfo.vgtest \
posix_spawn.stderr.exp posix_spawn.stdout.exp posix_spawn.vgtest \
pthread-stack.stderr.exp pthread-stack.vgtest \
--- /dev/null
+
+/proc/self/cmdline:
+./../procfs-cmdline-exe\0arg1\0arg 2\0arg3\0
+/proc/<pid>/cmdline:
+./../procfs-cmdline-exe\0arg1\0arg 2\0arg3\0
+readlink: No such file or directory
+readlink: No such file or directory
+readlinkat: No such file or directory
+readlinkat: No such file or directory
+
--- /dev/null
+
+/proc/self/cmdline:
+open(): No such file or directory
+/proc/<pid>/cmdline:
+open(): No such file or directory
+readlink: No such file or directory
+readlink: No such file or directory
+readlinkat: No such file or directory
+readlinkat: No such file or directory
+
--- /dev/null
+prog: ../procfs-cmdline-exe
+args: arg1 "arg 2" arg3
+stderr_filter: filter_stderr