/********************************************************************** TERMINATE Si occupa di: -Uccidere root e tutti i figli ricorsivamente -Rimettere i thread nella lista dei liberi -Togliere i thread dalle varie liste/array in cui sono presenti -Decrementare il valore di thread_count -Pulire la inbox da eventuali messaggi **********************************************************************/ void terminate (tcb_t *target) { msg_t *msg; tcb_t *child; /* Se ha un padre lo elimino dai suoi figli */ outChild(target); /* Caso ricorsivo -> HA figli (su cui viene chiamata la terminate) */ while (TRUE) { if ( (child = removeChild(target)) == NULL ) break; /* Passa al caso base e pulisce thread, liste, messaggi... */ terminate(child); } /* Caso base -> NON ha figli */ /* Se è in qualche lista o è il thread corrente lo elimino */ if (((outThread(&ready_queue, target)) != NULL) || (current_thread == target)) { /* Pulisco la inbox */ while (TRUE) { if ( (msg = popMessage(&(target->t_inbox), NULL)) == NULL ) break; freeMsg(msg); } /* Se è un manager lo elimino dal trap_managers array */ delete_manager(target); if (current_thread == target) current_thread=NULL; /* Restituisco ai thread liberi */ freeTcb(target); thread_count--; } else if (outThread(&wait_queue, target)) { /* Decremento contatore processi in attesa I/O o SSI */ if (target->waiting_for == SSI_tcb) soft_block_count--; /* Tutto come caso precedente*/ while (TRUE) { if ( (msg = popMessage(&(target->t_inbox), NULL)) == NULL ) break; freeMsg(msg); } delete_manager(target); freeTcb(target); thread_count--; } else PANIC(); }
/* close down the given client */ void shutdownClient (ClInfo *cp) { Msg *mp; /* close connection */ shutdown (cp->s, SHUT_RDWR); close (cp->s); /* free memory */ delLilXML (cp->lp); free (cp->props); /* decrement and possibly free any unsent messages for this client */ while ((mp = (Msg*) popFQ(cp->msgq)) != NULL) if (--mp->count == 0) freeMsg (mp); delFQ (cp->msgq); /* ok now to recycle */ cp->active = 0; if (verbose > 0) fprintf (stderr, "%s: Client %d: shut down complete - bye!\n", indi_tstamp(NULL), cp->s); #ifdef OSX_EMBEDED_MODE int active = 0; for (int i = 0; i < nclinfo; i++) if (clinfo[i].active) active++; fprintf(stderr, "CLIENTS %d\n", active); fflush(stderr); #endif }
void HandleServUpdate(stRcvdMsg * pstRcvdMsg ,int8 * pi8MsgPtr) { stRecord * pstRedAdd = NULL; int8 * pi8Token = NULL; int8 * pi8SavePtr = NULL; uint64 ui64RecId = 0; if(NULL != pstRcvdMsg && (NULL != pi8MsgPtr)) { pi8Token = strtok_r(pi8MsgPtr , DELIMITER , &pi8SavePtr); if(0 == strcmp(pi8Token , "CLIENTID")) { pi8Token = strtok_r(NULL , DELIMITER , &pi8SavePtr); ui64RecId = strtol(pi8Token,NULL,0); /*Look for the client record and then update the client*/ if(NULL != (pstRedAdd = SearchRecord(ui64RecId))) { FillRecord(pstRedAdd,pi8SavePtr); } } freeMsg(pstRcvdMsg); } }
void HandleServNew(stRcvdMsg * pstRcvdMsg ,int8 * pi8MsgPtr,uint64 ui64ID) { int8 * pi8SavePtr = NULL; int8 * pi8Token = NULL; uint64 ui64RecId = 0; stRecord * pstRedAdd = NULL; if(NULL != pi8MsgPtr) { pi8Token = strtok_r(pi8MsgPtr , DELIMITER , &pi8SavePtr); if(0 == strcmp("CLIENTID",pi8Token)) { pi8Token = strtok_r(NULL , DELIMITER , &pi8SavePtr); ui64RecId = strtol(pi8Token,NULL,0); if(NULL == (pstRedAdd = SearchRecord(ui64RecId))) { /*New record should be created for a new client*/ pstRedAdd = CreateRecord(ui64RecId); if(NULL != pstRedAdd) { pstRedAdd->ui64RecNum = ui64RecId; FillRecord(pstRedAdd,pi8SavePtr); pstRedAdd->ui32ContentFull = 0; } } else { /*Client already exists,just update*/ FillRecord(pstRedAdd,pi8SavePtr); } } freeMsg(pstRcvdMsg); } }
static int event_threadMsg(const EatEvent_st* event) { MSG_THREAD* msg = (MSG_THREAD*) event->data.user_msg.data_p; u8 msgLen = event->data.user_msg.len; size_t i = 0; int rc = 0; if (msg->length + sizeof(MSG_THREAD) != msgLen) { LOG_ERROR("Message length error"); freeMsg(msg); return -1; } for (i = 0; i < sizeof(msgProcs) / sizeof(msgProcs[0]); i++) { if (msgProcs[i].cmd == msg->cmd) { THREAD_MSG_FUNC pfn = msgProcs[i].pfn; if (pfn) { rc = pfn(msg); break; } else { LOG_ERROR("thread message %d not processed!", msg->cmd); rc = -1; break; } } } freeMsg(msg); return rc; }
/* write the next chunk of the current message in the queue to the given * client. pop message from queue when complete and free the message if we are * the last one to use it. shut down this client if trouble. * N.B. we assume we will never be called with cp->msgq empty. * return 0 if ok else -1 if had to shut down. */ int sendClientMsg (ClInfo *cp) { ssize_t nsend, nw; Msg *mp; /* get current message */ mp = (Msg *) peekFQ (cp->msgq); /* send next chunk, never more than MAXWSIZ to reduce blocking */ nsend = mp->cl - cp->nsent; if (nsend > MAXWSIZ) nsend = MAXWSIZ; nw = write (cp->s, &mp->cp[cp->nsent], nsend); /* shut down if trouble */ if (nw <= 0) { if (nw == 0) fprintf (stderr, "%s: Client %d: write returned 0\n", indi_tstamp(NULL), cp->s); else fprintf (stderr, "%s: Client %d: write: %s\n", indi_tstamp(NULL), cp->s, strerror(errno)); shutdownClient (cp); return (-1); } /* trace */ if (verbose > 2) { fprintf(stderr, "%s: Client %d: sending msg copy %d nq %d:\n%.*s\n", indi_tstamp(NULL), cp->s, mp->count, nFQ(cp->msgq), (int)nw, &mp->cp[cp->nsent]); } else if (verbose > 1) { fprintf(stderr, "%s: Client %d: sending %.50s\n", indi_tstamp(NULL), cp->s, &mp->cp[cp->nsent]); } /* update amount sent. when complete: free message if we are the last * to use it and pop from our queue. */ cp->nsent += nw; if (cp->nsent == mp->cl) { if (--mp->count == 0) freeMsg (mp); popFQ (cp->msgq); cp->nsent = 0; } return (0); }
/* write the next chunk of the current message in the queue to the given * driver. pop message from queue when complete and free the message if we are * the last one to use it. restart this driver if touble. * N.B. we assume we will never be called with dp->msgq empty. * return 0 if ok else -1 if had to shut down. */ int sendDriverMsg (DvrInfo *dp) { ssize_t nsend, nw; Msg *mp; /* get current message */ mp = (Msg *) peekFQ (dp->msgq); /* send next chunk, never more than MAXWSIZ to reduce blocking */ nsend = mp->cl - dp->nsent; if (nsend > MAXWSIZ) nsend = MAXWSIZ; nw = write (dp->wfd, &mp->cp[dp->nsent], nsend); /* restart if trouble */ if (nw <= 0) { if (nw == 0) fprintf (stderr, "%s: Driver %s: write returned 0\n", indi_tstamp(NULL), dp->name); else fprintf (stderr, "%s: Driver %s: write: %s\n", indi_tstamp(NULL), dp->name, strerror(errno)); shutdownDvr (dp, 1); return (-1); } /* trace */ if (verbose > 2) { fprintf(stderr, "%s: Driver %s: sending msg copy %d nq %d:\n%.*s\n", indi_tstamp(NULL), dp->name, mp->count, nFQ(dp->msgq), (int)nw, &mp->cp[dp->nsent]); } else if (verbose > 1) { fprintf(stderr, "%s: Driver %s: sending %.50s\n", indi_tstamp(NULL), dp->name, &mp->cp[dp->nsent]); } /* update amount sent. when complete: free message if we are the last * to use it and pop from our queue. */ dp->nsent += nw; if (dp->nsent == mp->cl) { if (--mp->count == 0) freeMsg (mp); popFQ (dp->msgq); dp->nsent = 0; } return (0); }
static void *netrequest_cmd_thread(void *arg){ msg *message = NULL; char* me = "netrequest_cmd_thread"; while(1){ requestNo++; freeMsg(message); netlog("%s waiting to process request number %d\n", me, requestNo); message = acceptMsg(STDIN_FILENO); if(message == NULL){ netlog("%s readMsg failed; %p", me, arg); continue; } netlog("%s processing request:\n\"%s\"\n", me, message->data); } return NULL; }
void parsePVSThenEcho(char *prompt, int from, int to){ msg* message; int length; message = readPVSMsg(prompt, from); if(message != NULL){ length = parseString(message->data, message->bytesUsed); message->bytesUsed = length; if(sendMsg(to, message) < 0){ fprintf(stderr, "sendMsg in parsePVSThenEcho failed\n"); } else { if(WRAPPER_DEBUG)writeMsg(STDERR_FILENO, message); announce("\nparseThenEcho wrote %d bytes\n", message->bytesUsed); } freeMsg(message); } }
/* close down the given driver and restart */ void shutdownDvr (DvrInfo *dp, int restart) { Msg *mp; /* make sure it's dead, reclaim resources */ if (dp->pid == REMOTEDVR) { /* socket connection */ shutdown (dp->wfd, SHUT_RDWR); close (dp->wfd); /* same as rfd */ } else { /* local pipe connection */ kill (dp->pid, SIGKILL); /* we've insured there are no zombies */ close (dp->wfd); close (dp->rfd); close (dp->efd); } #ifdef OSX_EMBEDED_MODE fprintf(stderr, "STOPPED \"%s\"\n", dp->name); fflush(stderr); #endif /* free memory */ free (dp->sprops); free(dp->dev); delLilXML (dp->lp); /* ok now to recycle */ dp->active = 0; dp->ndev = 0; /* decrement and possibly free any unsent messages for this client */ while ((mp = (Msg*) popFQ(dp->msgq)) != NULL) if (--mp->count == 0) freeMsg (mp); delFQ (dp->msgq); if (restart) { fprintf (stderr, "%s: Driver %s: restart #%d\n", indi_tstamp(NULL), dp->name, ++dp->restarts); startDvr (dp); } }
void parseSalThenEcho(int from, int to){ msg* message; int length; announce("parseSalThenEcho\t:\tCalling wrapper_readSalMsg\n"); message = wrapper_readSalMsg(from); if(message != NULL){ announce("parseSalThenEcho\t:\twrapper_readSalMsg returned %d bytes\n", message->bytesUsed); length = parseString(message->data, message->bytesUsed); message->bytesUsed = length; if(sendMsg(to, message) < 0){ fprintf(stderr, "sendMsg in parseSalThenEcho failed\n"); } else { if(SALWRAPPER_DEBUG)writeMsg(STDERR_FILENO, message); announce("\nparseThenEcho wrote %d bytes\n", message->bytesUsed); } freeMsg(message); } }
/* queue the xml command in root from the given device to each * interested client, except notme */ static void send2Clients (ClInfo *notme, XMLEle *root, char *dev) { ClInfo *cp; Msg *mp; /* build a new message */ mp = (Msg *) mymalloc (sizeof(Msg)); mp->ep = root; mp->count = 0; /* lock access to client info */ pthread_mutex_lock (&client_m); /* queue message to each interested client */ for (cp = clinfo; cp < &clinfo[nclinfo]; cp++) { int isblob; /* cp ok? notme? valid dev? blob? */ if (!cp->active || cp == notme) continue; if (findClDevice (cp, dev) < 0) continue; isblob = !strcmp (tagXMLEle(root), "setBLOBVector"); if ((isblob && cp->blob==B_NEVER) || (!isblob && cp->blob==B_ONLY)) continue; /* ok: queue message to given client */ mp->count++; pushFQ (cp->msgq, mp); } /* wake up client write threads, the last of which will free the Msg */ if (mp->count > 0) pthread_cond_broadcast(&client_c); else { if (verbose > 2) fprintf (stderr, "no clients want %s\n", xmlLog(root)); freeMsg (mp); /* no interested clients, free Msg now */ } /* finished with client info */ pthread_mutex_unlock (&client_m); }
void parseMaudeThenEcho(int from, int to){ msg* message; int length; announce("parseMaudeThenEcho\t:\tCalling readMaudeMsg\n"); message = readMaudeMsg(from); if(message != NULL){ announce("parseMaudeThenEcho\t:\treadMaudeMsg returned %d bytes\n", message->bytesUsed); if(WATCH_MAUDE)logMsg("maude", MAUDE_LOGFILE, message); length = parseString(message->data, message->bytesUsed); message->bytesUsed = length; if(sendMsg(to, message) < 0){ fprintf(stderr, "sendMsg in parseMaudeThenEcho failed\n"); } else { if(MAUDE_WRAPPER_DEBUG)writeMsg(STDERR_FILENO, message); announce("\nparseThenEcho wrote %d bytes\n", message->bytesUsed); } freeMsg(message); } }
static EBBRC MsgMgrPrim_handleEvent(EventHandlerRef _self) { MsgMgrPrimRef self = (MsgMgrPrimRef)ContainingCOPtr(_self,MsgMgrPrim,evHdlr); MsgStore *msg; EBBRC rc; rc = COBJ_EBBCALL(theEventMgrPrimId, ackIPI); LRT_RCAssert(rc); msg = MsgMgrPrim_dequeueMsgHead(self); while (msg != NULL) { switch(msg->numargs) { case 0: COBJ_EBBCALL(msg->id, msg0); break; case 1: COBJ_EBBCALL(msg->id, msg1, msg->args[0]); break; case 2: COBJ_EBBCALL(msg->id, msg2, msg->args[0], msg->args[1]); break; case 3: COBJ_EBBCALL(msg->id, msg3, msg->args[0], msg->args[1], msg->args[2]); break; } // FIXME: retain in a free list? freeMsg(self, msg); msg = MsgMgrPrim_dequeueMsgHead(self); } // we are re-enabling interrupts before returning to event mgr // not obvious yet if we should be doing this here, or lower down, // but its at least reasonable that we want to execute an entire message // disabled. Note, a whole chain of messages may be invoked here, so, // the implicit assumption is that you re-disable interrupts if you enable // them at the end of a message. rc = COBJ_EBBCALL(theEventMgrPrimId, enableIPI); LRT_RCAssert(rc); return EBBRC_OK; }
void* handleRequest(void* args){ int from = -1, to = -1; echofds* fds = (echofds*)args; if(fds == NULL) goto fail; from = fds->from; to = fds->to; while(1){ msg* message = acceptMsg(from); if(message != NULL){ msg2netlog(message); pthread_mutex_lock(&netrequest_output_mutex); sendMsg(to, message); pthread_mutex_unlock(&netrequest_output_mutex); freeMsg(message); } else { netlog("handleRequest exiting gracefully!\n"); break; } } fail: if(from != -1){ close(from); } return NULL; }
void PrepareCliRsp(stRcvdMsg * pstRcvdMsg,stRecord * pstRedAdd,uint32 ui32BitMask) { int8 * pachRepBuff = NULL; int8 achBuff[20] = {0}; pachRepBuff = (int8 *) malloc(MAX_MSG_LEN); /*For all the bits set in ui32BitMask , encode the parameter inside the mesage*/ if((NULL != pstRcvdMsg) && (NULL != pachRepBuff)) { memset(pachRepBuff , 0 , MAX_MSG_LEN); snprintf(pachRepBuff, sizeof(uint64),"%ld",gi64ServID); strcat(pachRepBuff , DELIMITER); if((ui32BitMask & CLIENT) != 0) { /*Message to another client*/ strcat(pachRepBuff , REPLY); } else if((ui32BitMask & SERVER) != 0) { /*Message to another Server*/ if((ui32BitMask & UPDATE) != 0) { strcat(pachRepBuff , "UPDATE"); } else if((ui32BitMask & NEW) != 0) { strcat(pachRepBuff , "NEW"); } } else { /*unknown type*/ free(pachRepBuff); return; } strcat(pachRepBuff , DELIMITER); if((ui32BitMask & CLIENTID) != 0) { strcat(pachRepBuff , "CLIENTID"); strcat(pachRepBuff , DELIMITER); snprintf(achBuff , 20,"%ld", pstRedAdd->ui64RecNum); strcat(pachRepBuff,achBuff); strcat(pachRepBuff , DELIMITER); } if((ui32BitMask & NAME) != 0) { strcat(pachRepBuff , "NAME"); strcat(pachRepBuff , DELIMITER); strcat(pachRepBuff,pstRedAdd->achName); strcat(pachRepBuff , DELIMITER); } if((ui32BitMask & EMAIL) != 0) { strcat(pachRepBuff , "EMAIL"); strcat(pachRepBuff , DELIMITER); strcat(pachRepBuff,pstRedAdd->achEmail); strcat(pachRepBuff , DELIMITER); } if((ui32BitMask & ADDRESS) != 0) { strcat(pachRepBuff , "ADDRESS"); strcat(pachRepBuff , DELIMITER); strcat(pachRepBuff,pstRedAdd->achAddr); strcat(pachRepBuff , DELIMITER); } if((ui32BitMask & LOCATION) != 0) { strcat(pachRepBuff , "LOCATION"); strcat(pachRepBuff , DELIMITER); strcat(pachRepBuff,pstRedAdd->achLastKnownLoc); strcat(pachRepBuff , DELIMITER); } if((ui32BitMask & NOTYPE) != 0) { strcat(pachRepBuff , "NOTYPE"); strcat(pachRepBuff , DELIMITER); } if((ui32BitMask & NOREC) != 0) { strcat(pachRepBuff , "NOREC"); strcat(pachRepBuff , DELIMITER); } pachRepBuff[strlen(pachRepBuff)-1] = '\0'; printf("Buffer: %s\n",pachRepBuff); /*TODO: Add sending part*/ freeMsg(pstRcvdMsg); free(pachRepBuff); } }
msg* wrapper_readSalMsg(int fd){ char prompt[] = "sal > "; char *promptPointer = NULL; int bytes = 0, iteration = 0; msg* retval = makeMsg(BUFFSZ); if(retval == NULL){ fprintf(stderr, "makeMsg in %d failed\n", getpid()); goto fail; } while(1){ char buff[BUFFSZ]; announce("wrapper_readSalMsg\t:\tcommencing a read\n"); restart: if((bytes = read(fd, buff, BUFFSZ)) < 0){ announce("wrapper_readSalMsg\t:\tread error read returned %d bytes\n", bytes); if(errno == EINTR){ announce("readMsg in %d restarting after being interrupted by a signal\n", getpid()); goto restart; } if(errno == EBADF){ fprintf(stderr, "readMsg in %d failing because of a bad file descriptor\n", getpid()); goto fail; } fprintf(stderr, "Read in %d returned with nothing\n", getpid()); return retval; } announce("wrapper_readSalMsg\t:\tread read %d bytes\n", bytes); announce("Read the following: buff \t = \t %s",buff); if(addToMsg(retval, bytes, buff) != 0){ fprintf(stderr, "addToMsg (wrapper_readSalMsg) in %d failed\n", getpid()); goto fail; } iteration++; if((promptPointer = strstr(retval->data, prompt)) != NULL){ fd_set readset; struct timeval delay; int sret; announce("wrapper_readSalMsg\t:\tsaw the prompt, making sure!\n"); FD_ZERO(&readset); FD_SET(fd, &readset); delay.tv_sec = 0; delay.tv_usec = 0; sret = select(fd + 1, &readset, NULL, NULL, &delay); if(sret < 0){ fprintf(stderr, "wrapper_readSalMsg\t:\tselect error\n"); goto fail; } else if(sret == 0){ announce("wrapper_readSalMsg\t:\tdefinitely the prompt!\n"); break; } else { announce("wrapper_readSalMsg\t:\tsret = %d more coming! TOO CONFUSING\n", sret); goto fail; } } }/* while */ if(retval != NULL){ announce("wrapper_readSalMsg\t:\tretval->bytesUsed = %d\n", retval->bytesUsed); announce("wrapper_readSalMsg\t:\tretval->data = \n\"%s\"\n", retval->data); announce("==================================================\n"); promptPointer[0] = '\0'; /* chomp the prompt I */ retval->bytesUsed -= strlen(prompt) ; /* chomp the prompt II */ announce("wrapper_readSalMsg\t:\tretval->bytesUsed = %d\n", retval->bytesUsed); announce("wrapper_readSalMsg\t:\tretval->data = \n\"%s\"\n", retval->data); announce("==================================================\n"); if((retval->bytesUsed == 0) || ((retval->bytesUsed == 1) && (retval->data[0] == '\n'))){ sprintf(retval->data, "OK\n"); retval->bytesUsed = strlen("OK\n"); } } announce("\nwrapper_readSalMsg\t:\tfinishing a read\n"); return retval; fail: freeMsg(retval); retval = NULL; return retval; }
/********************************************************************** RECV Mette in wait per un messaggio (settando prima gli opportuni campi ausiliari nella struttura del tcb richiedente) se non vi è il messaggio cercato nella inbox (o un qualsiasi messaggio per ANYMESSAGE). Caso BLOCCANTE. Altrimenti viene creata l'astrazione del messaggio ricevuto restituendo il payload inviato al thread all'indirizzo indicato nel registro a2 (reply) ---> CASO NON BLOCCANTE. **********************************************************************/ tcb_t *recv (tcb_t *receiver, tcb_t *sender, U32 *reply){ msg_t *msg; /* Caso ANYMESSAGE, attesa di un qualsiasi messaggio */ if (sender == ANYMESSAGE) { /* Cerco di estrarre il primo messaggio, se c'è */ msg = popMessage(&(receiver->t_inbox), NULL); /* Inbox vuota -> wait */ if (msg == NULL) { /* Per chi sono fermo */ receiver->waiting_for = ANYMESSAGE; /* Dove aspetto la risposta */ receiver->reply = reply; /* Metto in wait_queue */ insertThread(&wait_queue, receiver); current_thread = NULL; return NULL; } /* Inbox NON vuota -> preleva messaggio */ else { *reply = msg->m_message; sender = msg->m_sender; /* Restituisco il messaggio alla lista dei liberi */ freeMsg(msg); /* Restituisco il mittente del messaggio */ return(sender); } } /* Caso THREAD SPECIFICATO */ else if (sender != ANYMESSAGE) { /* Cerco di estrarre il messaggio inviato dal thread specificato */ msg = popMessage(&(receiver->t_inbox), sender); /* Messaggio non trovato -> wait */ if (msg == NULL) { /* Per chi sono fermo */ receiver->waiting_for = sender; /* Dove aspetto la risposta */ receiver->reply = reply; /* Metto in wait_queue */ insertThread(&wait_queue, receiver); current_thread = NULL; return NULL; } /* Messaggio trovato -> preleva messaggio */ else { *reply = msg->m_message; /* Se prelevo risposta ad un servizio decremento soft_block_count */ if (sender == (tcb_t *)MAGIC_SSI) soft_block_count--; /* Restituisco il messaggio alla lista dei liberi */ freeMsg(msg); /* Restituisco il mittente del messaggio */ return(sender); } } return NULL; }
int main(int argc, char** argv){ msg *message = NULL; char childName[SIZE], fdName[SIZE], iopPid[SIZE]; int retval, portNo; char *port, *sender, *rest, *body, *cmd; if(argv == NULL){ fprintf(stderr, "didn't understand: (argv == NULL)\n"); exit(EXIT_FAILURE); } if(argc != 3){ fprintf(stderr, "didn't understand: (argc != 3)\n"); exit(EXIT_FAILURE); } iop_pid = getppid(); self_debug_flag = SOCKETFACTORY_DEBUG; self = argv[0]; registry_fifo_in = argv[1]; registry_fifo_out = argv[2]; if(iop_install_handler(SIGCHLD, 0, socketfactory_sigchild_handler) != 0){ perror("socketfactory could not install signal handler"); exit(EXIT_FAILURE); } while(1){ requestNo++; freeMsg(message); message = acceptMsg(STDIN_FILENO); if(message == NULL){ perror("socketfactory acceptMsg failed"); continue; } announce("Received message->data = \"%s\"\n", message->data); retval = parseActorMsg(message->data, &sender, &body); if(!retval){ fprintf(stderr, "didn't understand: (parseActorMsg)\n\t \"%s\" \n", message->data); continue; } if(getNextToken(body, &cmd, &rest) <= 0){ fprintf(stderr, "didn't understand: (cmd)\n\t \"%s\" \n", body); continue; } if(!strcmp(cmd, "openclient")){ char *host; announce("openclient case\n"); if(getNextToken(rest, &host, &rest) <= 0){ fprintf(stderr, "didn't understand: (host)\n\t \"%s\" \n", rest); continue; } if(getNextToken(rest, &port, &rest) <= 0){ fprintf(stderr, "didn't understand: (port)\n\t \"%s\" \n", rest); continue; } portNo = atoi(port); announce("port = %d\n", portNo); if(allocateSocket(portNo, host, &clientFd) != 1){ goto openclientfail; } snprintf(childName, SIZE, "%s%d", clientChildName, clientNo); snprintf(fdName, SIZE, "%d", clientFd); clientChildArgv[0] = childName; announce("clientChildArgv[0] = %s\n", clientChildArgv[0]); clientChildArgv[1] = fdName; announce("clientChildArgv[1] = %s\n", clientChildArgv[1]); clientChildArgv[2] = registry_fifo_in; announce("clientChildArgv[2] = %s\n", clientChildArgv[2]); clientChildArgv[3] = registry_fifo_out; announce("clientChildArgv[3] = %s\n", clientChildArgv[3]); clientChildArgv[4] = NULL; announce("clientChildArgv[4] = %s\n", clientChildArgv[4]); announce("Spawning actor\n"); newActor(1, clientChildExe, clientChildArgv); announce("%s\n%s\nopenClientOK\n%s\n", sender, self, childName); sendFormattedMsgFP(stdout, "%s\n%s\nopenClientOK\n%s\n", sender, self, childName); clientNo++; if(close(clientFd) < 0){ fprintf(stderr, "close failed in openclient case\n"); } continue; openclientfail: announce("%s\n%s\nopenClientFailure\n", sender, self); sendFormattedMsgFP(stdout, "%s\n%s\nopenClientFailure\n", sender, self); continue; } else if(!strcmp(cmd, "openlistener")){ announce("openlistener case\n"); if(getNextToken(rest, &port, &rest) <= 0){ fprintf(stderr, "didn't understand: (port)\n\t \"%s\" \n", rest); continue; } portNo = atoi(port); announce("port = %d\n", portNo); if(allocateListeningSocket(portNo, &listenerFd) != 1){ fprintf(stderr, "Couldn't listen on port\n"); goto openlistenerfail; } snprintf(childName, SIZE, "%s%d", listenerChildName, listenerNo); snprintf(fdName, SIZE, "%d", listenerFd); snprintf(iopPid, SIZE, "%d", iop_pid); listenerChildArgv[0] = childName; announce("listenerChildArgv[0] = %s\n", listenerChildArgv[0]); listenerChildArgv[1] = fdName; announce("listenerChildArgv[1] = %s\n", listenerChildArgv[1]); listenerChildArgv[2] = sender; announce("listenerChildArgv[2] = %s\n", listenerChildArgv[2]); listenerChildArgv[3] = registry_fifo_in; announce("listenerChildArgv[3] = %s\n", listenerChildArgv[3]); listenerChildArgv[4] = registry_fifo_out; announce("listenerChildArgv[4] = %s\n", listenerChildArgv[4]); listenerChildArgv[5] = iopPid; announce("listenerChildArgv[5] = %s\n", listenerChildArgv[5]); listenerChildArgv[6] = NULL; announce("listenerChildArgv[6] = %s\n", listenerChildArgv[6]); announce("Spawning actor\n"); newActor(1, listenerChildExe, listenerChildArgv); announce("Spawned actor\n"); announce("%s\n%s\nopenListenerOK\n%s\n", sender, self, childName); sendFormattedMsgFP(stdout, "%s\n%s\nopenListenerOK\n%s\n", sender, self, childName); listenerNo++; if(close(listenerFd) < 0){ fprintf(stderr, "close failed in openlistener case\n"); } continue; openlistenerfail: announce("%s\n%s\nopenListenerFailure\n", sender, self); sendFormattedMsgFP(stdout, "%s\n%s\nopenListenerFailure\n", sender, self); continue; } else { fprintf(stderr, "didn't understand: (command)\n\t \"%s\" \n", message->data); continue; } } }
/* Aggiunge il tcb_t puntato da p alla lista tcbFree_h, rendendolo quindi nuovamente disponibile*/ void freeTcb(tcb_t *p) { msg_t*m=NULL; while((m=popMessage(&(p->t_inbox), NULL)) != NULL) freeMsg(m); list_add(&p->t_next, &tcbFree_h.t_next); }
/* this function is the thread to perform all writes to client carg. * return with client closed when we have problems or when shutdown flag is set. * N.B. coordinate all access to clinfo via client_m/c. * N.B. clinfo can move (be realloced) when unlocked so beware pointers thereto. */ static void * clientWThread(void *carg) { int c = (int)carg; ClInfo *cp; Msg *mp; /* start off wanting exclusive access to client info */ pthread_mutex_lock (&client_m); /* loop until told to shut down or get write error */ while (1) { /* check for message or shutdown, unlock while waiting */ while (nFQ(clinfo[c].msgq) == 0 && !clinfo[c].shutdown) { if (verbose > 2) fprintf (stderr,"Client %d: thread sleeping\n",clinfo[c].s); pthread_cond_wait (&client_c, &client_m); if (verbose > 2) fprintf (stderr, "Client %d: thread awake\n", clinfo[c].s); } if (clinfo[c].shutdown) break; /* get next message for this client */ mp = popFQ (clinfo[c].msgq); /* unlock client info while writing */ pthread_mutex_unlock (&client_m); prXMLEle (clinfo[c].wfp, mp->ep, 0); pthread_mutex_lock (&client_m); /* trace */ cp = &clinfo[c]; /* ok to use pointer while locked */ if (verbose > 2) { fprintf (stderr, "Client %d: send:\n", cp->s); prXMLEle (stderr, mp->ep, 0); } else if (verbose > 1) fprintf (stderr, "Client %d: send %s\n", cp->s, xmlLog(mp->ep)); /* update message usage count, free if goes to 0 */ if (--mp->count == 0) freeMsg (mp); /* exit this thread if encountered write errors */ if (ferror(cp->wfp)) { fprintf (stderr, "Client %d: %s\n", cp->s, strerror(errno)); break; } } /* close down this client */ cp = &clinfo[c]; /* ok to use pointer while locked */ fclose (cp->wfp); /* also closes cp->s */ delLilXML (cp->lp); myfree (cp->devs); /* decrement and possibly free any unsent messages for this client */ while ((mp = (Msg*) popFQ(cp->msgq)) != NULL) if (--mp->count == 0) freeMsg (mp); delFQ (cp->msgq); /* this thread is now finished with client info */ pthread_mutex_unlock (&client_m); /* exit thread */ return (0); }
int event_threadMsg(const EatEvent_st* event) { MSG_THREAD* msg = (MSG_THREAD*) event->data.user_msg.data_p; u8 msgLen = event->data.user_msg.len; int i = 0; switch (msg->cmd) { case CMD_THREAD_GPS: { LOCAL_GPS* gps = (LOCAL_GPS*) msg->data; if (msgLen < sizeof(LOCAL_GPS)) { LOG_ERROR("msg length error"); break; } if (!gps) { break; } data.isGpsFixed = gps->isGpsFixed; if (gps->isGpsFixed) //update the local GPS data { data.gps.latitude = gps->gps.latitude; data.gps.longitude = gps->gps.longitude; LOG_DEBUG("receive thread command CMD_GPS_UPDATE: lat(%f), lng(%f)", gps->gps.latitude, gps->gps.longitude); } else //update local cell info { data.cgi.mcc = gps->cellInfo.mcc; data.cgi.mnc = gps->cellInfo.mnc; data.cellNum = gps->cellInfo.cellNo; memcpy(data.cells, gps->cellInfo.cell, sizeof(CELL) * gps->cellInfo.cellNo); LOG_DEBUG("receive thread command CMD_GPS_UPDATE: cellid(%x), lac(%d)", data.cells[0].cellid, data.cells[0].lac); } break; } case CMD_THREAD_SMS: LOG_DEBUG("receive thread command CMD_SMS"); break; case CMD_THREAD_VIBRATE: LOG_DEBUG("receive thread command CMD_VIBRATE"); break; default: LOG_ERROR("unknown thread command:%d", msg->cmd); } freeMsg(msg); return 0; }
int main(int argc, char** argv){ msg *messageIn = NULL, *messageOut = NULL; char *sender, *rest, *body, *cmd; int retval; if(argv == NULL){ fprintf(stderr, "didn't understand: (argv == NULL)\n"); exit(EXIT_FAILURE); } if(argc != 4){ fprintf(stderr, "didn't understand: (argc != 4)\n"); exit(EXIT_FAILURE); } self_debug_flag = SOCKET_DEBUG; self = argv[0]; sock = atoi(argv[1]); registry_fifo_in = argv[2]; registry_fifo_out = argv[3]; if(socket_install_handler() != 0){ perror("socket couldn't install handler\n"); exit(EXIT_FAILURE); } while(1){ requestNo++; if(messageIn != NULL){ freeMsg(messageIn); messageIn = NULL; } if(messageOut != NULL){ freeMsg(messageOut); messageOut = NULL; } announce("%s waiting to process request number %d\n", self, requestNo); messageIn = acceptMsg(STDIN_FILENO); if(messageIn == NULL){ perror("socket acceptMsg failed"); continue; } announce("%s processing request:\n\"%s\"\n", self, messageIn->data); retval = parseActorMsg(messageIn->data, &sender, &body); if(!retval){ fprintf(stderr, "didn't understand: (parseActorMsg)\n\t \"%s\" \n", messageIn->data); continue; } if(getNextToken(body, &cmd, &rest) <= 0){ fprintf(stderr, "didn't understand: (cmd)\n\t \"%s\" \n", body); continue; } if(!strcmp(cmd, "read")){ if(closed){ goto readfail; } else { char *bytes2read; int bytesDesired; if(getNextToken(rest, &bytes2read, &rest) <= 0){ fprintf(stderr, "didn't understand: (bytes2read)\n\t \"%s\" \n", rest); continue; } bytesDesired = atoi(bytes2read); if(bytesDesired == 0){ goto readfail; } else { messageOut = readMsg(sock); if(messageOut == NULL){ perror("socket readMsg failed"); goto readfail; } announce("%s\n%s\nreadOK\n%d\n%s\n", sender, self, messageOut->bytesUsed, messageOut->data); sendFormattedMsgFP(stdout, "%s\n%s\nreadOK\n%d\n%s\n", sender, self, messageOut->bytesUsed, messageOut->data); } continue; readfail: announce("%s\n%s\nreadFailure\n", sender, self); sendFormattedMsgFP(stdout, "%s\n%s\nreadFailure\n", sender, self); continue; } } else if(!strcmp(cmd, "write")){ if(closed){ fprintf(stderr, "closed\n"); goto writefail; } else { char *bytes2write; int bytesToSend, bytesSent; if(getNextToken(rest, &bytes2write, &rest) <= 0){ fprintf(stderr, "didn't understand: (bytes2write)\n\t \"%s\" \n", rest); continue; } bytesToSend = atoi(bytes2write); if(bytesToSend == 0){ fprintf(stderr, "(bytesToSend == 0)\n"); goto writefail; } else { int len = strlen(rest); bytesToSend = (len < bytesToSend ) ? len : bytesToSend; if((bytesSent = write(sock, rest, bytesToSend)) != bytesToSend){ fprintf(stderr, "(bytesSent = write(sock, rest, bytesToSend)) != bytesToSend\n"); goto writefail; } else { announce("%s\n%s\nwriteOK\n%d\n", sender, self, bytesSent); sendFormattedMsgFP(stdout, "%s\n%s\nwriteOK\n%d\n", sender, self, bytesSent); } } } continue; writefail: announce("%s\n%s\nwriteFailure\n", sender, self); sendFormattedMsgFP(stdout, "%s\n%s\nwriteFailure\n", sender, self); } else if(!strcmp(cmd, "close")){ int slotNumber = -1; if(!closed){ closed = 1; if(close(sock) < 0){ fprintf(stderr, "close failed in socket close case\n"); } announce("%s\n%s\ncloseOK\n", sender, self); sendFormattedMsgFP(stdout, "%s\n%s\ncloseOK\n", sender, self); iop_usleep(1); announce("Socket called %s unregistering\n", self); slotNumber = deleteFromRegistry(self); announce("Socket called %s removed from slot %d, now exiting\n", self, slotNumber); exit(EXIT_SUCCESS); } else { announce("%s\n%s\ncloseFailure\n", sender, self); sendFormattedMsgFP(stdout, "%s\n%s\ncloseFailure\n", sender, self); } } else { fprintf(stderr, "didn't understand: (command)\n\t \"%s\" \n", messageIn->data); continue; } } }
/* read more from the given driver, send to each interested client when see * xml closure. if driver dies, try restarting. * return 0 if ok else -1 if had to shut down anything. */ int readFromDriver (DvrInfo *dp) { char buf[MAXRBUF]; int shutany = 0; ssize_t i, nr; /* read driver */ nr = read (dp->rfd, buf, sizeof(buf)); if (nr <= 0) { if (nr < 0) fprintf (stderr, "%s: Driver %s: stdin %s\n", indi_tstamp(NULL), dp->name, strerror(errno)); else fprintf (stderr, "%s: Driver %s: stdin EOF\n", indi_tstamp(NULL), dp->name); shutdownDvr (dp, 1); return (-1); } /* process XML, sending when find closure */ for (i = 0; i < nr; i++) { char err[1024]; XMLEle *root = readXMLEle (dp->lp, buf[i], err); if (root) { char *roottag = tagXMLEle(root); const char *dev = findXMLAttValu (root, "device"); const char *name = findXMLAttValu (root, "name"); int isblob = !strcmp (tagXMLEle(root), "setBLOBVector"); Msg *mp; if (verbose > 2) { fprintf(stderr, "%s: Driver %s: read ", indi_tstamp(0),dp->name); traceMsg (root); } else if (verbose > 1) { fprintf (stderr, "%s: Driver %s: read <%s device='%s' name='%s'>\n", indi_tstamp(NULL), dp->name, tagXMLEle(root), findXMLAttValu (root, "device"), findXMLAttValu (root, "name")); } /* that's all if driver is just registering a snoop */ if (!strcmp (roottag, "getProperties")) { addSDevice (dp, dev, name); delXMLEle (root); continue; } /* that's all if driver is just registering a BLOB mode */ if (!strcmp (roottag, "enableBLOB")) { Property *sp = findSDevice (dp, dev, name); if (sp) crackBLOB (pcdataXMLEle (root), &sp->blob); delXMLEle (root); continue; } /* Found a new device? Let's add it to driver info */ if (dev[0] && isDeviceInDriver(dev, dp) == 0) { dp->dev = (char **) realloc(dp->dev, (dp->ndev+1) * sizeof(char *)); dp->dev[dp->ndev] = (char *) malloc(MAXINDIDEVICE * sizeof(char)); strncpy (dp->dev[dp->ndev], dev, MAXINDIDEVICE-1); dp->dev[dp->ndev][MAXINDIDEVICE-1] = '\0'; #ifdef OSX_EMBEDED_MODE if (!dp->ndev) fprintf(stderr, "STARTED \"%s\"\n", dp->name); fflush(stderr); #endif dp->ndev++; } /* log messages if any and wanted */ if (ldir) logDMsg (root, dev); /* build a new message -- set content iff anyone cares */ mp = newMsg(); /* send to interested clients */ if (q2Clients (NULL, isblob, dev, name, mp, root) < 0) shutany++; /* send to snooping drivers */ q2SDrivers (isblob, dev, name, mp, root); /* set message content if anyone cares else forget it */ if (mp->count > 0) setMsgXMLEle (mp, root); else freeMsg (mp); delXMLEle (root); } else if (err[0]) { char *ts = indi_tstamp(NULL); fprintf (stderr, "%s: Driver %s: XML error: %s\n", ts, dp->name, err); fprintf (stderr, "%s: Driver %s: XML read: %.*s\n", ts, dp->name, (int)nr, buf); shutdownDvr (dp, 1); return (-1); } } return (shutany ? -1 : 0); }
/* read more from the given client, send to each appropriate driver when see * xml closure. also send all newXXX() to all other interested clients. * return -1 if had to shut down anything, else 0. */ int readFromClient (ClInfo *cp) { char buf[MAXRBUF]; int shutany = 0; ssize_t i, nr; /* read client */ nr = read (cp->s, buf, sizeof(buf)); if (nr <= 0) { if (nr < 0) fprintf (stderr, "%s: Client %d: read: %s\n", indi_tstamp(NULL), cp->s, strerror(errno)); else if (verbose > 0) fprintf (stderr, "%s: Client %d: read EOF\n", indi_tstamp(NULL), cp->s); shutdownClient (cp); return (-1); } /* process XML, sending when find closure */ for (i = 0; i < nr; i++) { char err[1024]; XMLEle *root = readXMLEle (cp->lp, buf[i], err); if (root) { char *roottag = tagXMLEle(root); const char *dev = findXMLAttValu (root, "device"); const char *name = findXMLAttValu (root, "name"); int isblob = !strcmp (tagXMLEle(root), "setBLOBVector"); Msg *mp; if (verbose > 2) { fprintf (stderr, "%s: Client %d: read ",indi_tstamp(NULL),cp->s); traceMsg (root); } else if (verbose > 1) { fprintf (stderr, "%s: Client %d: read <%s device='%s' name='%s'>\n", indi_tstamp(NULL), cp->s, tagXMLEle(root), findXMLAttValu (root, "device"), findXMLAttValu (root, "name")); } /* snag interested properties. * N.B. don't open to alldevs if seen specific dev already, else * remote client connections start returning too much. */ if (dev[0]) addClDevice (cp, dev, name, isblob); else if (!strcmp (roottag, "getProperties") && !cp->nprops) cp->allprops = 1; /* snag enableBLOB -- send to remote drivers too */ if (!strcmp (roottag, "enableBLOB")) // crackBLOB (pcdataXMLEle(root), &cp->blob); crackBLOBHandling (dev, name, pcdataXMLEle(root), cp); /* build a new message -- set content iff anyone cares */ mp = newMsg(); /* send message to driver(s) responsible for dev */ q2RDrivers (dev, mp, root); /* echo new* commands back to other clients */ if (!strncmp (roottag, "new", 3)) { if (q2Clients (cp, isblob, dev, name, mp, root) < 0) shutany++; } /* set message content if anyone cares else forget it */ if (mp->count > 0) setMsgXMLEle (mp, root); else freeMsg (mp); delXMLEle (root); } else if (err[0]) { char *ts = indi_tstamp(NULL); fprintf (stderr, "%s: Client %d: XML error: %s\n", ts, cp->s, err); fprintf (stderr, "%s: Client %d: XML read: %.*s\n", ts, cp->s, (int)nr, buf); shutdownClient (cp); return (-1); } } return (shutany ? -1 : 0); }
/* Read commands from FIFO and process them. Start/stop drivers accordingly */ void newFIFO(void) { //char line[MAXRBUF], tDriver[MAXRBUF], tConfig[MAXRBUF], tDev[MAXRBUF], tSkel[MAXRBUF], envDev[MAXRBUF], envConfig[MAXRBUF], envSkel[MAXR]; char line[MAXRBUF]; DvrInfo *dp = NULL; int startCmd=0, i=0; while (i < MAXRBUF) { if (read(fifo.fd, line+i, 1) <= 0) { // Reset FIFO now, otherwise select will always return with no data from FIFO. indiFIFO(); return; } if (line[i] == '\n') { line[i] = '\0'; i=0; } else { i++; continue; } if (verbose) fprintf(stderr, "FIFO: %s\n", line); char cmd[MAXSBUF], arg[4][1], var[4][MAXSBUF], tDriver[MAXSBUF], tName[MAXSBUF], envDev[MAXSBUF], envConfig[MAXSBUF], envSkel[MAXSBUF], envPrefix[MAXSBUF]; memset(&tDriver[0], 0, sizeof(MAXSBUF)); memset(&tName[0], 0, sizeof(MAXSBUF)); memset(&envDev[0], 0, sizeof(MAXSBUF)); memset(&envConfig[0], 0, sizeof(MAXSBUF)); memset(&envSkel[0], 0, sizeof(MAXSBUF)); memset(&envPrefix[0], 0, sizeof(MAXSBUF)); int n = sscanf(line, "%s %s -%1c \"%512[^\"]\" -%1c \"%512[^\"]\" -%1c \"%512[^\"]\" -%1c \"%512[^\"]\"", cmd, tDriver, arg[0], var[0], arg[1], var[1] , arg[2], var[2], arg[3], var[3]); int n_args = (n - 2)/2; int j=0; for (j=0; j < n_args; j++) { //fprintf(stderr, "arg[%d]: %c\n", i, arg[j][0]); //fprintf(stderr, "var[%d]: %s\n", i, var[j]); if (arg[j][0] == 'n') { strncpy(tName, var[j], MAXSBUF-1); tName[MAXSBUF-1] = '\0'; if (verbose) fprintf(stderr, "With name: %s\n", envDev); } else if (arg[j][0] == 'c') { strncpy(envConfig, var[j], MAXSBUF-1); envConfig[MAXSBUF-1] = '\0'; if (verbose) fprintf(stderr, "With config: %s\n", envConfig); } else if (arg[j][0] == 's') { strncpy(envSkel, var[j], MAXSBUF-1); envSkel[MAXSBUF-1] = '\0'; if (verbose) fprintf(stderr, "With skeketon: %s\n", envSkel); } else if (arg[j][0] == 'p') { strncpy(envPrefix, var[j], MAXSBUF-1); envPrefix[MAXSBUF-1] = '\0'; if (verbose) fprintf(stderr, "With prefix: %s\n", envPrefix); } } if (!strcmp(cmd, "start")) startCmd = 1; else startCmd = 0; if (startCmd) { if (verbose) fprintf(stderr, "FIFO: Starting driver %s with name (%s)\n", tDriver, tName); dp = allocDvr(); strncpy(dp->name, tDriver, MAXINDIDEVICE); //strncpy(dp->dev, tName, MAXINDIDEVICE); strncpy(dp->envDev, tName, MAXSBUF); strncpy(dp->envConfig, envConfig, MAXSBUF); strncpy(dp->envSkel, envSkel, MAXSBUF); strncpy(dp->envPrefix, envPrefix, MAXSBUF); startDvr (dp); } else { for (dp = dvrinfo; dp < &dvrinfo[ndvrinfo]; dp++) { fprintf(stderr, "dp->name: %s - tDriver: %s\n", dp->name, tDriver); if (!strcmp(dp->name, tDriver) && dp->active==1) { fprintf(stderr, "name: %s - dp->dev[0]: %s\n", tName, dp->dev[0]); /* If device name is given, check against it before shutting down */ //if (tName[0] && strcmp(dp->dev[0], tName)) if (tName[0] && isDeviceInDriver(tName, dp) == 0) continue; if (verbose) fprintf(stderr, "FIFO: Shutting down driver: %s\n", tDriver); for (i=0; i < dp->ndev; i++) { /* Inform clients that this driver is dead */ XMLEle *root = addXMLEle (NULL, "delProperty"); addXMLAtt(root, "device", dp->dev[i]); prXMLEle(stderr, root, 0); Msg * mp = newMsg(); q2Clients(NULL, 0, dp->dev[i], NULL, mp, root); if (mp->count > 0) setMsgXMLEle (mp, root); else freeMsg (mp); delXMLEle (root); } shutdownDvr(dp, 0); break; } } } } }
int main(int argc, char** argv){ if(argc != 1){ fprintf(stderr, "Usage: %s\n", argv[0]); } self_debug_flag = PVS_ACTOR_DEBUG; self = argv[0]; ec_neg1( iop_install_handlers(chld_handler, intr_handler) ); ec_neg1( pipe(pin) ); ec_neg1( pipe(perr) ); ec_neg1( pipe(pout) ); /*it's time to fork */ ec_neg1( child = fork() ); if(child == 0){ /* i'm destined to be pvs */ ec_neg1( dup2(pin[0], STDIN_FILENO) ); ec_neg1( dup2(perr[1], STDERR_FILENO) ); ec_neg1( dup2(pout[1], STDOUT_FILENO) ); ec_neg1( close(pin[0]) ); ec_neg1( close(perr[1]) ); ec_neg1( close(pout[1]) ); ec_neg1( execvp(pvs_exe, pvs_argv) ); } else { /* i'm the boss */ pthread_t errThread; fdBundle errFdB; /* for monitoring the error stream */ errFdB.fd = perr[0]; errFdB.exit = &child_died; ec_neg1( close(pin[0]) ); ec_neg1( close(perr[1]) ); ec_neg1( close(pout[1]) ); /* sleep(2); */ ec_rv( pthread_create(&errThread, NULL, echoErrorsSilently, &errFdB) ); announce("Listening to PVS\n"); parsePVSThenEcho("\ncl-user(", pout[0], STDOUT_FILENO); write(pin[1], "(in-package 'pvs)\n", strlen("(in-package 'pvs)\n")); announce("Listening to PVS\n"); parsePVSThenEcho("\npvs(", pout[0], STDOUT_FILENO); while(1){ int length, retval; msg *query = NULL, *response = NULL; char *sender, *command; announce("Listening to IO\n"); query = acceptMsg(STDIN_FILENO); if(query == NULL) continue; retval = parseActorMsg(query->data, &sender, &command); write(pin[1], command, strlen(command)); write(pin[1], "\n", 1); announce("Listening to PVS\n"); response = readPVSMsg("\npvs(", pout[0]); if(response != NULL){ length = parseString(response->data, response->bytesUsed); response->bytesUsed = length; sendFormattedMsgFP(stdout, "%s\n%s\n%s\n", sender, self, response->data); if(self_debug_flag)writeMsg(STDERR_FILENO, response); announce("\nparseThenEcho wrote %d bytes\n", response->bytesUsed); } freeMsg(query); freeMsg(response); } } exit(EXIT_SUCCESS); EC_CLEANUP_BGN exit(EXIT_FAILURE); EC_CLEANUP_END }