Example #1
0
void
serial_init()
{
    ring_init(&output_ring, output_buffer, SERIAL_BUF_SIZEOUT);
    ring_init(&input_ring, input_buffer, SERIAL_BUF_SIZEIN);
    serial_active = false;
}
Example #2
0
struct tty *tty_init(struct tty *t, const struct tty_ops *ops) {
	assert(t && ops);

	t->idesc = NULL;
	t->ops = ops;

	{
		struct termios *termios = &t->termios;
		cc_t cc_init[NCCS] = TTY_TERMIOS_CC_INIT;

		memcpy(termios->c_cc, cc_init, sizeof(cc_init));
		termios->c_iflag = TTY_TERMIOS_IFLAG_INIT;
		termios->c_oflag = TTY_TERMIOS_OFLAG_INIT;
		termios->c_cflag = TTY_TERMIOS_CFLAG_INIT;
		termios->c_lflag = TTY_TERMIOS_LFLAG_INIT;
	}

	mutex_init(&t->lock);

	ring_init(&t->rx_ring);

	ring_init(&t->i_ring);
	ring_init(&t->i_canon_ring);

	ring_init(&t->o_ring);

	t->pgrp = -1;

	return t;
}
Example #3
0
/* ------------------------------------------------------------------
 * Initialise the UART
 * ------------------------------------------------------------------ */
void uart_init() {
	INTERRUPTS_OFF();

	// setup ring buffers
	ring_init(&rx, rxbuffer, RX_BUFFER_LENGTH);
	ring_init(&tx, txbuffer, TX_BUFFER_LENGTH);

	// baud rate
	UART_BAUD_RATE_LOW 	= UBRRL_VALUE;
	UART_BAUD_RATE_HIGH = UBRRH_VALUE;

	// double speed?
#ifdef UART_DOUBLE_SPEED
	UART_CONTROL_STATUS_REG_A |= MASK(U2X0);
#else
	UART_CONTROL_STATUS_REG_A &= ~(MASK(U2X0));
#endif

	// mode: async 8N1
	UART_CONTROL_STATUS_REG_C = MASK(UART_CHARACTER_SIZE_0) | MASK(UART_CHARACTER_SIZE_1);

	// enable TX/RX
	UART_CONTROL_STATUS_REG_B = MASK(UART_ENABLE_TRANSMITTER) | MASK(UART_ENABLE_RECEIVER);

	// enable data register empty interrupt
	UART_CONTROL_STATUS_REG_B |= MASK(UART_DATA_REGISTER_EMPTY_INTERRUPT_ENABLE);

	// enable RX complete interrupt
	UART_CONTROL_STATUS_REG_B |= MASK(UART_RECEIVE_COMPLETE);

	INTERRUPTS_ON();
}
Example #4
0
void
init_network(void)
{
	ring_init(&netoring, netobuf, sizeof netobuf);
	ring_init(&netiring, netibuf, sizeof netibuf);
	SetNetTrace(NULL);
}
Example #5
0
/** Initialise buffered UART driver
    @param cfg pointer to configuration structure.
    @return pointer to buart device structure.
*/
buart_t 
buart_init (const buart_cfg_t *cfg)
{
    buart_dev_t *dev = 0;
    uint16_t baud_divisor;
    char *tx_buffer;
    char *rx_buffer;

    if (cfg->baud_rate == 0)
        baud_divisor = cfg->baud_divisor;
    else
        baud_divisor = BUART_BAUD_DIVISOR (cfg->baud_rate);

#if BUART0_ENABLE
    if (cfg->channel == 0)
        dev = buart0_init (baud_divisor);
#endif

#if BUART1_ENABLE
    if (cfg->channel == 1)
        dev = buart1_init (baud_divisor);
#endif

    if (!dev)
        return 0;

    dev->read_timeout_us = cfg->read_timeout_us;
    dev->write_timeout_us = cfg->write_timeout_us;
    
    tx_buffer = cfg->tx_buffer;
    rx_buffer = cfg->rx_buffer;

    if (!tx_buffer)
        tx_buffer = malloc (cfg->tx_size);
    if (!tx_buffer)
        return 0;

    if (!rx_buffer)
        rx_buffer = malloc (cfg->rx_size);
    if (!rx_buffer)
    {
        free (tx_buffer);
        return 0;
    }

    ring_init (&dev->tx_ring, tx_buffer, cfg->tx_size);
    
    ring_init (&dev->rx_ring, rx_buffer, cfg->rx_size);

    /* Enable the rx interrupt now.  The tx interrupt is enabled
       when we perform a write.  */
    dev->rx_irq_enable ();

    return dev;
}
void
init_network(void)
{
    if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) {
	exit(1);
    }
    if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) {
	exit(1);
    }
    NetTrace = stdout;
}
Example #7
0
    void
