Exemplo n.º 1
0
static void process_signals(void)
{
	int x;

	if (!signal_received)
		return;

	signal_received = 0;

	for (x = 1; x < _NSIG; x++) {
		if (sigismember(&signal_mask, x)) {
			sigdelset(&signal_mask, x);
			process_signal(x);
		}
	}
}
Exemplo n.º 2
0
void fit_complete_signal(matrix* ols_fit, matrix* design_matrix, matrix* signal, double min_signal, 
        double min_diffusivity, tensor** tensor_output) {
    int number_of_signals = signal->rows;
    int signal_elements = signal->columns;
    matrix* processed_signal_gpu = process_signal(signal, min_signal);

    //Switching dimensions to simulator transpose and conversion to column major 
    processed_signal_gpu->rows = signal_elements;
    processed_signal_gpu->columns = number_of_signals;

    matrix* column_major_weights_gpu = generate_weights(ols_fit, processed_signal_gpu);
    matrix* column_major_design_matrix_gpu = process_matrix(design_matrix);

    //Switching dimensions back
    processed_signal_gpu->rows = number_of_signals;
    processed_signal_gpu->columns = signal_elements;

    double* tensors_gpu = cuda_fitter(column_major_design_matrix_gpu, column_major_weights_gpu, 
            processed_signal_gpu);
    double* padded_eigendecompositions_gpu = cuda_decompose_tensors(tensors_gpu, column_major_design_matrix_gpu->columns , number_of_signals);
    cudaDeviceSynchronize();
    extract_eigendecompositions(padded_eigendecompositions_gpu, tensor_output, number_of_signals, min_diffusivity);
}
Exemplo n.º 3
0
Arquivo: sidc.c Projeto: sorki/sidc
int main( int argc, char *argv[])
{
   while( 1)
   {
      int c = getopt( argc, argv, "vfmic:p:");

      if( c == 'v') VFLAG++;
      else
      if( c == 'f') background = 0;
      else
      if( c == 'c') config_file = optarg;
      else
      if( c == 'p') pid_file = optarg;
      else
      if( c == -1) break;
      else bailout( "unknown option [%c]", c);
   }

   setup_signal_handling();
   load_config();

   if( CF_output_policy != OP_SPECTRUM)
   {
      int i;
      struct BAND *b;

      for( i=0, b=bands; i<nbands; i++, b++)
         report( 1, "band %s %d %d %s",
            b->ident, b->start, b->end, b->side->name);
   }

   if( background && !logfile)
      report( -1, "warning: no logfile specified for daemon");

   if( background) make_daemon();

   setup_input_stream();

   DF = (double) CF_sample_rate/(double) FFTWID;
   report( 1, "resolution: bins=%d fftwid=%d df=%f", CF_bins, FFTWID, DF);

   if( CF_uspec_file)
   {
      // Convert CF_uspec_secs seconds to uspec_max frames
      uspec_max = rint( CF_uspec_secs * CF_sample_rate / FFTWID);
      report( 2, "utility spectrum interval: %d frames", uspec_max);
      report( 2, "utility spectrum file: %s", CF_uspec_file); 
   }

   // Convert CF_output_interval seconds to output_int frames
   output_int = rint( CF_output_interval * CF_sample_rate / FFTWID);
   if( output_int == 0) output_int = 1;
   report( 2, "output interval: %d frames", output_int);

   if( CF_output_policy == OP_SPECTRUM)
   {
      // Convert range variables Hertz to bins
      cuton = CF_range1 / DF;
      cutoff = CF_range2 / DF;
      report( 2, "output bins: %d to %d", cuton, cutoff);
   }   

   // Both sets of channel data structures are initialised, even if mono
   initialise_channel( &left);
   initialise_channel( &right);

   setup_hamming_window();

   if( CF_card_delay) sleep( CF_card_delay);
   report( 0, "sidc version %s %s: starting work",
      PACKAGE_VERSION, soundsystem);
   alert_on = 1;
   if( CF_priority) set_scheduling();   // Setup real time scheduling

   process_signal();

   if( CF_output_policy != OP_SPECTRUM)
   {
      int i;
      struct BAND *b;

      for( i=0, b=bands; i<nbands; i++, b++)
         free( b->ident);
   }
   if( CF_uspec_file)
      free( CF_uspec_file);
   if( CF_mailaddr)
      free( CF_mailaddr);
   if( out_prefix)
      free( out_prefix);
   return 0;
}
Exemplo n.º 4
0
void network_thread ()
{
    /*
     * We loop forever waiting on either data from the ppp drivers or from
     * our network socket.  Control handling is no longer done here.
     */
    struct sockaddr_in from;
    struct in_pktinfo to;
    unsigned int fromlen;
    int tunnel, call;           /* Tunnel and call */
    int recvsize;               /* Length of data received */
    struct buffer *buf;         /* Payload buffer */
    struct call *c, *sc;        /* Call to send this off to */
    struct tunnel *st;          /* Tunnel */
    fd_set readfds;             /* Descriptors to watch for reading */
    int max;                    /* Highest fd */
    struct timeval tv, *ptv;    /* Timeout for select */
    struct msghdr msgh;
    struct iovec iov;
    char cbuf[256];
    unsigned int refme, refhim;
    int * currentfd;
    int server_socket_processed;

#ifdef HIGH_PRIO
    /* set high priority */
    if (setpriority(PRIO_PROCESS, 0, -20) < 0)
	l2tp_log (LOG_INFO, "xl2tpd: can't set priority to high: %m");
#endif

    /* This one buffer can be recycled for everything except control packets */
    buf = new_buf (MAX_RECV_SIZE);

    tunnel = 0;
    call = 0;

    for (;;)
    {
        int ret;
        process_signal();
        max = build_fdset (&readfds);
        ptv = process_schedule(&tv);
        ret = select (max + 1, &readfds, NULL, NULL, ptv);

        if (ret <= 0)
        {
#ifdef DEBUG_MORE
            if (ret == 0)
            {
                if (gconfig.debug_network)
                {
                    l2tp_log (LOG_DEBUG, "%s: select timeout\n", __FUNCTION__);
                }
            }
            else
            {
                if (gconfig.debug_network)
                {
                    l2tp_log (LOG_DEBUG,
                        "%s: select returned error %d (%s)\n",
                        __FUNCTION__, errno, strerror (errno));
                }
            }
#endif
            continue;
        }

        if (FD_ISSET (control_fd, &readfds))
        {
            do_control ();
        }
        server_socket_processed = 0;
        currentfd = NULL;
        st = tunnels.head;
        while (st || !server_socket_processed) {
            if (st && (st->udp_fd == -1)) {
                st=st->next;
                continue;
            }
            if (st) {
                currentfd = &st->udp_fd;
            } else {
                currentfd = &server_socket;
                server_socket_processed = 1;
            }
            if (FD_ISSET (*currentfd, &readfds))
        {
            /*
             * Okay, now we're ready for reading and processing new data.
             */
            recycle_buf (buf);

            /* Reserve space for expanding payload packet headers */
            buf->start += PAYLOAD_BUF;
            buf->len -= PAYLOAD_BUF;

	    memset(&from, 0, sizeof(from));
	    memset(&to,   0, sizeof(to));
	    
	    fromlen = sizeof(from);
	    
	    memset(&msgh, 0, sizeof(struct msghdr));
	    iov.iov_base = buf->start;
	    iov.iov_len  = buf->len;
	    msgh.msg_control = cbuf;
	    msgh.msg_controllen = sizeof(cbuf);
	    msgh.msg_name = &from;
	    msgh.msg_namelen = fromlen;
	    msgh.msg_iov  = &iov;
	    msgh.msg_iovlen = 1;
	    msgh.msg_flags = 0;
	    
	    /* Receive one packet. */
	    recvsize = recvmsg(*currentfd, &msgh, 0);

            if (recvsize < MIN_PAYLOAD_HDR_LEN)
            {
                if (recvsize < 0)
                {
                    if (errno == ECONNREFUSED) {
                        close(*currentfd);
                    }
                    if ((errno == ECONNREFUSED) ||
                        (errno == EBADF)) {
                        *currentfd = -1;
                    }
                    if (errno != EAGAIN)
                        l2tp_log (LOG_WARNING,
                             "%s: recvfrom returned error %d (%s)\n",
                             __FUNCTION__, errno, strerror (errno));
                }
                else
                {
                    l2tp_log (LOG_WARNING, "%s: received too small a packet\n",
                         __FUNCTION__);
                }
                if (st) st=st->next;
		continue;
            }


	    refme=refhim=0;


		struct cmsghdr *cmsg;
		/* Process auxiliary received data in msgh */
		for (cmsg = CMSG_FIRSTHDR(&msgh);
			cmsg != NULL;
			cmsg = CMSG_NXTHDR(&msgh,cmsg)) {
			/* extract destination(our) addr */
			if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) {
				struct in_pktinfo* pktInfo = ((struct in_pktinfo*)CMSG_DATA(cmsg));
				to = *pktInfo;
			}
			/* extract IPsec info out */
			else if (gconfig.ipsecsaref && cmsg->cmsg_level == IPPROTO_IP
			&& cmsg->cmsg_type == gconfig.sarefnum) {
				unsigned int *refp;
				
				refp = (unsigned int *)CMSG_DATA(cmsg);
				refme =refp[0];
				refhim=refp[1];
			}
		}

	    /*
	     * some logic could be added here to verify that we only
	     * get L2TP packets inside of IPsec, or to provide different
	     * classes of service to packets not inside of IPsec.
	     */
	    buf->len = recvsize;
	    fix_hdr (buf->start);
	    extract (buf->start, &tunnel, &call);

	    if (gconfig.debug_network)
	    {
		l2tp_log(LOG_DEBUG, "%s: recv packet from %s, size = %d, "
			 "tunnel = %d, call = %d ref=%u refhim=%u\n",
			 __FUNCTION__, inet_ntoa (from.sin_addr),
			 recvsize, tunnel, call, refme, refhim);
	    }

	    if (gconfig.packet_dump)
	    {
		do_packet_dump (buf);
	    }
			if (!(c = get_call (tunnel, call, from.sin_addr,
			       from.sin_port, refme, refhim)))
	    {
				if ((c = get_tunnel (tunnel, from.sin_addr.s_addr, from.sin_port)))
		{
		    /*
		     * It is theoretically possible that we could be sent
		     * a control message (say a StopCCN) on a call that we
		     * have already closed or some such nonsense.  To
		     * prevent this from closing the tunnel, if we get a
		     * call on a valid tunnel, but not with a valid CID,
		     * we'll just send a ZLB to ack receiving the packet.
		     */
		    if (gconfig.debug_tunnel)
			l2tp_log (LOG_DEBUG,
				  "%s: no such call %d on tunnel %d. Sending special ZLB\n",
				  __FUNCTION__, call, tunnel);
		    if (handle_special (buf, c, call) == 0)
			/* get a new buffer */
			buf = new_buf (MAX_RECV_SIZE);
		}
#ifdef DEBUG_MORE
		else{
		    l2tp_log (LOG_DEBUG,
			      "%s: unable to find call or tunnel to handle packet.  call = %d, tunnel = %d Dumping.\n",
			      __FUNCTION__, call, tunnel);
		    }
#endif
	    }
	    else
	    {
		if (c->container) {
			c->container->my_addr = to;
		}

		buf->peer = from;
		/* Handle the packet */
		c->container->chal_us.vector = NULL;
		if (handle_packet (buf, c->container, c))
		{
		    if (gconfig.debug_tunnel)
			l2tp_log (LOG_DEBUG, "%s: bad packet\n", __FUNCTION__);
		}
		if (c->cnu)
		{
		    /* Send Zero Byte Packet */
		    control_zlb (buf, c->container, c);
		    c->cnu = 0;
		}
		}
	}
	if (st) st=st->next;
	}

	/*
	 * finished obvious sources, look for data from PPP connections.
	 */
	st = tunnels.head;
        while (st)
        {
            sc = st->call_head;
            while (sc)
            {
                if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds))
                {
                    /* Got some payload to send */
                    int result;

                    while ((result = read_packet (sc)) > 0)
                    {
                        add_payload_hdr (sc->container, sc, sc->ppp_buf);
                        if (gconfig.packet_dump)
                        {
                            do_packet_dump (sc->ppp_buf);
                        }


                        sc->prx = sc->data_rec_seq_num;
                        if (sc->zlb_xmit)
                        {
                            deschedule (sc->zlb_xmit);
                            sc->zlb_xmit = NULL;
                        }
                        sc->tx_bytes += sc->ppp_buf->len;
                        sc->tx_pkts++;
                        udp_xmit (sc->ppp_buf, st);
                        recycle_payload (sc->ppp_buf, sc->container->peer);
                    }
                    if (result != 0)
                    {
                        l2tp_log (LOG_WARNING,
                             "%s: tossing read packet, error = %s (%d).  Closing call.\n",
                             __FUNCTION__, strerror (-result), -result);
                        strcpy (sc->errormsg, strerror (-result));
                        sc->needclose = -1;
                    }
                }
                sc = sc->next;
            }
            st = st->next;
        }
    }

}
Exemplo n.º 5
0
static bool
process_signal_p2p (struct context *c)
{
  remap_signal (c);
  return process_signal (c);
}
Exemplo n.º 6
0
void network_thread ()
{
    /*
     * We loop forever waiting on either data from the ppp drivers or from
     * our network socket.  Control handling is no longer done here.
     */
    struct sockaddr_in from, to;
    unsigned int fromlen, tolen;
    int tunnel, call;           /* Tunnel and call */
    int recvsize;               /* Length of data received */
    struct buffer *buf;         /* Payload buffer */
    struct call *c, *sc;        /* Call to send this off to */
    struct tunnel *st;          /* Tunnel */
    fd_set readfds;             /* Descriptors to watch for reading */
    int max;                    /* Highest fd */
    struct timeval tv, *ptv;    /* Timeout for select */
    struct msghdr msgh;
    struct iovec iov;
    char cbuf[256];
    unsigned int refme, refhim;

    /* This one buffer can be recycled for everything except control packets */
    buf = new_buf (MAX_RECV_SIZE);

    tunnel = 0;
    call = 0;

    for (;;)
    {
        int ret;
        process_signal();
        max = build_fdset (&readfds);
        ptv = process_schedule(&tv);
        ret = select (max + 1, &readfds, NULL, NULL, ptv);
        if (ret <= 0)
        {
            if (ret == 0)
            {
                if (gconfig.debug_network)
                {
                    l2tp_log (LOG_DEBUG, "%s: select timeout\n", __FUNCTION__);
                }
            }
            else
            {
                if (gconfig.debug_network)
                {
                    l2tp_log (LOG_DEBUG,
                        "%s: select returned error %d (%s)\n",
                        __FUNCTION__, errno, strerror (errno));
                }
            }
            continue;
        }
        if (FD_ISSET (control_fd, &readfds))
        {
            do_control ();
        }
        if (FD_ISSET (server_socket, &readfds))
        {
            /*
             * Okay, now we're ready for reading and processing new data.
             */
            recycle_buf (buf);

            /* Reserve space for expanding payload packet headers */
            buf->start += PAYLOAD_BUF;
            buf->len -= PAYLOAD_BUF;

	    memset(&from, 0, sizeof(from));
	    memset(&to,   0, sizeof(to));
	    
	    fromlen = sizeof(from);
	    tolen   = sizeof(to);
	    
	    memset(&msgh, 0, sizeof(struct msghdr));
	    iov.iov_base = buf->start;
	    iov.iov_len  = buf->len;
	    msgh.msg_control = cbuf;
	    msgh.msg_controllen = sizeof(cbuf);
	    msgh.msg_name = &from;
	    msgh.msg_namelen = fromlen;
	    msgh.msg_iov  = &iov;
	    msgh.msg_iovlen = 1;
	    msgh.msg_flags = 0;
	    
	    /* Receive one packet. */
	    recvsize = recvmsg(server_socket, &msgh, 0);

            if (recvsize < MIN_PAYLOAD_HDR_LEN)
            {
                if (recvsize < 0)
                {
                    if (errno != EAGAIN)
                        l2tp_log (LOG_WARNING,
                             "%s: recvfrom returned error %d (%s)\n",
                             __FUNCTION__, errno, strerror (errno));
                }
                else
                {
                    l2tp_log (LOG_WARNING, "%s: received too small a packet\n",
                         __FUNCTION__);
                }
		continue;
            }


	    refme=refhim=0;

	    /* extract IPsec info out */
	    if(gconfig.ipsecsaref) {
		    struct cmsghdr *cmsg;
		    /* Process auxiliary received data in msgh */
		    for (cmsg = CMSG_FIRSTHDR(&msgh);
			 cmsg != NULL;
			 cmsg = CMSG_NXTHDR(&msgh,cmsg)) {
			    if (cmsg->cmsg_level == IPPROTO_IP
				&& cmsg->cmsg_type == IP_IPSEC_REFINFO) {
				    unsigned int *refp;
				    
				    refp = (unsigned int *)CMSG_DATA(cmsg);
				    refme =refp[0];
				    refhim=refp[1];
			    }
		    }
	    }

	    /*
	     * some logic could be added here to verify that we only
	     * get L2TP packets inside of IPsec, or to provide different
	     * classes of service to packets not inside of IPsec.
	     */
	    buf->len = recvsize;
	    fix_hdr (buf->start);
	    extract (buf->start, &tunnel, &call);

	    if (gconfig.debug_network)
	    {
		l2tp_log(LOG_DEBUG, "%s: recv packet from %s, size = %d, "
			 "tunnel = %d, call = %d ref=%u refhim=%u\n",
			 __FUNCTION__, inet_ntoa (from.sin_addr),
			 recvsize, tunnel, call, refme, refhim);
	    }

	    if (gconfig.packet_dump)
	    {
		do_packet_dump (buf);
	    }
	    if (!
		(c = get_call (tunnel, call, from.sin_addr.s_addr,
			       from.sin_port, refme, refhim)))
	    {
		if ((c =
		     get_tunnel (tunnel, from.sin_addr.s_addr,
				 from.sin_port)))
		{
		    /*
		     * It is theoretically possible that we could be sent
		     * a control message (say a StopCCN) on a call that we
		     * have already closed or some such nonsense.  To
		     * prevent this from closing the tunnel, if we get a
		     * call on a valid tunnel, but not with a valid CID,
		     * we'll just send a ZLB to ack receiving the packet.
		     */
		    if (gconfig.debug_tunnel)
			l2tp_log (LOG_DEBUG,
				  "%s: no such call %d on tunnel %d.  Sending special ZLB\n",
				  __FUNCTION__);
		    handle_special (buf, c, call);

		    /* get a new buffer */
		    buf = new_buf (MAX_RECV_SIZE);
		}
		else
		    l2tp_log (LOG_DEBUG,
			      "%s: unable to find call or tunnel to handle packet.  call = %d, tunnel = %d Dumping.\n",
			      __FUNCTION__, call, tunnel);
		
	    }
	    else
	    {
		buf->peer = from;
		/* Handle the packet */
		c->container->chal_us.vector = NULL;
		if (handle_packet (buf, c->container, c))
		{
		    if (gconfig.debug_tunnel)
			l2tp_log (LOG_DEBUG, "%s: bad packet\n", __FUNCTION__);
		};
		if (c->cnu)
		{
		    /* Send Zero Byte Packet */
		    control_zlb (buf, c->container, c);
		    c->cnu = 0;
		}
	    };
	}

	/*
	 * finished obvious sources, look for data from PPP connections.
	 */
	st = tunnels.head;
        while (st)
        {
            sc = st->call_head;
            while (sc)
            {
                if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds))
                {
                    /* Got some payload to send */
                    int result;
                    recycle_payload (buf, sc->container->peer);
/*
#ifdef DEBUG_FLOW_MORE
                    l2tp_log (LOG_DEBUG, "%s: rws = %d, pSs = %d, pLr = %d\n",
                         __FUNCTION__, sc->rws, sc->pSs, sc->pLr);
#endif
		    if ((sc->rws>0) && (sc->pSs > sc->pLr + sc->rws) && !sc->rbit) {
#ifdef DEBUG_FLOW
						log(LOG_DEBUG, "%s: throttling payload (call = %d, tunnel = %d, Lr = %d, Ss = %d, rws = %d)!\n",__FUNCTION__,
								 sc->cid, sc->container->tid, sc->pLr, sc->pSs, sc->rws); 
#endif
						sc->throttle = -1;
						We unthrottle in handle_packet if we get a payload packet, 
						valid or ZLB, but we also schedule a dethrottle in which
						case the R-bit will be set
						FIXME: Rate Adaptive timeout? 						
						tv.tv_sec = 2;
						tv.tv_usec = 0;
						sc->dethrottle = schedule(tv, dethrottle, sc); 					
					} else */
/*					while ((result=read_packet(buf,sc->fd,sc->frame & SYNC_FRAMING))>0) { */
                    while ((result =
                            read_packet (buf, sc->fd, SYNC_FRAMING)) > 0)
                    {
                        add_payload_hdr (sc->container, sc, buf);
                        if (gconfig.packet_dump)
                        {
                            do_packet_dump (buf);
                        }


                        sc->prx = sc->data_rec_seq_num;
                        if (sc->zlb_xmit)
                        {
                            deschedule (sc->zlb_xmit);
                            sc->zlb_xmit = NULL;
                        }
                        sc->tx_bytes += buf->len;
                        sc->tx_pkts++;
                        udp_xmit (buf, st);
                        recycle_payload (buf, sc->container->peer);
                    }
                    if (result != 0)
                    {
                        l2tp_log (LOG_WARNING,
                             "%s: tossing read packet, error = %s (%d).  Closing call.\n",
                             __FUNCTION__, strerror (-result), -result);
                        strcpy (sc->errormsg, strerror (-result));
                        sc->needclose = -1;
                    }
                }
                sc = sc->next;
            }
            st = st->next;
        }
    }

}
Exemplo n.º 7
0
/* thread spawned for each connection */
void process_echo_request(void *p)
{
	int sd = (int)p;
	int n, i, nsamples;
	float sample_rate, center_freq;
	win_peak peak;
	jam_info info;
	time_info time;
	cplx *buf = prot_mem_malloc(sizeof(cplx) * WIN_SIZE);
	float *bhwin = prot_mem_malloc(sizeof(float) * WIN_SIZE);
	unsigned int run_time;

	blackman_harris(bhwin, WIN_SIZE);

	union Fpass{
		unsigned int i[UNION_SIZE];
		float fl[UNION_SIZE];
		char ch[RECV_BUF_SIZE];
	} fpass;

	time.trigger = 0;
	time.time = 0;
	time.index = 0;
	time.freq_vs_time = NULL;
	run_time = 0;

	while (1) {
		/* read a max of RECV_BUF_SIZE bytes from socket */
		if ((n = read(sd, fpass.ch, RECV_BUF_SIZE)) < 0) {
			xil_printf("%s: error reading from socket %d, closing socket\r\n", __FUNCTION__, sd);
#ifndef OS_IS_FREERTOS			
			close(sd);
			return;
#else
			break;
#endif
		}

		/* break if the recved message = "quit" */
		if (!strncmp(fpass.ch, "quit", 4))
			break;

		/* break if client closed connection */
		if (n <= 0)
			break;
		++run_time;
		/* Rearrange from network order */
		for (i = 0; i < UNION_SIZE; ++i)
		{
			fpass.i[i] = ntohl(fpass.i[i]);
		}

		/* Get info from header */
		nsamples = fpass.i[0];
		sample_rate = fpass.fl[1];
		center_freq = fpass.fl[2];

		if (nsamples != 64)
			continue;
		/* Limit nsamples to window size */
		if (nsamples > WIN_SIZE)
			nsamples = WIN_SIZE;

		uninter(&fpass.fl[3], buf, nsamples);


		for (i = 0; i < WIN_SIZE; ++i)
		{
			buf[i] *= bhwin[i];
		}

		/* fft and get peak */
		fft(buf, nsamples);
		peak = get_peak(buf, nsamples, sample_rate, center_freq);
		info = process_signal(peak, sample_rate, &time);

		if (info.valid)
		{
			printf("Time: %.2f Bandwidth: %.2f, Chirp Rate: %.2f\r\n", run_time / (sample_rate / 64000), info.bandwidth, info.chirprate);
			info.valid = 0;
		}



		/* handle request */
		/*if ((nwrote = write(sd, fpass.ch, n)) < 0) {
			xil_printf("%s: ERROR responding to client echo request. received = %d, written = %d\r\n",
					__FUNCTION__, n, nwrote);
			xil_printf("Closing socket %d\r\n", sd);


#ifndef OS_IS_FREERTOS
			close(sd);
			return;
#else
			break;
#endif
		}
*/

	}
	/* close connection */
	clear_led(7);
	prot_mem_free(bhwin);
	prot_mem_free(buf);
	close(sd);
#ifdef OS_IS_FREERTOS
	vTaskDelete(NULL);
#endif
}
Exemplo n.º 8
0
int main(int argc, char **argv)
{
    sigset_t mask;
    sigemptyset(&mask);
    struct sigaction sig;
    memset(&sig, 0, sizeof(sig));
    sig.sa_handler = &signal_handler;
    sig.sa_mask = mask;
    const int signals[] = { SIGTERM, SIGQUIT, SIGINT, SIGHUP, 0 };

    for (int c = 0; signals[c]; c++)
    {
        if (sigaction(signals[c], &sig, NULL) != 0)
        {
            printf("Unable to set signal handlers\n");
            return 1;
        }
    }

    for (int c = 1; c < argc; c++)
    {
        if (strcmp(argv[c], "--spawn-process") == 0)
        {
            if (++c + 1 >= argc)
            {
                printf("%s requires two arguments\n", argv[c]);
                return 1;
            }
            // The reason for splitting the argument into two parts is to avoid
            // a false match on a process just because the it has an argument
            // containing the string we are looking for.
            SPAWN_PROCESS = malloc(strlen(argv[c]) + strlen(argv[c+1]) + 2);
            sprintf(SPAWN_PROCESS, "%s/%s", argv[c], argv[c+1]);

            c++;
        }
        else if (strcmp(argv[c], "--spawn-process-on-signal") == 0)
        {
            if (++c + 1 >= argc)
            {
                printf("%s requires two arguments\n", argv[c]);
                return 1;
            }
            // See comment for SPAWN_PROCESS.
            SPAWN_PROCESS_ON_SIGNAL = malloc(strlen(argv[c]) + strlen(argv[c+1]) + 2);
            sprintf(SPAWN_PROCESS_ON_SIGNAL, "%s/%s", argv[c], argv[c+1]);

            c++;
        }
        else if (strcmp(argv[c], "--refuse-to-die") == 0)
        {
            REFUSE_TO_DIE = 1;
        }
        else if (strcmp(argv[c], "--pass-to-next-process") == 0)
        {
            // Stops argument processing and passes all remaining arguments to
            // the spawned process instead.
            NEXT_PROCESS_ARGV = &argv[++c];
            NEXT_PROCESS_ARGC = argc - c;
            break;
        }
        else
        {
            printf("Unknown argument: %s\n", argv[c]);
            return 1;
        }
    }

    const char *piddir = getenv("CFTEST_PREFIX");
    if (piddir)
    {
        const char *file = strrchr(argv[0], '/');
        file++;
        PIDFILE = malloc(strlen(piddir) + strlen(file) + 6);
        sprintf(PIDFILE, "%s/%s.pid", piddir, file);
    }

    pid_t child = fork();
    if (child < 0)
    {
        printf("Could not fork\n");
        exit(1);
    }
    else if (child > 0)
    {
        // Daemonize.
        if (PIDFILE)
        {
            FILE *fptr = fopen(PIDFILE, "w");
            if (!fptr)
            {
                printf("Could not open file %s\n", PIDFILE);
                exit(1);
            }
            fprintf(fptr, "%d\n", (int)child);
            fclose(fptr);
        }

        return 0;
    }

    if (SPAWN_PROCESS)
    {
        spawn_process(SPAWN_PROCESS);
    }

    // 60 seconds of consecutive sleep will end the program, just so that we do
    // in fact terminate if we are left over.
    while (sleep(60) != 0)
    {
        // If we didn't sleep the whole time, then it must be a signal.
        process_signal();
    }

    return 1;
}