this makes autoconf bend the way we need. i am not for a split second 
claiming this is "right", but it works. seems to be ok on linux and 
netbsd.

renato, can you test whether makes it unnecessary to manually patch 
Makefile.am and screwing with platform CFLAGS on freebsd? (you still 
wll have to apply the intl/gettext overrides)

>From 067e8ead916162deca41b9bfadb6623ae913843d Mon Sep 17 00:00:00 2001
From: Tamas TEVESZ <[email protected]>
Date: Tue, 23 Mar 2010 20:27:53 +0100
Subject: [PATCH] Half-assed fix to make autoconf bend

- this should make platform detection automagic
- also fixes debian builds that broke in the meantime
- fix osdep_darwin.c
---
 configure.ac       |   35 +++++++++++
 src/Makefile.am    |    2 +-
 src/osdep/bsd.c    |  171 ----------------------------------------------------
 src/osdep/darwin.c |   92 ----------------------------
 src/osdep/linux.c  |   80 ------------------------
 src/osdep/stub.c   |   11 ----
 src/osdep/test.c   |   49 ---------------
 src/osdep_bsd.c    |  171 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/osdep_darwin.c |   96 +++++++++++++++++++++++++++++
 src/osdep_linux.c  |   80 ++++++++++++++++++++++++
 src/osdep_stub.c   |   19 ++++++
 11 files changed, 402 insertions(+), 404 deletions(-)
 delete mode 100644 src/osdep/bsd.c
 delete mode 100644 src/osdep/darwin.c
 delete mode 100644 src/osdep/linux.c
 delete mode 100644 src/osdep/stub.c
 delete mode 100644 src/osdep/test.c
 create mode 100644 src/osdep_bsd.c
 create mode 100644 src/osdep_darwin.c
 create mode 100644 src/osdep_linux.c
 create mode 100644 src/osdep_stub.c

diff --git a/configure.ac b/configure.ac
index a2b1ccd..8667f84 100644
--- a/configure.ac
+++ b/configure.ac
@@ -37,6 +37,41 @@ dnl AC_PROG_INSTALL -- already done by AM_INIT_AUTOMAKE
 AC_PROG_LN_S
 AC_PROG_GCC_TRADITIONAL
 
+dnl Platform-specific Makefile setup
+dnl ================================
+
+case "${host}" in
+       *-*-linux*)
+               WM_OSDEP="linux"
+       ;;
+       *-*-freebsd*)
+               WM_OSDEP="bsd"
+               CFLAGS="$CFLAGS -DFREEBSD"
+       ;;
+       *-*-netbsd*)
+               WM_OSDEP="bsd"
+               CFLAGS="$CFLAGS -DNETBSD"
+       ;;
+       *-*-openbsd*)
+               WM_OSDEP="bsd"
+       CFLAGS="$CFLAGS -DOPENBSD"
+       ;;
+       *-*-dragonfly*)
+               WM_OSDEP="bsd"
+               CFLAGS="$CFLAGS -DDRAGONFLYBSD"
+       ;;
+       *-apple-darwin*)
+               WM_OSDEP="darwin"
+       ;;
+       *-*-solaris*)
+               WM_OSDEP="stub"         # solaris.c when done
+       ;;
+       *)
+               WM_OSDEP="stub"
+       ;;
+esac
+AC_SUBST(WM_OSDEP)
+
 
 dnl the prefix
 dnl ==========
diff --git a/src/Makefile.am b/src/Makefile.am
index dbab5a2..ae65870 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -45,7 +45,7 @@ wmaker_SOURCES =      \
        menu.c \
        menu.h \
        misc.c \
-       osdep/linux.c \
+       osd...@[email protected] \
        monitor.c \
        motif.c \
        motif.h \
