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;

}

      

+2


a source to share


3 answers


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

.

+2


a source


@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.

+3


a source


Please read the exec (3) man page.

In your case, the execl system call will replace the current process image with the / usr / bin / zenity image.

You have two solutions, use system (3) as you tried there, or fork, and inside the execlp child run.

+1


a source







All Articles