Prevent crash when switchpanel is not initialised.
[wmaker-crm.git] / src / osdep_linux.c
blob1336d2f82c3874143153494dfd36d73c69bbe8fd
2 #include <sys/types.h>
3 #include <sys/stat.h>
5 #include <errno.h>
6 #include <fcntl.h>
7 #include <limits.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
12 #include <WINGs/WUtil.h>
14 #include "wconfig.h"
15 #include "funcs.h"
18 #define RETRY( x ) do { \
19 x; \
20 } while (errno == EINTR);
23 * copy argc and argv for an existing process identified by `pid'
24 * into suitable storage given in ***argv and *argc.
26 * subsequent calls use the same static area for argv and argc.
28 * returns 0 for failure, in which case argc := 0 and argv := NULL
29 * returns 1 for success
31 Bool GetCommandForPid(int pid, char ***argv, int *argc)
33 static char buf[_POSIX_ARG_MAX];
34 int fd, i, j;
35 ssize_t count;
37 *argv = NULL;
38 *argc = 0;
40 /* cmdline is a flattened series of null-terminated strings */
41 snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
42 while (1) {
43 /* not switching this to stdio yet, as this does not need
44 * to be portable, and i'm lazy */
45 if ((fd = open(buf, O_RDONLY)) != -1)
46 break;
47 if (errno == EINTR)
48 continue;
49 return False;
52 while (1) {
53 if ((count = read(fd, buf, sizeof(buf))) != -1)
54 break;
55 if (errno == EINTR)
56 continue;
57 RETRY( close(fd) )
58 return False;
60 RETRY( close(fd) )
62 /* count args */
63 for (i = 0; i < count; i++)
64 if (buf[i] == '\0')
65 (*argc)++;
67 if (*argc == 0)
68 return False;
70 *argv = (char **)wmalloc(sizeof(char *) * (*argc + 1 /* term. null ptr */));
71 (*argv)[0] = buf;
73 /* go through buf, set argv[$next] to the beginning of each string */
74 for (i = 0, j = 1; i < count; i++) {
75 if (buf[i] != '\0')
76 continue;
77 if (i < count - 1)
78 (*argv)[j++] = &buf[i + 1];
79 if (j == *argc)
80 break;
83 /* the list of arguments must be terminated by a null pointer */
84 (*argv)[j] = NULL;
85 return True;