Функция fread () зависла и не выполняется - PullRequest
0 голосов
/ 26 апреля 2020

Я пытаюсь выполнить cat|grep, но, похоже, что-то не так с моей fread() функцией. Вот мой код:

На стороне клиента:

#include <stdio.h> 
#include <sys/socket.h> 
#include <arpa/inet.h> 
#include <unistd.h> 
#include <string.h> 
#include <stdlib.h>
#include<errno.h>

#define PORT 8080

int main(int argc, char const *argv[]) 
{ 
    int sock = 0, valread; 
    struct sockaddr_in serv_addr; 

     int buffer[1024];
     char buffer2[1024]={0};
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
        { 
        printf("\n Socket creation error \n"); 
        return -1; 
         } 

    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_port = htons(PORT); 


    if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)  
        { 
        perror("Invalid address \n"); 
        return -1; 
        } 

    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) 
       { 
        perror("Connection Failed \n"); 
        return -1; 
        } 

      int i, array[argc], countsize=0;
     if(argc>=2){
     for(i=1; i<argc; i++) {
       int number=atoi(argv[i]);
       array[i-1]=number;
       countsize++;
}

   if(send(sock, array, countsize*sizeof(int), 0)<0)
    {
    printf("Error in send! %s\n", strerror(errno));
        return -1; 
    }

 if(argc>=2){
 int i=0;
 for(int i=0; i<argc; i++) {
            if(atoi(argv[i])==6){
            puts("Please enter the name/word you want to search for in the history file: ");
            char word[30];
            fgets(word, 30, stdin); 
            if(send(sock, &word , 30, 0)<0)
                printf("Error in send! %s\n", strerror(errno));

              valread = read( sock , buffer2, 1024); 
              puts("The result cat|grep is:");
              printf("%s\n", buffer2);
            }     
}  
}
}      
 return 0; 
} 

На стороне сервера :

#include <stdio.h> 
#include <unistd.h> 
#include <sys/socket.h> 
#include <stdlib.h> 
#include <netinet/in.h> 
#include <string.h> 
#include<errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <sys/wait.h>
#include<time.h> 
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>
#include <arpa/inet.h> 

#define PORT 8080
void *catgrep(void *);

int main() 
{ 
    int server_fd, new_socket;
    struct sockaddr_in address; 
    int opt = 1; 
    int addrlen = sizeof(address); 
    char buffer2[1024]={0};

    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) 
        { 
        perror("socket failed"); 
        exit(EXIT_FAILURE); 
        } 


    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR , &opt, sizeof(opt))) 
        { 
        perror("setsockopt"); 
        exit(EXIT_FAILURE); 
        } 

    address.sin_family = AF_INET; 
    address.sin_addr.s_addr = INADDR_ANY; 
    address.sin_port = htons( PORT ); 

    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0) 
        { 
        perror("bind failed"); 
        exit(EXIT_FAILURE); 
        } 

 while (1){

    if (listen(server_fd, 20) < 0) 
        { 
        perror("listen"); 
        exit(EXIT_FAILURE); 
        } 
    if ((new_socket = accept(server_fd, (struct sockaddr *)&address,(socklen_t*)&addrlen))<0) 
        { 
        perror("accept"); 
        exit(EXIT_FAILURE); 
        } 

    int arguments[10]={0};
    int n = recv(new_socket, arguments ,1024*sizeof(int),0);
    int j;

   int argumentsize=n/sizeof(int);
    for(j=0; j<argumentsize;j++){
    if(arguments[j]==6){
        pthread_t th5;
        pthread_attr_t attr5;
        pthread_attr_init(&attr5);
        if(pthread_create(&th5,&attr5,catgrep,&new_socket)!=0){
        printf("Error in pthread_create %s\n", strerror(errno));
        return -1; 
        }
        pthread_join(th5, NULL);
       return -1; 
    }
}
close(new_socket);
}
close(server_fd);
return 1;
}

Функция catgrep ():

void *catgrep(void * param){

int *sock = (int*) param; //this is a multi-threaded server so I am receiving the socket as parameter
int new_sock = *sock;

int fd[2];
pipe(fd);
pid_t pid = fork(); 
char word[30];
recv(new_sock, word ,30, 0); 
printf("%s", word); //printing word from client, working fine

 if(pid==0){
       close(1);
       dup(fd[1]);
       close(fd[0]);
       close(fd[1]);

    char *cat_args[] = {"/bin/cat", "file.txt", NULL};
    execv(cat_args[0], cat_args);

    puts("test1"); //executing

    exit(0);
}

  if(pid > 0){
    close(0);
    dup(fd[0]);
    close (fd[1]);
    close(fd[0]);

    puts("test2"); //executing

    FILE *fp2;
    if ((fp2 = popen("grep -w tries", "r")) == NULL) {
        perror("popen failed");
        return NULL;
    }

    puts("test3"); //executing


  size_t str_size = 1024;
    char *stringts2 = malloc(str_size);
    if (!stringts2) {
        perror("stringts allocation failed");
        return NULL;
    }


    puts("test4"); //executing

    stringts2[0] = '\0';
    char buf[128];
    size_t n;
    puts("test5");//executing
    while ((n = fread(buf, 1, sizeof(buf) - 1, fp2)) > 0) {
         puts("test6"); //not executing
         buf[n] = '\0';
         size_t capacity = str_size - strlen(stringts2) - 1;
         while (n > capacity) {
            str_size *= 2;
            stringts2 = realloc(stringts2, str_size);
            if (!stringts2) {
                perror("stringts realloation failed");
                 return NULL;
            }
            capacity = str_size - strlen(stringts2) - 1;
        }
        strcat(stringts2, buf);
    }

    puts("test7"); //not executing obviously

    if (pclose(fp2) != 0) {
        perror("pclose failed");
         return NULL;
    }
        puts("test8"); //not executing obviously
    if(send(new_sock, stringts2, 10000, 0)<0){
       printf("Error in send! %s\n", strerror(errno));
    }
}
  return NULL;
}

Так как, кажется, что-то происходит в fread(), я пытаюсь использовать этот формат в других функциях, и все, кажется, работает хорошо, есть идеи, почему это происходит и как это исправить? Я не получаю ошибок при компиляции / выполнении, просто запрограммируйте что-то вроде тупика после того, как напечатан test5, так как клиент ждет, пока сервер отправит строку, а сервер просто застрял.

...