Search code examples
csocketsudpbroadcastos.execl

execl doesn't work in a while(1) loop, server side; C script


I have a problem with a little C script which should run as a server and launch a popup for every message arriving. The execl syntax is correct because if I try a little script with

main() { execl(...); }

it works.

When I put it in a while(1) loop it doesn't work. Everything else is working, like printf or string operation, but not the execl. Even if I fork it doesn't work. How can I make it work?

And I've tried with the fork(), but it doesn't work either.

Here's the complete server C 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;

}

Solution

  • There's a stack overflow in your call to recvfrom.

    recvfrom(s, buf, BUFLEN, 0, &si_other, &slen)
    

    I believe you mixed the 2 buffers. You're using buf, which has size 100, but telling its size is BUFLEN, which is 512. Whenever someone sends more than 100 bytes, it's very likely your program is going to crash.

    Besides that, it's possible that the recvfrom is not returning because it isn't receiving anything. Is your printf being executed?


    UPDATE: as pointed by @Daniel and @Dale, execl won't return unless an error occurs. Quoting from the man-page:

    The exec family of functions replaces the current process image with a new process image.

    As alternative, you can use system.