0

I have read several forums but can't find the solution to this.

int sIndex = 3;
char serverArgs[serverCommandCount + 3][20];


strcpy(serverArgs[0], "ant");
strcpy(serverArgs[1], "-f");
strcpy(serverArgs[2], "/dev/server1/trunk/build.xml");
if(serverStop){strcpy(serverArgs[sIndex], "jboss-stop"); sIndex++;}
if(serverClean){strcpy(serverArgs[sIndex], "clean"); sIndex++;}
if(serverDeploy){strcpy(serverArgs[sIndex], "deploy"); sIndex++;}
if(releaseDB){strcpy(serverArgs[sIndex], "releasedb"); sIndex++;}
if(createDB){strcpy(serverArgs[sIndex], "createdb"); sIndex++;}
if(serverStart){strcpy(serverArgs[sIndex], "jboss-start"); sIndex++;}
if(serverDebug){strcpy(serverArgs[sIndex], "jboss-start-debug"); sIndex++;}

execv(antEx, serverArgs);

In this solution the problem is the execv wanting a char *[ ] rather than a char[ ].

int sIndex = 3;
char *serverArgs[serverCommandCount + 3];

for(index = 0; index < serverCommandCount + 3; index++)
    serverArgs[index] = malloc(20);
strcpy(serverArgs[0], "ant");
strcpy(serverArgs[1], "-f");
strcpy(serverArgs[2], "/dev/server1/trunk/build.xml");
if(serverStop){strcpy(serverArgs[sIndex], "jboss-stop"); sIndex++;}
if(serverClean){strcpy(serverArgs[sIndex], "clean"); sIndex++;}
if(serverDeploy){strcpy(serverArgs[sIndex], "deploy"); sIndex++;}
if(releaseDB){strcpy(serverArgs[sIndex], "releasedb"); sIndex++;}
if(createDB){strcpy(serverArgs[sIndex], "createdb"); sIndex++;}
if(serverStart){strcpy(serverArgs[sIndex], "jboss-start"); sIndex++;}
if(serverDebug){strcpy(serverArgs[sIndex], "jboss-start-debug"); sIndex++;}

execv(antEx, serverArgs);

When I try it this way, I get a segmentation fault when it tries to execute

strcpy(serverArgs[1], "-f");

What am I missing?

7
  • I have also tried this without the malloc. Commented Jun 22, 2012 at 20:35
  • 4
    The line strcpy(serverArgs[2], "/dev/server1/trunk/build.xml"); is probably no good -- that string is larger than twenty characters. Commented Jun 22, 2012 at 20:37
  • @Peter You should add that as an answer (instead of a comment on the question). Commented Jun 22, 2012 at 20:43
  • Another thing to note: use of strcpy is generally frowned upon, for exactly this reason – it's much too easy to create buffer overflows. Use strncpy and provide an explicit length instead. Commented Jun 22, 2012 at 20:44
  • 1
    @JustinSpahr-Summers, strncpy is probably more "frowned upon" than strcpy, because you have to watch that the result is always nul terminated. Commented Jun 22, 2012 at 20:47

3 Answers 3

2

Turning my comment into an answer: The line strcpy(serverArgs[2], "/dev/server1/trunk/build.xml"); is probably no good -- that string is larger than twenty characters. You should be completely sure that you malloc enough space for everything that could possibly go into the array.

Sign up to request clarification or add additional context in comments.

Comments

1

Check the man page for execv:

The array of pointers must be terminated by a NULL pointer.

5 Comments

Ok, but I dont think i can even get that far because it crashes when adding the second element. This is my goal: char serverArgs[] = {"ant", "-f", "/dev/server1/trunk/build.xml", "solr-stop", "solr-start",(char) 0}; but i need to determine which/how many options to include.
Given the code we see, it doesn't make sense that it crashes at that line, except if malloc returned NULL. One should always check for that anyway, but in this case, even more so. Add the NULL check, adjust your malloced size for the long string, make your array one longer for the terminating NULL and try again. If it still crashes, we need more code, because that ought to be impossible then.
Ok, here's where I'm at now: <code> int sIndex = 3; char *serverArgs[serverCommandCount + 4]; for(index = 0; index < serverCommandCount + 4; index++) serverArgs[index] = malloc(100); ... execv(antEx, serverArgs); </code> Now it makes it to the execv() command but crashes there. Here is the message I get when I compile: warning: passing argument 2 of 'execv' from incompatible pointer type
Nevermind, I forgot the null on the end. it works now, thanks!
Let the loop run only for index < serverCommandCount + 3, since the last pointer should be NULL. Don't forget to set serverArgs[sIndex] = NULL after the copying loop (free unused allocated storage before that). The incompatible pointer type should be because execv expects a char *const argv[], that shouldn't cause a crash.
0

Your 2nd solution is generally the good one, but if you have it on your platform, use strdup instead of malloc and strcpy to allocate and copy the strings in one go. If you don't have strdup, it would not be very difficult to write one yourself.

Also, for that you don't have a surprise for your string array, do:

char *serverArgs[serverCommandCount + 3] = { 0 };

to initialize all the pointers correctly.

3 Comments

I don't really understand how strdup would work in this circumstance, will you give me an example?
You would use something like serverArgs[i] = strndup("foo bar baz mumble pies", 19);. This copies the "foo..." string up to 19 characters (the size of the buffer minus one null character at the end), and puts it into the array. Try man strdup.
"the size of the buffer minus one null character" -- there is no buffer here (the malloc loop can/should be omitted). strdup, not strndup, is the correct function to use here. There are rare use cases for strndup, but this isn't one of them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.