Exemplo n.º 1
0
void select_call::prepare_to_poll()
{
	/* 
	 * Create copies of all sets and zero out the originals.
	 * This is needed because polling might be successful.
	 * 
	 * If the read set is zero, use the local copy every time.
	 * This is OK because it will hold only the CQ, and wait()
	 * clears the CQ from the set after orig_select() call.
	 * 
	 * m_readfds is non-NULL here because there are offloaded sockets.
	 */

	// copy sets, and zero out the originals
	if (m_readfds) {
		FD_COPY(&m_orig_readfds, m_readfds, m_nfds);
		FD_ZERO(m_readfds, m_nfds);
	}

	if (m_writefds) {
		FD_COPY(&m_orig_writefds, m_writefds, m_nfds);
		FD_ZERO(m_writefds, m_nfds);
	}
	if (m_exceptfds) {
		FD_COPY(&m_orig_exceptfds, m_exceptfds, m_nfds);
		FD_ZERO(m_exceptfds, m_nfds);
	}
	m_b_run_prepare_to_poll = true;
}
Exemplo n.º 2
0
Arquivo: events.c Projeto: pikpik/Msg
int listening ( void ) {
	
	debug();
	
	
	FD_COPY ( & listeningToRead, & listenersCanRead );
	
	FD_COPY ( & listeningToWrite, & listenersCanWrite );
	
	FD_COPY ( & listeningForFailure, & listenersHaveFailed );
	
	
	//struct timeval timeout;
	
	//timeout.tv_sec = 2;
	
	
	int result = select (
		
		getHighestFileDescriptor () + 1,
		
		& listenersCanRead,
		
		& listenersCanWrite,
		
		& listenersHaveFailed,
		
		NULL //& timeout
		
	);
	
	
	if ( result < 0 ) {
		
		error ( __FILE__ );
		
		stillListening = false;
		
	}
	
	
	for (
		
		int listener = 0;
		
		listener < numberOfListeners;
		
		listener++
		
	)	recognize ( listener );
	
	
	return stillListening;
	
}
Exemplo n.º 3
0
int
SockSelect (double timeout, char *flags)
{
  int r;
  fd_set readfds;
  struct timeval tv, *tvp;

#ifdef USE_BCOPY
  if (bcmp (&readable, &zero, sizeof (zero)))
    return 1;
#else
  if (memcmp (&readable, &zero, sizeof (zero)))
    return 1;
#endif
  if (timeout < 0.0)
    tvp = 0;
  else
    {
      tv.tv_sec = timeout;
      tv.tv_usec = (timeout - tv.tv_sec) * 1e+6;
      tvp = &tv;
    }
  FD_COPY (&fds, &readfds);
  r = select (max_sd + 1, &readfds, (fd_set *) 0, (fd_set *) 0, tvp);
  return r;
}
Exemplo n.º 4
0
void netClientReadBinary(netClient *client, void *base, int *cnt, int timeout)
{
	fd_set selectSet;
	fd_set copySet;
	
	FD_ZERO(&selectSet);
	FD_SET(client->m_socket, &selectSet);
	
	int bufferSize = *cnt;
	*cnt = 0;
	
	FD_COPY(&selectSet, &copySet);
	
	struct timeval to;
	to.tv_sec = timeout;
	to.tv_usec = 0;
	
	int sel = select(client->m_socket+1, &copySet, NULL, NULL, &to);
	
	if (sel == -1)
		errorRaise(error_net, "Network error while waiting for data");
	
	if (sel != 0)
	{
		*cnt = read(client->m_socket, base, bufferSize);
		//printf(" [%i/%i] ", bufferSize, *cnt);
	}
	
	if (*cnt == -1)
		errorRaise(error_net, "Network error while reading data");
}
Exemplo n.º 5
0
bool select_call::wait_os(bool zero_timeout)
{
	timeval to, *pto = NULL;
	timespec to_pselect, *pto_pselect = NULL;
	
/* Avner: I put it in comment, because this logic is wrong

	// optimization: do not call os select if ALL fds are excluded
	// extend check to write/except fds
	if (m_rfd_count == m_n_exclude_fds)
		return;
*/
	
	if (zero_timeout) {
		to.tv_sec = to.tv_usec = 0;
		pto = &to;
	}
	else {
		pto = m_timeout;
	}

	// Restore original sets
	if (m_b_run_prepare_to_poll) {
		if (m_readfds)	FD_COPY(m_readfds, &m_os_rfds, m_nfds);
		if (m_writefds)	FD_COPY(m_writefds, &m_os_wfds, m_nfds);
		if (m_exceptfds)FD_COPY(m_exceptfds, &m_orig_exceptfds, m_nfds);
	}
	__log_func("calling os select: %d", m_nfds);
	if (m_sigmask) {
		if (pto) {
			to_pselect.tv_sec = pto->tv_sec;
			to_pselect.tv_nsec = pto->tv_usec * 1000;
			pto_pselect = &to_pselect;
		}
		m_n_all_ready_fds = orig_os_api.pselect(m_nfds, m_readfds, m_writefds, m_exceptfds, pto_pselect, m_sigmask);
	} else {
		m_n_all_ready_fds = orig_os_api.select(m_nfds, m_readfds, m_writefds, m_exceptfds, pto);
	}
	if (m_n_all_ready_fds < 0) {
		vma_throw_object(io_mux_call::io_error);
	}
	if (m_n_all_ready_fds > 0) {
		__log_func("wait_os() returned with %d", m_n_all_ready_fds);
	}
	return false; // No cq_fd in select() event
}
Exemplo n.º 6
0
Arquivo: test.cpp Projeto: happyj/qcn
bool writePipeState(const int iSeconds = 0, const int iMicroSeconds = 0)
{
   if (fdPipe[PIPE_STATE] == -1) return false;

   struct timeval tvTimeout; // timeout value for the select
   tvTimeout.tv_sec = iSeconds;
   tvTimeout.tv_usec = 0;

   FDSET_GROUP fdsCopy; // FDSET_GROUP is a struct taken from boinc/lib/network.h
   FD_COPY(&(fdsWatch.read_fds), &(fdsCopy.read_fds));
   FD_COPY(&(fdsWatch.write_fds), &(fdsCopy.write_fds));
   FD_COPY(&(fdsWatch.exc_fds), &(fdsCopy.exc_fds));
   fdsCopy.max_fd = fdsWatch.max_fd;

   // write the results to the sensor pipe, i.e. if sensor was found or not
   if (FD_ISSET(fdPipe[PIPE_STATE], &fdsWatch.write_fds)) {
     if (select(fdsCopy.max_fd+1, NULL, &(fdsCopy.write_fds), NULL,
       iSeconds > 0 || iMicroSeconds > 0 ? &tvTimeout : NULL) < 0) { // check the write fs (PIPE_STATE)
          fprintf(stderr, "writePipeState Level 0\n");
          return false;
     }
     // which file descriptors are ready to be read from?
     if (FD_ISSET(fdPipe[PIPE_STATE], &fdsCopy.write_fds)) {
         // file is ready to be written to
         // now write this sensor information
         int retval = write(fdPipe[PIPE_STATE], tsm, sizeof(CQCNUSBState));
         if (retval < 0) { // pipe error
            fprintf(stderr, "writePipeState Level 1\n");
            return false;
         }
         else if (!retval) { //pipe has been closed
            fprintf(stderr, "writePipeState Level 2\n");
            return false;
         }
         //else { // bytes were written to the pipe OK
         //}
     }
     else { // something wrong, just return
         fprintf(stderr, "writePipeState Level 3\n");
         return false;
     }
   }
   return true;  // must have written OK
}
Exemplo n.º 7
0
void	run_clt(char **av)
{
	t_env	e;

	if ((e.my_sock = create_clt(av[1], ft_atoi(av[2]))) != -1)
	{
		init_clt(&e);
		while (my_exit(1, NULL) != 1)
		{
			FD_COPY(&e.fd_read, &e.fd_read_cpy);
			FD_COPY(&e.fd_write, &e.fd_write_cpy);
			do_select(&e);
			check_actions(&e);
			FD_ZERO(&e.fd_read_cpy);
			FD_ZERO(&e.fd_write_cpy);
		}
		close(e.my_sock);
	}
}
Exemplo n.º 8
0
Arquivo: test.cpp Projeto: happyj/qcn
bool readPipeSensor(const int iSeconds = 0, const int iMicroSeconds = 0)
{
   if (fdPipe[PIPE_SENSOR] == -1) return false;

   struct timeval tvTimeout; // timeout value for the select
   tvTimeout.tv_sec = iSeconds;
   tvTimeout.tv_usec = iMicroSeconds;

   FDSET_GROUP fdsCopy; // FDSET_GROUP is a struct taken from boinc/lib/network.h
   FD_COPY(&(fdsWatch.read_fds), &(fdsCopy.read_fds));
   FD_COPY(&(fdsWatch.write_fds), &(fdsCopy.write_fds));
   FD_COPY(&(fdsWatch.exc_fds), &(fdsCopy.exc_fds));
   fdsCopy.max_fd = fdsWatch.max_fd;

   // write the results to the sensor pipe, i.e. if sensor was found or not
   if (FD_ISSET(fdPipe[PIPE_SENSOR], &fdsWatch.read_fds)) {
     if (select(fdsCopy.max_fd+1, &(fdsCopy.read_fds), NULL, NULL,
       iSeconds > 0 || iMicroSeconds > 0 ? &tvTimeout : NULL) < 0) { // check the write fs (PIPE_STATE)
          fprintf(stderr, "readPipeSensor Level 0\n");
          return false;
     }

     // which file descriptors are ready to be read from?
     if (FD_ISSET(fdPipe[PIPE_SENSOR], &fdsCopy.read_fds)) {
        //file is ready to be read from
        int retval = read(fdPipe[PIPE_SENSOR], tsm, sizeof(CQCNUSBSensor));
        if (retval < 0) { // pipe error
           fprintf(stderr, "readPipeSensor Level 1\n");
           return false;
        }
        else if (!retval) { //pipe has been closed
           //remove the closed pipe from the set
           fprintf(stderr, "readPipeSensor Level 2\n");
           return false;
        }
     }
     else { // something wrong, just return
       fprintf(stderr, "readPipeSensor Level 3\n");
       return false;
     }
   }
   return true;  // must have read OK
}
Exemplo n.º 9
0
void Reactor::check_selects()
{
    fd_set read_filedescriptors;
    fd_set write_filedescriptors;
    fd_set error_filedescriptors;
    FD_COPY(&this->read_filedescriptors,
            &read_filedescriptors);
    FD_COPY(&this->write_filedescriptors,
            &write_filedescriptors);
    FD_COPY(&this->error_filedescriptors,
            &error_filedescriptors);
    timeval timeout;
    timeout.tv_sec = 0;
    timeout.tv_usec = select_timeval * 1000000;
    if (select(0,
               &read_filedescriptors,
               &write_filedescriptors,
               &error_filedescriptors,
               &timeout) > 0)
    {
    }
}
Exemplo n.º 10
0
bool mainLoop(int argc, char **argv)
{
  const char *port = PORT;
  int backlog = BACKLOG;
  int bufferSize = BUFFER_SIZE;
  bool interactive = INTERACTIVE;
  args_param_t args_param_list[] =
  {
    {"-p",            &port,        argsString },
    {"--port",        &port,        argsString },
    {"-b",            &backlog,     argsInteger },
    {"--backlog",     &backlog,     argsInteger },
    {"-B",            &bufferSize,  argsInteger },
    {"--buffer",      &bufferSize,  argsInteger },
    {"-i",            &interactive, argsBoolTrue },
    {"--interactive", &interactive, argsBoolTrue },
    {"-d",            &interactive, argsBoolFalse },
    {"--daemon",      &interactive, argsBoolFalse },
    ARGS_DONE
  };
  argsProcess(argc, argv, args_param_list);

  int socket = -1;
  fd_set socketSet;

  bool success = true;
  success = success && socketOpen(port, backlog, &socket);
  success = success && socketSetInitialize(socket, &socketSet, interactive);
  if (success) {
    infof("Message buffer size set to %d.", bufferSize);
  }

  // main loop
  int maxSocket = socket;
  success = success && protocolInit(socket, &socketSet, maxSocket, bufferSize);
  bool done = !success; // skip loop on error
  while (!done) {
    fd_set readSocketSet;
    FD_COPY(&socketSet, &readSocketSet);
    success = success && socketSelect(maxSocket, &readSocketSet);
    for (int s = 0; !done && s <= maxSocket; s++) {
      if (FD_ISSET(s, &readSocketSet)) {
        if (s == socket) {
          socketConnectionNew(s, &maxSocket, &socketSet, bufferSize); // failure is not terminal
        }
        else if (STDIN_FILENO == s) {
          // system control
          done = localControl(s, &socketSet, maxSocket, bufferSize);
        }
        else {
          // existing connection
          protocolUpdate(s, &socketSet, maxSocket, bufferSize); // failure is not terminal
        }
      }
    }
    done = done || !success;
  }
  protocolCleanup(socket, &socketSet, maxSocket, bufferSize); // always

  close(socket);

  return done;
}
Exemplo n.º 11
0
int
main(int argc, char *argv[])
{
	int err;
	int nfds;
	int socketfd;

        db_t db;
        db_option_t option;

	fd_set readfds;
	fd_set writefds;

	char *dbfilename;
	char *idxfilename;

	struct addrinfo hints, *ai, *p;

	if (argc == 2) {
		dbfilename  = argv[1];
		idxfilename = NULL;
	} else if (argc != 3) {
		dbfilename  = argv[1];
		idxfilename = argv[2];
	} else {
		fprintf(stderr, "usage: %s dbfile [indexfile]\n", argv[0]);

		return 0;
	}

	memset(&hints, 0, sizeof(hints));
	
	hints.ai_family   = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags    = AI_PASSIVE;

	if ((err = getaddrinfo(NULL, PORT, &hints, &ai)) != 0) {
		fprintf(stderr, "db-server: getaddrinfo: %s\n", gai_strerror(err));

		exit(1);
	}

	for (p = ai; p != NULL; p = p->ai_next) {
		int optval = 1;

		socketfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
		if (socketfd == -1) {
			fprintf(stderr, "db-server: socket: %s\n", gai_strerror(err));

			continue;
		}
		if (fcntl(socketfd, F_SETFL, O_NONBLOCK) == -1) {
			fprintf(stderr, "db-server: fcntl NONBLOCK: %s\n", strerror(errno));

			continue;
		}

		if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) {
			fprintf(stderr, "db-server: setsockopt REUSEADDR: %s\n", strerror(errno));

			continue;
		}

		if (bind(socketfd, p->ai_addr, p->ai_addrlen) < 0) {
			fprintf(stderr, "db-server: bind: %s\n", strerror(errno));

			close(socketfd);

			continue;
		}
		break;
	}

	if (p == NULL) {
		fprintf(stderr, "db-server: failed to bind: %s\n", PORT);
		exit(1);
	}

	freeaddrinfo(ai);

        option.table  = 256;
        option.bucket = 256;
        option.rdonly = 0;
        if (db_open(&db, dbfilename, idxfilename, &option) != DB_OK) {
                fprintf(stderr, "db-server: open db %s failed\n", dbfilename);

                exit(0);
        }

	if (listen(socketfd, 32) == -1) {
		fprintf(stderr, "db-server: listen: %s\n", strerror(errno));

		exit(1);
	}

	FD_ZERO(&readfds);
	FD_ZERO(&writefds);

	nfds = socketfd;
	FD_SET(socketfd, &readfds);

	inbuf  = malloc(INBUF_LEN);
	outbuf = malloc(OUTBUF_LEN);
	valbuf = malloc(VALBUF_LEN);

	for (;;) {
		int n;
		int fd;
		fd_set readfds_;
		fd_set writefds_;

		FD_ZERO(&readfds_);
		FD_ZERO(&writefds_);

#ifdef LINUX
		memcpy(&readfds_, &readfds, sizeof(readfds));
		memcpy(&writefds_, &writefds, sizeof(writefds));
#else
		FD_COPY(&readfds, &readfds_);
		FD_COPY(&writefds, &writefds_);
#endif

		if ((n = select(nfds + 1, &readfds_, &writefds_, NULL, NULL)) == -1) {
			fprintf(stderr, "db-server: select: %s\n", strerror(errno));

			exit(1);
		}

		for (fd = 0; fd <= nfds && n > 0; fd++) {
			if (FD_ISSET(fd, &writefds_)) {
				n--;
				handle_write(fd, &readfds, &writefds);
			}

			if (FD_ISSET(fd, &readfds_)) {
				n--;
				if (fd == socketfd) {
					int acceptfd;

					acceptfd = handle_accept(fd, &readfds, &writefds);
					if (acceptfd > nfds) {
						nfds = acceptfd;
					}
				} else {
					err = handle_read(fd, &db, &readfds, &writefds);
					if (err == -1 && fd >= nfds) {
						nfds = fd;
						while (FD_ISSET(nfds, &readfds)  == 0 &&
						       FD_ISSET(nfds, &writefds) == 0)
						{
							nfds--;
						}
					}
				}
			}
		}
	}
	free(inbuf);
	free(outbuf);
	free(valbuf);

	return 0;
}
Exemplo n.º 12
0
 	int main (int argc,char *argv[])

 	{
 		int sockfd, n, newsockfd, childpid, servlen,fin, i, tab[FD_SETSIZE], nbfd, maxfd, sockcli;
 		struct sockaddr_in  serv_addr, cli_addr;
 		socklen_t clilen;
 		fd_set rset, pset;


 /* Verifier le nombre de paramètre en entrée */
 		if (argc != 2){
 			usage();
 			exit(1);}


	/*
	 * Ouvrir une socket (a TCP socket)
	 */
	 if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) <0) {
	 	perror("servmulti : Probleme socket\n");
	 	exit (2);
	 }

	 
	/*
	 * Lier l'adresse  locale à la socket
	 */
	 memset( (char*) &serv_addr,0, sizeof(serv_addr) );
	 serv_addr.sin_family = PF_INET;
	 serv_addr.sin_addr.s_addr = htonl (INADDR_ANY);
	 serv_addr.sin_port = htons(atoi(argv[1]));
	 maxfd = sockfd+1;
	 
	 if (bind(sockfd,(struct sockaddr *)&serv_addr, sizeof(serv_addr) ) <0) {
	 	perror ("servmulti : erreur bind\n");
	 	exit (1);
	 }

	/* Paramètrer le nombre de connexion "pending" */
	 if (listen(sockfd, SOMAXCONN) <0) {
	 	perror ("servmulti : erreur listen\n");
	 	exit (1);
	 }
	 for(i = 0; i < FD_SETSIZE; i++){
	 	tab[i] = -1;
	 }
	 FD_ZERO(&rset);
	 FD_ZERO(&pset);
	 FD_SET(sockfd, &rset);

	 for (;;) {
	 	FD_COPY(&rset,&pset);
	 	nbfd = select(maxfd, &pset, NULL, NULL, NULL);
	 	if (nbfd  < 0){
	 		perror("servmulti : erreur select");
	 	}
	 	
 		if(FD_ISSET(sockfd, &pset)){
 			
	 			/*Tentative de connection*/
 				clilen = sizeof(cli_addr);
 				newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,  &clilen);
 				if (newsockfd < 0) {
 					perror("servmulti : erreur accept\n");
 					exit (1);
 				}

 		}
 		i = 0;
 		while((i < FD_SETSIZE) && (tab[i] >= 0)) i ++;
 		if( i == FD_SETSIZE) exit(1);
 		tab[i] = newsockfd;
 		FD_SET(newsockfd, &rset);

		if(newsockfd >= maxfd){
			maxfd = newsockfd + 1;
		}
 		
 		i= 0;
 		while((nbfd > 0) && (i < FD_SETSIZE)){
 			if(((sockcli = tab[i]))>= 0 && (FD_ISSET(sockcli, &pset))){
 				if(str_echo(sockcli) == 0){
 					close(sockcli);
 					tab[i] = -1;
 					FD_CLR(sockcli, &rset);
 				}
 				nbfd --;
 			}
 			i++;
 		}
	 }
}
Exemplo n.º 13
0
void ZSocketWatcher::pRun()
	{
	ZGuardMtx guard(fMtx);
	for (;;)
		{
		if (fSet.empty())
			{
			// Nothing pending, wait 100ms in case something else comes along.
			fCnd.WaitFor(fMtx, 0.1);
			if (fSet.empty())
				{
				// Still nothing pending, exit thread.
				fThreadRunning = false;
				break;
				}
			}
		else
			{
			fd_set readSet;
			FD_ZERO(&readSet);
			int largest = 0;
			foreachi (ii, fSet)
				{
				const int theFD = ii->first;
				if (largest < theFD)
					largest = theFD;
				FD_SET(ii->first, &readSet);
				}

			fd_set exceptSet;
			FD_COPY(&readSet, &exceptSet);

			struct timeval timeout;
			timeout.tv_sec = 1;
			timeout.tv_usec = 0;

			guard.Release();

			int count = ::select(largest + 1, &readSet, nullptr, &exceptSet, &timeout);

			guard.Acquire();

			if (count < 1)
				{
				// Didn't get any
				continue;
				}

			// Gather the callables
			set<ZRef<ZCallable_Void> > toCall;

			for (int fd = 1; fd <= largest; ++fd)
				{
				if (FD_ISSET(fd, &readSet))
					{
					--count;
					if (FD_ISSET(fd, &exceptSet))
						--count;
					}
				else if (FD_ISSET(fd, &exceptSet))
					--count;
				else
					continue;

				const Set_t::iterator iterBegin = fSet.lower_bound(Pair_t(fd, null));
				Set_t::iterator iterEnd = iterBegin;
				const Set_t::iterator SetEnd = fSet.end();
				while (iterEnd->first == fd and iterEnd != SetEnd)
					{
					toCall.insert(iterEnd->second);
					++iterEnd;
					}
				fSet.erase(iterBegin, iterEnd);

				if (count <= 0)
					break;
				}

			guard.Release();
			foreachi (ii, toCall)
				{
				try { (*ii)->Call(); }
				catch (...) {}
				}
			guard.Acquire();
			}
		}
	}