init_terminal()
{
	if (ring_init(&ttyoring, ttyobuf, sizeof (ttyobuf)) != 1) {
		exit(1);
	}
	if (ring_init(&ttyiring, ttyibuf, sizeof (ttyibuf)) != 1) {
		exit(1);
	}
	autoflush = 1;
}
Example #8
0
void
init_terminal(void)
{
    if (ring_init(&ttyoring, ttyobuf, sizeof ttyobuf) != 1) {
	exit(1);
    }
    if (ring_init(&ttyiring, ttyibuf, sizeof ttyibuf) != 1) {
	exit(1);
    }
    autoflush = TerminalAutoFlush();
}
Example #9
0
/* create ring of n processes */
int main(int argc, char *argv[])
{
    int nproc;
    struct ring l, r;	/* 'left' ring and 'right' ring */
    pid_t pid;
    int i, status;
    pid_t *ltp, *rtp;

    bzero(&r, sizeof(struct ring));
    bzero(&l, sizeof(struct ring));
    status = nproc = pid = 0;
    if (argc != 2 || ((nproc = atoi(argv[1])) <= 0))
        err_quit("Uasge: %s processes", argv[0]);

    fprintf(stderr, "Creating ring of %d processes\n", nproc);
    ring_init(&r);
    ring_init(&l);

    for (i = 1; i < nproc; i++) {
        Pipe(r.fd);
        Pipe(l.fd);
        if ((pid = Fork()) > 0) {
            ring_dup_out(&r);
            ring_dup_in(&l);
        } else {
            ring_dup_in(&r);
            ring_dup_out(&l);
        }
        ring_close_fd(&r);
        ring_close_fd(&l);
        if (pid > 0)
            break;
    }

    if ((rtp = calloc((size_t)nproc, sizeof(pid_t))) == NULL)
        err_sys("calloc error");
    (void)msg_all(r.in, r.out, rtp, nproc);
    if ((ltp = calloc((size_t)nproc, sizeof(pid_t))) == NULL)
        err_sys("calloc error");
    (void)msg_all(l.in, l.out, ltp, nproc);

    if (pid > 0)
        if (wait(&status) == -1)
            err_sys("wait error");
    pprintt(rtp, nproc);
    pprintt(ltp, nproc);
    free(rtp);
    free(ltp);
    return 0;
}
Example #10
0
EVENT *event_create(int size)
{
	EVENT *ev = NULL;

	switch (__event_mode) {
	case FIBER_EVENT_POLL:
#ifdef	HAS_POLL
		ev = event_poll_create(size);
#else
		msg_fatal("%s(%d): not support!", __FUNCTION__, __LINE__);
#endif
		break;
	case FIBER_EVENT_SELECT:
		ev = event_select_create(size);
		break;
	case FIBER_EVENT_WMSG:
#ifdef	HAS_WMSG
		ev = event_wmsg_create(1024);
#else
		msg_fatal("%s(%d): not support!", __FUNCTION__, __LINE__);
#endif
		break;
	default:
#if	defined(HAS_EPOLL)
		ev = event_epoll_create(size);
#elif	defined(HAS_KQUEUE)
		ev = event_kqueue_create(size);
#elif	defined(HAS_IOCP)
		ev = event_iocp_create(size);
#else
#error	"unknown OS"
#endif
		break;
	}

	ring_init(&ev->events);
	ev->timeout = -1;
	ev->setsize = size;
	ev->fdcount = 0;
	ev->maxfd   = -1;

#ifdef HAS_POLL
	ring_init(&ev->poll_list);
#endif

#ifdef HAS_EPOLL
	ring_init(&ev->epoll_list);
#endif
	return ev;
}
Example #11
0
void fiber_io_check(void)
{
	if (__thread_fiber != NULL) {
		if (__thread_fiber->ev_fiber == NULL) {
			__thread_fiber->ev_fiber  = acl_fiber_create(
				fiber_io_loop, __thread_fiber->event,
				STACK_SIZE);
			__thread_fiber->io_count  = 0;
			__thread_fiber->nsleeping = 0;
			__thread_fiber->io_stop   = 0;
			ring_init(&__thread_fiber->ev_timer);
		}
		return;
	}

	if (pthread_once(&__once_control, thread_init) != 0) {
		msg_fatal("%s(%d), %s: pthread_once error %s",
			__FILE__, __LINE__, __FUNCTION__, last_serror());
	}

	var_maxfd = open_limit(0);
	if (var_maxfd <= 0) {
		var_maxfd = MAXFD;
	}

	__thread_fiber = (FIBER_TLS *) malloc(sizeof(FIBER_TLS));
	__thread_fiber->event = event_create(var_maxfd);
	__thread_fiber->ev_fiber  = acl_fiber_create(fiber_io_loop,
			__thread_fiber->event, STACK_SIZE);
	__thread_fiber->io_count  = 0;
	__thread_fiber->nsleeping = 0;
	__thread_fiber->io_stop   = 0;
	ring_init(&__thread_fiber->ev_timer);

#ifdef SYS_WIN
	__thread_fiber->events = htable_create(var_maxfd);
#else
	__thread_fiber->events = (FILE_EVENT **)
		calloc(var_maxfd, sizeof(FILE_EVENT*));
#endif

	if (__pthread_self() == main_thread_self()) {
		__main_fiber = __thread_fiber;
		atexit(fiber_io_main_free);
	} else if (pthread_setspecific(__fiber_key, __thread_fiber) != 0) {
		msg_fatal("pthread_setspecific error!");
	}
}
Example #12
0
CursorChannelClient* cursor_channel_client_new(CursorChannel *cursor, RedClient *client, RedsStream *stream,
                                               int mig_target,
                                               uint32_t *common_caps, int num_common_caps,
                                               uint32_t *caps, int num_caps)
{
    spice_return_val_if_fail(cursor, NULL);
    spice_return_val_if_fail(client, NULL);
    spice_return_val_if_fail(stream, NULL);
    spice_return_val_if_fail(!num_common_caps || common_caps, NULL);
    spice_return_val_if_fail(!num_caps || caps, NULL);

    CursorChannelClient *ccc =
        (CursorChannelClient*)common_channel_new_client(&cursor->common,
                                                        sizeof(CursorChannelClient),
                                                        client, stream,
                                                        mig_target,
                                                        FALSE,
                                                        common_caps,
                                                        num_common_caps,
                                                        caps,
                                                        num_caps);
    spice_return_val_if_fail(ccc != NULL, NULL);

    ring_init(&ccc->cursor_cache_lru);
    ccc->cursor_cache_available = CLIENT_CURSOR_CACHE_SIZE;

    return ccc;
}
static void usart_setup(void)
{
	/* Initialize output ring buffer. */
	ring_init(&output_ring, output_ring_buffer, BUFFER_SIZE);

	/* Enable the USART2 interrupt. */
	nvic_enable_irq(NVIC_USART2_IRQ);

	/* Setup GPIO pin GPIO_USART2_TX on GPIO port A for transmit. */
	gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ,
		      GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART2_TX);

	/* Setup GPIO pin GPIO_USART2_RX on GPIO port A for receive. */
	gpio_set_mode(GPIOA, GPIO_MODE_INPUT,
		      GPIO_CNF_INPUT_FLOAT, GPIO_USART2_RX);

	/* Setup UART parameters. */
	usart_set_baudrate(USART2, 230400);
	usart_set_databits(USART2, 8);
	usart_set_stopbits(USART2, USART_STOPBITS_1);
	usart_set_parity(USART2, USART_PARITY_NONE);
	usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);
	usart_set_mode(USART2, USART_MODE_TX_RX);

	/* Enable USART2 Receive interrupt. */
	USART_CR1(USART2) |= USART_CR1_RXNEIE;

	/* Finally enable the USART. */
	usart_enable(USART2);
}
Example #14
0
static void event_prepare(EVENT *ev)
{
	FILE_EVENT *fe;
	RING *next;

	while ((next = ring_first(&ev->events))) {
		fe = ring_to_appl(next, FILE_EVENT, me);

		if (fe->oper & EVENT_DEL_READ) {
			ev->del_read(ev, fe);
		}
		if (fe->oper & EVENT_DEL_WRITE) {
			ev->del_write(ev, fe);
		}
		if (fe->oper & EVENT_ADD_READ) {
			ev->add_read(ev, fe);
		}
		if (fe->oper & EVENT_ADD_WRITE) {
			ev->add_write(ev, fe);
		}

		ring_detach(next);
		fe->oper = 0;
	}

	ring_init(&ev->events);
}
Example #15
0
t_gfx		*graphe_news(t_server *srv, t_gfx *prev, t_fds *fds, int s)
{
	t_gfx	tmp;
	t_gfx	*gfx;

	tmp.len = sizeof(struct sockaddr_in);
	if (!(gfx = (t_gfx *)malloc(sizeof(t_gfx))))
	{
		if ((s = accept(s, (struct sockaddr *)&tmp.sin, &tmp.len)) >= 0)
			close(s);
		graphe_log(srv, 1, gfx);
		return (gfx);
	}
	gfx->len = sizeof(struct sockaddr_in);
	if ((gfx->socket = accept(s, (struct sockaddr *)&gfx->sin, &gfx->len)) < 0)
	{
		graphe_log(srv, 2, gfx);
		graphe_kill(srv, gfx, fds, false);
		return (NULL);
	}
	graphe_log(srv, 3, gfx);
	gfx->ring = ring_init(srv, 1);
	gfx->isgfx = false;
	gfx->prev = prev;
	gfx->next = NULL;
	send(gfx->socket, g_sgm[0], strlen(g_sgm[0]), 0);
	return (gfx);
}
Example #16
0
GSwifi::GSwifi( HardwareSerialX *serial ) :
    serial_(serial),
    server_cid_(-1)
{
    _buf_cmd          = &ring_buffer_;
    ring_init( _buf_cmd, __buf_cmd, GS_CMD_SIZE + 1 );
}
Example #17
0
void
init_network(void)
{
    void *obuf, *ibuf;

    if ((obuf = malloc(netobufsize)) == NULL)
	exit(1);
    if ((ibuf = malloc(netibufsize)) == NULL)
	exit(1);

    if (ring_init(&netoring, obuf, netobufsize) != 1) {
	exit(1);
    }
    if (ring_init(&netiring, ibuf, netibufsize) != 1) {
	exit(1);
    }
    NetTrace = stdout;
}
Example #18
0
int main()
{
    ringbuffer_t ring1, ring2;
    ringbuffer_t *ro = &ring1, *rw = &ring2;
    ring_init(ro, 1024, 0);
    ring_init(rw, 0, ro->header);

    ring_dump(ro, "ro"); ring_dump(rw, "rw");

    ring_write(rw, "test", 4);
    ring_dump(ro, "ro"); ring_dump(rw, "rw");

    ring_write(rw, "test", 0);
    ring_dump(ro, "ro"); ring_dump(rw, "rw");

    ring_shift(ro);
    ring_dump(ro, "ro"); ring_dump(rw, "rw");

    ring_shift(ro);
    ring_dump(ro, "ro"); ring_dump(rw, "rw");
}
Example #19
0
HardwareSerialX::HardwareSerialX(volatile RingBuffer *rx_buffer, volatile RingBuffer *tx_buffer,
  volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
  volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
  volatile uint8_t *ucsrc, volatile uint8_t *udr,
  uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x)
{
  ring_init( &rx_buffer1, rx_buffer1_data, RX_BUFFER_SIZE + 1 );
  ring_init( &tx_buffer1, tx_buffer1_data, TX_BUFFER_SIZE + 1 );

  _rx_buffer = rx_buffer;
  _tx_buffer = tx_buffer;
  _ubrrh = ubrrh;
  _ubrrl = ubrrl;
  _ucsra = ucsra;
  _ucsrb = ucsrb;
  _ucsrc = ucsrc;
  _udr = udr;
  _rxen = rxen;
  _txen = txen;
  _rxcie = rxcie;
  _udrie = udrie;
  _u2x = u2x;
}
Example #20
0
void image_cache_init(ImageCache *cache)
{
    static SpiceImageCacheOps image_cache_ops = {
        image_cache_put,
        image_cache_get,
    };

    cache->base.ops = &image_cache_ops;
    memset(cache->hash_table, 0, sizeof(cache->hash_table));
    ring_init(&cache->lru);
#ifdef IMAGE_CACHE_AGE
    cache->age = 0;
#else
    cache->num_items = 0;
#endif
}
Example #21
0
static void event_process_poll(EVENT *ev)
{
	while (1) {
		POLL_EVENT *pe;
		RING *head = ring_pop_head(&ev->poll_list);

		if (head == NULL) {
			break;
		}

		pe = TO_APPL(head, POLL_EVENT, me);
		pe->proc(ev, pe);
	}

	ring_init(&ev->poll_list);
}
Example #22
0
int gpm_init(gp_simple_hook_t trigger_output, void *trigger_output_data, gp_with_addr_hook_t register_changed, void *register_changed_data)
{
	int i;

	gpm_hooks.trigger_output = trigger_output;
	gpm_hooks.trigger_output_data = trigger_output_data;
	gpm_hooks.register_changed = register_changed;
	gpm_hooks.register_changed_data = register_changed_data;

	for(i=0; i<32; i++)
		gpm_register_map[i] = 0;

	ring_init(&gpm_output_ring, gpm_output_buffer, 128);

	return 0;
}
Example #23
0
t_gfx		*graphe_init(t_server *srv)
{
	t_gfx	*gfx;

	if (!(gfx = (t_gfx *)malloc(sizeof(t_gfx))))
	{
		graphe_log(srv, 1, gfx);
		return (gfx);
	}
	gfx->socket = 0;
	gfx->ring = ring_init(srv, 1);
	gfx->isgfx = false;
	gfx->prev = NULL;
	gfx->next = NULL;
	return (gfx);
}
Example #24
0
int main (void)
{
    ring_t ring;                /* Ring buffer structure.    */
    char buffer[128];           /* Ring buffer data.    */
    char *msg1 = "abcde";
    char *msg2 = "fghij";
    char foo[64];
    int num;
    
    ring_init (&ring, buffer, sizeof (buffer));

    ring_write (&ring, msg1, strlen (msg1));

    ring_write (&ring, msg2, strlen (msg2));

    num = ring_read (&ring, foo, sizeof (foo));
    foo[num] = '\0';

    printf ("%d: %s\n", num, foo);

    return 0;
}
Example #25
0
int gpc_init(gp_simple_hook_t trigger_output, void *trigger_output_data,
	     gp_with_addr_hook_t register_changed, void *register_changed_data)
{
	int i;

	gpc_state = GPCS_IDLE;

	gpc_hooks.trigger_output = trigger_output;
	gpc_hooks.trigger_output_data = trigger_output_data;
	gpc_hooks.register_changed = register_changed;
	gpc_hooks.register_changed_data = register_changed_data;
	gpc_hooks.get_version = 0;
	gpc_hooks.get_version_data = 0;

	for (i = 0; i < 32; i++)
		gpc_register_map[i] = 0;

	gpc_monitor_map = 0;

	ring_init(&gpc_output_ring, gpc_output_buffer, GPC_OUTPUT_BUFFER_SIZE);

	return 0;
}
Example #26
0
/* initialize hardware */
void
init(void)
{
  led_init();
  ledon();

  strobo_init();
  strobooff();

  door_init();
  doordisengage();

  ring_init();

  /* timer initialization
   *
   * CTC mode
   * clocked from system clock
   * prescaler /1024
   * compare value 10
   *
   * this gives about 100 Hz at 1 MHz system clock
   *
   * we also enable the compare match interrupt
   * 
   */
  TCNT2 =  0;
  OCR2  = 10;
  TCCR2 = _BV(WGM21)|_BV(CS22)|_BV(CS21)|_BV(CS20);
  TIMSK = _BV(OCIE2);

  /* initialize usart */
  uinit(9600);

  /* enable interrupts */
  sei();
}
Example #27
0
int main() {
    ok( 1, "ok" );

    {
        struct RingBuffer buf_;
        struct RingBuffer *buf = &buf_;
        char data[65];
        ring_init( buf, data, 65 );
        ok( ring_used(buf) == 0, "0 used" );
        ok( ring_isempty(buf) == 1, "is empty" );

        ring_put(buf, 'a');
        ok( ring_used(buf) == 1, "1 used after put" );
        ok( ring_isfull(buf) == 0, "not full" );
        ok( ring_isempty(buf) == 0, "is empty" );

        char buf2[64];
        ring_get(buf, &buf2[0], 1);
        ok( buf2[0] == 'a', "get" );
        ok( ring_used(buf) == 0, "0 used after get" );
        ok( ring_isfull(buf) == 0, "not full" );
        ok( ring_isempty(buf) == 1, "is empty" );

        ring_put(buf, 'b');
        ring_clear(buf);

        ok( ring_used(buf) == 0, "0 used after clear" );
        ok( ring_isfull(buf) == 0, "not full" );
        ok( ring_isempty(buf) == 1, "is empty" );

        ring_put(buf, '0');        ring_put(buf, '1');        ring_put(buf, '2');        ring_put(buf, '3');
        ring_put(buf, '4');        ring_put(buf, '5');        ring_put(buf, '6');        ring_put(buf, '7');
        ring_put(buf, '8');        ring_put(buf, '9');        ring_put(buf, 'a');        ring_put(buf, 'b');
        ring_put(buf, 'c');        ring_put(buf, 'd');        ring_put(buf, 'e');        ring_put(buf, 'f');
        ring_put(buf, '0');        ring_put(buf, '1');        ring_put(buf, '2');        ring_put(buf, '3');
        ring_put(buf, '4');        ring_put(buf, '5');        ring_put(buf, '6');        ring_put(buf, '7');
        ring_put(buf, '8');        ring_put(buf, '9');        ring_put(buf, 'a');        ring_put(buf, 'b');
        ring_put(buf, 'c');        ring_put(buf, 'd');        ring_put(buf, 'e');        ring_put(buf, 'f');
        ring_put(buf, '0');        ring_put(buf, '1');        ring_put(buf, '2');        ring_put(buf, '3');
        ring_put(buf, '4');        ring_put(buf, '5');        ring_put(buf, '6');        ring_put(buf, '7');
        ring_put(buf, '8');        ring_put(buf, '9');        ring_put(buf, 'a');        ring_put(buf, 'b');
        ring_put(buf, 'c');        ring_put(buf, 'd');        ring_put(buf, 'e');        ring_put(buf, 'f');
        ring_put(buf, '0');        ring_put(buf, '1');        ring_put(buf, '2');        ring_put(buf, '3');
        ring_put(buf, '4');        ring_put(buf, '5');        ring_put(buf, '6');        ring_put(buf, '7');
        ring_put(buf, '8');        ring_put(buf, '9');        ring_put(buf, 'a');        ring_put(buf, 'b');
        ring_put(buf, 'c');        ring_put(buf, 'd');        ring_put(buf, 'e');        ring_put(buf, 'f');
        ok( ring_used(buf) == 64, "64 used after 64 puts" );
        ok( ring_isfull(buf) == 1, "is full" );
        ok( ring_isempty(buf) == 0, "is empty" );

        // dropped feature to protect buffer from overflow
        // ok( ring_put(buf, 'x') == -1, "can't put into full" );

        uint8_t fetched = ring_get(buf, &buf2[0], 64);
        ok( buf2[0] == '0', "get 1" );
        ok( buf2[1] == '1', "get 2" );
        ok( buf2[2] == '2', "get 3" );
        ok( buf2[3] == '3', "get 4" );
        ok( fetched == 64, "fetched all" );

        ok( ring_used(buf) == 0, "0 used after all get" );
        ok( ring_isfull(buf) == 0, "not full again" );
        ok( ring_isempty(buf) == 1, "is empty" );
    }

    done_testing();
}
Example #28
0
/*
 * Play on @sock.
 * The session must be in the playing phase.
 * Return 0 when the session ended, -1 on error.
 */
