mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-19 12:28:22 +01:00
Patch for GetCommandForPid() in osdep_darwin.c
the function mentioned above caused segfaults on MacOS. The attached patch seems to solve that. Details: The functions provides an array of string pointers (the argument vector) pointing to a buffer allocated and referred to by a static local variable `args`. This buffer was used on each subsequent call. For one thing this would overwrite old values and for another this caused segfaults. My new implementation allocates a buffer for the argument vector plus the actual string data on each call. The caller will wfree() the buffer, but until then has available an independent copy of the strings.
This commit is contained in:
committed by
Carlos R. Mafra
parent
7d423a3a0f
commit
a98680cd14
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
|
|
||||||
@@ -23,8 +22,8 @@
|
|||||||
Bool GetCommandForPid(int pid, char ***argv, int *argc)
|
Bool GetCommandForPid(int pid, char ***argv, int *argc)
|
||||||
#ifdef KERN_PROCARGS2
|
#ifdef KERN_PROCARGS2
|
||||||
{
|
{
|
||||||
int j, mib[4];
|
int mib[4];
|
||||||
unsigned int i, idx;
|
unsigned int idx;
|
||||||
size_t count;
|
size_t count;
|
||||||
static char *args = NULL;
|
static char *args = NULL;
|
||||||
static int argmax = 0;
|
static int argmax = 0;
|
||||||
@@ -70,21 +69,46 @@ Bool GetCommandForPid(int pid, char ***argv, int *argc)
|
|||||||
idx++;
|
idx++;
|
||||||
/* args[idx] is at at begininng of args now */
|
/* args[idx] is at at begininng of args now */
|
||||||
|
|
||||||
*argv = (char **)wmalloc(sizeof(char *) * (*argc + 1 /* term. null ptr */));
|
int found = 0;
|
||||||
(*argv)[0] = args + idx;
|
char *p = &args[idx];
|
||||||
|
while(found < *argc)
|
||||||
|
{
|
||||||
|
while(*p != '\0') p++; // look for the next \0
|
||||||
|
while(*p == '\0') p++; // skip over padding \0s
|
||||||
|
found++;
|
||||||
|
|
||||||
/* go through args, set argv[$next] to the beginning of each string */
|
// Don’t overrun!
|
||||||
for (i = 0, j = 1; i < count - idx /* do not overrun */; i++) {
|
if (p-args >= argmax)
|
||||||
if (args[idx + i] != '\0')
|
{
|
||||||
continue;
|
return False;
|
||||||
if (args[idx + i] == '\0')
|
}
|
||||||
(*argv)[j++] = &args[idx + i + 1];
|
}
|
||||||
if (j == *argc)
|
// At this point, p points to the last \0 in the source array.
|
||||||
break;
|
|
||||||
}
|
// Buffer needed for the strings
|
||||||
|
unsigned stringbuf_size = p - &args[idx];
|
||||||
|
|
||||||
|
// Buffer needed for the pointers (plus one terminating NULL)
|
||||||
|
unsigned pointerbuf_size = sizeof(char *) * (*argc + 1);
|
||||||
|
|
||||||
|
*argv = wmalloc(pointerbuf_size + stringbuf_size);
|
||||||
|
char* stringstart = (char *)(*argv) + pointerbuf_size;
|
||||||
|
|
||||||
|
memcpy(stringstart, &args[idx], stringbuf_size);
|
||||||
|
|
||||||
|
found = 0;
|
||||||
|
p = stringstart;
|
||||||
|
while(found < *argc)
|
||||||
|
{
|
||||||
|
(*argv)[found] = p;
|
||||||
|
|
||||||
|
while(*p != '\0') p++; // look for the next \0
|
||||||
|
while(*p == '\0') p++; // skip over padding \0s
|
||||||
|
|
||||||
|
found++;
|
||||||
|
}
|
||||||
|
(*argv)[found] = NULL; // Terminating NULL
|
||||||
|
|
||||||
/* the list of arguments must be terminated by a null pointer */
|
|
||||||
(*argv)[j] = NULL;
|
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
#else /* !KERN_PROCARGS2 */
|
#else /* !KERN_PROCARGS2 */
|
||||||
|
|||||||
Reference in New Issue
Block a user