Fredszky 0 Newbie Poster

Server code part:

                   void spawn (char* program, char** arg_list)  // Executing the clients command
                    {

                        printf("\n\nprogram = %s\narg_list = %s\n\str1=%s!!!\nstr2=%s\n\n",program,arg_list,str1,str2);

                        dup2(s2, STDOUT_FILENO);  //Redericting information to socket
                        dup2(s2, STDERR_FILENO);
                        execvp (program, arg_list);abort ();    // Executing the clients command - After this, program gets stuck, why?

                        /*
                        if (send(s2, "This works multiple times", 27, 0) == -1) {
                        perror("send");
                        exit(1);
                        }  */
                    }

So, im making a server to handle multiple clients. The clients sends simple commands like "ls -l" or "mkdir test" and the server executes and send information back to the client.

When i connect my client, i can get the output from the server to my client, one time, but then the server program seems to get stuck.
If i use a test string with send(), it will work multiple times as it should be.

Why does my program gets stuck using execvp?

Whole server code:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define SOCK_PATH "socket"


int main( int argc, char *argv[] )
{

    int s, s2, t, len;
    struct sockaddr_un local, remote;
    char str[1000];
    char* arg_list[2220];
    char str1[1000], str2[1000];


    int z=0;
    for(z=0;z<99;z++){
    str1[z] = NULL;
    str2[z] = NULL;
    }

    for(;;){


        if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
            perror("socket");
            exit(1);
        }

        local.sun_family = AF_UNIX;
        strcpy(local.sun_path, SOCK_PATH);
        unlink(local.sun_path);
        len = strlen(local.sun_path) + sizeof(local.sun_family);
        if (bind(s, (struct sockaddr *)&local, len) == -1) {
            perror("bind");
            exit(1);
        }

        if (listen(s, 5) == -1) {
            perror("listen");
            exit(1);
        }

        printf("Waiting for connections\n");

        t = sizeof(remote);
        if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) {   // Server waits for client to connect
            perror("accept");
            exit(1);
        }


        pid_t childPID;

        childPID = fork();

        if(childPID >= 0) // Fork was successful
        {
            if(childPID == 0) // Child process
            {
                printf("\I am child\n");

                close(s);

                printf("Connected.\n");

                int        active = 0;
                int done = 0;
                int sent = 0;
                do{

                    int n = recv(s2, str, 1000, 0);
                    if(n <= 0) {
                        if (n < 0) perror("recv");
                            done = 1;
                    }

                    active = 1;

                    str[strcspn ( str, "\n" )] = '\0';  // String stuff below ***

                    strcpy(str1,str);

                    int i=0,k=0;

                    while (str1[i] != ' ')
                        i++;

                    while (str1[i] != '\0'){
                        str2[k] = str1[i+1];
                        k++;
                        i++;
                    }

                    i=0;

                    while (str1[i] != ' ')
                    i++;

                    str1[i] = '\0'; // String stuff above ***


                    void spawn (char* program, char** arg_list)  // Executing the clients command
                    {

                        printf("\n\nprogram = %s\narg_list = %s\n\str1=%s!!!\nstr2=%s\n\n",program,arg_list,str1,str2);

                        dup2(s2, STDOUT_FILENO);  //Redericting information to socket
                        dup2(s2, STDERR_FILENO);
                        execvp (program, arg_list);abort ();    // Executing the clients command - Program gets stuck, why?

                        /*
                        if (send(s2, "This works multiple times", 27, 0) == -1) {
                        perror("send");
                        exit(1);
                        }  */
                    }


                    char command[2222];


                    char * tmp;

                    i=0;

                    tmp = strtok (command," ");
                    arg_list[0] = tmp;

                    while (tmp != NULL)
                    {
                        tmp = strtok (NULL, " ");
                        arg_list[i+1] = tmp;
                        i++;
                    }

                    char* arg1[] = {
                        str1,
                        NULL
                    };
                    char* arg2[] = {
                        str1,
                        str2,
                        NULL
                    };


                    if (!done && sent == 0 && active == 1){
                        if(str2[0] >= '+' && str2[0] <= 'DEL'){     // Ugly solution to make commands work.. .sometimes.
                            if(str2[1] >= '+' && str2[1] <= 'DEL')

                                spawn (str1, arg2);}
                            else
                                spawn (str1, arg1);
                    }

                    sent = 0;
                    for(z=0;z<99;z++){
                        str1[z] = NULL;
                        str2[z] = NULL;
                    }

                }while (!done);


            }
            else //Parent process
            {
                printf("\nI'll just get back to my listening state - the (;;)/>/>/>/> loop \n");
            }

        }
        else // Fork failed
        {
            printf("\nFork failed, quitting!\n");
            return 1;
        }
    }
    return 0;
}

Whole client code:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define SOCK_PATH "socket"

int main(void)
{
    int s, t, len,i=0;
    struct sockaddr_un remote;
    char str[10000];

    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    printf("Trying to connect...\n");

    remote.sun_family = AF_UNIX;
    strcpy(remote.sun_path, SOCK_PATH);
    len = strlen(remote.sun_path) + sizeof(remote.sun_family);
    if (connect(s, (struct sockaddr *)&remote, len) == -1) {
        perror("connect");
        exit(1);
    }

    printf("Connected.\n");

    while(printf("> "), fgets(str, 10000, stdin), !feof(stdin)) {


        if (send(s, str, strlen(str), 0) == -1) {
            perror("send");
            exit(1);
        }

        if ((t=recv(s, str, 10000, 0)) > 0) {
            str[t] = '\0';
            printf("echo> %s", str);

            for(i=0;i<9999;i++)
            str[i]=NULL;

        } else {
            if (t < 0) perror("recv");
            else printf("Connection with server terminated.\n");
            exit(1);
        }
    }

    close(s);

    return 0;
}