/* * 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() */
/* * 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; }