/* * Write nmea sentences to serial output * Args: pointer to interface * Returns: Nothing. errno supplied to iface_thread_exit() */ void write_serial(struct iface *ifa) { struct if_serial *ifs = (struct if_serial *) ifa->info; senblk_t *senblk_p; int fd=ifs->fd; int n=0; char *ptr; while(n >= 0) { /* NULL return from next_senblk means the queue has been shut * down. Time to die */ if ((senblk_p = next_senblk(ifa->q)) == NULL) break; if (senfilter(senblk_p,ifa->ofilter)) { senblk_free(senblk_p,ifa->q); continue; } ptr=senblk_p->data; while(senblk_p->len) { if ((n=write(fd,ptr,senblk_p->len)) < 0) break; senblk_p->len -=n; ptr+=n; } senblk_free(senblk_p,ifa->q); } iface_thread_exit(errno); }
/* * This is the heart of the multiplexer. All inputs add to the tail of the * Engine's queue. The engine takes from the head of its queue and copies * to all outputs on its output list. * Args: Pointer to information structure (iface_t, cast to void) * Returns: Nothing */ void *run_engine(void *info) { senblk_t *sptr; iface_t *optr; iface_t *eptr = (iface_t *)info; int retval=0; (void) pthread_detach(pthread_self()); for (;;) { sptr = next_senblk(eptr->q); if (isactive(eptr->ofilter,sptr)) { pthread_mutex_lock(&eptr->lists->io_mutex); /* Traverse list of outputs and push a copy of senblk to each */ for (optr=eptr->lists->outputs;optr;optr=optr->next) { if ((optr->q) && ((!sptr) || ((sptr->src != optr->id) || (flag_test(optr,F_LOOPBACK))))) { push_senblk(sptr,optr->q); } } pthread_mutex_unlock(&eptr->lists->io_mutex); } if (sptr==NULL) /* Queue has been marked inactive */ break; senblk_free(sptr,eptr->q); } pthread_exit(&retval); }
void write_tcp(struct iface *ifa) { struct if_tcp *ift = (struct if_tcp *) ifa->info; senblk_t *sptr; /* Porters: MSG_NOSIGNAL / SO_NOSIGPIPE are redundant as of v0.3: We're * ignorning SIGPIPE so you can forget this if porting to a platform on * which none of this is supported. Will be removed in a later release. */ #ifndef MSG_NOSIGNAL #define MSG_NOSIGNAL 0 int n=1; setsockopt(ift->fd,SOL_SOCKET, SO_NOSIGPIPE, (void *)&n, sizeof(int)); #endif for(;;) { if ((sptr = next_senblk(ifa->q)) == NULL) break; if (senfilter(sptr,ifa->ofilter)) { senblk_free(sptr,ifa->q); continue; } if ((send(ift->fd,sptr->data,sptr->len,MSG_NOSIGNAL)) <0) break; senblk_free(sptr,ifa->q); } iface_thread_exit(errno); }
void write_file(iface_t *ifa) { struct if_file *ifc = (struct if_file *) ifa->info; senblk_t *sptr; /* ifc->fp will only be NULL if we're opening a FIFO. */ if (ifc->fp == NULL) { if ((ifc->fp=fopen(ifc->filename,"w")) == NULL) { logerr(errno,"Failed to open FIFO %s for writing\n",ifc->filename); iface_thread_exit(errno); } if ((ifa->q =init_q(ifc->qsize)) == NULL) { logerr(errno,"Could not create queue for FIFO %s",ifc->filename); iface_thread_exit(errno); } if (setvbuf(ifc->fp,NULL,_IOLBF,0) !=0) iface_thread_exit(errno); } for(;;) { if ((sptr = next_senblk(ifa->q)) == NULL) { break; } if (senfilter(sptr,ifa->ofilter)) { senblk_free(sptr,ifa->q); continue; } if (ifc->usereturn == 0) { sptr->data[sptr->len-2] = '\n'; sptr->data[sptr->len-1] = '\0'; } if (fputs(sptr->data,ifc->fp) == EOF) { if (!(ifa->persist && errno == EPIPE) ) break; if (((ifc->fp=freopen(ifc->filename,"w",ifc->fp)) == NULL) || (setvbuf(ifc->fp,NULL,_IOLBF,0) !=0)) break; } senblk_free(sptr,ifa->q); } iface_thread_exit(errno); }
void write_file(iface_t *ifa) { struct if_file *ifc = (struct if_file *) ifa->info; senblk_t *sptr; int usereturn=flag_test(ifa,F_NOCR)?0:1; int data=0; int cnt=1; struct iovec iov[2]; /* ifc->fd will only be < 0 if we're opening a FIFO. */ if (ifc->fd < 0) { if ((ifc->fd=open(ifc->filename,O_WRONLY)) < 0) { logerr(errno,"Failed to open FIFO %s for writing\n",ifc->filename); iface_thread_exit(errno); } if ((ifa->q =init_q(ifc->qsize)) == NULL) { logerr(errno,"Could not create queue for FIFO %s",ifc->filename); iface_thread_exit(errno); } } if (ifa->tagflags) { if ((iov[0].iov_base=malloc(TAGMAX)) == NULL) { logerr(errno,"Disabing tag output on interface id %u (%s)", ifa->id,(ifa->name)?ifa->name:"unlabelled"); ifa->tagflags=0; } else { cnt=2; data=1; } } for(;;) { if ((sptr = next_senblk(ifa->q)) == NULL) { break; } if (senfilter(sptr,ifa->ofilter)) { senblk_free(sptr,ifa->q); continue; } if (!usereturn) { sptr->data[sptr->len-2] = '\n'; sptr->len--; } if (ifa->tagflags) if ((iov[0].iov_len = gettag(ifa,iov[0].iov_base,sptr)) == 0) { logerr(errno,"Disabing tag output on interface id %u (%s)", ifa->id,(ifa->name)?ifa->name:"unlabelled"); ifa->tagflags=0; cnt=1; data=0; free(iov[0].iov_base); } iov[data].iov_base=sptr->data; iov[data].iov_len=sptr->len; if (writev(ifc->fd,iov,cnt) <0) { if (!(flag_test(ifa,F_PERSIST) && errno == EPIPE) ) break; if ((ifc->fd=open(ifc->filename,O_WRONLY)) < 0) break; } senblk_free(sptr,ifa->q); } if (cnt == 2) free(iov[0].iov_base); iface_thread_exit(errno); }