Execl doesn't work after a while (1), on the server side; C script
I have a problem with a small C script that needs to run as a server and trigger a popup for every message sent. The execl syntax is correct because if I try a little script with
main() { execl(...); }
it works.
When I put this after a while (1) it doesn't work. Everything else works, for example printf
or string, but not execl
. Even if my plug doesn't work. How can I get it to work?
And I tried with fork()
but it doesn't work either.
Here's the complete C server code.
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#define BUFLEN 512
#define PORT 9930
void diep(char *s) {
perror(s);
exit(1);
}
int main() {
struct sockaddr_in si_me, si_other;
int s, i, slen=sizeof(si_other), broadcastPermission;
char buf[100], zeni[BUFLEN];
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
diep("socket");
broadcastPermission = 1;
if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (void *) &broadcastPermission, sizeof(broadcastPermission)) < 0)
diep("setsockopt() failed");
memset((char *) &si_me, 0, sizeof(si_me));
si_me.sin_family = AF_INET;
si_me.sin_port = htons(PORT);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s, &si_me, sizeof(si_me))==-1)
diep("bind");
while (1) {
if (recvfrom(s, buf, BUFLEN, 0, &si_other, &slen)==-1) diep("recvfrom()");
//printf("Received packet from %s:%d\nData: %s\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), buf);
strcpy(zeni, "");
strcat(zeni, "zenity --warning --title Hack!! --text ");
strcat(zeni, buf);
printf("cmd: %s\n", zeni);
//system (zeni);
execl("/usr/bin/zenity", "/usr/bin/zenity", "--warning", "--title", "Warn!", "--text", buf, (char *) NULL);
}
close(s);
return 0;
}
a source to share
There's a stack overflow in your call recvfrom
.
recvfrom(s, buf, BUFLEN, 0, &si_other, &slen)
I believe you have mixed 2 buffers. You are using buf
that has a size of 100, but reporting that its BUFLEN size is 512. Whenever someone sends more than 100 bytes, it is very likely that your program will crash.
In addition, it is possible that it is recvfrom
not returned because it receives nothing. Is yours fulfilled printf
?
UPDATE: as @Daniel and @Dale pointed out, execl
not returned unless an error occurs. Quoting from the man page:
The exec family of functions replaces the current process image with a new process image.
Alternatively, you can use system
.
a source to share
@jweyrich already pointed out some problems with your use recvfrom
, however there is a more fundamental problem. The code
while (1) {
recvfrom(...);
execl(...);
}
will only be executed once. This is because the family of system calls exec
(including execl
) replaces the currently executing program with the one specified in the call execl
. In fact, it execl
never returns except with an error.
To create a new child process in unix, you must first call fork
that clones the existing process and then in a child call execl
(or some related system call) to replace the child process with the program you actually want to run. Doing this correctly by hand is somewhat tricky, so the function system
wraps this for you, however it has its drawbacks.
a source to share