Exemplo n.º 1
0
void keyboard(unsigned char key, int mouseX, int mouseY) {
	//printf("received char %c, value %d\n", key, key);
	if(EITHERCASE(key, 'q')){
	  master_cleanup();
		exit(0);
	}
		
	//if keys were pressed, redraw	
	glutPostRedisplay();
	return;
}
Exemplo n.º 2
0
/* Acquire or release the lock on the communication socket */
static int acquire_lock( int acquire )
{
   static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
   struct flock lock;

   lock.l_whence=SEEK_SET;
   lock.l_start=0;
   lock.l_len=0;

   if( acquire ) {
      if( pthread_mutex_lock(&mutex)!=0 )
      {
         /* The mutex is invalid. Assume we terminated */
         master_cleanup();

         return 0;
      }

      /* Acquire the fcntl lock on the socket. Need to retry in case of EINTR */
      lock.l_type=F_WRLCK;

      int res;
      while( (res=fcntl(COMM_SOCKET, F_SETLKW, &lock))!=0 && errno==EINTR )
         ;

      if( res!=0 )
         pthread_mutex_unlock(&mutex);

      return res==0;
   } else {
      /* Need to unlock, opposite order than locking */

      /* Release the fcntl lock */
      lock.l_type=F_UNLCK;
      int res;

      while( (res=fcntl(COMM_SOCKET, F_SETLKW, &lock))!=0 && errno==EINTR )
         ;

      pthread_mutex_unlock(&mutex);

      return res==0;
   }
}
Exemplo n.º 3
0
int bind( int sockfd, const struct sockaddr *my_addr, socklen_t addrlen)
{
#ifdef SO_REUSEPORT
   // parse environment property (just once)
   if (reuse_ports.count < 0){
     char *env_reuse = getenv("PRIVBIND_REUSE_PORTS");
     if (env_reuse == NULL){
       reuse_ports.count = 0;
     }else{
       if (parselist(env_reuse, &reuse_ports, 1, 65535) != 0){
         reuse_ports.count = -1;
         return -1;
       }
     }
   }
   
   // get bind port
   int port = -1;
   if (my_addr->sa_family==AF_INET)
      port = (int) ntohs(((struct sockaddr_in *) my_addr)->sin_port);
   else if (my_addr->sa_family==AF_INET6)
      port = (int) ntohs(((struct sockaddr_in6 *) my_addr)->sin6_port);
   
   // check if we should setup SO_REUSEPORT for this port
   if (port != -1 && is_in_list(&reuse_ports, port)){
      int optval = 1;
      int retval = setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
      if (retval != 0)
        return retval;
   }
#endif
  
   /* First of all, attempt the bind. We only need the socket if it fails with access denied */

   int oret=_bind( sockfd, my_addr, addrlen );
   if( oret==0 || errno!=EACCES )
      return oret;

   /* In most cases, we can let the bind go through as is */
   if( master_quit || (my_addr->sa_family!=AF_INET && my_addr->sa_family!=AF_INET6) 
       || (my_addr->sa_family==AF_INET && addrlen<sizeof(struct sockaddr_in)) 
       || (my_addr->sa_family==AF_INET6 && addrlen<sizeof(struct sockaddr_in6))  
     ) { 
      errno=EACCES;
      return oret;
   }

   /* Prepare the ancillary data for passing the actual FD */
   struct msghdr msghdr={.msg_name=NULL};
   struct cmsghdr *cmsg;
   char buf[CMSG_SPACE(sizeof(int))];
   int *fdptr;

    msghdr.msg_control=buf;
    msghdr.msg_controllen=sizeof(buf);

    cmsg=CMSG_FIRSTHDR(&msghdr);
    cmsg->cmsg_level=SOL_SOCKET;
    cmsg->cmsg_type=SCM_RIGHTS;
    cmsg->cmsg_len=CMSG_LEN(sizeof(int));

    /* Initialize the payload */
    fdptr=(int *)CMSG_DATA(cmsg);
    fdptr[0]=sockfd;
    msghdr.msg_controllen=cmsg->cmsg_len;

    /* Don't forget the data component */
    struct ipc_msg_req request;
    struct iovec iov;

    msghdr.msg_iov=&iov;
    msghdr.msg_iovlen=1;

    iov.iov_base=&request;
    iov.iov_len=sizeof(request);

    request.type=MSG_REQ_BIND;

    /* Check family of the request, only INET and INET6 should make it here */
    if (my_addr->sa_family==AF_INET)
      request.data.bind4.addr=*(struct sockaddr_in *) my_addr;
    else if (my_addr->sa_family==AF_INET6)
      request.data.bind6.addr=*(struct sockaddr_in6 *) my_addr;

    int retval=oret;

    if( acquire_lock(1) ) {
       if( sendmsg( COMM_SOCKET, &msghdr, MSG_NOSIGNAL )>0 ) {
          /* Request was sent - wait for reply */
          struct ipc_msg_reply reply;

          if( recv( COMM_SOCKET, &reply, sizeof(reply), 0 )>0 ) {
             retval=reply.data.stat.retval;
             if( retval<0 )
                errno=reply.data.stat.error;
          } else {
             /* It would appear that the other process has closed, just return the original retval */
             master_cleanup();
          }
       } else {
          /* An error has occured! */
          if( errno==EPIPE || errno==ENOTCONN || errno==EBADF ) {
             master_cleanup();
          } else {
             perror("privbind communication socket error");
             master_cleanup();
          }
       }

       acquire_lock(0);
    }

    /* Make sure we return the original errno, regardless of what caused us to fail */
    if( retval!=0 )
        errno=EACCES;

    return retval;
}