summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2010-02-04 17:47:31 -0800
committerJosh Stone <jistone@redhat.com>2010-02-04 18:12:22 -0800
commita2d399c87a642190f08ede63dc6fc434a5a8363a (patch)
tree29054d563a84cb72e59b81bd566d38261728259b
parent463d666cc53a2f9d2df0f68310d6575ccae42bfe (diff)
downloadsystemtap-steved-a2d399c87a642190f08ede63dc6fc434a5a8363a.tar.gz
systemtap-steved-a2d399c87a642190f08ede63dc6fc434a5a8363a.tar.xz
systemtap-steved-a2d399c87a642190f08ede63dc6fc434a5a8363a.zip
PR11234: Rewrite __get_argv without embedded-C
We now implement __get_argv's string building in pure stap script. Also, every argument is now quoted, which is different than before, but it's much more robust about handling special characters.
-rw-r--r--tapset/aux_syscalls.stp159
1 files changed, 44 insertions, 115 deletions
diff --git a/tapset/aux_syscalls.stp b/tapset/aux_syscalls.stp
index bab0f640..e762b37a 100644
--- a/tapset/aux_syscalls.stp
+++ b/tapset/aux_syscalls.stp
@@ -399,124 +399,53 @@ function __sem_flags:string(semflg:long)
/* This function copies an argv from userspace. */
-function __get_argv:string(a:long, first:long)
-%{ /* pure */
- char __user *__user *argv = (char __user *__user *)(long)THIS->a;
- char __user *vstr;
- int space, rc, len = MAXSTRINGLEN;
- char *str = THIS->__retvalue;
- char buf[80];
- char *ptr = buf;
-
-
- if (THIS->first && argv)
- argv++;
-
- while (argv != NULL) {
- if (__stp_get_user (vstr, argv))
- break;
-
- if (vstr == NULL)
- break;
-
- rc = _stp_strncpy_from_user(buf, vstr, 79);
- if (rc <= 0)
- break;
-
- /* check for whitespace in string */
- buf[rc] = 0;
- ptr = buf;
- space = 0;
- while (*ptr && rc--) {
- if (isspace(*ptr++)) {
- space = 1;
- break;
- }
- }
-
- if (len != MAXSTRINGLEN && len) {
- *str++=' ';
- len--;
- }
-
- if (space && len) {
- *str++='\"';
- len--;
- }
-
- rc = strlcpy (str, buf, len);
- str += rc;
- len -= rc;
-
- if (space && len) {
- *str++='\"';
- len--;
- }
-
- argv++;
+function __get_argv:string(argv:long, first:long)
+{
+%( CONFIG_64BIT == "y" %?
+ if (first && argv)
+ argv += 8
+ while (argv) {
+ vstr = user_long(argv)
+ if (!vstr)
+ break
+ if (len)
+ str .= " "
+ str .= user_string_quoted(vstr)
+
+ newlen = strlen(str)
+ if (newlen == len)
+ break
+ len = newlen
+ argv += 8
}
- *str = 0;
-%}
-/* This function copies an argv from userspace. */
-function __get_compat_argv:string(a:long, first:long)
-%{ /* pure */
-#ifdef CONFIG_COMPAT
- compat_uptr_t __user *__user *argv = (compat_uptr_t __user *__user *)(long)THIS->a;
- compat_uptr_t __user *vstr;
- int space, rc, len = MAXSTRINGLEN;
- char *str = THIS->__retvalue;
- char buf[80];
- char *ptr = buf;
-
- if (THIS->first && argv)
- argv++;
-
- while (argv != NULL) {
- if (__stp_get_user (vstr, argv))
- break;
-
- if (vstr == NULL)
- break;
-
- rc = _stp_strncpy_from_user(buf, (char *)vstr, 79);
- if (rc <= 0)
- break;
-
- /* check for whitespace in string */
- buf[rc] = 0;
- ptr = buf;
- space = 0;
- while (*ptr && rc--) {
- if (isspace(*ptr++)) {
- space = 1;
- break;
- }
- }
-
- if (len != MAXSTRINGLEN && len) {
- *str++=' ';
- len--;
- }
-
- if (space && len) {
- *str++='\"';
- len--;
- }
-
- rc = strlcpy (str, buf, len);
- str += rc;
- len -= rc;
-
- if (space && len) {
- *str++='\"';
- len--;
- }
- argv++;
+ return str
+%:
+ return __get_compat_argv(argv, first)
+%)
+}
+/* This function copies an argv from userspace. */
+function __get_compat_argv:string(argv:long, first:long)
+{
+ if (first && argv)
+ argv += 4
+ while (argv) {
+ vstr = user_int(argv) & 0xffffffff
+ if (!vstr)
+ break
+ if (len)
+ str .= " "
+ str .= user_string_quoted(vstr)
+
+ newlen = strlen(str)
+ if (newlen == len)
+ break
+ len = newlen
+ argv += 4
}
- *str = 0;
-#endif
-%}
+
+ return str
+}
/*
* Return the symbolic string representation