diff --git a/src/osdep/bsd.c b/src/osdep/bsd.c
deleted file mode 100644
index 0057adc..0000000
--- a/src/osdep/bsd.c
+++ /dev/null
@@ -1,171 +0,0 @@
-
-#if defined( FREEBSD ) || defined( DRAGONFLYBSD )
-#   include <sys/types.h>
-#else /* OPENBSD || NETBSD */
-#   include <sys/param.h>
-#endif
-#include <sys/sysctl.h>
-
-#include <assert.h>
-
-#if defined( OPENBSD )
-#   include <kvm.h>
-#   include <limits.h> /* _POSIX2_LINE_MAX */
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#if defined( OPENBSD )
-#   include <string.h>
-#endif
-
-#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
- */
-/*
- * NetBSD, FreeBSD and DragonFlyBSD supply the necessary information via
- * sysctl(3). The result is a plain simple flat octet stream and its length.
- * The octet stream represents argv, with members separated by a null 
character.
- * The argv array returned by GetCommandForPid() consists of pointers into this
- * stream (which is stored in a static array, `args'). Net and Free/DFly only
- * differ slightly in the MIB vector given to sysctl(3). Free and DFly are
- * identical.
- *
- * OpenBSD supplies the necessary informationvia kvm(3) in the form of a real
- * argv array. This array is flattened to be in the same way as Net/Free/DFly
- * returns the arguments in the first place. This is done in order for the
- * storage (`args') to easily be made static, which means some memory bytes
- * are sacrificed to save hoops of memory management.
- */
-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;
-#if defined( OPENBSD )
-       char kvmerr[_POSIX2_LINE_MAX];  /* for kvm*() error reporting */
-       int procs;                      /* kvm_getprocs() */
-       kvm_t *kd;
-       struct kinfo_proc *kp;
-       char **nargv;                   /* kvm_getarg() */
-#endif
-
-       *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);
-
-       /* space for args; no need to free before returning even on errors */
-       if (args == NULL)
-               args = (char *)wmalloc(argmax);
-
-#if defined( OPENBSD )
-       /* kvm descriptor */
-       if ((kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, kvmerr)) == 
NULL)
-               return False;
-
-       procs = 0;
-       /* the process we are interested in */
-       if ((kp = kvm_getprocs(kd, KERN_PROC_PID, pid, &procs)) == NULL || 
procs == 0)
-               /* if kvm_getprocs() bombs out or does not find the process */
-               return False;
-
-       /* get it's argv */
-       if ((nargv = kvm_getargv(kd, kp, 0)) == NULL)
-               return False;
-
-       /* flatten nargv into args */
-       count = 0;
-       memset(args, 0, argmax);
-       /*
-        * must have this much free space in `args' in order for the current
-        * iteration not to overflow it: we are at `count', and will append
-        * the next ((*argc)+1) arg and a null (+1)
-        * technically, overflow (or truncation, which isn't handled) can not
-        * happen (should not, at least).
-        */
-       #define ARGSPACE ( count + strlen(nargv[ (*argc) + 1 ] ) + 1 )
-       while (nargv[*argc] && ARGSPACE < argmax ) {
-               memcpy(args + count, nargv[*argc], strlen(nargv[*argc]));
-               count += strlen(nargv[*argc]) + 1;
-               (*argc)++;
-       }
-       #undef ARGSPACE
-       /* by now *argc is correct as a byproduct */
-
-       kvm_close(kd);
-#else /* FREEBSD || NETBSD || DRAGONFLYBSD */
-
-       mib[0] = CTL_KERN;
-#if defined( NETBSD )
-       mib[1] = KERN_PROC_ARGS;
-       mib[2] = pid;
-       mib[3] = KERN_PROC_ARGV;
-#elif defined( FREEBSD ) || defined( DRAGONFLYBSD )
-       mib[1] = KERN_PROC;
-       mib[2] = KERN_PROC_ARGS;
-       mib[3] = pid;
-#endif
-
-       count = argmax;
-       /* canary */
-       *args = 0;
-       if (sysctl(mib, 4, args, &count, NULL, 0) == -1 || *args == 0)
-               return False;
-
-       /* args is a flattened series of null-terminated strings */
-       for (i = 0; i < count; i++)
-               if (args[i] == '\0')
-                       (*argc)++;
-#endif
-
-       *argv = (char **)wmalloc(sizeof(char *) * (*argc + 1 /* term. null ptr 
*/));
-       (*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;
-       }
-
-       /* the list of arguments must be terminated by a null pointer */
-       (*argv)[j] = NULL;
-       return True;
-}
diff --git a/src/osdep/darwin.c b/src/osdep/darwin.c
deleted file mode 100644
index e037b5d..0000000
--- a/src/osdep/darwin.c
+++ /dev/null
@@ -1,92 +0,0 @@
-
-#include <sys/types.h>
-#include <sys/sysctl.h>
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.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)
-#ifdef KERN_PROCARGS2
-{
-       int j, mib[4];
-       unsigned int i, idx;
-       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[3] = 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);
-
-       /* space for args; no need to free before returning even on errors */
-       if (args == NULL)
-               args = (char *)wmalloc(argmax);
-
-       /* get process args */
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_PROCARGS2;
-       mib[2] = pid;
-
-       count = argmax;
-       if (sysctl(mib, 3, args, &count, NULL, 0) == -1 || count == 0)
-               return False;
-
-       /* get argc, skip */
-       memcpy(argc, args, sizeof(*argc));
-       idx = sizeof(*argc);
-
-       while (args[idx++] != '\0')             /* skip execname */
-               ;
-       while (args[idx] == '\0')               /* padding too */
-               idx++;
-       /* args[idx] is at at begininng of args now */
-
-       *argv = (char **)wmalloc(sizeof(char *) * (*argc + 1 /* term. null ptr 
*/));
-       (*argv)[0] = args + idx;
-
-       /* go through args, set argv[$next] to the beginning of each string */
-       for (i = 0, j = 1; i < count - idx /* do not overrun */; i++) {
-               if (args[idx + i] != '\0')
-                       continue;
-               if (args[idx + i] == '\0')
-                       (*argv)[j++] = &args[idx + i + 1];
-               if (j == *argc)
-                       break;
-       }
-
-       /* the list of arguments must be terminated by a null pointer */
-       (*argv)[j] = NULL;
-       return True;
-}
-#else /* !KERN_PROCARGS2 */
-{
-       *argv = NULL;
-       *argc = 0;
-
-       return False;
-}
-#endif
diff --git a/src/osdep/linux.c b/src/osdep/linux.c
deleted file mode 100644
index a754bb6..0000000
--- a/src/osdep/linux.c
+++ /dev/null
@@ -1,80 +0,0 @@
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.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)
-{
-       static char buf[_POSIX_ARG_MAX];
-       int fd, i, j;
-       ssize_t count;
-
-       *argv = NULL;
-       *argc = 0;
-
-       /* cmdline is a flattened series of null-terminated strings */
-       snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
-       while (1) {
-               if ((fd = open(buf, O_RDONLY)) != -1)
-                       break;
-               if (errno == EINTR)
-                       continue;
-               return False;
-       }
-
-       while (1) {
-               if ((count = read(fd, buf, sizeof(buf))) != -1)
-                       break;
-               if (errno == EINTR)
-                       continue;
-               return False;
-       }
-
-       do {
-               close(fd);
-       } while (errno == EINTR);
-
-       /* count args */
-       for (i = 0; i < count; i++)
-               if (buf[i] == '\0')
-                       (*argc)++;
-
-       if (*argc == 0)
-               return False;
-
-       *argv = (char **)wmalloc(sizeof(char *) * (*argc + 1 /* term. null ptr 
*/));
-       (*argv)[0] = buf;
-
-       /* go through buf, set argv[$next] to the beginning of each string */
-       for (i = 0, j = 1; i < count; i++) {
-               if (buf[i] != '\0')
-                       continue;
-               if (i < count - 1)
-                       (*argv)[j++] = &buf[i + 1];
-               if (j == *argc)
-                       break;
-       }
-
-       /* the list of arguments must be terminated by a null pointer */
-       (*argv)[j] = NULL;
-       return True;
-}
diff --git a/src/osdep/stub.c b/src/osdep/stub.c
deleted file mode 100644
index 38b9820..0000000
--- a/src/osdep/stub.c
+++ /dev/null
@@ -1,11 +0,0 @@
-
-#include <WINGs/WUtil.h>
-#include "../wconfig.h"
-
-Bool GetCommandForPid(int pid, char ***argv, int *argc)
-{
-       *argv = NULL;
-       *argc = 0;
-
-       return False;
-}
diff --git a/src/osdep/test.c b/src/osdep/test.c
deleted file mode 100644
index 3bba44e..0000000
--- a/src/osdep/test.c
+++ /dev/null
@@ -1,49 +0,0 @@
-
-#include <stdio.h>
-#include <unistd.h>
-
-#include <WINGs/WUtil.h>
-
-/*
- * gcc -D{$os} -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;
-}
diff --git a/src/osdep_bsd.c b/src/osdep_bsd.c
new file mode 100644
index 0000000..e3063a9
--- /dev/null
+++ b/src/osdep_bsd.c
@@ -0,0 +1,171 @@
+
+#if defined( FREEBSD ) || defined( DRAGONFLYBSD )
+#   include <sys/types.h>
+#else /* OPENBSD || NETBSD */
+#   include <sys/param.h>
+#endif
+#include <sys/sysctl.h>
+
+#include <assert.h>
+
+#if defined( OPENBSD )
+#   include <kvm.h>
+#   include <limits.h> /* _POSIX2_LINE_MAX */
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined( OPENBSD )
+#   include <string.h>
+#endif
+
+#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
+ */
+/*
+ * NetBSD, FreeBSD and DragonFlyBSD supply the necessary information via
+ * sysctl(3). The result is a plain simple flat octet stream and its length.
+ * The octet stream represents argv, with members separated by a null 
character.
+ * The argv array returned by GetCommandForPid() consists of pointers into this
+ * stream (which is stored in a static array, `args'). Net and Free/DFly only
+ * differ slightly in the MIB vector given to sysctl(3). Free and DFly are
+ * identical.
+ *
+ * OpenBSD supplies the necessary informationvia kvm(3) in the form of a real
+ * argv array. This array is flattened to be in the same way as Net/Free/DFly
+ * returns the arguments in the first place. This is done in order for the
+ * storage (`args') to easily be made static, which means some memory bytes
+ * are sacrificed to save hoops of memory management.
+ */
+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;
+#if defined( OPENBSD )
+       char kvmerr[_POSIX2_LINE_MAX];  /* for kvm*() error reporting */
+       int procs;                      /* kvm_getprocs() */
+       kvm_t *kd;
+       struct kinfo_proc *kp;
+       char **nargv;                   /* kvm_getarg() */
+#endif
+
+       *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);
+
+       /* space for args; no need to free before returning even on errors */
+       if (args == NULL)
+               args = (char *)wmalloc(argmax);
+
+#if defined( OPENBSD )
+       /* kvm descriptor */
+       if ((kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, kvmerr)) == 
NULL)
+               return False;
+
+       procs = 0;
+       /* the process we are interested in */
+       if ((kp = kvm_getprocs(kd, KERN_PROC_PID, pid, &procs)) == NULL || 
procs == 0)
+               /* if kvm_getprocs() bombs out or does not find the process */
+               return False;
+
+       /* get it's argv */
+       if ((nargv = kvm_getargv(kd, kp, 0)) == NULL)
+               return False;
+
+       /* flatten nargv into args */
+       count = 0;
+       memset(args, 0, argmax);
+       /*
+        * must have this much free space in `args' in order for the current
+        * iteration not to overflow it: we are at `count', and will append
+        * the next ((*argc)+1) arg and a null (+1)
+        * technically, overflow (or truncation, which isn't handled) can not
+        * happen (should not, at least).
+        */
+       #define ARGSPACE ( count + strlen(nargv[ (*argc) + 1 ] ) + 1 )
+       while (nargv[*argc] && ARGSPACE < argmax ) {
+               memcpy(args + count, nargv[*argc], strlen(nargv[*argc]));
+               count += strlen(nargv[*argc]) + 1;
+               (*argc)++;
+       }
+       #undef ARGSPACE
+       /* by now *argc is correct as a byproduct */
+
+       kvm_close(kd);
+#else /* FREEBSD || NETBSD || DRAGONFLYBSD */
+
+       mib[0] = CTL_KERN;
+#if defined( NETBSD )
+       mib[1] = KERN_PROC_ARGS;
+       mib[2] = pid;
+       mib[3] = KERN_PROC_ARGV;
+#elif defined( FREEBSD ) || defined( DRAGONFLYBSD )
+       mib[1] = KERN_PROC;
+       mib[2] = KERN_PROC_ARGS;
+       mib[3] = pid;
+#endif
+
+       count = argmax;
+       /* canary */
+       *args = 0;
+       if (sysctl(mib, 4, args, &count, NULL, 0) == -1 || *args == 0)
+               return False;
+
+       /* args is a flattened series of null-terminated strings */
+       for (i = 0; i < count; i++)
+               if (args[i] == '\0')
+                       (*argc)++;
+#endif
+
+       *argv = (char **)wmalloc(sizeof(char *) * (*argc + 1 /* term. null ptr 
*/));
+       (*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;
+       }
+
+       /* the list of arguments must be terminated by a null pointer */
+       (*argv)[j] = NULL;
+       return True;
+}
diff --git a/src/osdep_darwin.c b/src/osdep_darwin.c
new file mode 100644
index 0000000..ca38df2
--- /dev/null
+++ b/src/osdep_darwin.c
@@ -0,0 +1,96 @@
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.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)
+#ifdef KERN_PROCARGS2
+{
+       int j, mib[4];
+       unsigned int i, idx;
+       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[3] = 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);
+
+       /* space for args; no need to free before returning even on errors */
+       if (args == NULL)
+               args = (char *)wmalloc(argmax);
+
+       /* get process args */
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_PROCARGS2;
+       mib[2] = pid;
+
+       count = argmax;
+       if (sysctl(mib, 3, args, &count, NULL, 0) == -1 || count == 0)
+               return False;
+
+       /* get argc, skip */
+       memcpy(argc, args, sizeof(*argc));
+       idx = sizeof(*argc);
+
+       while (args[idx++] != '\0')             /* skip execname */
+               ;
+       while (args[idx] == '\0')               /* padding too */
+               idx++;
+       /* args[idx] is at at begininng of args now */
+
+       *argv = (char **)wmalloc(sizeof(char *) * (*argc + 1 /* term. null ptr 
*/));
+       (*argv)[0] = args + idx;
+
+       /* go through args, set argv[$next] to the beginning of each string */
+       for (i = 0, j = 1; i < count - idx /* do not overrun */; i++) {
+               if (args[idx + i] != '\0')
+                       continue;
+               if (args[idx + i] == '\0')
+                       (*argv)[j++] = &args[idx + i + 1];
+               if (j == *argc)
+                       break;
+       }
+
+       /* the list of arguments must be terminated by a null pointer */
+       (*argv)[j] = NULL;
+       return True;
+}
+#else /* !KERN_PROCARGS2 */
+{
+       *argv = NULL;
+       *argc = 0;
+
+       return False;
+}
+#endif
diff --git a/src/osdep_linux.c b/src/osdep_linux.c
new file mode 100644
index 0000000..ed4953f
--- /dev/null
+++ b/src/osdep_linux.c
@@ -0,0 +1,80 @@
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.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)
+{
+       static char buf[_POSIX_ARG_MAX];
+       int fd, i, j;
+       ssize_t count;
+
+       *argv = NULL;
+       *argc = 0;
+
+       /* cmdline is a flattened series of null-terminated strings */
+       snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
+       while (1) {
+               if ((fd = open(buf, O_RDONLY)) != -1)
+                       break;
+               if (errno == EINTR)
+                       continue;
+               return False;
+       }
+
+       while (1) {
+               if ((count = read(fd, buf, sizeof(buf))) != -1)
+                       break;
+               if (errno == EINTR)
+                       continue;
+               return False;
+       }
+
+       do {
+               close(fd);
+       } while (errno == EINTR);
+
+       /* count args */
+       for (i = 0; i < count; i++)
+               if (buf[i] == '\0')
+                       (*argc)++;
+
+       if (*argc == 0)
+               return False;
+
+       *argv = (char **)wmalloc(sizeof(char *) * (*argc + 1 /* term. null ptr 
*/));
+       (*argv)[0] = buf;
+
+       /* go through buf, set argv[$next] to the beginning of each string */
+       for (i = 0, j = 1; i < count; i++) {
+               if (buf[i] != '\0')
+                       continue;
+               if (i < count - 1)
+                       (*argv)[j++] = &buf[i + 1];
+               if (j == *argc)
+                       break;
+       }
+
+       /* the list of arguments must be terminated by a null pointer */
+       (*argv)[j] = NULL;
+       return True;
+}
diff --git a/src/osdep_stub.c b/src/osdep_stub.c
new file mode 100644
index 0000000..6a24e18
--- /dev/null
+++ b/src/osdep_stub.c
@@ -0,0 +1,19 @@
+
+#include <WINGs/WUtil.h>
+
+#include "wconfig.h"
+
+Bool GetCommandForPid(int pid, char ***argv, int *argc)
+{
+       *argv = NULL;
+       *argc = 0;
+       static int notified = 0;
+
+       if (!notified) {
+               wwarning(_("%s is not implemented on this platform; "
+                   "notify [email protected]"), __FUNCTION__);
+               notified = 1;
+       }
+
+       return False;
+}
-- 
1.7.0


