es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

El demonio no está respondiendo.

Ya he hecho una pregunta similar hace unos días. Básicamente tengo que hacer que un demonio-cliente se comunique a través de tuberías con nombre. La parte del cliente está hecha y envía mensajes correctamente, pero parece que la parte del demonio no está recibiendo nada… Aquí está el código:

void makeDaemon(){
  int i,fd0,fd1,fd2;
  pid_t pid;
  struct sigaction sa;
  struct rlimit rl;

umask(0);

if(getrlimit(RLIMIT_NOFILE, &rl)<0) exit(EXIT_FAILURE);

if((pid=fork())<0) exit(EXIT_FAILURE);
  if(pid>0) exit(EXIT_SUCCESS);

setsid();

sa.sa_handler=SIG_IGN;
  sigemptyset(&sa.sa_mask);
  sa.sa_flags=0;

if(sigaction(SIGHUP, &sa, NULL)<0) exit(EXIT_FAILURE);

if((pid=fork())<0) exit(EXIT_FAILURE);
  if(pid>0) exit(EXIT_SUCCESS);

//if(chdir("/")<0) exit(EXIT_FAILURE);

if(rl.rlim_max=RLIM_INFINITY) rl.rlim_max=1024;
  for(i=0;i< rl.rlim_max; i++) close(i);

close(STDIN_FILENO);
  close(STDOUT_FILENO);
  close(STDERR_FILENO);

//sigaction(SIGUSR1,&sac,NULL);
}

int main(){
  makeDaemon();

char* path="./run/pipes/saturnd-request-pipe";
  char* path2="./run/pipes/saturnd-reply-pipe";

//Creación de una tubería en caso de que no exista
  //mkfireply_pipe(path,0666);
  int timeout=5000;
  struct pollfd pf[1];

int request_pipe;

while(1){
    request_pipe=open(path,O_RDONLY);
    if(request_pipe==-1){
        perror("Erreur d'ouverture du pipe");
        exit(EXIT_FAILURE);
    }

pf[0].fd=request_pipe;
pf[0].events=POLLIN;

int p=poll(pf,1,timeout);

if(pf[0].revents & POLLIN){
  char tmp1[2];
  ssize_t s=read(request_pipe,tmp1,2);
   if(s==-1) exit(EXIT_FAILURE);
   printf("%s\n",tmp1);
   int i=1;
}else{
  printf("Timed out\n");
  break;
}
return 0;
}

}

Mi pregunta es, ¿debería tal vez hacer un manejador que contenga este bucle while para que el demonio pueda recibir una señal? En este momento, simplemente se agota el tiempo y muere. No podemos utilizar sockets, y todo se hace a través de estas dos tuberías con nombre. Cualquier sugerencia sería apreciada. ¡Gracias!

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Según el código proporcionado, su demonio actualmente está abriendo y leyendo desde una tubería con nombre, y espera entrada utilizando la función poll(). Sin embargo, parece que el código que proporcionó solo lee dos bytes a la vez, y luego sale del bucle inmediatamente después de la primera lectura. Es posible que la entrada enviada por el cliente sea más larga que dos bytes, por lo que el demonio sale antes de recibir todo el mensaje.

    Para solucionar esto, debería modificar su bucle para leer continuamente desde la tubería hasta que haya recibido todo el mensaje. Una forma de hacer esto es primero leer la longitud del mensaje (que el cliente también debería enviar antes de enviar el mensaje real) y luego leer esa cantidad de bytes. Por ejemplo:

    // Leer la longitud del mensaje
    int len;
    ssize_t s = read(request_pipe, &len, sizeof(len));
    if (s == -1) exit(EXIT_FAILURE);
    
    // Asignar un buffer para el mensaje
    char* buf = malloc(len);
    if (buf == NULL) exit(EXIT_FAILURE);
    
    // Leer el mensaje real
    s = read(request_pipe, buf, len);
    if (s == -1) {
        free(buf);
        exit(EXIT_FAILURE);
    }
    
    // Hacer algo con el mensaje...
    
    free(buf);
    

    También debería eliminar la instrucción return 0 al final del bucle, ya que eso hará que el demonio salga después de la primera lectura.

    Finalmente, para responder a su pregunta original, no necesariamente necesita utilizar un manejador de señales para recibir mensajes del cliente. Utilizar un bucle como el anterior debería ser suficiente, siempre y cuando el cliente esté enviando mensajes correctamente y el demonio pueda abrir y leer desde la tubería con nombre.

Comments are closed.