Exemple #1
0
/*
 * xdd_raw_reader_init() - init the reader side of a read-after-write
 *
 */
int32_t
xdd_raw_reader_init(ptds_t *p) {
	int  status; /* status of various function calls */
	/* Set the target_options flag that identifies this target as a reader */
	p->target_options |= RX_RAW_READER;
	/* init the sockets */
	status = xdd_raw_sockets_init();
	if (status == FALSE) {
		xdd_raw_err("couldn't initialize sockets for RAW reader");
		return(FALSE);
	}
	/* Get the name of the machine that we are running on */
	status = gethostname(p->raw_myhostname, sizeof(p->raw_myhostname));
	if (status != 0 ) {
		xdd_raw_err("could not get hostname");
		return(FALSE);
	}
	/* Get the IP address of this host */
	p->raw_hostent = gethostbyname(p->raw_myhostname);
	if (! p->raw_hostent) {
		xdd_raw_err("unable to identify host");
		return(FALSE);
	}
	p->raw_addr = ntohl(((struct in_addr *) p->raw_hostent->h_addr)->s_addr);
	/* Set up the server sockets */
	status = xdd_raw_setup_reader_socket(p);
	if (status == FALSE) {
		xdd_raw_err("could not init raw reader socket");
		return(FALSE);
	}
	/* clear out the csd table */
	for (p->raw_current_csd = 0; p->raw_current_csd < FD_SETSIZE; p->raw_current_csd++)
		p->raw_csd[p->raw_current_csd] = 0;
	p->raw_current_csd = p->raw_next_csd = 0;
	/* Initialize the socket sets for select() */
    FD_ZERO(&p->raw_readset);
    FD_SET(p->raw_sd, &p->raw_readset);
	p->raw_active = p->raw_readset;
	p->raw_current_csd = p->raw_next_csd = 0;
	/* Find out how many sockets are in each set (berkely only) */
#if (IRIX || WIN32 || ALTIX)
    p->raw_nd = getdtablehi();
#endif
#if (LINUX || OSX)
    p->raw_nd = getdtablesize();
#endif
#if (AIX)
	p->raw_nd = FD_SETSIZE;
#endif
#if (SOLARIS || HPUX)
	p->raw_nd = FD_SETSIZE;
#endif
	p->raw_msg_recv = 0;
	p->raw_msg_sequence = 0;
	return(TRUE);
} /* end of xdd_raw_reader_init() */
Exemple #2
0
/*
 * xdd_raw_read_wait() - wait for a message from the writer to do something
 *
 */