-- 
[-]

mkdir /nonexistent
From 067e8ead916162deca41b9bfadb6623ae913843d Mon Sep 17 00:00:00 2001
From: Tamas TEVESZ <[email protected]>
Date: Tue, 23 Mar 2010 20:27:53 +0100
Subject: [PATCH] Half-assed fix to make autoconf bend

- this should make platform detection automagic
- also fixes debian builds that broke in the meantime
- fix osdep_darwin.c
---
 configure.ac       |   35 +++++++++++
 src/Makefile.am    |    2 +-
 src/osdep/bsd.c    |  171 ----------------------------------------------------
 src/osdep/darwin.c |   92 ----------------------------
 src/osdep/linux.c  |   80 ------------------------
 src/osdep/stub.c   |   11 ----
 src/osdep/test.c   |   49 ---------------
 src/osdep_bsd.c    |  171 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/osdep_darwin.c |   96 +++++++++++++++++++++++++++++
 src/osdep_linux.c  |   80 ++++++++++++++++++++++++
 src/osdep_stub.c   |   19 ++++++
 11 files changed, 402 insertions(+), 404 deletions(-)
 delete mode 100644 src/osdep/bsd.c
 delete mode 100644 src/osdep/darwin.c
 delete mode 100644 src/osdep/linux.c
 delete mode 100644 src/osdep/stub.c
 delete mode 100644 src/osdep/test.c
 create mode 100644 src/osdep_bsd.c
 create mode 100644 src/osdep_darwin.c
 create mode 100644 src/osdep_linux.c
 create mode 100644 src/osdep_stub.c