Exemplo n.º 14
0
int main (int argc, char *argv[])
{
    int i=0;
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    for(i=0;i<2;i++){
        s[i] = socket(AF_INET, SOCK_STREAM, 0);
        addr.sin_port = htons(8080+i);
        fcntl(s[i], F_SETFL, O_NONBLOCK);
        int res = connect(s[i], (struct sockaddr*)&addr, sizeof(addr));

        if(res != -1){
            printf("Connect failed.\n");
            fflush(stdout);
            exit(1);
        }

        FD_SET(s[i],&readset);	
        FD_SET(s[i],&writeset);	
        FD_SET(s[i],&exceptionset);	
    }

    while(1){

        FD_COPY(&readset,&readset1);
        FD_COPY(&writeset,&writeset1);
        FD_COPY(&readset,&readset1);
        int rdy = select(FD_SETSIZE,&readset1,&writeset1,&exceptionset1,0);

        for(i=0;i<2;i++){
            if(FD_ISSET(s[i],&readset1)) {
                char buf[2048];
				int rec_count = recv(s[i],buf,255,0);
                printf("Readset for port %d---=%d bytes read\n", 8080+i, rec_count);
                if(rec_count==-1){
					shutdown(s[i],SHUT_RDWR);
					close(s[i]);						
					FD_CLR(s[i],&readset);
					FD_CLR(s[i],&writeset);
					FD_CLR(s[i],&exceptionset);
					printf("Connection closed.\n");
					continue;
                }
            }
            if(FD_ISSET(s[i],&writeset1)) {
                printf("Writeset for port %d\n", 8080+i);
                int status=0;
                char buf[2048]="Ritesh is the god of programming";
                status = send(s[i],buf,strlen(buf)+1,0);		
                if(status < 0)
                    printf("xxxxWriteset for port %d, send status = %d\n", 8080+i, status);
                printf("Writeset for port %d, send status = %d\n", 8080+i, status);
            }
            if(FD_ISSET(s[i],&exceptionset1)) {
                printf("Exceptionset for port %d\n", 8080+i);
            }
        }
    }
    
}/* main */
Exemplo n.º 15
0
Arquivo: jsio.c Projeto: atifs/juise
/*
 * Called initially after the process is forked.
 * This handles the initial error from process being emitted to stderr and
 * also handles the password prompt from ssh.
 */
