You are not logged in.
Disclaimer: My experience with C pretty much starts and ends with "Hello World" examples...
Hopefully someone can point me on the right path...
if (NULL != program) {
// check that the program is executable
if (0 != access(program_cmd, X_OK)) {
fprintf(stderr, "Program doesn't have execute permission, aborting: %s\n", program_cmd);
exit(-1);
}
}
I'm fairly sure the bug in the above code is that "program" can contain an entire command line, not just the first argument (ie, "cat foo.txt" not just "cat").
For the life I me I can not fix the damn thing using strtok:
if (NULL != program) {
// check that the program is executable
char *program_cmd; // pointer for strtok
program_cmd = strtok(program," "); // split using space as divider
if (0 != access(program_cmd, X_OK)) {
fprintf(stderr, "Program doesn't have execute permission, aborting: %s\n", program_cmd);
exit(-1);
}
}
"program" is a char const pointer which I think it what's screwing me up, but I can't figure out how to copy it to a new variable either using strcpy without getting this error:
amqpspawn.c:293: warning: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast
Context for the above code: https://github.com/fukawi2/amqptools/bl … awn.c#L289
I get these errors:
$ make AMQPTOOLS_RABBITHOME=../rabbitmq-c
rm -f bin/amqpsend bin/amqpspawn
gcc -o bin/amqpspawn amqpspawn.c -I../rabbitmq-c/librabbitmq ../rabbitmq-c/librabbitmq/.libs/librabbitmq.a
amqpspawn.c: In function ‘main’:
amqpspawn.c:292: warning: passing argument 1 of ‘strtok’ discards qualifiers from pointer target type
gcc -o bin/amqpsend amqpsend.c -I../rabbitmq-c/librabbitmq ../rabbitmq-c/librabbitmq/.libs/librabbitmq.a
Are you familiar with our Forum Rules, and How To Ask Questions The Smart Way?
BlueHackers // fscanary // resticctl
Offline
Two likely problems, one strtok seems to be the wrong tool for the job. I'm not familiar with it, but the docs suggest it returns a single character (or integer) which you are treating as a pointer.
More importantly you have not allocated any space for your new string. If 'program' can be altered, the simplest solution would be
strchr(program,' ')='\0';
If 'program' should not be tampered with then you'll need to allocate space for 'program_cmd' copy 'program' to it, then do the above command on program_cmd.
Edit: As I suspect it probably would be bad to tamper with 'program' here's my suggestion for leaving it be:
if (NULL != program) {
// check that the program is executable
char *program_cmd = malloc( (strlen(program) + 1) * sizeof(char));
strcpy(program_cmd,program);
strchr(program_cmd,' ')='\0';
if (0 != access(program_cmd, X_OK)) {
fprintf(stderr, "Program doesn't have execute permission, aborting: %s\n", program_cmd);
exit(-1);
}
free(program_cmd); // OOPS ... I forgot this the first time around.
}
Some real experts may suggest improvements. I've never been good at keeping up on all the "best practices", but I do fiddle around enough to find solutions that should work.
Last edited by Trilby (2012-02-01 03:14:53)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
Thanks for taking the time to reply
Success! With a small tweak... Thank you very much
if (NULL != program) {
// check that the program is executable
char *program_cmd = malloc( (strlen(program) + 1) * sizeof(char));
strcpy(program_cmd,program);
*strchr(program_cmd,' ') = '\0';
if (0 != access(program_cmd, X_OK)) {
fprintf(stderr, "Program doesn't have execute permission, aborting: %s\n", program_cmd);
exit(-1);
}
free(program_cmd);
}
Tweak: treat the call to strchr as a pointer by prefixing with *
Edit: https://github.com/fukawi2/amqptools/co … 40fc47e747
Last edited by fukawi2 (2012-02-01 03:59:14)
Are you familiar with our Forum Rules, and How To Ask Questions The Smart Way?
BlueHackers // fscanary // resticctl
Offline
Assigning directly to the return of strchr() is going to bite you hard with a segfault when program_cmd doesn't contain a space. You really should check the return and only dereference/reassign once you know that it's not NULL.
Offline
const isn't hard to get around. You don't have to even try when using strchr.
char *wend;
wend = strchr(program, ' ');
if(wend){
*wend = '\0';
}
access(program);
if(wend){
*wend = ' ';
}
PS you were using strtok right. It returns a pointer. I'd prefer strchr because its easier to re-insert the space.
Offline
Ah, much nicer - definitely use that one.
My coding is a lot like duct tape - I can slap enough around to make things work, but they can be pretty ugly ... and can get all gummed up under the wrong conditions.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
Didn't even think of that (that's why I don't program C )
Thanks juster, I've amended the code
https://github.com/fukawi2/amqptools/co … 35d7a5b160
Are you familiar with our Forum Rules, and How To Ask Questions The Smart Way?
BlueHackers // fscanary // resticctl
Offline
The thing about strtok() is not that it simply "discards" the const qualifier, it actually changes the contents. It actually inserts nul bytes at the points where the string is supposed to be tokenized, and you can subsequently call strtok(NULL, ...) to get the next token from the previously used string (NOT threadsafe btw - you need strtok_r for that)
char blah[] = "Hello you cool fool.";
// Both of the next 2 lines print: 'Hello'
printf("'%s'\n", strtok(blah, " "));
printf("'%s'\n", blah);
// Next one prints 'you'
printf("'%s'\n", strtok(NULL, " "));
Output:
'Hello'
'Hello'
'you'
This is why you have to always consider strchr and its friends before deciding to use strtok(). There are situations where strtok() can be more comfortable though.
If you want to use strtok(), you can always take a look at strdup() (in which case you must not forget free() on the duplicate, unless you use the alloca-using variants)
Last edited by Blµb (2012-02-02 10:17:31)
You know you're paranoid when you start thinking random letters while typing a password.
A good post about vim
Python has no multithreading.
Offline