Reputation: 319
I'm new to C pointers and trying to execute process with command line and obtain its pid. Any of system(), sh(), etc, that use command line doesn't return pid, so I desided to use execve(). But it needs command line to be parsed to string array.
I found some existing solutions, but I could not make any to work. So, I wrote mine own. It works in my test program, but causes segmentation error in real one. Can somebody tell me, where I am wrong? Code is:
void cmdline_to_argv(const char* cmd_line, char*** argv, int* argc){
int len, i, count, spc;
char *s,*d;
/* make a copy to play with */
char *cmd_line1 = strdup(cmd_line);
/* count items to deal with and trim multiple spaces */
d = s = cmd_line1; spc = 1; count = 0; len=strlen(cmd_line1);
for (i=0; i<len;i++,s++) {
switch (*s) {
case ' ':
if (spc) continue;
*d++ = '\0'; /* replace spaces with zeroes */
spc = 1;
break;
default:
if (spc) { count++; spc = 0; }
*d++ = *s;
}
}
(*d++) = '\0'; /* line termination */
/* reallocate copy to correct size */
cmd_line1 = realloc( cmd_line1, d - cmd_line1);
/* allocate array of poiters */
*argv = (char**) malloc(sizeof(char*) * (count+1));
argv[count] = NULL;
/* scan line again to find all lines starts and register */
s = cmd_line1;
for (i=0; i<count; i++) {
(*argv)[i] = s;
while (*(s++)) ;
}
*argc = count;
}
and there is how I call it:
char **chargv = NULL;
int chargc;
/* parse line to argument array */
cmdline_to_argv(cmdline, &chargv, &chargc);
I think all the trouble here with pointer operations where I allocate array and write to it. How to do it correct?
Upvotes: 0
Views: 513
Reputation: 319
The question is closed. Solution is found. The tricky pointer declaration syntax solved. Here is the working one.
Thanks to All. :-|
void cmdline_to_argv(const char* cmd_line, char ***argv, int* argc){
int i, spc;
size_t len;
char *s,*d;
/* make a copy to play with */
char *cmd_line1 = strdup(cmd_line);
/* count items to deal with and trim multiple spaces */
d = s = cmd_line1; spc = 1; *argc = 0; len=strlen(cmd_line1);
for (i=0; i<len;i++,s++) {
switch (*s) {
case ' ':
if (spc) continue;
*d++ = '\0'; /* replace spaces with zeroes */
spc = 1;
break;
default:
if (spc) { (*argc)++; spc = 0; }
*d++ = *s;
}
}
(*d++) = '\0'; /* line termination */
/* calc actual size */
len = d - cmd_line1;
/* allocate array of poiters */
*argv = (char**) malloc(sizeof(char*) * ((*argc)+1) + len);
(*argv)[*argc] = (char*) NULL;
d = (char*) &(*argv)[(*argc)+1];
memmove(d, cmd_line1, len);
free(cmd_line1);
cmd_line1 = d;
/* scan line again to find all lines starts and register */
for (i=0; i<*argc; i++) {
(*argv)[i] = d;
while (*(d++)) ;
}
}
/* deallocate array and strings */
void free_argv(char ***argv) {
free(*argv); /* strings laying together at once after pointers array */
}
Upvotes: 2
Reputation: 613
Have you looked here https://www.kernel.org/doc/man-pages/online/pages/man2/getpid.2.html I believe what you want is getpid() although maybe you are asking something more.
Upvotes: 1