diff --git a/configure.ac b/configure.ac
index a2b1ccd..8667f84 100644
--- a/configure.ac
+++ b/configure.ac
@@ -37,6 +37,41 @@ dnl AC_PROG_INSTALL -- already done by AM_INIT_AUTOMAKE
 AC_PROG_LN_S
 AC_PROG_GCC_TRADITIONAL
 
+dnl Platform-specific Makefile setup
+dnl ================================
+
+case "${host}" in
+	*-*-linux*)
+		WM_OSDEP="linux"
+	;;
+	*-*-freebsd*)
+		WM_OSDEP="bsd"
+		CFLAGS="$CFLAGS -DFREEBSD"
+	;;
+	*-*-netbsd*)
+		WM_OSDEP="bsd"
+		CFLAGS="$CFLAGS -DNETBSD"
+	;;
+	*-*-openbsd*)
+		WM_OSDEP="bsd"
+	CFLAGS="$CFLAGS -DOPENBSD"
+	;;
+	*-*-dragonfly*)
+		WM_OSDEP="bsd"
+		CFLAGS="$CFLAGS -DDRAGONFLYBSD"
+	;;
+	*-apple-darwin*)
+		WM_OSDEP="darwin"
+	;;
+	*-*-solaris*)
+		WM_OSDEP="stub"		# solaris.c when done
+	;;
+	*)
+		WM_OSDEP="stub"
+	;;
+esac
+AC_SUBST(WM_OSDEP)
+
 
 dnl the prefix
 dnl ==========