static int
js_initial_read (js_session_t *jsp, time_t secs, long usecs)
{
    struct timeval tmo = { secs, usecs };
    fd_set rfds, xfds;
    int sin = jsp->js_stdin, serr = jsp->js_stderr, smax, rc;
    int askpassfd = jsp->js_askpassfd ?: jsio_askpass_socket;

    do {
	smax = MAX(sin, serr);

	if (askpassfd >= 0)
	    smax = MAX(smax, askpassfd);

	FD_ZERO(&rfds);
	FD_SET(sin, &rfds);
	if (serr >= 0)
	    FD_SET(serr, &rfds);

	if (askpassfd >= 0)
	    FD_SET(askpassfd, &rfds);

	FD_COPY(&rfds, &xfds);

	rc = select(smax + 1, &rfds, NULL, &xfds, &tmo);
	if (rc < 0) {
	    if (errno == EINTR)
		continue;
	    jsio_trace("error from rpc session: %m");
	    return -1;
	}

	if (rc == 0) {
	    if (secs)
		jsio_trace("timeout from rpc session");
	    return -1;
	}

	if (serr >= 0 && (FD_ISSET(serr, &rfds) || FD_ISSET(serr, &xfds))) {
	    char buf[BUFSIZ];

	    rc = read(serr, buf, sizeof(buf) - 1);
	    if (rc > 0) {
		buf[sizeof(buf) - 1] = '\0';
		jsio_trace("error from rpc session: %s", buf);
	    }
	}

	if (askpassfd >= 0 && FD_ISSET(askpassfd, &rfds)) {
	    if (askpassfd == jsio_askpass_socket) {
		askpassfd = js_ssh_askpass_accept(jsp);
	    } else {
		js_ssh_askpass(jsp, askpassfd);
		askpassfd = jsio_askpass_socket;
	    }
	}

    } while (!FD_ISSET(sin, &rfds));

    return 0;
}
Exemplo n.º 16
0
Arquivo: hw4.c Projeto: lfcmpi/UIC
int main(int argc, char **argv) {	
  int port;	
  if(argc==2) {
		port=atoi(argv[1]);
	}
	setlinebuf(stdout);	
	

	int server_sock = socket(AF_INET, SOCK_STREAM, 0);
	if(server_sock < 0) {
		perror("Creating socket failed: ");
		exit(1);
	}
	
	struct sockaddr_in addr; 	// internet socket address data structure
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port); // byte order is significant
	addr.sin_addr.s_addr = INADDR_ANY; // listen to all interfaces
	
	int res = bind(server_sock, (struct sockaddr*)&addr, sizeof(addr));
	if(res < 0) {
		perror("Error binding to port");
		exit(1);
	}

	int yes=1;
  if (setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
    perror("setsockopt");
    exit(1);
  }

	/* workaround for funny OS X bug - need to start listening without select */
	res=fcntl(server_sock, F_SETFL, O_NONBLOCK);
  if(res<0) { perror("fcntl"); } 
	if (listen (server_sock, 1) < 0) { perror ("listen"); exit(1); } 
	fcntl(server_sock, F_SETFL, 0);

	/* initializing data structure for select call */
	fd_set readset;
	FD_ZERO(&readset);
	FD_SET(server_sock,&readset);	

	while(1) {
		fd_set rdyset;
		FD_COPY(&readset,&rdyset);
		int rdy = select(FD_SETSIZE,&rdyset,0,0,0);

		/* if the server_sock has a new connection coming in, accept it */
		if(FD_ISSET(server_sock,&rdyset)) {
			int sock;
			struct sockaddr_in remote_addr;
			unsigned int socklen = sizeof(remote_addr); 
			
			sock = accept(server_sock, (struct sockaddr*)&remote_addr, &socklen);
			if(res < 0) { perror("Error accepting connection"); exit(1); }

			/* allocate and initialize new client state */
			struct client_state *state=
				(struct client_state*)malloc(sizeof(struct client_state));
			state->next=clients;
			if(clients)
				clients->prev=state;
			state->prev=0;
			state->message_count=0;
			clients=state;
			state->socket=sock;
			client_count++;

			// added
			sprintf(state->name,"Client %d",client_count);
			printf("Got connection (%s)\n",state->name);
			// added

			/* add new socket to fd_set for select */
			FD_SET(sock,&readset);
		}

		/* if any of the active clients are ready to deliver a message,
			 read it and print it */
		struct client_state *clstate = clients;
		while(clstate) {
			if(FD_ISSET(clstate->socket,&rdyset)) {
				char buf[255];
				memset(buf,0,255);
				int rec_count = recv(clstate->socket,buf,255,0);
				if(rec_count > 0) {
					clstate->message_count++;

					// added
					clstate->byte_count+=rec_count;
					handle_command(buf,clstate);
					// added
				}
				/* if we got nothing, that means the connection is closed */
				else {
					printf("closing connection...\n");
					if(clstate->prev == 0) {
						clients = clstate->next;
						if(clients)
							clients->prev = 0;
					}
					else {
						clstate->prev->next = clstate->next;						
						if(clstate->next) 
							clstate->next->prev = clstate->prev;
					}					
					client_count--;

					// tell the others
					char send_msg[255];
					sprintf(send_msg, "%s disconnected.\n", clstate->name);
					broadcast_msg(send_msg, clstate);
					printf("%s disconnected. A total of %d bytes received from %s.\n",clstate->name, clstate->byte_count, clstate->name);

					// clean up the rest of the state
					shutdown(clstate->socket,SHUT_RDWR);
					close(clstate->socket);						
					FD_CLR(clstate->socket,&readset);
					struct client_state *tofree = clstate;
					clstate = clstate->next;
					free(tofree);					
					continue;
				}
			} // end if(FD_ISSET...
			clstate=clstate->next;
		} // end while
	}
	shutdown(server_sock,SHUT_RDWR);
}
Exemplo n.º 17
0
void listen_from_peers() 
{
    struct peer_state* peer = peers;
    unsigned int msglen = 0;
    while(missing_blocks() > 0)
    {
        fd_set fdrset_clone;
        fd_set fdwset_clone;
        FD_COPY(&fdrset,&fdrset_clone);
        FD_COPY(&fdwset,&fdwset_clone);
        int rdy = select(FD_SETSIZE,&fdrset_clone,&fdwset_clone,0, 0);
        if(rdy <= 0) {
            continue;
        }
        peer = peers;
        if(active_peers() == 0){
            break;
        }
        while(peer){
        
            if(FD_ISSET(peer->socket,&fdwset_clone)){
                if(peer->connected == 0){
                    //to send the handshake if it is not connected
                    send_handshake(peer);
                }
                else if(peer->send_count > 0) {
                    //to send the have/interested/piece messages to peers
                    send_buffed_msg(peer);
                }
            }

            if(FD_ISSET(peer->socket,&fdrset_clone)) 
            {
                int newbytes = recv(peer->socket,peer->incoming+peer->count,BUFSIZE-peer->count,0);
                if(newbytes <= 0){ 
                    peer->trying_to_connect = 0;
                    if(newbytes == 0){
                        piece_status[peer->requested_piece] = PIECE_EMPTY;
                    }
                    disconnet_peer(peer);
                    reconnect_peer(peer);
                    peer = peer->next;
                    continue; 
                } 
                peer->count += newbytes;
                if(!peer->handshaked){                    
                    peer->count -= peer->incoming[0]+49;
                    if(peer->count) {
                        memmove(peer->incoming,peer->incoming + peer->incoming[0]+49,peer->count);
                    }
                    peer->handshaked = 1;
                }

               if(memcmp(peer->incoming+peer->incoming[0]+8+20,"-UICCS450-",strlen("-UICCS450-"))==0) {
                    fprintf(stderr,"Caught a CS450 peer, exiting.\n");
                    disconnet_peer(peer);
                    continue;
                }   

                while(peer->count >= (ntohl(((int*)peer->incoming)[0])) + 4){ 
                msglen = ntohl(((int*)peer->incoming)[0]);

                   switch(peer->incoming[4]) {
                        // CHOKE
                        case 0: {
                                    if(debug)
                                        fprintf(stderr,"Choke\n");
                                    peer->choked = 1;
                                    piece_status[peer->requested_piece]=PIECE_EMPTY;
                                    peer->requested_piece = -1;
                                    break;
                                }
                                // UNCHOKE
                        case 1: {
                                    if(debug)
                                        fprintf(stderr,"Unchoke\n");
                                    peer->choked = 0;
                                    peer->requested_piece = next_piece(-1,peer);    
                                    request_block(peer,peer->requested_piece,0);
                                    break;
                                }
                                //Interested
                        case 2: {
                                    //dev_notifier();
                                    send_choke_unchoke_msg(peer,0); //ischoked = 0
                                    peer->not_interested = 0;
                                    break;
                                }
                                //Not interested
                        case 3: {
                                    //dev_notifier();
                                    peer->not_interested = 1;
                                    break;
                                }
                                // HAVE -- update the bitfield for this peer
                        case 4: {
                                    int piece = ntohl(*((int*)&peer->incoming[5]));
                                    int bitfield_byte = piece/8;
                                    int bitfield_bit = piece%8;
                                    if(debug)
                                        fprintf(stderr,"Have %d\n",piece);

                                    peer->bitfield[bitfield_byte] |= 1 << (7 - bitfield_bit);
                                    piece_occurence_value[piece]++;
                                    send_interested(peer);
                                    break;
                                }
                                // BITFIELD -- set the bitfield for this peer
                        case 5:
                                //peer->choked = 0; //commenting it according to prof's note in class
                                if(debug) 
                                    printf("Bitfield of length %d\n",msglen-1);
                                int fieldlen = msglen - 1;
                                if(fieldlen != (file_length/piece_length/8+1)) {
                                    disconnet_peer(peer);
                                    if(active_peers() == 0){
                                        break;
                                    }
                                    peer = peer->next;
                                    continue;
                                }               
                                memcpy(peer->bitfield,peer->incoming+5,fieldlen);
                                read_bit_maps(peer->bitfield,fieldlen);
                                send_interested(peer);
                                break;
                                //Request piece
                        case 6: { 
                                if(peer->i_choked_it == 1) 
                                    break;
                                decode_request_send_piece_to_peer(peer);
                                }       
                                break;                         
                                // PIECE
                        case 7: {
                                    //make the tit for tatter
                                    peer->send_recv_balancer++;
                                    if(peer->i_choked_it && peer->send_recv_balancer == 0){
                                        peer->i_choked_it = 0;
                                        send_choke_unchoke_msg(peer,0); //unchoke peer
                                    }
                                    int piece = ntohl(*((int*)&peer->incoming[5]));
                                    int offset = ntohl(*((int*)&peer->incoming[9]));
                                    int datalen = msglen - 9;

                                    fprintf(stderr,"Writing piece %d, offset %d, ending at %d\n",piece,offset,piece*piece_length+offset+datalen);
                                    write_block(peer->incoming+13,piece,offset,datalen,1);
                                    draw_state();
                                    offset+=datalen;
                                    if(offset==piece_length || (piece*piece_length+offset == file_length) ) {
                                        broadcast_have_msg(piece);
                                        draw_state();
                                        if(debug) 
                                            fprintf(stderr,"Reached end of piece %d at offset %d\n",piece,offset);

                                        peer->requested_piece=next_piece(piece,peer);
                                        offset = 0;
                                    }
                                    request_block(peer,peer->requested_piece,offset);
                                    break;                                  
                                }
                    }
                    drop_message(peer);      
                }
            }
            peer = peer->next;
        }
    }
    return;
}
Exemplo n.º 18
0
bool select_call::wait(const timeval &elapsed)
{
	timeval timeout, *pto = NULL;
	timespec to_pselect, *pto_pselect = NULL;
	
	BULLSEYE_EXCLUDE_BLOCK_START
	if (m_n_all_ready_fds > 0) {
		__log_panic("wait() called when there are ready fd's!!!");
		// YossiE TODO make this and some more checks as debug assertions
		// In all functions
	}
	BULLSEYE_EXCLUDE_BLOCK_END

	// Restore original sets
	if (m_b_run_prepare_to_poll) {
		if (m_readfds)	FD_COPY(m_readfds, &m_os_rfds, m_nfds);
		if (m_writefds)	FD_COPY(m_writefds, &m_os_wfds, m_nfds);
		if (m_exceptfds)FD_COPY(m_exceptfds, &m_orig_exceptfds, m_nfds);
	}

	// Call OS select() on original sets + CQ epfd in read set
	if (m_readfds)
		FD_SET(m_cqepfd, m_readfds);
	if (m_timeout) {
		tv_sub(m_timeout, &elapsed, &timeout);
		if (timeout.tv_sec < 0 || timeout.tv_usec < 0) {
			// Already reached timeout
			return false;
		}
		pto = &timeout;
	}

	__log_func("going to wait on select CQ+OS nfds=%d cqfd=%d pto=%p!!!", m_nfds_with_cq, m_cqepfd, pto);

	// ACTUAL CALL TO SELECT
	if (m_sigmask) {
		if (pto) {
			to_pselect.tv_sec = pto->tv_sec;
			to_pselect.tv_nsec = pto->tv_usec * 1000;
			pto_pselect = &to_pselect;
		}
		m_n_all_ready_fds = orig_os_api.pselect(m_nfds, m_readfds, m_writefds, m_exceptfds, pto_pselect, m_sigmask);
	} else {
		m_n_all_ready_fds = orig_os_api.select(m_nfds_with_cq, m_readfds, m_writefds, m_exceptfds, pto);
	}
	__log_func("done select CQ+OS nfds=%d cqfd=%d pto=%p ready=%d!!!", m_nfds_with_cq, m_cqepfd, pto, m_n_all_ready_fds);
	if (m_n_all_ready_fds < 0) {
		vma_throw_object(io_mux_call::io_error);
	}

	// Clear CQ from the set and don't count it
	if (m_readfds)
	{
		if (FD_ISSET(m_cqepfd, m_readfds)) {
			FD_CLR(m_cqepfd, m_readfds); // Not needed if m_readfds is NULL
			--m_n_all_ready_fds;
			return true;
		}
	}
	return false;
}
Exemplo n.º 19
0
int
main(int argc, char **argv)
{
	int	i, c, maxfd, rval, qpsock, fd;
	fd_set	fds, rfds;
	FILE	*fp, *client[MAX_CLIENT];

	m_debug = 0;
	l_debug = LOG_INFO;
	fp = NULL;
	for (i = 0; i < MAX_CLIENT; i++)
		client[i] = NULL;

	while ((c = getopt(argc, argv, "f:vdl:")) != -1) {
		switch (c) {
		case 'f':
			altqconfigfile = optarg;
			break;
		case 'v':
			l_debug = LOG_DEBUG;
			m_debug |= DEBUG_ALTQ;
			daemonize = 0;
			break;
		case 'd':
			daemonize = 0;
			break;
		case 'l':
			l_debug = atoi(optarg);
			break;
		default:
			usage();
		}
	}

	signal(SIGINT, sig_handler);
	signal(SIGTERM, sig_handler);
	signal(SIGHUP, sig_handler);
	signal(SIGPIPE, sig_handler);

	if (daemonize)
		openlog("altqd", LOG_PID, LOG_DAEMON);

	if (qcmd_init() != 0) {
		if (daemonize)
			closelog();
		exit(1);
	}

	/*
	 * open a unix domain socket for altqd clients
	 */
	if ((qpsock = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0)
		LOG(LOG_ERR, errno, "can't open unix domain socket");
	else {
		struct sockaddr_un addr;

		bzero(&addr, sizeof(addr));
		addr.sun_family = AF_LOCAL;
		strlcpy(addr.sun_path, QUIP_PATH, sizeof(addr.sun_path));
		unlink(QUIP_PATH);
		if (bind(qpsock, (struct sockaddr *)&addr,
		    sizeof(addr)) < 0) {
			LOG(LOG_ERR, errno, "can't bind to %s", QUIP_PATH);
			close(qpsock);
			qpsock = -1;
		}
		chmod(QUIP_PATH, 0666);
		if (listen(qpsock, SOMAXCONN) < 0) {
			LOG(LOG_ERR, errno, "can't listen to %s", QUIP_PATH);
			close(qpsock);
			qpsock = -1;
		}
	}

	if (daemonize) {
		daemon(0, 0);

		/* save pid to the pid file (/var/tmp/altqd.pid) */
#ifdef __FreeBSD__
		{
			FILE *fp;

			if ((fp = fopen(ALTQD_PID_FILE, "w")) != NULL) {
				fprintf(fp, "%d\n", getpid());
				fclose(fp);
			} else
				LOG(LOG_WARNING, errno, "can't open pid file");
		}
#else
		pidfile(NULL);
#endif
	} else {
		/* interactive mode */
		fp = stdin;
		printf("\nEnter ? or command:\n");
		printf("altqd %s> ", cur_ifname());
		fflush(stdout);
	}

	/*
	 * go into the command mode.
	 */
	FD_ZERO(&fds);
	maxfd = 0;
	if (fp != NULL) {
	    fd = fileno(fp);
	    if (fd == -1)
		    LOG(LOG_ERR, 0, "bad file descriptor", QUIP_PATH);
	} else
		fd = -1;

	if (fd != -1) {
		FD_SET(fd, &fds);
		maxfd = MAX(maxfd, fd + 1);
	}
	if (qpsock >= 0) {
		FD_SET(qpsock, &fds);
		maxfd = MAX(maxfd, qpsock + 1);
	}

	rval = 1;
	while (rval) {
		if (gotsig_hup) {
			qcmd_destroyall();
			gotsig_hup = 0;
			LOG(LOG_INFO, 0, "reinitializing altqd...");
			if (qcmd_init() != 0) {
				LOG(LOG_INFO, 0, "reinitialization failed");
				break;
			}
		}
		if (gotsig_term || gotsig_int) {
			LOG(LOG_INFO, 0, "Exiting on signal %d",
			    gotsig_term ? SIGTERM : SIGINT);
			break;
		}

		FD_COPY(&fds, &rfds);
		if (select(maxfd, &rfds, NULL, NULL, NULL) < 0) {
			if (errno != EINTR)
				err(1, "select");
			continue;
		}

		/*
		 * if there is command input, read the input line,
		 * parse it, and execute.
		 */
		if (fp && FD_ISSET(fd, &rfds)) {
			rval = do_command(fp);
			if (rval == 0) {
				/* quit command or eof on input */
				LOG(LOG_INFO, 0, "Exiting.");
			} else if (fp == stdin)
				printf("altqd %s> ", cur_ifname());
			fflush(stdout);
		} else if (qpsock >= 0 && FD_ISSET(qpsock, &rfds)) {
			/*
			 * quip connection request from client via unix
			 * domain socket; get a new socket for this
			 * connection and add it to the select list.
			 */
			int newsock = accept(qpsock, NULL, NULL);

			if (newsock == -1) {
				LOG(LOG_ERR, errno, "accept");
				continue;
			}
			FD_SET(newsock, &fds);
			for (i = 0; i < MAX_CLIENT; i++)
				if (client[i] == NULL) {
					client[i] = fdopen(newsock, "r+");
					break;
				}
			maxfd = MAX(maxfd, newsock + 1);
		} else {
			/*
			 * check input from a client via unix domain socket
			 */
			for (i = 0; i < MAX_CLIENT; i++) {
				int fd1;

				if (client[i] == NULL)
					continue;
				fd1 = fileno(client[i]);
				if (FD_ISSET(fd1, &rfds)) {
					if (quip_input(client[i]) != 0 ||
					    fflush(client[i]) != 0) {
						/* connection closed */
						fclose(client[i]);
						client[i] = NULL;
						FD_CLR(fd1, &fds);
					}
				}
			}
		}
	}

	/* cleanup and exit */
	qcmd_destroyall();
	if (qpsock >= 0)
		(void)close(qpsock);
	unlink(QUIP_PATH);

	for (i = 0; i < MAX_CLIENT; i++)
		if (client[i] != NULL)
			(void)fclose(client[i]);
	if (daemonize) {
#ifdef __FreeBSD__
		/* if we have a pid file, remove it */
		unlink(ALTQD_PID_FILE);
#endif
		closelog();
	}
	exit(0);
}
Exemplo n.º 20
0
int
main(int argc, char **argv)
{
	int ch_options, errs, f, funix, *finet, i, lfd, socket_debug;
	fd_set defreadfds;
	struct sockaddr_un un, fromunix;
	struct sockaddr_storage frominet;
	socklen_t fromlen;
	sigset_t omask, nmask;
	struct servent *sp, serv;
	int inet_flag = 0, inet6_flag = 0;

	euid = geteuid();	/* these shouldn't be different */
	uid = getuid();

	ch_options = 0;
	socket_debug = 0;
	gethostname(local_host, sizeof(local_host));

	progname = "lpd";

	if (euid != 0)
		errx(EX_NOPERM,"must run as root");

	errs = 0;
	while ((i = getopt(argc, argv, "cdlpswW46")) != -1)
		switch (i) {
		case 'c':
			/* log all kinds of connection-errors to syslog */
			ch_options |= LPD_LOGCONNERR;
			break;
		case 'd':
			socket_debug++;
			break;
		case 'l':
			lflag++;
			break;
		case 'p':		/* letter initially used for -s */
			/*
			 * This will probably be removed with 5.0-release.
			 */
			/* FALLTHROUGH */
		case 's':		/* secure (no inet) */
			sflag++;
			break;
		case 'w':		/* netbsd uses -w for maxwait */
			/*
			 * This will be removed after the release of 4.4, as
			 * it conflicts with -w in netbsd's lpd.  For now it
			 * is just a warning, so we won't suddenly break lpd
			 * for anyone who is currently using the option.
			 */
			syslog(LOG_WARNING,
			    "NOTE: the -w option has been renamed -W");
			syslog(LOG_WARNING,
			    "NOTE: please change your lpd config to use -W");
			/* FALLTHROUGH */
		case 'W':
			/* allow connections coming from a non-reserved port */
			/* (done by some lpr-implementations for MS-Windows) */ 
			ch_options |= LPD_NOPORTCHK;
			break;
		case '4':
			family = PF_INET;
			inet_flag++;
			break;
		case '6':
#ifdef INET6
			family = PF_INET6;
			inet6_flag++;
#else
			errx(EX_USAGE, "lpd compiled sans INET6 (IPv6 support)");
#endif
			break;
		/*
		 * The following options are not in FreeBSD (yet?), but are
		 * listed here to "reserve" them, because the option-letters
		 * are used by either NetBSD or OpenBSD (as of July 2001).
		 */ 
		case 'b':		/* set bind-addr */
		case 'n':		/* set max num of children */
		case 'r':		/* allow 'of' for remote ptrs */
					/* ...[not needed in freebsd] */
			/* FALLTHROUGH */
		default:
			errs++;
		}
	if (inet_flag && inet6_flag)
		family = PF_UNSPEC;
	argc -= optind;
	argv += optind;
	if (errs)
		usage();

	if (argc == 1) {
		if ((i = atoi(argv[0])) == 0)
			usage();
		if (i < 0 || i > USHRT_MAX)
			errx(EX_USAGE, "port # %d is invalid", i);

		serv.s_port = htons(i);
		sp = &serv;
		argc--;
	} else {
		sp = getservbyname("printer", "tcp");
		if (sp == NULL)
			errx(EX_OSFILE, "printer/tcp: unknown service");
	}

	if (argc != 0)
		usage();

	/*
	 * We run chkprintcap right away to catch any errors and blat them
	 * to stderr while we still have it open, rather than sending them
	 * to syslog and leaving the user wondering why lpd started and
	 * then stopped.  There should probably be a command-line flag to
	 * ignore errors from chkprintcap.
	 */
	{
		pid_t pid;
		int status;
		pid = fork();
		if (pid < 0) {
			err(EX_OSERR, "cannot fork");
		} else if (pid == 0) {	/* child */
			execl(_PATH_CHKPRINTCAP, _PATH_CHKPRINTCAP, (char *)0);
			err(EX_OSERR, "cannot execute %s", _PATH_CHKPRINTCAP);
		}
		if (waitpid(pid, &status, 0) < 0) {
			err(EX_OSERR, "cannot wait");
		}
		if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
			errx(EX_OSFILE, "%d errors in printcap file, exiting",
			     WEXITSTATUS(status));
	}

#ifndef DEBUG
	/*
	 * Set up standard environment by detaching from the parent.
	 */
	daemon(0, 0);
#endif

	openlog("lpd", LOG_PID, LOG_LPR);
	syslog(LOG_INFO, "lpd startup: logging=%d%s%s", lflag,
	    socket_debug ? " dbg" : "", sflag ? " net-secure" : "");
	(void) umask(0);
	/*
	 * NB: This depends on O_NONBLOCK semantics doing the right thing;
	 * i.e., applying only to the O_EXLOCK and not to the rest of the
	 * open/creation.  As of 1997-12-02, this is the case for commonly-
	 * used filesystems.  There are other places in this code which
	 * make the same assumption.
	 */
	lfd = open(_PATH_MASTERLOCK, O_WRONLY|O_CREAT|O_EXLOCK|O_NONBLOCK,
		   LOCK_FILE_MODE);
	if (lfd < 0) {
		if (errno == EWOULDBLOCK)	/* active daemon present */
			exit(0);
		syslog(LOG_ERR, "%s: %m", _PATH_MASTERLOCK);
		exit(1);
	}
	fcntl(lfd, F_SETFL, 0);	/* turn off non-blocking mode */
	ftruncate(lfd, 0);
	/*
	 * write process id for others to know
	 */
	sprintf(line, "%u\n", getpid());
	f = strlen(line);
	if (write(lfd, line, f) != f) {
		syslog(LOG_ERR, "%s: %m", _PATH_MASTERLOCK);
		exit(1);
	}
	signal(SIGCHLD, reapchild);
	/*
	 * Restart all the printers.
	 */
	startup();
	(void) unlink(_PATH_SOCKETNAME);
	funix = socket(AF_UNIX, SOCK_STREAM, 0);
	if (funix < 0) {
		syslog(LOG_ERR, "socket: %m");
		exit(1);
	}

	sigemptyset(&nmask);
	sigaddset(&nmask, SIGHUP);
	sigaddset(&nmask, SIGINT);
	sigaddset(&nmask, SIGQUIT);
	sigaddset(&nmask, SIGTERM);
	sigprocmask(SIG_BLOCK, &nmask, &omask);

	(void) umask(07);
	signal(SIGHUP, mcleanup);
	signal(SIGINT, mcleanup);
	signal(SIGQUIT, mcleanup);
	signal(SIGTERM, mcleanup);
	memset(&un, 0, sizeof(un));
	un.sun_family = AF_UNIX;
	strcpy(un.sun_path, _PATH_SOCKETNAME);
#ifndef SUN_LEN
#define SUN_LEN(unp) (strlen((unp)->sun_path) + 2)
#endif
	if (bind(funix, (struct sockaddr *)&un, SUN_LEN(&un)) < 0) {
		syslog(LOG_ERR, "ubind: %m");
		exit(1);
	}
	(void) umask(0);
	sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0);
	FD_ZERO(&defreadfds);
	FD_SET(funix, &defreadfds);
	listen(funix, 5);
	if (sflag == 0) {
		finet = socksetup(family, socket_debug);
	} else
		finet = NULL;	/* pretend we couldn't open TCP socket. */
	if (finet) {
		for (i = 1; i <= *finet; i++) {
			FD_SET(finet[i], &defreadfds);
			listen(finet[i], 5);
		}
	}
	/*
	 * Main loop: accept, do a request, continue.
	 */
	memset(&frominet, 0, sizeof(frominet));
	memset(&fromunix, 0, sizeof(fromunix));
	if (lflag)
		syslog(LOG_INFO, "lpd startup: ready to accept requests");
	/*
	 * XXX - should be redone for multi-protocol
	 */
	for (;;) {
		int domain, nfds, s;
		fd_set readfds;

		FD_COPY(&defreadfds, &readfds);
		nfds = select(20, &readfds, 0, 0, 0);
		if (nfds <= 0) {
			if (nfds < 0 && errno != EINTR)
				syslog(LOG_WARNING, "select: %m");
			continue;
		}
		domain = -1;		    /* avoid compile-time warning */
		s = -1;			    /* avoid compile-time warning */
		if (FD_ISSET(funix, &readfds)) {
			domain = AF_UNIX, fromlen = sizeof(fromunix);
			s = accept(funix,
			    (struct sockaddr *)&fromunix, &fromlen);
 		} else {
                        for (i = 1; i <= *finet; i++) 
				if (FD_ISSET(finet[i], &readfds)) {
					domain = AF_INET;
					fromlen = sizeof(frominet);
					s = accept(finet[i],
					    (struct sockaddr *)&frominet,
					    &fromlen);
				}
		}
		if (s < 0) {
			if (errno != EINTR)
				syslog(LOG_WARNING, "accept: %m");
			continue;
		}
		if (fork() == 0) {
			/*
			 * Note that printjob() also plays around with
			 * signal-handling routines, and may need to be
			 * changed when making changes to signal-handling.
			 */
			signal(SIGCHLD, SIG_DFL);
			signal(SIGHUP, SIG_IGN);
			signal(SIGINT, SIG_IGN);
			signal(SIGQUIT, SIG_IGN);
			signal(SIGTERM, SIG_IGN);
			(void) close(funix);
			if (sflag == 0 && finet) {
                        	for (i = 1; i <= *finet; i++) 
					(void)close(finet[i]);
			}
			dup2(s, STDOUT_FILENO);
			(void) close(s);
			if (domain == AF_INET) {
				/* for both AF_INET and AF_INET6 */
				from_remote = 1;
 				chkhost((struct sockaddr *)&frominet,
				    ch_options);
			} else
				from_remote = 0;
			doit();
			exit(0);
		}
		(void) close(s);
	}
}
Exemplo n.º 21
0
void *netServerThread(void *eData)
{
	x_try
		netServer *sData = (netServer*)eData;
		
		fd_set selectSet;
		fd_set copySet;
		
		mpMutex *mtx = sData->r_mutex;
		
		mpMutexLock(mtx);
		
		FD_ZERO(&selectSet);
		FD_SET(sData->m_socket, &selectSet);
		
		mpMutexUnlock(mtx);
		
		for (;;)
		{
			FD_COPY(&selectSet, &copySet);
			
			//Wait for a bit of time, locking the mutex...
			mpMutexLock(mtx);
			
			if (sData->m_client == NULL)
			{
				if (sData->m_socket != -1)
				{
					struct timeval to;
					to.tv_sec = 5;
					to.tv_usec = 0;
					int sel = select(sData->m_socket+1, &copySet, NULL, NULL, &to);
					
					if (sel == -1)
					{
						mpMutexUnlock(mtx);
						goto done;
					}
					
					if (!((sData->m_flags) & NETS_SINGLE_CLIENT) ||
									sData->m_runningThreads == 0)
					{
						if (sel != 0)			//Not timed out
						{
							struct sockaddr remoteAddress;
							socklen_t remoteSize;
							remoteSize = sizeof(remoteAddress);
							int clientSock = accept(sData->m_socket,
													&remoteAddress,
													&remoteSize);
							if (clientSock != -1)
							{
								printf("Server got connection\n");
								netClient *client = netClientFromSocket(clientSock);
								if (client != NULL)
								{
									pthread_t tmp;
								
								
									sData->m_client = client;
									sData->m_runningThreads++;
									
									x_pthread_create(&tmp, NULL, netServerConnection,
													eData);
								}
							}
						}
					}
				}
				else
				{
					mpMutexUnlock(mtx);
					goto done;
				}
			}
			
			mpMutexUnlock(mtx);
		}
	x_catch(e)
		printf("%s",errorMsg(e));
	x_finally

done:
	printf("Killed Server!\n");
	return NULL;
}
Exemplo n.º 22
0
int
main( int argc, char** argv )
{	
  int i, j, ret;
  char buf[1024];
  size_t buf_len;
  
  // Parse args. 
  if ( argc != 2 ) 
  {
    (void) fprintf( stderr, "usage:  %s port#\n", argv[0] );
    exit( 1 );
  }
  
  // Initialize server
  init_server( (unsigned short) atoi( argv[1] ) );
  
  // Get file descripter table size and initize request table
  maxfd = getdtablesize();
  requestP = ( request* ) malloc( sizeof( request ) * maxfd );
  if ( requestP == (request*) 0 )
    ERR_EXIT( "out of memory allocating all requests" );
  for ( i = 0; i < maxfd; i ++ )
    init_request( &requestP[i] );
  requestP[ svr.listen_fd ].conn_fd = svr.listen_fd;
  requestP[ svr.listen_fd ].status = READING;
  strcpy( requestP[ svr.listen_fd ].host, svr.hostname );
  
  // Loop for handling connections
  fprintf( stderr, "\nstarting on %.80s, port %d, fd %d, maxconn %d...\n", 
          svr.hostname, svr.port, svr.listen_fd, maxfd );
  
  // mark socket that is no-blocking
  fcntl( svr.listen_fd, F_SETFL, O_NONBLOCK );
  
  // work flags
  struct fd_set theConnectedFDs; // set of connected fds
  FD_ZERO( &theConnectedFDs ); // clear the set
  
  struct fd_set theCommandFDs;
  
  while (1)
  {
    int conn_fd;
    struct sockaddr_in cliaddr;
    socklen_t clilen = sizeof(cliaddr);
    
    // Fetch Check Connection
    if( (conn_fd = accept( svr.listen_fd, (struct sockaddr *) &cliaddr, &clilen ))!=-1){
      // OK
      requestP[conn_fd].conn_fd = conn_fd;
      requestP[conn_fd].status = READING;		
      strcpy( requestP[conn_fd].host, inet_ntoa( cliaddr.sin_addr ) );
      
      fprintf( stderr, "getting a new connection... fd %d from %s\n", conn_fd, requestP[conn_fd].host );
      
      FD_SET( conn_fd, &theConnectedFDs );
    }
    
    FD_COPY(&theConnectedFDs, &theCommandFDs); // update theCommandFDs
    
    struct timeval req_timeout = { 0, 10000 };
    
    // Scan The Descriptors for Read Commands
    int available_fds = select( maxfd, &theCommandFDs, NULL, NULL, &req_timeout );
    if( available_fds > 0 ){
      for( i=3; i<maxfd; i++ ){
        if( FD_ISSET(i, &theCommandFDs) ){
          conn_fd = i;
          
          // Read Buffer
          buf_len = requestP[conn_fd].buf_len;
          ret = handle_read( &requestP[conn_fd] );
          
          // Check Connection
          if( requestP[conn_fd].buf_len == buf_len ){
            fprintf(stderr, "disconnection detected: fd %d.\n", conn_fd );
            fprintf(stderr, "someone logout\n");
            close( requestP[conn_fd].conn_fd );
            free_request( &requestP[conn_fd] );
            FD_CLR( conn_fd, &theConnectedFDs );
          }else if( ret==0 ){
            // Process Command
            const char* command_content = requestP[conn_fd].buf;
            
            fprintf( stderr, "receive complete command from fd %d\n", conn_fd );
            
            if( strncmp( command_content, "<RD>", 4 )==0 ){
              requestP[conn_fd].status = WRITING;
              
            }else if( strncmp( command_content, "<WR>", 4 )==0 ){
              strcpy( buf, command_content );
              buf_len = requestP[conn_fd].buf_len;
              
              // Write out
              for ( j=3; j<maxfd; j++ ){
                if ( requestP[j].status == WRITING ){
                  // Write!
                  write( requestP[j].conn_fd, buf, buf_len );
                }
              }
              
              // Clean!
              close( requestP[conn_fd].conn_fd );
              free_request( &requestP[conn_fd] );
              FD_CLR( conn_fd, &theConnectedFDs );
            }
            
            fputs( "command processing completed.\n", stderr );
          }
          
        }
      }
    }
    
    sched_yield();
  }
  
  // 
  
  free( requestP );
  return 0;
}