You are not logged in.

#1 2012-02-01 02:31:29

fukawi2
Ex-Administratorino
From: .vic.au
Registered: 2007-09-28
Posts: 6,231
Website

C - strtok discards qualifiers from pointer target type

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

Offline

#2 2012-02-01 03:03:25

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,330
Website

Re: C - strtok discards qualifiers from pointer target type

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

#3 2012-02-01 03:55:04

fukawi2
Ex-Administratorino
From: .vic.au
Registered: 2007-09-28
Posts: 6,231
Website

Re: C - strtok discards qualifiers from pointer target type

Thanks for taking the time to reply smile

Success! With a small tweak... Thank you very much big_smile

   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)

Offline

#4 2012-02-01 04:02:09

falconindy
Developer
From: New York, USA
Registered: 2009-10-22
Posts: 4,111
Website

Re: C - strtok discards qualifiers from pointer target type

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

#5 2012-02-01 04:19:28

juster
Forum Fellow
Registered: 2008-10-07
Posts: 195

Re: C - strtok discards qualifiers from pointer target type

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

#6 2012-02-01 04:26:23

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,330
Website

Re: C - strtok discards qualifiers from pointer target type

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

#7 2012-02-01 22:18:15

fukawi2
Ex-Administratorino
From: .vic.au
Registered: 2007-09-28
Posts: 6,231
Website

Re: C - strtok discards qualifiers from pointer target type

Didn't even think of that (that's why I don't program C tongue)

Thanks juster, I've amended the code smile
https://github.com/fukawi2/amqptools/co … 35d7a5b160

Offline

#8 2012-02-02 10:16:08

Blµb
Member
Registered: 2008-02-10
Posts: 224

Re: C - strtok discards qualifiers from pointer target type

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

Board footer

Powered by FluxBB