2

I'm currently trying to run a server to attend several "clients'"(local processes) requests at the same time using a Named Pipe as IPC. Clients are able to write on it but it seems the select() function on the server is not working properly, its returning 0 all the time.

This is the server's main code:

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

    fd_set set;         //fds to monitor
    Request * r;
    struct timeval tv;  //timeout
    Connection *c;      //where the fd will be saved
    fd_set foo;         //debugging purpose

    //opens the NamedPipe and saves de ReadOnly fd on c
    if( (c = openConnection()) == NULL) {
        return ERROR_OPEN_REQUEST_QUEUE;
    }

    //sets up the fds to monitor  FD_ZERO and FD_SET
    setConnection(c, &set); 

    FD_ZERO(&foo);

    tv.tv_sec = 2;
    tv.tv_usec = 0;

    while(1){

        int fdCount = select(2, &set, &foo, &foo, &tv);

            //it seems select directly modifies this value
            tv.tv_sec = 2;

            //saw it on another post        
            setConnection(c, &set); 
        if( fdCount > 0){

            r = getRequest(c);

            if( r != NULL ){
                TODO processRequest(r);
            }
        } else {
            printf("No requests to process\n");
        }
    }
    return 0;
}

Both server and client use openConnection to get the fd from the NamedPipe. openConnections calls this function and creates a Connection Object:

int * openNamedPipe(char * name) {
  char origin[] = "/tmp/";
  char myfifo[80];
  int * fd;
  fd = malloc(sizeof(int)*2);

  strcpy(myfifo,origin);
  strcat(myfifo,name);
  mkfifo(myfifo, 0777);

  fd[0] = open(myfifo, O_RDONLY|O_NONBLOCK);
  fcntl(fd[0], F_SETFL, fcntl(fd[0], F_GETFL) &~O_NONBLOCK);
  fd[1] = open(myfifo, O_WRONLY);

  return fd;
}

My questions are the following:

  • Is calling mkfifo() several times over the same pipe for each client a problem?
  • Same for opening/closing the pipe

I'm manually checking the fifo with cat, I'm able to read stuff from the shell. So if clients are able to write, the server should be able to read with the ReadOnly fd.

Adding setConnection function just in case:

void setConnection(Connection * connection, fd_set* set){
  FD_ZERO(set);
  FD_SET(connection -> np -> fd, set);
  return;
}
J. Nicastro
  • 254
  • 3
  • 11

1 Answers1

4

First parameter to selectshould be highest numbered file descriptor +1. You are passing value 2, so your select is only concerned about fds 0 and 1 (if they are set in the passed sets). Does your pipe really use those? If not, you need to test in the code which is the highest and pass that to select.

Another thing, seems like you should just pass NULL instead of that foo, if you don't want to watch those events.

hyde
  • 60,639
  • 21
  • 115
  • 176