diff --git a/src/Makefile.am b/src/Makefile.am
index dbab5a2..ae65870 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -45,7 +45,7 @@ wmaker_SOURCES = 	\
 	menu.c \
 	menu.h \
 	misc.c \
-	osdep/linux.c \
+	osd...@[email protected] \
 	monitor.c \
 	motif.c \
 	motif.h \
diff --git a/src/osdep/bsd.c b/src/osdep/bsd.c
deleted file mode 100644
index 0057adc..0000000
--- a/src/osdep/bsd.c
+++ /dev/null
@@ -1,171 +0,0 @@
-
-#if defined( FREEBSD ) || defined( DRAGONFLYBSD )
-#   include <sys/types.h>
-#else /* OPENBSD || NETBSD */
-#   include <sys/param.h>
-#endif
-#include <sys/sysctl.h>
-
-#include <assert.h>
-
-#if defined( OPENBSD )
-#   include <kvm.h>
-#   include <limits.h>	/* _POSIX2_LINE_MAX */
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#if defined( OPENBSD )
-#   include <string.h>
-#endif
-
-#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
- */
-/*
- * NetBSD, FreeBSD and DragonFlyBSD supply the necessary information via
- * sysctl(3). The result is a plain simple flat octet stream and its length.
- * The octet stream represents argv, with members separated by a null character.
- * The argv array returned by GetCommandForPid() consists of pointers into this
- * stream (which is stored in a static array, `args'). Net and Free/DFly only
- * differ slightly in the MIB vector given to sysctl(3). Free and DFly are
- * identical.
- *
- * OpenBSD supplies the necessary informationvia kvm(3) in the form of a real
- * argv array. This array is flattened to be in the same way as Net/Free/DFly
- * returns the arguments in the first place. This is done in order for the
- * storage (`args') to easily be made static, which means some memory bytes
- * are sacrificed to save hoops of memory management.
- */
-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;
-#if defined( OPENBSD )
-	char kvmerr[_POSIX2_LINE_MAX];	/* for kvm*() error reporting */
-	int procs;			/* kvm_getprocs() */
-	kvm_t *kd;
-	struct kinfo_proc *kp;
-	char **nargv;			/* kvm_getarg() */
-#endif
-
-	*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);
-
-	/* space for args; no need to free before returning even on errors */
-	if (args == NULL)
-		args = (char *)wmalloc(argmax);
-
-#if defined( OPENBSD )
-	/* kvm descriptor */
-	if ((kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, kvmerr)) == NULL)
-		return False;
-
-	procs = 0;
-	/* the process we are interested in */
-	if ((kp = kvm_getprocs(kd, KERN_PROC_PID, pid, &procs)) == NULL || procs == 0)
-		/* if kvm_getprocs() bombs out or does not find the process */
-		return False;
-
-	/* get it's argv */
-	if ((nargv = kvm_getargv(kd, kp, 0)) == NULL)
-		return False;
-
-	/* flatten nargv into args */
-	count = 0;
-	memset(args, 0, argmax);
-	/*
-	 * must have this much free space in `args' in order for the current
-	 * iteration not to overflow it: we are at `count', and will append
-	 * the next ((*argc)+1) arg and a null (+1)
-	 * technically, overflow (or truncation, which isn't handled) can not
-	 * happen (should not, at least).
-	 */
-	#define ARGSPACE ( count + strlen(nargv[ (*argc) + 1 ] ) + 1 )
-	while (nargv[*argc] && ARGSPACE < argmax ) {
-		memcpy(args + count, nargv[*argc], strlen(nargv[*argc]));
-		count += strlen(nargv[*argc]) + 1;
-		(*argc)++;
-	}
-	#undef ARGSPACE
-	/* by now *argc is correct as a byproduct */
-
-	kvm_close(kd);
-#else /* FREEBSD || NETBSD || DRAGONFLYBSD */
-
-	mib[0] = CTL_KERN;
-#if defined( NETBSD )
-	mib[1] = KERN_PROC_ARGS;
-	mib[2] = pid;
-	mib[3] = KERN_PROC_ARGV;
-#elif defined( FREEBSD ) || defined( DRAGONFLYBSD )
-	mib[1] = KERN_PROC;
-	mib[2] = KERN_PROC_ARGS;
-	mib[3] = pid;
-#endif
-
-	count = argmax;
-	/* canary */
-	*args = 0;
-	if (sysctl(mib, 4, args, &count, NULL, 0) == -1 || *args == 0)
-		return False;
-
-	/* args is a flattened series of null-terminated strings */
-	for (i = 0; i < count; i++)
-		if (args[i] == '\0')
-			(*argc)++;
-#endif
-
-	*argv = (char **)wmalloc(sizeof(char *) * (*argc + 1 /* term. null ptr */));
-	(*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;
-	}
-
-	/* the list of arguments must be terminated by a null pointer */
-	(*argv)[j] = NULL;
-	return True;
-}
diff --git a/src/osdep/darwin.c b/src/osdep/darwin.c
deleted file mode 100644
index e037b5d..0000000
--- a/src/osdep/darwin.c
+++ /dev/null
@@ -1,92 +0,0 @@
-
-#include <sys/types.h>
-#include <sys/sysctl.h>
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.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)
-#ifdef KERN_PROCARGS2
-{
-	int j, mib[4];
-	unsigned int i, idx;
-	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[3] = 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);
-
-	/* space for args; no need to free before returning even on errors */
-	if (args == NULL)
-		args = (char *)wmalloc(argmax);
-
-	/* get process args */
-	mib[0] = CTL_KERN;
-	mib[1] = KERN_PROCARGS2;
-	mib[2] = pid;
-
-	count = argmax;
-	if (sysctl(mib, 3, args, &count, NULL, 0) == -1 || count == 0)
-		return False;
-
-	/* get argc, skip */
-	memcpy(argc, args, sizeof(*argc));
-	idx = sizeof(*argc);
-
-	while (args[idx++] != '\0')		/* skip execname */
-		;
-	while (args[idx] == '\0')		/* padding too */
-		idx++;
-	/* args[idx] is at at begininng of args now */
-
-	*argv = (char **)wmalloc(sizeof(char *) * (*argc + 1 /* term. null ptr */));
-	(*argv)[0] = args + idx;
-
-	/* go through args, set argv[$next] to the beginning of each string */
-	for (i = 0, j = 1; i < count - idx /* do not overrun */; i++) {
-		if (args[idx + i] != '\0')
-			continue;
-		if (args[idx + i] == '\0')
-			(*argv)[j++] = &args[idx + i + 1];
-		if (j == *argc)
-			break;
-	}
-
-	/* the list of arguments must be terminated by a null pointer */
-	(*argv)[j] = NULL;
-	return True;
-}
-#else /* !KERN_PROCARGS2 */
-{
-	*argv = NULL;
-	*argc = 0;
-
-	return False;
-}
-#endif
diff --git a/src/osdep/linux.c b/src/osdep/linux.c
deleted file mode 100644
index a754bb6..0000000
--- a/src/osdep/linux.c
+++ /dev/null
@@ -1,80 +0,0 @@
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.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)
-{
-	static char buf[_POSIX_ARG_MAX];
-	int fd, i, j;
-	ssize_t count;
-
-	*argv = NULL;
-	*argc = 0;
-
-	/* cmdline is a flattened series of null-terminated strings */
-	snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
-	while (1) {
-		if ((fd = open(buf, O_RDONLY)) != -1)
-			break;
-		if (errno == EINTR)
-			continue;
-		return False;
-	}
-
-	while (1) {
-		if ((count = read(fd, buf, sizeof(buf))) != -1)
-			break;
-		if (errno == EINTR)
-			continue;
-		return False;
-	}
-
-	do {
-		close(fd);
-	} while (errno == EINTR);
-
-	/* count args */
-	for (i = 0; i < count; i++)
-		if (buf[i] == '\0')
-			(*argc)++;
-
-	if (*argc == 0)
-		return False;
-
-	*argv = (char **)wmalloc(sizeof(char *) * (*argc + 1 /* term. null ptr */));
-	(*argv)[0] = buf;
-
-	/* go through buf, set argv[$next] to the beginning of each string */
-	for (i = 0, j = 1; i < count; i++) {
-		if (buf[i] != '\0')
-			continue;
-		if (i < count - 1)
-			(*argv)[j++] = &buf[i + 1];
-		if (j == *argc)
-			break;
-	}
-
-	/* the list of arguments must be terminated by a null pointer */
-	(*argv)[j] = NULL;
-	return True;
-}
diff --git a/src/osdep/stub.c b/src/osdep/stub.c
deleted file mode 100644
index 38b9820..0000000
--- a/src/osdep/stub.c
+++ /dev/null
@@ -1,11 +0,0 @@
-
-#include <WINGs/WUtil.h>
-#include "../wconfig.h"
-
-Bool GetCommandForPid(int pid, char ***argv, int *argc)
-{
-	*argv = NULL;
-	*argc = 0;
-
-	return False;
-}
diff --git a/src/osdep/test.c b/src/osdep/test.c
deleted file mode 100644
index 3bba44e..0000000
--- a/src/osdep/test.c
+++ /dev/null
@@ -1,49 +0,0 @@
-
-#include <stdio.h>
-#include <unistd.h>
-
-#include <WINGs/WUtil.h>
-
-/*
- * gcc -D{$os} -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;
-}
diff --git a/src/osdep_bsd.c b/src/osdep_bsd.c
new file mode 100644
index 0000000..e3063a9
--- /dev/null
+++ b/src/osdep_bsd.c
@@ -0,0 +1,171 @@
+
+#if defined( FREEBSD ) || defined( DRAGONFLYBSD )
+#   include <sys/types.h>
+#else /* OPENBSD || NETBSD */
+#   include <sys/param.h>
+#endif
+#include <sys/sysctl.h>
+
+#include <assert.h>
+
+#if defined( OPENBSD )
+#   include <kvm.h>
+#   include <limits.h>	/* _POSIX2_LINE_MAX */
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined( OPENBSD )
+#   include <string.h>
+#endif
+
+#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
+ */
+/*
+ * NetBSD, FreeBSD and DragonFlyBSD supply the necessary information via
+ * sysctl(3). The result is a plain simple flat octet stream and its length.
+ * The octet stream represents argv, with members separated by a null character.
+ * The argv array returned by GetCommandForPid() consists of pointers into this
+ * stream (which is stored in a static array, `args'). Net and Free/DFly only
+ * differ slightly in the MIB vector given to sysctl(3). Free and DFly are
+ * identical.
+ *
+ * OpenBSD supplies the necessary informationvia kvm(3) in the form of a real
+ * argv array. This array is flattened to be in the same way as Net/Free/DFly
+ * returns the arguments in the first place. This is done in order for the
+ * storage (`args') to easily be made static, which means some memory bytes
+ * are sacrificed to save hoops of memory management.
+ */
+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;
+#if defined( OPENBSD )
+	char kvmerr[_POSIX2_LINE_MAX];	/* for kvm*() error reporting */
+	int procs;			/* kvm_getprocs() */
+	kvm_t *kd;
+	struct kinfo_proc *kp;
+	char **nargv;			/* kvm_getarg() */
+#endif
+
+	*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);
+
+	/* space for args; no need to free before returning even on errors */
+	if (args == NULL)
+		args = (char *)wmalloc(argmax);
+
+#if defined( OPENBSD )
+	/* kvm descriptor */
+	if ((kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, kvmerr)) == NULL)
+		return False;
+
+	procs = 0;
+	/* the process we are interested in */
+	if ((kp = kvm_getprocs(kd, KERN_PROC_PID, pid, &procs)) == NULL || procs == 0)
+		/* if kvm_getprocs() bombs out or does not find the process */
+		return False;
+
+	/* get it's argv */
+	if ((nargv = kvm_getargv(kd, kp, 0)) == NULL)
+		return False;
+
+	/* flatten nargv into args */
+	count = 0;
+	memset(args, 0, argmax);
+	/*
+	 * must have this much free space in `args' in order for the current
+	 * iteration not to overflow it: we are at `count', and will append
+	 * the next ((*argc)+1) arg and a null (+1)
+	 * technically, overflow (or truncation, which isn't handled) can not
+	 * happen (should not, at least).
+	 */
+	#define ARGSPACE ( count + strlen(nargv[ (*argc) + 1 ] ) + 1 )
+	while (nargv[*argc] && ARGSPACE < argmax ) {
+		memcpy(args + count, nargv[*argc], strlen(nargv[*argc]));
+		count += strlen(nargv[*argc]) + 1;
+		(*argc)++;
+	}
+	#undef ARGSPACE
+	/* by now *argc is correct as a byproduct */
+
+	kvm_close(kd);
+#else /* FREEBSD || NETBSD || DRAGONFLYBSD */
+
+	mib[0] = CTL_KERN;
+#if defined( NETBSD )
+	mib[1] = KERN_PROC_ARGS;
+	mib[2] = pid;
+	mib[3] = KERN_PROC_ARGV;
+#elif defined( FREEBSD ) || defined( DRAGONFLYBSD )
+	mib[1] = KERN_PROC;
+	mib[2] = KERN_PROC_ARGS;
+	mib[3] = pid;
+#endif
+
+	count = argmax;
+	/* canary */
+	*args = 0;
+	if (sysctl(mib, 4, args, &count, NULL, 0) == -1 || *args == 0)
+		return False;
+
+	/* args is a flattened series of null-terminated strings */
+	for (i = 0; i < count; i++)
+		if (args[i] == '\0')
+			(*argc)++;
+#endif
+
+	*argv = (char **)wmalloc(sizeof(char *) * (*argc + 1 /* term. null ptr */));
+	(*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;
+	}
+
+	/* the list of arguments must be terminated by a null pointer */
+	(*argv)[j] = NULL;
+	return True;
+}
diff --git a/src/osdep_darwin.c b/src/osdep_darwin.c
new file mode 100644
index 0000000..ca38df2
--- /dev/null
+++ b/src/osdep_darwin.c
@@ -0,0 +1,96 @@
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.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)
+#ifdef KERN_PROCARGS2
+{
+	int j, mib[4];
+	unsigned int i, idx;
+	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[3] = 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);
+
+	/* space for args; no need to free before returning even on errors */
+	if (args == NULL)
+		args = (char *)wmalloc(argmax);
+
+	/* get process args */
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_PROCARGS2;
+	mib[2] = pid;
+
+	count = argmax;
+	if (sysctl(mib, 3, args, &count, NULL, 0) == -1 || count == 0)
+		return False;
+
+	/* get argc, skip */
+	memcpy(argc, args, sizeof(*argc));
+	idx = sizeof(*argc);
+
+	while (args[idx++] != '\0')		/* skip execname */
+		;
+	while (args[idx] == '\0')		/* padding too */
+		idx++;
+	/* args[idx] is at at begininng of args now */
+
+	*argv = (char **)wmalloc(sizeof(char *) * (*argc + 1 /* term. null ptr */));
+	(*argv)[0] = args + idx;
+
+	/* go through args, set argv[$next] to the beginning of each string */
+	for (i = 0, j = 1; i < count - idx /* do not overrun */; i++) {
+		if (args[idx + i] != '\0')
+			continue;
+		if (args[idx + i] == '\0')
+			(*argv)[j++] = &args[idx + i + 1];
+		if (j == *argc)
+			break;
+	}
+
+	/* the list of arguments must be terminated by a null pointer */
+	(*argv)[j] = NULL;
+	return True;
+}
+#else /* !KERN_PROCARGS2 */
+{
+	*argv = NULL;
+	*argc = 0;
+
+	return False;
+}
+#endif
diff --git a/src/osdep_linux.c b/src/osdep_linux.c
new file mode 100644
index 0000000..ed4953f
--- /dev/null
+++ b/src/osdep_linux.c
@@ -0,0 +1,80 @@
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.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)
+{
+	static char buf[_POSIX_ARG_MAX];
+	int fd, i, j;
+	ssize_t count;
+
+	*argv = NULL;
+	*argc = 0;
+
+	/* cmdline is a flattened series of null-terminated strings */
+	snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
+	while (1) {
+		if ((fd = open(buf, O_RDONLY)) != -1)
+			break;
+		if (errno == EINTR)
+			continue;
+		return False;
+	}
+
+	while (1) {
+		if ((count = read(fd, buf, sizeof(buf))) != -1)
+			break;
+		if (errno == EINTR)
+			continue;
+		return False;
+	}
+
+	do {
+		close(fd);
+	} while (errno == EINTR);
+
+	/* count args */
+	for (i = 0; i < count; i++)
+		if (buf[i] == '\0')
+			(*argc)++;
+
+	if (*argc == 0)
+		return False;
+
+	*argv = (char **)wmalloc(sizeof(char *) * (*argc + 1 /* term. null ptr */));
+	(*argv)[0] = buf;
+
+	/* go through buf, set argv[$next] to the beginning of each string */
+	for (i = 0, j = 1; i < count; i++) {
+		if (buf[i] != '\0')
+			continue;
+		if (i < count - 1)
+			(*argv)[j++] = &buf[i + 1];
+		if (j == *argc)
+			break;
+	}
+
+	/* the list of arguments must be terminated by a null pointer */
+	(*argv)[j] = NULL;
+	return True;
+}
diff --git a/src/osdep_stub.c b/src/osdep_stub.c
new file mode 100644
index 0000000..6a24e18
--- /dev/null
+++ b/src/osdep_stub.c
@@ -0,0 +1,19 @@
+
+#include <WINGs/WUtil.h>
+
+#include "wconfig.h"
+
+Bool GetCommandForPid(int pid, char ***argv, int *argc)
+{
+	*argv = NULL;
+	*argc = 0;
+	static int notified = 0;
+
+	if (!notified) {
+		wwarning(_("%s is not implemented on this platform; "
+		    "notify [email protected]"), __FUNCTION__);
+		notified = 1;
+	}
+
+	return False;
+}
-- 
1.7.0

Reply via email to