/** Setting up aperture cordinate grid aper_locs, and amplitude map for performance evaluation. */ APER_T * setup_aper(const PARMS_T *const parms){ APER_T *aper = mycalloc(1,APER_T); tic; if(parms->aper.fnamp){ info2("Reading aperture amplitude map from %s\n", parms->aper.fnamp); aper->ampground=mapread("%s",parms->aper.fnamp); if(fabs(aper->ampground->h)>1.e-14){ warning("ampground is not on ground, this is not tested\n"); }else{ double amp_d, amp_din; map_d_din(aper->ampground, &_d, &_din); if(fabs(parms->aper.d - amp_d) > 1 || fabs(parms->aper.din - amp_din) > 0.5){ if(!parms->aper.fnampuser){ warning2("Amplitude map does not match aperture diameter: amp.d=(%g, %g) aper.d=(%g, %g). Disabled\n", amp_d, amp_din, parms->aper.d, parms->aper.din); mapfree(aper->ampground); free(((PARMS_T*)parms)->aper.fnamp); ((PARMS_T*)parms)->aper.fnamp=0; }else{ error("Use supplied amplitude map does not match aperture diameter: amp.d=(%g, %g) aper.d=(%g, %g).\n", amp_d, amp_din, parms->aper.d, parms->aper.din); } } } if(fabs(parms->aper.rotdeg)>1.e-12){ warning("Pupil is rotated by %g deg\n",parms->aper.rotdeg); const long nx=aper->ampground->nx; const long ny=aper->ampground->ny; dmat *B=dnew_data(nx, ny, aper->ampground->p); aper->ampground->p=mycalloc(nx*ny,double); dembed((dmat*)aper->ampground,B,parms->aper.rotdeg/180.*M_PI); dfree(B); }
static void signal_handler(int sig, self_code_info_t *info, self_sig_context_t *scp) { if (InterruptedContext::the_interrupted_context->forwarded_to_self_thread(sig)) return; if (SignalInterface::currentNonTimerSignal || SignalInterface::currentTimerSignal) { fatal3("signal_handler: cannot nest (only one interrupted context).\n" "Received sig %d while in sig %d or timer sig %d.\n" "MacOSX ApplicationEnhancer causes apps to get signals that should be blocked.", sig, SignalInterface::currentNonTimerSignal, SignalInterface::currentTimerSignal); } SignalInterface::currentNonTimerSignal = sig; sigset_t oset; if (sigprocmask(0, NULL, &oset) != 0) { perror("sigprocmask"); fatal("sigprocmask failed"); } if (!sigismember(&oset, sig)) # ifdef ROSETTA warning2("signal %d is not member of 0x%x", sig, oset); # else fatal2("signal %d is not member of 0x%x", sig, (int*)(int*)&oset); # endif InterruptedContext::the_interrupted_context->set(scp); SignalInterface::handle_signal( sig, info == NULL ? NULL : (char*)info->si_addr, info == NULL ? NULL : info->si_code ); InterruptedContext::the_interrupted_context->invalidate(); SignalInterface::currentNonTimerSignal = 0; }
/* Add a parameter to the current element */ void addpar(M_NOPAR) { PARAMETER *paramp, *last = NULL ; int length ; parcount++ ; pcount++ ; for (paramp = plist ; paramp ; paramp = paramp->next) { if (w_strcmp(name, paramp->paramname) == 0) warning2("Multiple definition of parameter %s for element %s", name, thisrule) ; last = paramp ; } newpar = (PARAMETER *) m_malloc(sizeof(PARAMETER), "parameter") ; if (! plist) plist = newpar ; else last->next = newpar ; *nextpar = newpar ; nextpar = &newpar->nextptr ; *nextpar = NULL ; newpar->next = NULL ; newpar->deftype = NULLDEF ; newpar->defval = M_NULLVAL ; newpar->defstring = NULL ; newpar->kwlist = M_NULLVAL ; length = w_strlen(name) + 1 ; pnamelen += length ; newpar->paramname = (M_WCHAR *) m_malloc(length, "parameter name") ; w_strcpy(newpar->paramname, name) ; newpar->ptypep = NULL ; }
int32 MonitorSampledBar::used2() { int32 u = sum3 + sum4; int32 c = capacity(); // this can exceed capacity slightly due to sampling errors if (u > 2*c) warning2("MonitorSampledBar: usage(2) is way too high: %ld >> %ld", u, c); return u <= c ? u : c; }
bool XPlatformWindow::open_xdisplay(const char *n) { if (n == NULL) n = ""; _display = XOpenDisplay(n); if (_display == NULL) { warning2("cannot open X display '%s' a.k.a. '%s'! window won't work.", n, XDisplayName(n)); return false; } return true; }
/** Connect to a host at port. hostname may start with / to indicate a local UNIX port */ int connect_port(const char *hostname, int port, int block, int nodelay){ int sock=-1; if(hostname[0]=='/'){//connect locally so we can pass fd. sock = socket(PF_UNIX, SOCK_STREAM, 0); struct sockaddr_un addr={0}; addr.sun_family=AF_UNIX; strncpy(addr.sun_path, hostname, sizeof(addr.sun_path)-1); if(connect(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr_un))<0){ warning("connect locally failed: %s\n", strerror(errno)); close(sock); sock=-1; } return sock; //hostname="localhost"; }else{ //if(sock!=-1) return sock; struct sockaddr_in servername; for(int count=0; count<25; count++){ sock = socket (PF_INET, SOCK_STREAM, 0); socket_tcp_keepalive(sock); if(nodelay){ socket_tcp_nodelay(sock); } if(!block){ socket_block(sock, 0); } int res; struct addrinfo *result; struct addrinfo hints={0}; hints.ai_family=AF_INET; hints.ai_socktype=SOCK_STREAM; char portstr[20]; snprintf(portstr, 20, "%d", port); if((res=getaddrinfo(hostname, portstr, &hints, &result))){ warning("getaddrinfo for %s failed with %d: %s\n", hostname, res, gai_strerror(res)); return -1; } res=connect(sock, result->ai_addr, sizeof (servername)); freeaddrinfo(result); /* Give the socket the target hostname. */ if(res<0){ warning2("connect to %s at %d failed: %s\n", hostname, port, strerror(errno)); close(sock); if(!block){ return -1; } sleep(10); }else{ return sock; } } } return -1; }
static OSStatus playProc(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets, AudioBufferList *outOutputData, AudioStreamPacketDescription **outDataPacketDescription, void* inClientData) { mpg123_coreaudio_t *ca = (mpg123_coreaudio_t *)inClientData; long n; if(ca->last_buffer) { ca->play_done = 1; return noErr; } for(n = 0; n < outOutputData->mNumberBuffers; n++) { unsigned int wanted = *ioNumberDataPackets * ca->channels * ca->bps; unsigned char *dest; unsigned int read; if(ca->buffer_size < wanted) { debug1("Allocating %d byte sample conversion buffer", wanted); ca->buffer = realloc( ca->buffer, wanted); ca->buffer_size = wanted; } dest = ca->buffer; /* Only play if we have data left */ if ( sfifo_used( &ca->fifo ) < (int)wanted ) { if(!ca->decode_done) { warning("Didn't have any audio data in callback (buffer underflow)"); return -1; } wanted = sfifo_used( &ca->fifo ); ca->last_buffer = 1; } /* Read audio from FIFO to SDL's buffer */ read = sfifo_read( &ca->fifo, dest, wanted ); if (wanted!=read) warning2("Error reading from the ring buffer (wanted=%u, read=%u).\n", wanted, read); outOutputData->mBuffers[n].mDataByteSize = read; outOutputData->mBuffers[n].mData = dest; } return noErr; }
/* The audio function callback takes the following parameters: stream: A pointer to the audio buffer to be filled len: The length (in bytes) of the audio buffer */ static void audio_callback_sdl(void *udata, Uint8 *stream, int len) { out123_handle *ao = (out123_handle*)udata; sfifo_t *fifo = (sfifo_t*)ao->userptr; int bytes_read; int bytes_avail; bytes_avail = sfifo_used(fifo); if(bytes_avail < len) len = bytes_avail; /* Read audio from FIFO to SDL's buffer */ bytes_read = sfifo_read( fifo, stream, len ); if (len!=bytes_read) warning2("Error reading from the FIFO (wanted=%u, bytes_read=%u).\n", len, bytes_read); }
/** Time domain physical simulation. noisy: - 0: no noise at all; - 1: poisson and read out noise. - 2: only poisson noise. */ dmat *skysim_sim(dmat **mresout, const dmat *mideal, const dmat *mideal_oa, double ngsol, ASTER_S *aster, const POWFS_S *powfs, const PARMS_S *parms, int idtratc, int noisy, int phystart){ int dtratc=0; if(!parms->skyc.multirate){ dtratc=parms->skyc.dtrats->p[idtratc]; } int hasphy; if(phystart>-1 && phystart<aster->nstep){ hasphy=1; }else{ hasphy=0; } const int nmod=mideal->nx; dmat *res=dnew(6,1);/*Results. 1-2: NGS and TT modes., 3-4:On axis NGS and TT modes, 4-6: On axis NGS and TT wihtout considering un-orthogonality.*/ dmat *mreal=NULL;/*modal correction at this step. */ dmat *merr=dnew(nmod,1);/*modal error */ dcell *merrm=dcellnew(1,1);dcell *pmerrm=NULL; const int nstep=aster->nstep?aster->nstep:parms->maos.nstep; dmat *mres=dnew(nmod,nstep); dmat* rnefs=parms->skyc.rnefs; dcell *zgradc=dcellnew3(aster->nwfs, 1, aster->ngs, 0); dcell *gradout=dcellnew3(aster->nwfs, 1, aster->ngs, 0); dmat *gradsave=0; if(parms->skyc.dbg){ gradsave=dnew(aster->tsa*2,nstep); } SERVO_T *st2t=0; kalman_t *kalman=0; dcell *mpsol=0; dmat *pgm=0; dmat *dtrats=0; int multirate=parms->skyc.multirate; if(multirate){ kalman=aster->kalman[0]; dtrats=aster->dtrats; }else{ if(parms->skyc.servo>0){ const double dtngs=parms->maos.dt*dtratc; st2t=servo_new(merrm, NULL, 0, dtngs, aster->gain->p[idtratc]); pgm=aster->pgm->p[idtratc]; }else{ kalman=aster->kalman[idtratc]; } } if(kalman){ kalman_init(kalman); mpsol=dcellnew(aster->nwfs, 1); //for psol grad. } const long nwvl=parms->maos.nwvl; dcell **psf=0, **mtche=0, **ints=0; ccell *wvf=0,*wvfc=0, *otf=0; if(hasphy){ psf=mycalloc(aster->nwfs,dcell*); wvf=ccellnew(aster->nwfs,1); wvfc=ccellnew(aster->nwfs,1); mtche=mycalloc(aster->nwfs,dcell*); ints=mycalloc(aster->nwfs,dcell*); otf=ccellnew(aster->nwfs,1); for(long iwfs=0; iwfs<aster->nwfs; iwfs++){ const int ipowfs=aster->wfs[iwfs].ipowfs; const long ncomp=parms->maos.ncomp[ipowfs]; const long nsa=parms->maos.nsa[ipowfs]; wvf->p[iwfs]=cnew(ncomp,ncomp); wvfc->p[iwfs]=NULL; psf[iwfs]=dcellnew(nsa,nwvl); //cfft2plan(wvf->p[iwfs], -1); if(parms->skyc.multirate){ mtche[iwfs]=aster->wfs[iwfs].pistat->mtche[(int)aster->idtrats->p[iwfs]]; }else{ mtche[iwfs]=aster->wfs[iwfs].pistat->mtche[idtratc]; } otf->p[iwfs]=cnew(ncomp,ncomp); //cfft2plan(otf->p[iwfs],-1); //cfft2plan(otf->p[iwfs],1); ints[iwfs]=dcellnew(nsa,1); int pixpsa=parms->skyc.pixpsa[ipowfs]; for(long isa=0; isa<nsa; isa++){ ints[iwfs]->p[isa]=dnew(pixpsa,pixpsa); } } } for(int irep=0; irep<parms->skyc.navg; irep++){ if(kalman){ kalman_init(kalman); }else{ servo_reset(st2t); } dcellzero(zgradc); dcellzero(gradout); if(ints){ for(int iwfs=0; iwfs<aster->nwfs; iwfs++){ dcellzero(ints[iwfs]); } } for(int istep=0; istep<nstep; istep++){ memcpy(merr->p, PCOL(mideal,istep), nmod*sizeof(double)); dadd(&merr, 1, mreal, -1);/*form NGS mode error; */ memcpy(PCOL(mres,istep),merr->p,sizeof(double)*nmod); if(mpsol){//collect averaged modes for PSOL. for(long iwfs=0; iwfs<aster->nwfs; iwfs++){ dadd(&mpsol->p[iwfs], 1, mreal, 1); } } pmerrm=0; if(istep>=parms->skyc.evlstart){/*performance evaluation*/ double res_ngs=dwdot(merr->p,parms->maos.mcc,merr->p); if(res_ngs>ngsol*100){ dfree(res); res=NULL; break; } { res->p[0]+=res_ngs; res->p[1]+=dwdot2(merr->p,parms->maos.mcc_tt,merr->p); double dot_oa=dwdot(merr->p, parms->maos.mcc_oa, merr->p); double dot_res_ideal=dwdot(merr->p, parms->maos.mcc_oa, PCOL(mideal,istep)); double dot_res_oa=0; for(int imod=0; imod<nmod; imod++){ dot_res_oa+=merr->p[imod]*IND(mideal_oa,imod,istep); } res->p[2]+=dot_oa-2*dot_res_ideal+2*dot_res_oa; res->p[4]+=dot_oa; } { double dot_oa_tt=dwdot2(merr->p, parms->maos.mcc_oa_tt, merr->p); /*Notice that mcc_oa_tt2 is 2x5 marix. */ double dot_res_ideal_tt=dwdot(merr->p, parms->maos.mcc_oa_tt2, PCOL(mideal,istep)); double dot_res_oa_tt=0; for(int imod=0; imod<2; imod++){ dot_res_oa_tt+=merr->p[imod]*IND(mideal_oa,imod,istep); } res->p[3]+=dot_oa_tt-2*dot_res_ideal_tt+2*dot_res_oa_tt; res->p[5]+=dot_oa_tt; } }//if evl if(istep<phystart || phystart<0){ /*Ztilt, noise free simulation for acquisition. */ dmm(&zgradc->m, 1, aster->gm, merr, "nn", 1);/*grad due to residual NGS mode. */ for(int iwfs=0; iwfs<aster->nwfs; iwfs++){ const int ipowfs=aster->wfs[iwfs].ipowfs; const long ng=parms->maos.nsa[ipowfs]*2; for(long ig=0; ig<ng; ig++){ zgradc->p[iwfs]->p[ig]+=aster->wfs[iwfs].ztiltout->p[istep*ng+ig]; } } for(int iwfs=0; iwfs<aster->nwfs; iwfs++){ int dtrati=(multirate?(int)dtrats->p[iwfs]:dtratc); if((istep+1) % dtrati==0){ dadd(&gradout->p[iwfs], 0, zgradc->p[iwfs], 1./dtrati); dzero(zgradc->p[iwfs]); if(noisy){ int idtrati=(multirate?(int)aster->idtrats->p[iwfs]:idtratc); dmat *nea=aster->wfs[iwfs].pistat->sanea->p[idtrati]; for(int i=0; i<nea->nx; i++){ gradout->p[iwfs]->p[i]+=nea->p[i]*randn(&aster->rand); } } pmerrm=merrm;//record output. } } }else{ /*Accumulate PSF intensities*/ for(long iwfs=0; iwfs<aster->nwfs; iwfs++){ const double thetax=aster->wfs[iwfs].thetax; const double thetay=aster->wfs[iwfs].thetay; const int ipowfs=aster->wfs[iwfs].ipowfs; const long nsa=parms->maos.nsa[ipowfs]; ccell* wvfout=aster->wfs[iwfs].wvfout[istep]; for(long iwvl=0; iwvl<nwvl; iwvl++){ double wvl=parms->maos.wvl[iwvl]; for(long isa=0; isa<nsa; isa++){ ccp(&wvfc->p[iwfs], IND(wvfout,isa,iwvl)); /*Apply NGS mode error to PSF. */ ngsmod2wvf(wvfc->p[iwfs], wvl, merr, powfs+ipowfs, isa, thetax, thetay, parms); cembedc(wvf->p[iwfs],wvfc->p[iwfs],0,C_FULL); cfft2(wvf->p[iwfs],-1); /*peak in corner. */ cabs22d(&psf[iwfs]->p[isa+nsa*iwvl], 1., wvf->p[iwfs], 1.); }/*isa */ }/*iwvl */ }/*iwfs */ /*Form detector image from accumulated PSFs*/ double igrad[2]; for(long iwfs=0; iwfs<aster->nwfs; iwfs++){ int dtrati=dtratc, idtrat=idtratc; if(multirate){//multirate idtrat=aster->idtrats->p[iwfs]; dtrati=dtrats->p[iwfs]; } if((istep+1) % dtrati == 0){/*has output */ dcellzero(ints[iwfs]); const int ipowfs=aster->wfs[iwfs].ipowfs; const long nsa=parms->maos.nsa[ipowfs]; for(long isa=0; isa<nsa; isa++){ for(long iwvl=0; iwvl<nwvl; iwvl++){ double siglev=aster->wfs[iwfs].siglev->p[iwvl]; ccpd(&otf->p[iwfs],psf[iwfs]->p[isa+nsa*iwvl]); cfft2i(otf->p[iwfs], 1); /*turn to OTF, peak in corner */ ccwm(otf->p[iwfs], powfs[ipowfs].dtf[iwvl].nominal); cfft2(otf->p[iwfs], -1); dspmulcreal(ints[iwfs]->p[isa]->p, powfs[ipowfs].dtf[iwvl].si, otf->p[iwfs]->p, siglev); } /*Add noise and apply matched filter. */ #if _OPENMP >= 200805 #pragma omp critical #endif switch(noisy){ case 0:/*no noise at all. */ break; case 1:/*both poisson and read out noise. */ { double bkgrnd=aster->wfs[iwfs].bkgrnd*dtrati; addnoise(ints[iwfs]->p[isa], &aster->rand, bkgrnd, bkgrnd, 0,0,IND(rnefs,idtrat,ipowfs)); } break; case 2:/*there is still poisson noise. */ addnoise(ints[iwfs]->p[isa], &aster->rand, 0, 0, 0,0,0); break; default: error("Invalid noisy\n"); } igrad[0]=0; igrad[1]=0; double pixtheta=parms->skyc.pixtheta[ipowfs]; if(parms->skyc.mtch){ dmulvec(igrad, mtche[iwfs]->p[isa], ints[iwfs]->p[isa]->p, 1); } if(!parms->skyc.mtch || fabs(igrad[0])>pixtheta || fabs(igrad[1])>pixtheta){ if(!parms->skyc.mtch){ warning2("fall back to cog\n"); }else{ warning_once("mtch is out of range\n"); } dcog(igrad, ints[iwfs]->p[isa], 0, 0, 0, 3*IND(rnefs,idtrat,ipowfs), 0); igrad[0]*=pixtheta; igrad[1]*=pixtheta; } gradout->p[iwfs]->p[isa]=igrad[0]; gradout->p[iwfs]->p[isa+nsa]=igrad[1]; }/*isa */ pmerrm=merrm; dcellzero(psf[iwfs]);/*reset accumulation.*/ }/*if iwfs has output*/ }/*for wfs*/ }/*if phystart */ //output to mreal after using it to ensure two cycle delay. if(st2t){//Type I or II control. if(st2t->mint->p[0]){//has output. dcp(&mreal, st2t->mint->p[0]->p[0]); } }else{//LQG control kalman_output(kalman, &mreal, 0, 1); } if(kalman){//LQG control int indk=0; //Form PSOL grads and obtain index to LQG M for(int iwfs=0; iwfs<aster->nwfs; iwfs++){ int dtrati=(multirate?(int)dtrats->p[iwfs]:dtratc); if((istep+1) % dtrati==0){ indk|=1<<iwfs; dmm(&gradout->p[iwfs], 1, aster->g->p[iwfs], mpsol->p[iwfs], "nn", 1./dtrati); dzero(mpsol->p[iwfs]); } } if(indk){ kalman_update(kalman, gradout->m, indk-1); } }else if(st2t){ if(pmerrm){ dmm(&merrm->p[0], 0, pgm, gradout->m, "nn", 1); } servo_filter(st2t, pmerrm);//do even if merrm is zero. to simulate additional latency } if(parms->skyc.dbg){ memcpy(PCOL(gradsave, istep), gradout->m->p, sizeof(double)*gradsave->nx); } }/*istep; */ } if(parms->skyc.dbg){ int dtrati=(multirate?(int)dtrats->p[0]:dtratc); writebin(gradsave,"%s/skysim_grads_aster%d_dtrat%d",dirsetup, aster->iaster,dtrati); writebin(mres,"%s/skysim_sim_mres_aster%d_dtrat%d",dirsetup,aster->iaster,dtrati); } dfree(mreal); dcellfree(mpsol); dfree(merr); dcellfree(merrm); dcellfree(zgradc); dcellfree(gradout); dfree(gradsave); if(hasphy){ dcellfreearr(psf, aster->nwfs); dcellfreearr(ints, aster->nwfs); ccellfree(wvf); ccellfree(wvfc); ccellfree(otf); free(mtche); } servo_free(st2t); /*dfree(mres); */ if(mresout) { *mresout=mres; }else{ dfree(mres); } dscale(res, 1./((nstep-parms->skyc.evlstart)*parms->skyc.navg)); return res; }
/** Open a port and listen to it. Calls respond(sock) to handle data. If timeout_fun is not NULL, it will be called when 1) connection is establed/handled, 2) every timeout_sec if timeout_sec>0. This function only return at error. if localpath is not null and start with /, open the local unix port also if localpath is not null and contains ip address, only bind to that ip address */ void listen_port(uint16_t port, char *localpath, int (*responder)(int), double timeout_sec, void (*timeout_fun)(), int nodelay){ register_signal_handler(scheduler_signal_handler); fd_set read_fd_set; fd_set active_fd_set; FD_ZERO (&active_fd_set); char *ip=0; int sock_local=-1; if(localpath){ if(localpath[0]=='/'){ //also bind to AF_UNIX sock_local = bind_socket_local(localpath); if(sock_local==-1){ info("bind to %s failed\n", localpath); }else{ if(!listen(sock_local, 1)){ FD_SET(sock_local, &active_fd_set); }else{ perror("listen"); close(sock_local); sock_local=-1; } } }else{ ip=localpath; } } int sock = bind_socket (ip, port); if(nodelay){//turn off tcp caching. socket_tcp_nodelay(sock); } if (listen (sock, 1) < 0){ perror("listen"); exit(EXIT_FAILURE); } FD_SET (sock, &active_fd_set); while(quit_listen!=2){ if(quit_listen==1){ /* shutdown(sock, SHUT_WR) sends a FIN to the peer, therefore initialize a active close and the port will remain in TIME_WAIT state. shutdown(sock, SHUT_RD) sends nother, just mark the scoket as not readable. accept() create a new socket on the existing port. A socket is identified by client ip/port and server ip/port. It is the port that remain in TIME_WAIT state. */ //shutdown(sock, SHUT_RDWR); //shutdown(sock_local, SHUT_RDWR); /*Notice existing client to shutdown*/ for(int i=0; i<FD_SETSIZE; i++){ if(FD_ISSET(i, &active_fd_set) && i!=sock && i!=sock_local){ int cmd[3]={-1, 0, 0}; stwrite(i, cmd, 3*sizeof(int)); //We ask the client to actively close the connection //shutdown(i, SHUT_WR); } } usleep(1e5); quit_listen=2; //don't break. Listen for connection close events. } if(timeout_fun){ timeout_fun(); } struct timeval timeout; timeout.tv_sec=timeout_sec; timeout.tv_usec=(timeout_sec-timeout.tv_sec)*1e6; read_fd_set = active_fd_set; if(select(FD_SETSIZE, &read_fd_set, NULL, NULL, &timeout)<0){ if(errno==EINTR){ warning("select failed: %s\n", strerror(errno)); continue; }else if(errno==EBADF){ warning("bad file descriptor: %s\n", strerror(errno)); break;//bad file descriptor }else{ warning("unknown error: %s\n", strerror(errno)); break; } } for(int i=0; i<FD_SETSIZE; i++){ if(FD_ISSET(i, &read_fd_set)){ if(i==sock){ /* Connection request on original socket. */ socklen_t size=sizeof(struct sockaddr_in); struct sockaddr_in clientname; int port2=accept(i, (struct sockaddr*)&clientname, &size); if(port2<0){ warning("accept failed: %s. close port %d\n", strerror(errno), i); FD_CLR(i, &active_fd_set); close(i); }else{ info2("port %d is connected\n", port2); FD_SET(port2, &active_fd_set); } }else if(i==sock_local){ socklen_t size=sizeof(struct sockaddr_un); struct sockaddr_un clientname; int port2=accept(i, (struct sockaddr*)&clientname, &size); if(port2<0){ warning("accept failed: %s. close port %d\n", strerror(errno), i); FD_CLR(i, &active_fd_set); close(i); }else{ info2("port %d is connected locally\n", port2); FD_SET(port2, &active_fd_set); } }else{ /* Data arriving on an already-connected socket. Call responder to handle. On return: negative value: Close read of socket. -1: also close the socket. */ int ans=responder(i); if(ans<0){ FD_CLR(i, &active_fd_set); if(ans==-1){ warning2("close port %d\n", i); close(i); }else{ warning("ans=%d is not understood.\n", ans); } } } } } } /* Error happened. We close all connections and this server socket.*/ close(sock); close(sock_local); FD_CLR(sock, &active_fd_set); FD_CLR(sock_local, &active_fd_set); warning("listen_port exited\n"); for(int i=0; i<FD_SETSIZE; i++){ if(FD_ISSET(i, &active_fd_set)){ warning("sock %d is still connected\n", i); close(i); FD_CLR(i, &active_fd_set); } } usleep(100); sync(); }