if() entry but instructions are not executed

Asked

Viewed 74 times

0

I am trying to make a chat using Pipes (chat between server and client). I made an output condition, in case the server wants to quit/turn off the chat writes "quit" on the client in the same way. Making "quit" from the server is working, however from the client no. My code is this:

client. c

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <pthread.h>
#include <string.h>
#include <fcntl.h>
#include "fifo.h"

int main()
{
    int readfd, writefd;
    umask(0);
    if((writefd=open(FIFO1, 1))<0)
        printf("client: Erro a abrir write fifo\n");
    if((readfd=open(FIFO2, 0))<0)
        printf("client: Erro ao abrir read fifo\n");

    char name[20], mensagem[200], OtherName[20];
    printf("Bem-vindo ao chat!\n");
    printf("Introduza o seu nome: ");
    fgets(name, 20, stdin);
    printf("Introduza quit caso deseja fechar o chat\n");

    if(fork()==0)
    {   
        while(1)
        {
            fgets(mensagem, 200, stdin);
            printf("\n");
            if(strncmp(mensagem, "quit", 4) == 0)
                exit(0);
            write(writefd, name, 20);
            write(writefd, mensagem, 200);
        }
    }

    else
    {
        while(1)
        {
            read(readfd, OtherName, 20);
            read(readfd, mensagem, 200);
            printf("\n%s -->%s\n", OtherName, mensagem);
        }
    }

    close(readfd);
    close(writefd);
    if(unlink(FIFO1)<0)
        printf("client: não foi possível fazer unlink\n");
    if(unlink(FIFO2)<0)
        printf("client: não foi possível fazer unlink\n");
    return 0;
}

server. c

#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <pthread.h>
#include <string.h>
#include <fcntl.h>
#include "fifo.h"

int main()
{
    int readfd, writefd;
    umask(0);
    unlink(FIFO1);
    unlink(FIFO2);//unlink dos fifos anteriores
    if((mknod(FIFO1, S_IFIFO | PERMS, 0))<0)
        printf("Erro a criar o fifo\n");
    if((mknod(FIFO2, S_IFIFO | PERMS, 0))<0)//criação de fifos
        printf("Erro a criar o fifo\n");
    if((readfd=open(FIFO1, 0))<0)//abrir o fifo em modo de leitura
        printf("Erro ao abrir read fifo\n");
    if((writefd=open(FIFO2, 1))<0)//abrir o fifo em modo de escrita
        printf("Erro ao abrir write fifo\n");

    char name[20], mensagem[200], OtherName[20];
    printf("Bem-vindo ao chat!\n");
    printf("Introduza o seu nome: ");
    fgets(name, 20, stdin);//nome do user no chat
    printf("Introduza quit caso deseja fechar o chat\n");

    if(fork()==0)//se fork()==0, então o server vai receber uma mensagem
    {   
        while(1)
        {
            read(readfd, OtherName, 20);//lê o nome do outro user
            read(readfd, mensagem, 200);//lê a mensagem do outro user
            printf("\n%s -->%s\n", OtherName, mensagem);//escreve a mensagem
        }
    }   

    else//se o servidor vai enviar uma mensagem
    {
        while(1)
        {
            fgets(mensagem, 200, stdin);//user introduz a mensagem
            printf("\n");
            if(strncmp(mensagem, "quit", 4) == 0)
                exit(0);
            write(writefd, name, 20);//escrever o nome para o pipe de escrita   
            write(writefd, mensagem, 200);//escrever a mensagem
        }
    }   

    close(readfd);
    close(writefd);     
    return 0;
}

No client. c, no seguinte if:

if(strncmp(mensagem, "quit", 4) == 0)
 exit(0);

The program enters if but does not execute instruction. Why does this happen? Thank you!

  • sera' that there is no ' n' at the end of message? Sorry, I am not accentuated on my Linux.

  • What do you mean? I don’t understand @lemoce

  • Are you sure you enter if, try to put a pause inside if... I think what the lemoce meant is that if the message is not " quit n" it is going with a line break.. then it is not entering if, because the message is bigger.

  • already tested the if, it really enters the if so I don’t think the error is there @Matheusfrancisco

  • @Gazelle, the pitch is that you have two processes. Father and son. The parent process will wait until the child finishes, s'o that the son is in an infinite loop. I’m sure, but you have to send an end message to the process, son. I’ll run some tests.

1 answer

1

I made a minimal example:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
  pid_t myPid = 0;

  if ((myPid = fork()) == 0)
    {
      printf ("processo pai %d\n", myPid);
      if (1)
        {
          exit(0);
        }
    }
  else
    {
      printf ("processo filho %d\n", myPid);
      while(1)
        {
          sleep(1);
          printf("mensagem do filho: dentro do while\n");
        }
    }

  return 0;
}

This example has the output:

macbook% ./a.out   
processo filho 2439
processo pai 0
mensagem do filho: dentro do while
mensagem do filho: dentro do while
mensagem do filho: dentro do while
^C
macbook% 

I found a reply in the OS. Follow the minimum example based on the answer:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include <signal.h>

int main()
{

  // para testar o pid do pai apos o termino do pai
  pid_t ppid_before_fork = getpid();
  pid_t pid = fork();

  if (pid == -1)
    {
      perror(0);
      exit(1);
    }

  if (pid)
    {
      printf ("processo pai %d\n", pid);
      sleep(10);
      if (1)
        {
          exit(0);
        }
    }
  else
    {
      // do comando $ man prctl
      // Return  the current value of the parent process death signal, in
      //   the location pointed to by (int *) arg2.
      int r = prctl (PR_SET_PDEATHSIG, SIGTERM);
      printf ("processo filho %d\n", pid);
      while(1)
        {
          sleep(1);
          printf("mensagem do filho: dentro do while\n");
          // if que testa se o pid do pai esta diferente
          // ocorre apos o exit
          if (getppid() != ppid_before_fork)
            exit(1);
        }
    }

  return 0;
}

Basically, the example of the colleague is based on specifying Posix:

The Parent process ID of all of the existing Child processes and zombie processes of the Calling process Shall be set to the process ID of an implementation-defined system process. That is, These processes Shall be inherited by a special system process.

With a quotation from the author of the reply:

Traditionally, the system process Adopting all Orphans is PID 1, i.e. init - which is the Ancestor of all processes.

In short, the entire orphan process traditionally receives pid 1, as it is the ancestor of all processes.

One more quote from the author:

Note that storing the Parent process id before the Fork and testing it in the Child after prctl() eliminates a race condition between prctl() and the Exit of the process that called the Child.

Storing the parent process before Fork and testing it after prctl() eliminates the race condition between prctl() and the exit from the process calling the child.

ps1: $man prctl info

This call is Linux-specific. IRIX has a prctl() system call (also introduced in Linux 2.1.44 as irix_prctl on the MIPS Architecture), with prototype

Might not work on Unix

Browser other questions tagged

You are not signed in. Login or sign up in order to post.