I am trying to execute a program with the execvp
function within an overseer and client distributed system. The client sends a program to be executed with the arguments:
char buf[500];
int bytes_recieved = 0;
char array[1][26];
bytes_recieved = recv(clientfd, buf, 5000, 0);
buf[bytes_recieved] = '\0';
char buf1[50];
int bytes_recieved1 = 0;
char *array1[4];
for (int i = 0; i < 3; i++){
bytes_recieved1 = recv(clientfd, buf1, 50, 0);
array1[i] = buf1;
printf("%s = buffer\n", buf1);
}
buf1[bytes_recieved] = '\0';
if(bytes_recieved != -1){
printTime();
fprintf(stdout,"atempting to execute program: %s\n", buf);
if(execvp(buf, array1) == -1) {
return 1;
}
}
I'm stuck on trying to figure out what happens when I print out the array of arguments in the program the last argument is the same for all of them? for example I run this in the client program to be executed:
./client 12345 home/user/test_program 1 2 3
the result from a simple printf is:
3
3
3
When I manually assign each argument in the array in the overseer:
array1[0] = "1";
array1[1] = "2";
array1[2] = "3";
and send it to the executed program it prints correctly.
I have also tested that the received buffer from the file descriptor is correctly assigning the variables in the array:
printf("%s = buffer\n", array1[i]);
within the assignment for loop, which returns:
1 = buffer
2 = buffer
3 = buffer
What am I doing wrong? Let me know if you need any more information.
This is some skeletal code, based on your code fragment. I can't test it — you did not provide an MCVE (Minimal, Complete, Verifiable Example — or MRE or whatever name SO now uses) or an SSCCE (Short, Self-Contained, Correct Example).
Multiple changes include:
sizeof
to determine array sizes.array1
big enough to hold a terminal NULL pointer and initializing (indirectly) the elements after the zeroth to NULL. This is important; the argument array toexecvp()
must be terminated with a NULL pointer.buf1
array local to the loop; dittobytes_received1
.strdup()
— this is a key change.buf1
at a position based on the data received inbuf
.execvp()
.stderr
instead ofstdout
. I ended up leaving it going tostdout
, but that isn't necessarily the best choice.fprintf(stdout, …)
toprintf(…)
for consistency.fflush(0)
to send any pending output to its devices. With the debugging output going tostdout
, if the output is piped to another program, the data will be fully buffered, not line buffered, and won't appear unless you force it to. Callingfflush(stdout)
would also be an option. It's probable that you shouldn't (don't) have any file streams other thanstdin
,stdout
,stderr
open when you're callingexecvp()
.O_CLOEXEC
orFC_CLOEXEC
options to ensure that the file descriptors are closed on successful exec, so that the executed process doesn't get active file descriptors it doesn't know about.execvp()
. If it returns, it failed; if it succeeds, it doesn't return.execvp()
fails to execute.return 1;
as part of the code after the failedexecvp()
. It would often be better to useexit(EXIT_FAILURE);
or similar (_exit(EXIT_FAILURE)
perhaps). Without the larger context of the function that calls this fragment of a function, it isn't possible to know what's best here.execvp()
fails and returns, rather than exits, you're leaking the memory allocated bystrdup()
. There should probably be a loopfor (int i = 0; i < 3; i++) free(array1[i+1]);
to release the copied memory before thereturn 1;
.recv()
calls would have read more data than it did because there wasn't enough space to store all the data. You'd probably want to check that the actual data size is smaller than the space available to ensure that there wasn't truncation.1
,2
,3
, this is not a problem.