int
play(int sock)
{
    /*
     * Player input flows from INPUT_FD through recv_input() into ring
     * buffer INBUF, which drains into SOCK.  This must not block.
     * Server output flows from SOCK into recv_output().  Reading SOCK
     * must not block.
     */
    struct sigaction sa;
    struct ring inbuf;		/* input buffer, draining to SOCK */
    int eof_fd0;		/* read fd 0 hit EOF? */
    int partial_line_sent;	/* partial input line sent? */
    fd_set rdfd, wrfd;
    int n;

    sa.sa_flags = 0;
    sigemptyset(&sa.sa_mask);
    sa.sa_handler = intr;
    sigaction(SIGINT, &sa, NULL);
    sa.sa_handler = SIG_IGN;
    sigaction(SIGPIPE, &sa, NULL);

    ring_init(&inbuf);
    eof_fd0 = partial_line_sent = send_eof = send_intr = 0;
    input_fd = 0;
    sysdep_stdin_init();

    for (;;) {
	FD_ZERO(&rdfd);
	FD_ZERO(&wrfd);

	/*
	 * Want to read player input only when we don't need to send
	 * cookies, and INPUT_FD is still open, and INBUF can accept
	 * some.
	 */
	if (!send_intr && !send_eof && input_fd >= 0 && ring_space(&inbuf))
	    FD_SET(input_fd, &rdfd);
	/* Want to send player input only when we have something */
	if (send_intr || send_eof || ring_len(&inbuf))
	    FD_SET(sock, &wrfd);
	/* Always want to read server output */
	FD_SET(sock, &rdfd);

	n = select(MAX(input_fd, sock) + 1, &rdfd, &wrfd, NULL, NULL);
	if (n < 0) {
	    if (errno != EINTR) {
		perror("select");
		return -1;
	    }
	}

	if ((send_eof || send_intr) && partial_line_sent
	    && ring_putc(&inbuf, '\n') != EOF)
	    partial_line_sent = 0;
	if (send_eof && !partial_line_sent
	    && ring_putm(&inbuf, EOF_COOKIE, sizeof(EOF_COOKIE) - 1) >= 0)
	    send_eof--;
	if (send_intr && !partial_line_sent
	    && ring_putm(&inbuf, INTR_COOKIE, sizeof(INTR_COOKIE) - 1) >= 0) {
	    send_intr = 0;
	    if (input_fd) {
		/* execute aborted, switch back to fd 0 */
		close(input_fd);
		input_fd = eof_fd0 ? -1 : 0;
	    }
	}

	if (n < 0)
	    continue;

	/* read player input */
	if (input_fd >= 0 && FD_ISSET(input_fd, &rdfd)) {
	    n = recv_input(input_fd, &inbuf);
	    if (n < 0) {
		perror("read stdin"); /* FIXME stdin misleading, could be execing */
		n = 0;
	    }
	    if (n == 0) {
		/* EOF on input */
		send_eof++;
		if (input_fd) {
		    /* execute done, switch back to fd 0 */
		    close(input_fd);
		    input_fd = eof_fd0 ? -1 : 0;
		} else {
		    /* stop reading input, drain socket ring buffers */
		    eof_fd0 = 1;
		    input_fd = -1;
		    sa.sa_handler = SIG_DFL;
		    sigaction(SIGINT, &sa, NULL);
		}
	    } else
		partial_line_sent = ring_peek(&inbuf, -1) != '\n';
	}

	/* send it to the server */
	if (FD_ISSET(sock, &wrfd)) {
	    n = ring_to_file(&inbuf, sock);
	    if (n < 0) {
		perror("write socket");
		return -1;
	    }
	}

	/* read server output and print it */
	if (FD_ISSET(sock, &rdfd)) {
	    n = recv_output(sock);
	    if (n < 0) {
		perror("read socket");
		return -1;
	    }
	    if (n == 0)
		return 0;
	}
    }
}
Example #29
0
Ring *ring_malloc(unsigned int size) {
  Ring *ring = malloc(sizeof(Ring));
  unsigned char *buf = malloc(size);
  ring_init(ring, buf, size);
  return ring;
}
Example #30
0
Ring *ring_init_from_memory(unsigned char *buf, unsigned int size) {
  Ring *ring = ring_from_memory(buf, size);
  ring_init(ring, buf + sizeof(Ring), size - sizeof(Ring));
  return ring;
}