>From f43e598eac48aa7a6bd533a269b666ba18c4a937 Mon Sep 17 00:00:00 2001
From: Tamas TEVESZ <[email protected]>
Date: Sat, 20 Mar 2010 20:02:27 +0100
Subject: [PATCH] Add the BSD version of GetCommandForPid()
It is not connected to wmaker, but when someone adds platform
detection to the autohell stuff, this can easily be integrated.
Or you can just do it by hand in the meantime.
---
src/osdep/bsd.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++
src/osdep/linux.c | 4 ++-
src/osdep/test.c | 50 +++++++++++++++++++++++++++++
3 files changed, 144 insertions(+), 1 deletions(-)
create mode 100644 src/osdep/bsd.c
create mode 100644 src/osdep/test.c
diff --git a/src/osdep/bsd.c b/src/osdep/bsd.c
new file mode 100644
index 0000000..b8220fe
--- /dev/null
+++ b/src/osdep/bsd.c
@@ -0,0 +1,91 @@
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <WINGs/WUtil.h>
+
+#include "../wconfig.h"
+
+/*
+ * copy argc and argv for an existing process identified by `pid'
+ * into suitable storage given in ***argv and *argc.
+ *
+ * subsequent calls use the same static area for argv and argc.
+ *
+ * returns 0 for failure, in which case argc := 0 and argv := NULL
+ * returns 1 for success
+ */
+Bool GetCommandForPid(int pid, char ***argv, int *argc)
+{
+ /*
+ * it just returns failure if the sysctl calls fail; since there's
+ * apparently no harm done to the caller because of this, it seems
+ * more user-friendly than to bomb out.
+ */
+ int j, mib[4];
+ unsigned int i;
+ size_t count;
+ static char *args = NULL;
+ static int argmax = 0;
+
+ *argv = NULL;
+ *argc = 0;
+
+ /* the system-wide limit */
+ if (argmax == 0) { /* it hopefully doesn't change at runtime *g* */
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_ARGMAX;
+ mib[2] = 0;
+ mib[4] = 0;
+
+ count = sizeof(argmax);
+ if (sysctl(mib, 2, &argmax, &count, NULL, 0) == -1)
+ return False;
+ }
+
+ /* if argmax is still 0, something went very seriously wrong */
+ assert( argmax > 0);
+
+ /* get space for args */
+ if (args == NULL)
+ args = (char *)wmalloc(argmax);
+
+ /* canary */
+ *args = 0;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC_ARGS;
+ mib[2] = pid;
+ mib[3] = KERN_PROC_ARGV;
+
+ count = argmax;
+
+ if (sysctl(mib, 4, args, &count, NULL, 0) == -1 || *args == 0)
+ /* no need to free args */
+ return False;
+
+ /* args is a flattened series of null-terminated strings */
+ for (i = 0; i < count; i++)
+ if (args[i] == '\0')
+ (*argc)++;
+
+ *argv = (char **)wmalloc(sizeof(char *) * *argc);
+ (*argv)[0] = args;
+
+ /* go through args, set argv[$next] to the beginning of each string */
+ for (i = 0, j = 1; i < count; i++) {
+ if (args[i] != '\0')
+ continue;
+ if (i < count - 1)
+ (*argv)[j++] = &args[i + 1];
+ if (j == *argc)
+ break;
+ }
+
+ return True;
+}
diff --git a/src/osdep/linux.c b/src/osdep/linux.c
index 9f87a3c..bf6841e 100644
--- a/src/osdep/linux.c
+++ b/src/osdep/linux.c
@@ -17,7 +17,9 @@
* copy argc and argv for an existing process identified by `pid'
* into suitable storage given in ***argv and *argc.
*
- * returns 0 for failure, in which case argc := 0 and arv := NULL
+ * subsequent calls use the same static area for argv and argc.
+ *
+ * returns 0 for failure, in which case argc := 0 and argv := NULL
* returns 1 for success
*/
Bool GetCommandForPid(int pid, char ***argv, int *argc)
diff --git a/src/osdep/test.c b/src/osdep/test.c
new file mode 100644
index 0000000..ef1f808
--- /dev/null
+++ b/src/osdep/test.c
@@ -0,0 +1,50 @@
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <WINGs/WUtil.h>
+
+/*
+ * gcc -I ../../WINGs ${includes...} -Wall -Wextra -g -ggdb3 -c -o ${plat}.o
${plat}.c
+ * gcc -I ../../WINGs ${includes...} -g -ggdb3 -c -o test.o test.c
+ * gcc -g -ggdb3 -o test ${plat}.o ../../WINGs/.libs/libWUtil.a test.o
+ *
+ * $ ./test 1 2 'foo bar' "`date`" `date`
+ * arg[0] = [./test]
+ * arg[1] = [1]
+ * arg[2] = [2]
+ * arg[3] = [foo bar]
+ * arg[4] = [Sat Mar 20 18:36:22 CET 2010]
+ * arg[5] = [Sat]
+ * arg[6] = [Mar]
+ * arg[7] = [20]
+ * arg[8] = [18:36:22]
+ * arg[9] = [CET]
+ * arg[10] = [2010]
+ * $
+ */
+
+Bool GetCommandForPid(int pid, char ***argv, int *argc);
+extern char *__progname;
+
+int main(int argc, char **argv) {
+
+ char **nargv;
+ int i, nargc;
+
+ if (argc < 2) {
+ printf("Usage: %s arg arg arg ...\n", __progname);
+ return 0;
+ }
+
+ if (GetCommandForPid(getpid(), &nargv, &nargc) == False) {
+ printf("GetCommandForPid() failed\n");
+ } else {
+ printf("nargv = %d\n", nargc);
+ for(i = 0; i < nargc; i++)
+ printf("arg[%d] = [%s]\n", i, nargv[i]);
+ }
+
+ return 0;
+}
+
--
1.7.0
--
[-]
mkdir /nonexistentFrom f43e598eac48aa7a6bd533a269b666ba18c4a937 Mon Sep 17 00:00:00 2001
From: Tamas TEVESZ <[email protected]>
Date: Sat, 20 Mar 2010 20:02:27 +0100
Subject: [PATCH] Add the BSD version of GetCommandForPid()
It is not connected to wmaker, but when someone adds platform
detection to the autohell stuff, this can easily be integrated.
Or you can just do it by hand in the meantime.
---
src/osdep/bsd.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++
src/osdep/linux.c | 4 ++-
src/osdep/test.c | 50 +++++++++++++++++++++++++++++
3 files changed, 144 insertions(+), 1 deletions(-)
create mode 100644 src/osdep/bsd.c
create mode 100644 src/osdep/test.c
diff --git a/src/osdep/bsd.c b/src/osdep/bsd.c
new file mode 100644
index 0000000..b8220fe
--- /dev/null
+++ b/src/osdep/bsd.c
@@ -0,0 +1,91 @@
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <WINGs/WUtil.h>
+
+#include "../wconfig.h"
+
+/*
+ * copy argc and argv for an existing process identified by `pid'
+ * into suitable storage given in ***argv and *argc.
+ *
+ * subsequent calls use the same static area for argv and argc.
+ *
+ * returns 0 for failure, in which case argc := 0 and argv := NULL
+ * returns 1 for success
+ */
+Bool GetCommandForPid(int pid, char ***argv, int *argc)
+{
+ /*
+ * it just returns failure if the sysctl calls fail; since there's
+ * apparently no harm done to the caller because of this, it seems
+ * more user-friendly than to bomb out.
+ */
+ int j, mib[4];
+ unsigned int i;
+ size_t count;
+ static char *args = NULL;
+ static int argmax = 0;
+
+ *argv = NULL;
+ *argc = 0;
+
+ /* the system-wide limit */
+ if (argmax == 0) { /* it hopefully doesn't change at runtime *g* */
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_ARGMAX;
+ mib[2] = 0;
+ mib[4] = 0;
+
+ count = sizeof(argmax);
+ if (sysctl(mib, 2, &argmax, &count, NULL, 0) == -1)
+ return False;
+ }
+
+ /* if argmax is still 0, something went very seriously wrong */
+ assert( argmax > 0);
+
+ /* get space for args */
+ if (args == NULL)
+ args = (char *)wmalloc(argmax);
+
+ /* canary */
+ *args = 0;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC_ARGS;
+ mib[2] = pid;
+ mib[3] = KERN_PROC_ARGV;
+
+ count = argmax;
+
+ if (sysctl(mib, 4, args, &count, NULL, 0) == -1 || *args == 0)
+ /* no need to free args */
+ return False;
+
+ /* args is a flattened series of null-terminated strings */
+ for (i = 0; i < count; i++)
+ if (args[i] == '\0')
+ (*argc)++;
+
+ *argv = (char **)wmalloc(sizeof(char *) * *argc);
+ (*argv)[0] = args;
+
+ /* go through args, set argv[$next] to the beginning of each string */
+ for (i = 0, j = 1; i < count; i++) {
+ if (args[i] != '\0')
+ continue;
+ if (i < count - 1)
+ (*argv)[j++] = &args[i + 1];
+ if (j == *argc)
+ break;
+ }
+
+ return True;
+}
diff --git a/src/osdep/linux.c b/src/osdep/linux.c
index 9f87a3c..bf6841e 100644
--- a/src/osdep/linux.c
+++ b/src/osdep/linux.c
@@ -17,7 +17,9 @@
* copy argc and argv for an existing process identified by `pid'
* into suitable storage given in ***argv and *argc.
*
- * returns 0 for failure, in which case argc := 0 and arv := NULL
+ * subsequent calls use the same static area for argv and argc.
+ *
+ * returns 0 for failure, in which case argc := 0 and argv := NULL
* returns 1 for success
*/
Bool GetCommandForPid(int pid, char ***argv, int *argc)
diff --git a/src/osdep/test.c b/src/osdep/test.c
new file mode 100644
index 0000000..ef1f808
--- /dev/null
+++ b/src/osdep/test.c
@@ -0,0 +1,50 @@
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <WINGs/WUtil.h>
+
+/*
+ * gcc -I ../../WINGs ${includes...} -Wall -Wextra -g -ggdb3 -c -o ${plat}.o ${plat}.c
+ * gcc -I ../../WINGs ${includes...} -g -ggdb3 -c -o test.o test.c
+ * gcc -g -ggdb3 -o test ${plat}.o ../../WINGs/.libs/libWUtil.a test.o
+ *
+ * $ ./test 1 2 'foo bar' "`date`" `date`
+ * arg[0] = [./test]
+ * arg[1] = [1]
+ * arg[2] = [2]
+ * arg[3] = [foo bar]
+ * arg[4] = [Sat Mar 20 18:36:22 CET 2010]
+ * arg[5] = [Sat]
+ * arg[6] = [Mar]
+ * arg[7] = [20]
+ * arg[8] = [18:36:22]
+ * arg[9] = [CET]
+ * arg[10] = [2010]
+ * $
+ */
+
+Bool GetCommandForPid(int pid, char ***argv, int *argc);
+extern char *__progname;
+
+int main(int argc, char **argv) {
+
+ char **nargv;
+ int i, nargc;
+
+ if (argc < 2) {
+ printf("Usage: %s arg arg arg ...\n", __progname);
+ return 0;
+ }
+
+ if (GetCommandForPid(getpid(), &nargv, &nargc) == False) {
+ printf("GetCommandForPid() failed\n");
+ } else {
+ printf("nargv = %d\n", nargc);
+ for(i = 0; i < nargc; i++)
+ printf("arg[%d] = [%s]\n", i, nargv[i]);
+ }
+
+ return 0;
+}
+
--
1.7.0