int32_t
xdd_raw_read_wait(ptds_t *p) 
{
	int status; /* status of send/recv function calls */
	int  bytes_received;
	int  bytes_remaining;
#if (IRIX || WIN32 || ALTIX)
	p->raw_nd = getdtablehi();
#endif
	status = select(p->raw_nd, &p->raw_readset, NULL, NULL, NULL);
	/* Handle all the descriptors that are ready */
	/* There are two type of sockets: the one sd socket and multiple 
		* client sockets. We first check to see if the sd is in the readset.
		* If so, this means that a client is trying to make a new connection
		* in which case we need to issue an accept to establish the connection
		* and obtain a new Client Socket Descriptor (csd).
		*/
	if (FD_ISSET(p->raw_sd, &p->raw_readset)) { /* Process an incoming connection */
		p->raw_current_csd = p->raw_next_csd;
		p->raw_csd[p->raw_current_csd] = accept(p->raw_sd, NULL, NULL);
		FD_SET(p->raw_csd[p->raw_current_csd], &p->raw_active); /* Mark this fd as active */
		FD_SET(p->raw_csd[p->raw_current_csd], &p->raw_readset); /* Put in readset so that it gets processed */
		/* Find the next available csd close to the beginning of the CSD array */
		p->raw_next_csd = 0;
		while (p->raw_csd[p->raw_next_csd] != 0) {
			p->raw_next_csd++;
			if (p->raw_next_csd == FD_SETSIZE) {
					p->raw_next_csd = 0;
					fprintf(xgp->errout,"%s: xdd_raw_read_wait: no csd entries left\n",xgp->progname);
					break;
			}
		} /* end of WHILE loop that finds the next csd entry */
	} /* End of processing an incoming connection */
	/* This section will check to see which of the Client Socket Descriptors
		* are in the readset. For those csd's that are ready, a recv is issued to 
		* receive the incoming data. The clock is then read from pclk() and the
		* new clock value is sent back to the client.
		*/
	for (p->raw_current_csd = 0; p->raw_current_csd < FD_SETSIZE; p->raw_current_csd++) {
		if (FD_ISSET(p->raw_csd[p->raw_current_csd], &p->raw_readset)) { /* Process this csd */
			/* Receive the writer's current location and length.
				*
				* When the writer closes the socket we get a read
				* indication.  Treat any short send or receive as
				* a failed connection and silently clean up.
				*/
			bytes_received = 0;
			while (bytes_received < sizeof(p->raw_msg)) {
				bytes_remaining = sizeof(p->raw_msg) - bytes_received;
				status = recv(p->raw_csd[p->raw_current_csd], (char *) &p->raw_msg+bytes_received, bytes_remaining, 0);
				if (status < 0) break;
				bytes_received += status;
			}
			p->raw_msg_recv++;
			pclk_now(&p->raw_msg.recvtime);
			p->raw_msg.recvtime += xgp->gts_delta;
			if (status > 0) status = bytes_received;
			if (status == sizeof(p->raw_msg)) { /* Successful receive */
				if (p->raw_msg.magic != RX_RAW_MAGIC) {
					fprintf(stderr,"xdd_raw_read_wait: Bad magic number %08x on recv %d\n",p->raw_msg.magic, p->raw_msg_recv);
				}
				if (p->raw_msg.recvtime < p->raw_msg.sendtime) {
					fprintf(stderr,"xdd_raw_read_wait: msg %d recv time before send time by %llu picoseconds\n",p->raw_msg.sequence,p->raw_msg.sendtime-p->raw_msg.recvtime);
				}
				return(TRUE);
			} /* end of successful recv processing */
			else { /* error on the read operation */
				/* At this point, a recv returned an error in which case the connection
					* was most likely closed and we need to clear out this csd */
				/*"Deactivate" the socket. */
				FD_CLR(p->raw_csd[p->raw_current_csd], &p->raw_active);
				(void) closesocket(p->raw_csd[p->raw_current_csd]);
				p->raw_csd[p->raw_current_csd] = 0;
				return(FALSE);
				/* indicate that the writer is done and the reader should finish too */
			}
		} /* End of IF stmnt that processes a CSD */
	} /* End of FOR loop that processes all CSDs that were ready */
	p->raw_readset = p->raw_active;  /* Prepare for the next select */
    return(TRUE);
} /* end of xdd_raw_read_wait() */
int
main(int argc, char* argv[])
{
  PRStatus status;

  // launch daemon
  printf("### launch daemon...\n");

  PRProcessAttr *attributes = PR_NewProcessAttr();
  if (attributes == nsnull) {
    printf("PR_NewProcessAttr() failed.\n");
    return -1;
  }

  PRProcess *daemon = PR_CreateProcess("nsDnsAsyncLookup", nsnull, nsnull, attributes);
  if (daemon == nsnull) {
    printf("PR_CreateProcess failed.\n");
  } else {
    //    status = PR_DetachProcess(daemon);
    //if (status != 0)
    //  printf("PR_DetachProcess returned %d\n", status);
    //daemon = nsnull;
  }

  PR_DestroyProcessAttr(attributes);

  // create socket and connect to daemon
  int socket_fd = 0;


  bool notDone = true;
  char buf[1024];

  while(notDone) {
    int status = 0;
    fd_set fdset;

    FD_ZERO(&fdset);
    FD_SET(fileno(stdin), &fdset);
    if (socket_fd > 0)
      FD_SET(socket_fd, &fdset);
	   
    status = select(getdtablehi(), &fdset, 0, 0, 0);
    if (status <= 0)
      {
	fprintf(stderr, "%s: select() returned %d\n", argv[0], status);
	exit(-1);
      }

    // which fd is set?

    if (FD_ISSET(fileno(stdin), &fdset))
      {
	char *line = fgets(buf, sizeof(buf)-1, stdin);
	line = string_trim(line);
	
	if(!strcmp(line, "quit") || !strcmp(line, "exit"))
	  {
	    fprintf(stderr, "bye now.\n");
	    notDone = false;
	  }
	else if (!strncmp(line, "abort ", 6))
	  {
	    // abort id
	  }
	else if (strchr(line, ' ') || strchr(line, '\t'))
	  {
	    fprintf(stderr, "%s: unrecognized command %s.\n", argv[0], line);
	  }
	else
	  {
	    fprintf(stderr, "%s: looking up %s...\n", argv[0], line);
	    // initiate dns lookup
	    socket_fd = async_dns_lookup(line);
	  }
      }

    if (socket_fd && FD_ISSET(socket_fd, &fdset))
      {
	// read from socket, parse results
	int size = read(socket_fd, buf, 1024);
	if (size > 0)
	  {
	    // parse buffer into hostent
	    char *p = buf;
	    fprintf(stderr, "bytes read: %d\n", size);
	    fprintf(stderr, "response code: %d\n", *(int *)p);
	    p += sizeof(int);

	    for (int i=0; i < size; i++) {
	      if (!(i%8))
		fprintf(stderr, "\n");
	      fprintf(stderr, "%2.2x ",(unsigned char)buf[i]);
	    }
	    fprintf(stderr, "\n");
	    hostent *h;
	    h = bytesToHostent(p);
	  }
	close(socket_fd);
	socket_fd = 0;
      }
  }

  return 0;
}