예제 #1
0
/* Test code for removing of the first, last and middle item. */
static void
test_01a()
{
	int i, f;
	slist sl;
	slist *l = &sl;

	slist_init(&sl);
	slist_add(&sl, (void *)1);

	ASSERT(sl.list_size == 256);

#define	SETUP()						\
    {							\
	l->last_idx =  64;				\
	l->first_idx = 192;				\
	for (i = 0; i < slist_length(l); i++) {		\
		slist_set(l, i, (void *)i);		\
	}						\
    }

	/* Remove the first item. */
	SETUP();
	f = 0;
	while (slist_length(l) > 0) {
		slist_remove(l, 0);
		f++;
		for (i = 0; i < slist_length(l); i++) {
			ASSERT((int)slist_get(l, i) == i + f);
		}
	}

	/* Remove the last item. */
	SETUP();
	while (slist_length(l) > 0) {
		slist_remove(l, slist_length(l) - 1);
		for (i = 0; i < slist_length(l); i++) {
			ASSERT((int)slist_get(l, i) == i);
		}
	}
	/* Remove the second item from the end. */
	SETUP();
	while (slist_length(l) > 1) {
		slist_remove(l, slist_length(l) - 2);
		for (i = 0; i < slist_length(l) - 1; i++) {
			ASSERT((int)slist_get(l, i) == i);
		}
		if (slist_length(l) > 0) {
			ASSERT((int)slist_get(l, slist_length(l) - 1) == 127);
		}
	}
	slist_remove(l, slist_length(l) - 1);
	ASSERT(slist_length(l) == 0);
}
예제 #2
0
static void
test_itr_subr_01(slist *l)
{
	int i;

	for (i = 0; i < slist_length(l); i++)
		slist_set(l, i, (void *)(i + 1));

	slist_itr_first(l);
	ASSERT((int)slist_itr_next(l) == 1);	/* normal iterate */
	ASSERT((int)slist_itr_next(l) == 2);	/* normal iterate */
	slist_remove(l, 2);		      /* remove next. "3" is removed */
	ASSERT((int)slist_itr_next(l) == 4);	/* removed item is skipped */
	slist_remove(l, 1);		 /* remove past item. "2" is removed */
	ASSERT((int)slist_itr_next(l) == 5);	/* no influence */
	ASSERT((int)slist_get(l, 0) == 1);	/* checking for removing */
	ASSERT((int)slist_get(l, 1) == 4);	/* checking for removing */
	ASSERT((int)slist_get(l, 2) == 5);	/* checking for removing */

	/*
	 * Total number was 255. We removed 2 items and iterated 4 times.
	 * 1 removing was past item, so the remaining is 250.
	 */

	for (i = 0; i < 249; i++)
		ASSERT(slist_itr_next(l) != NULL);
	ASSERT(slist_itr_next(l) != NULL);
	ASSERT(slist_itr_next(l) == NULL);

	/*
	 * Same as above except removing before getting the last item.
	 */

	/* Reset (253 items) */
	for (i = 0; i < slist_length(l); i++)
		slist_set(l, i, (void *)(i + 1));
	slist_itr_first(l);

	ASSERT(slist_length(l) == 253);

	for (i = 0; i < 252; i++)
		ASSERT(slist_itr_next(l) != NULL);

	slist_remove(l, 252);
	ASSERT(slist_itr_next(l) == NULL);	/* The last item is NULL */

	slist_itr_first(l);
	while (slist_length(l) > 0)
		slist_remove_first(l);
	ASSERT(slist_length(l) == 0);
	ASSERT(slist_itr_next(l) == NULL);
}
예제 #3
0
파일: joystick_sdl.c 프로젝트: jedie/XRoar
static void close_device(struct device *d) {
	d->open_count--;
	if (d->open_count == 0) {
		SDL_JoystickClose(d->joystick);
		device_list = slist_remove(device_list, d);
		free(d);
	}
}
예제 #4
0
/* Verify removing the last item on the physical location */
static void
test_05()
{
	int i;
	slist sl;
	slist *l = &sl;

	slist_init(&sl);
	/* Fill */
	for (i = 0; i < 255; i++) {
		slist_add(&sl, (void *)i);
	}
	/* Remove 254 items */
	for (i = 0; i < 254; i++) {
		slist_remove_first(&sl);
	}
	slist_set(l, 0, (void *)0);
	/* Add 7 items */
	for (i = 0; i < 8; i++) {
		slist_add(&sl, (void *)i + 1);
	}
	ASSERT(sl.first_idx == 254);
	ASSERT(sl.last_idx == 7);

	slist_remove(l, 0);
	ASSERT((int)slist_get(l, 0) == 1);
	ASSERT((int)slist_get(l, 1) == 2);
	ASSERT((int)slist_get(l, 2) == 3);
	ASSERT((int)slist_get(l, 3) == 4);
	ASSERT((int)slist_get(l, 4) == 5);
	ASSERT((int)slist_get(l, 5) == 6);
	ASSERT((int)slist_get(l, 6) == 7);
	ASSERT((int)slist_get(l, 7) == 8);
	ASSERT(l->first_idx == 255);

	slist_remove(l, 0);
	ASSERT((int)slist_get(l, 0) == 2);
	ASSERT((int)slist_get(l, 1) == 3);
	ASSERT((int)slist_get(l, 2) == 4);
	ASSERT((int)slist_get(l, 3) == 5);
	ASSERT((int)slist_get(l, 4) == 6);
	ASSERT((int)slist_get(l, 5) == 7);
	ASSERT((int)slist_get(l, 6) == 8);
	ASSERT(l->first_idx == 0);
}
예제 #5
0
파일: slist.c 프로젝트: qgewfg/gtk-gnutella
/**
 * Move entry to the head of the slist.
 */
bool
slist_moveto_head(slist_t *slist, void *key)
{
	if (slist_remove(slist, key)) {
		slist_prepend(slist, key);
		return TRUE;
	}
	return FALSE;
}
예제 #6
0
파일: slist.c 프로젝트: qgewfg/gtk-gnutella
/**
 * Move entry to the tail of the slist.
 */
bool
slist_moveto_tail(slist_t *slist, void *key)
{
	if (slist_remove(slist, key)) {
		slist_append(slist, key);
		return TRUE;
	}
	return FALSE;
}
void hash_table_remove(struct hash_table *m, void *key)
{
    if (!m) { return; }
     
    struct slist *bucket = get_map_bucket(m, key, false);
    if (!bucket) { return; }
    
    slist_remove(bucket, key);
    --m->count;
}
예제 #8
0
void
event_remove(Event *event)
	{
	if (!event)
		return;
	pthread_mutex_lock(&event_mutex);
	event_list = slist_remove(event_list, event);
	pthread_mutex_unlock(&event_mutex);
	free(event);
	}
예제 #9
0
/*
 * Function free_headerq(q)
 *
 *    Free all headers in a header queue.
 *
 */
static void free_headerq(slist_t **q)
{
	struct obex_header_element *h;

	DEBUG(4, "\n");
	while (*q != NULL) {
		h = (*q)->data;
		*q = slist_remove(*q, h);
		buf_free(h->buf);
		free(h);
	}
}
예제 #10
0
/* Return the contents of the first item in the global loader list
   with a matching NAME after removing it from that list.  If there
   was no match, return NULL; if there is an error, return NULL and
   set an error for lt_dlerror; do not set an error if only resident
   modules need this loader; in either case, the loader list is not
   changed if NULL is returned.  */
lt_dlvtable *
lt_dlloader_remove (const char *name)
{
  const lt_dlvtable *	vtable	= lt_dlloader_find (name);
  static const char	id_string[] = "lt_dlloader_remove";
  lt_dlinterface_id	iface;
  lt_dlhandle		handle = 0;
  int			in_use = 0;
  int			in_use_by_resident = 0;

  if (!vtable)
    {
      LT__SETERROR (INVALID_LOADER);
      return 0;
    }

  /* Fail if there are any open modules which use this loader.  */
  iface = lt_dlinterface_register (id_string, NULL);
  while ((handle = lt_dlhandle_iterate (iface, handle)))
    {
      lt_dlhandle cur = handle;
      if (cur->vtable == vtable)
	{
	  in_use = 1;
	  if (lt_dlisresident (handle))
	    in_use_by_resident = 1;
	}
    }
  lt_dlinterface_free (iface);
  if (in_use)
    {
      if (!in_use_by_resident)
	LT__SETERROR (REMOVE_LOADER);
      return 0;
    }

  /* Call the loader finalisation function.  */
  if (vtable && vtable->dlloader_exit)
    {
      if ((*vtable->dlloader_exit) (vtable->dlloader_data) != 0)
	{
	  /* If there is an exit function, and it returns non-zero
	     then it must set an error, and we will not remove it
	     from the list.  */
	  return 0;
	}
    }

  /* If we got this far, remove the loader from our global list.  */
  return (lt_dlvtable *)
      slist_unbox ((SList *) slist_remove (&loaders, loader_callback, (void *) name));
}
예제 #11
0
파일: clients.c 프로젝트: gjz22cn/openwrt
int clients_write(clients_t* list, fd_set* set)
{
  if(!list)
    return -1;

  slist_element_t* tmp = list->list_.first_;
  while(tmp) {
    client_t* c = (client_t*)tmp->data_;
    tmp = tmp->next_;
    if(c && c->state_ == CONNECTED) {
      int i;
      for(i=0; i<2; ++i) {
        if(FD_ISSET(c->fd_[i], set)) {
          int len = send(c->fd_[i], c->write_buf_[i].buf_, c->write_buf_offset_[i], 0);
          if(len < 0) {
            log_printf(INFO, "Error on send(): %s, removing client %d", strerror(errno), c->fd_[0]);
            slist_remove(&(list->list_), c);
            break;
          }
          else {
            c->transferred_[i] += len;
            if(c->write_buf_offset_[i] > len) {
              memmove(c->write_buf_[i].buf_, &c->write_buf_[i].buf_[len], c->write_buf_offset_[i] - len);
              c->write_buf_offset_[i] -= len;
            }
            else
              c->write_buf_offset_[i] = 0;
          }
        }
      }
    } else if(c && c->state_ == CONNECTING && FD_ISSET(c->fd_[1], set)) {
      int ret = handle_connect(c, list->buffer_size_);
      if(ret)
        slist_remove(&(list->list_), c);
    }
  }

  return 0;
}
예제 #12
0
파일: clients.c 프로젝트: gjz22cn/openwrt
int clients_read(clients_t* list, fd_set* set)
{
  if(!list)
    return -1;

  slist_element_t* tmp = list->list_.first_;
  while(tmp) {
    client_t* c = (client_t*)tmp->data_;
    tmp = tmp->next_;
    if(c && c->state_ == CONNECTED) {
      int i;
      for(i=0; i<2; ++i) {
        int in, out;
        if(FD_ISSET(c->fd_[i], set)) {
          in = i;
          out = i ^ 1;
        }
        else continue;

        int len = recv(c->fd_[in], &(c->write_buf_[out].buf_[c->write_buf_offset_[out]]),  c->write_buf_[out].length_ - c->write_buf_offset_[out], 0);
        if(len < 0) {
          log_printf(INFO, "Error on recv(): %s, removing client %d", strerror(errno), c->fd_[0]);
          slist_remove(&(list->list_), c);
          break;
        }
        else if(!len) {
          log_printf(INFO, "client %d closed connection, removing it", c->fd_[0]);
          slist_remove(&(list->list_), c);
          break;
        }
        else
          c->write_buf_offset_[out] += len;
      }
    }
  }

  return 0;
}
예제 #13
0
/*
 * Function send_body(object, header, txmsg, tx_left)
 *
 *  Fragment and send the body
 *
 */
static int send_body(obex_object_t *object,
				struct obex_header_element *h,
				buf_t *txmsg, unsigned int tx_left)
{
	struct obex_byte_stream_hdr *body_txh;
	unsigned int actual;

	body_txh = (struct obex_byte_stream_hdr*) buf_reserve_end(txmsg, sizeof(struct obex_byte_stream_hdr));

	if (!h->body_touched) {
		/* This is the first time we try to send this header
		   obex_object_addheaders has added a struct_byte_stream_hdr
		   before the actual body-data. We shall send this in every fragment
		   so we just remove it for now.*/

		buf_remove_begin(h->buf,  sizeof(struct obex_byte_stream_hdr) );
		h->body_touched = TRUE;
	}

	if (tx_left < ( h->buf->data_size +
			sizeof(struct obex_byte_stream_hdr) ) )	{
		DEBUG(4, "Add BODY header\n");
		body_txh->hi = OBEX_HDR_BODY;
		body_txh->hl = htons((uint16_t)tx_left);

		buf_insert_end(txmsg, h->buf->data, tx_left
				- sizeof(struct obex_byte_stream_hdr) );

		buf_remove_begin(h->buf, tx_left
				- sizeof(struct obex_byte_stream_hdr) );
		/* We have completely filled the tx-buffer */
		actual = tx_left;
	} else {
		DEBUG(4, "Add BODY_END header\n");

		body_txh->hi = OBEX_HDR_BODY_END;
		body_txh->hl = htons((uint16_t) (h->buf->data_size + sizeof(struct obex_byte_stream_hdr)));
		buf_insert_end(txmsg, h->buf->data, h->buf->data_size);
		actual = h->buf->data_size;

		object->tx_headerq = slist_remove(object->tx_headerq, h);
		buf_free(h->buf);
		free(h);
	}

	return actual;
}
예제 #14
0
/*
 * Function obex_object_getnextheader()
 *
 * Return the next header in the rx-queue
 *
 */
int obex_object_getnextheader(obex_t *self, obex_object_t *object, uint8_t *hi,
				obex_headerdata_t *hv, uint32_t *hv_size)
{
	uint32_t *bq4;
	struct obex_header_element *h;

	DEBUG(4, "\n");

	/* No more headers */
	if (object->rx_headerq == NULL)
		return 0;

	/* New headers are appended at the end of the list while receiving, so
	   we pull them from the front.
	   Since we cannot free the mem used just yet just put the header in
	   another list so we can free it when the object is deleted. */

	h = object->rx_headerq->data;
	object->rx_headerq = slist_remove(object->rx_headerq, h);
	object->rx_headerq_rm = slist_append(object->rx_headerq_rm, h);

	*hi = h->hi;
	*hv_size= h->length;

	switch (h->hi & OBEX_HI_MASK) {
		case OBEX_BYTE_STREAM:
			hv->bs = &h->buf->data[0];
			break;

		case OBEX_UNICODE:
			hv->bs = &h->buf->data[0];
			break;

		case OBEX_INT:
			bq4 = (uint32_t*) h->buf->data;
			hv->bq4 = ntohl(*bq4);
			break;

		case OBEX_BYTE:
			hv->bq1 = h->buf->data[0];
			break;
	}

	return 1;
}
예제 #15
0
static void
test_03()
{
	int i;
	slist sl;
	slist *l = &sl;

	slist_init(&sl);
	slist_add(&sl, (void *)1);

	for (i = 0; i < 255; i++) {
		slist_add(&sl, (void *)1);
		ASSERT(sl.last_idx >= 0 && sl.last_idx < sl.list_size);
		slist_remove_first(&sl);
		ASSERT(sl.last_idx >= 0 && sl.last_idx < sl.list_size);
	}
	slist_remove(&sl, 0);
	ASSERT(slist_length(&sl) == 0);
	/* dump(&sl); */
	/* TEST(test_02); */
}
예제 #16
0
void
pptpd_ctrl_finished_notify(pptpd *_this, pptp_ctrl *ctrl)
{
	pptp_ctrl *ctrl1;
	int i, nctrl;

	PPTPD_ASSERT(_this != NULL);
	PPTPD_ASSERT(ctrl != NULL);

	nctrl = 0;
	for (i = 0; i < slist_length(&_this->ctrl_list); i++) {
		ctrl1 = slist_get(&_this->ctrl_list, i);
		if (ctrl1 == ctrl) {
			slist_remove(&_this->ctrl_list, i);
			break;
		}
	}
	pptp_ctrl_destroy(ctrl);

	PPTPD_DBG((_this, LOG_DEBUG, "Remains %d ctrls", nctrl));
	if (pptpd_is_shutting_down(_this) && nctrl == 0)
		pptpd_stop_immediatly(_this);
}
예제 #17
0
slist slist_ssort(slist lista)
{
  slist listaNueva = slist_create();
  slist aux = slist_create();

  int i,j, lonLista;

  lonLista = slist_length(lista);

  for(i = 0; i < lonLista; i++)
    aux = slist_append(aux, slist_elem(lista, i));

  slist aux2 = aux;
  int posMenor = 0;
  int menor = slist_data(aux);

  for(j = 0; j < lonLista; j++)
  {
    posMenor = 0;
    menor = slist_data(aux);
    for(i = 0 ; aux != slist_empty(); aux = slist_next(aux), i++)
    {
      if(slist_data(aux) < menor)
      {
        posMenor = i;
        menor = slist_data(aux);
      }
    }
    aux = aux2;

    listaNueva = slist_append(listaNueva, menor);
    aux = slist_remove(aux, posMenor);
    aux2 = aux;
  }

  return listaNueva;
}
예제 #18
0
파일: clients.c 프로젝트: gjz22cn/openwrt
void clients_remove(clients_t* list, int fd)
{
  slist_remove(&(list->list_), clients_find(list, fd));
}
예제 #19
0
void os_remove_nick(NickCore * nc)
{
    slist_remove(&servadmins, nc);
    slist_remove(&servopers, nc);
}
예제 #20
0
파일: test.c 프로젝트: chengw1005/alg_ex
void test_list()
{
    printf("\ntesting single list\n");

    //
    // single link list
    //
    struct snode {
        struct slist lnk;
        
        int i;
        int j;
    };

    struct slist shead;
    slist_init(&shead);

    struct snode* n1 = (struct snode*)malloc(sizeof(struct snode));
    n1->i = 1; n1->j = 1;
    slist_insert(&shead, &n1->lnk); // insert n1 AFTER head

    struct snode* n2 = (struct snode*)malloc(sizeof(struct snode));
    n2->i = 2; n2->j = 2;
    slist_insert(&n1->lnk, &n2->lnk);   // insert n2 after n1

    struct snode* n3 = (struct snode*)malloc(sizeof(struct snode));
    n3->i = 3; n3->j = 3;
    slist_insert(&n2->lnk, &n3->lnk);   // insert n3 after n2

    struct snode* n0 = (struct snode*)malloc(sizeof(struct snode));
    n0->i = 0; n0->j = 0;
    slist_insert(&shead, &n0->lnk);     // insert n0 after head

    struct snode* pos;
    slist_for_each_entry(pos, struct snode, &shead, lnk) {
        printf("%d ", pos->i);
    }

    slist_remove(&n1->lnk, &n2->lnk);   // remove n2
    slist_remove(&n1->lnk, &n3->lnk);   // remove n3
    slist_remove(&shead, &n0->lnk);     // remove n0
    slist_remove(&shead, &n1->lnk);     // remove n1
    slist_for_each_entry(pos, struct snode, &shead, lnk) {
        printf("%d ", pos->i);
    }


    printf("\ntesting double link list\n");

    //
    // double link list
    //
    struct dnode {
        struct dlist lnk;

        int i;
        int j;
    };

    struct dlist dhead;
    dlist_init(&dhead);

    struct dnode* d0 = (struct dnode*)malloc(sizeof(struct dnode));
    d0->i = 0; d0->j = 0;
    dlist_insert(&dhead, &d0->lnk); // insert d0 before head

    struct dnode* d2 = (struct dnode*)malloc(sizeof(struct dnode));
    d2->i = 2; d2->j = 2;
    dlist_insert(&dhead, &d2->lnk); // insert d2 before head

    struct dnode* d1 = (struct dnode*)malloc(sizeof(struct dnode));
    d1->i = 1; d1->j = 1;
    dlist_insert(&d2->lnk, &d1->lnk);   // insert d2 before d1

    struct dnode* p;
    dlist_for_each_entry(p, struct dnode, &dhead, lnk) {
        printf("%d ", p->i);
    }

    // remove first and last node
    dlist_remove(&d0->lnk);
    dlist_remove(&d2->lnk);
    dlist_for_each_entry(p, struct dnode, &dhead, lnk) {
        printf("%d ", p->i);
    }
    // remove the only left node
    dlist_remove(&d1->lnk);
    dlist_for_each_entry(p, struct dnode, &dhead, lnk) {
        printf("%d ", p->i);
    }
}
예제 #21
0
/*
 * Function obex_object_send()
 *
 *    Send away all headers attached to an object. Returns:
 *       1 on sucessfully done
 *       0 on progress made
 *     < 0 on error
 */
int obex_object_send(obex_t *self, obex_object_t *object,
		      int allowfinalcmd, int forcefinalbit)
{
	struct obex_header_element *h;
	buf_t *txmsg;
	int actual, finished = 0;
	uint16_t tx_left;
	int addmore = TRUE;
	int real_opcode;

	DEBUG(4, "\n");

	/* Don't do anything of object is suspended */
	if (object->suspend)
		return 0;

	/* Calc how many bytes of headers we can fit in this package */
	tx_left = self->mtu_tx - sizeof(struct obex_common_hdr);
	switch (self->trans.type) {
#ifdef HAVE_IRDA
	case OBEX_TRANS_IRDA:
		if (self->trans.mtu > 0 && self->mtu_tx > self->trans.mtu)
			tx_left -= self->mtu_tx%self->trans.mtu;
		break;
#endif /*HAVE_IRDA*/
	default:
		break;
	}

	/* Reuse transmit buffer */
	txmsg = buf_reuse(self->tx_msg);

	/* Add nonheader-data first if any (SETPATH, CONNECT)*/
	if (object->tx_nonhdr_data) {
		DEBUG(4, "Adding %d bytes of non-headerdata\n", object->tx_nonhdr_data->data_size);
		buf_insert_end(txmsg, object->tx_nonhdr_data->data, object->tx_nonhdr_data->data_size);

		buf_free(object->tx_nonhdr_data);
		object->tx_nonhdr_data = NULL;
	}

	DEBUG(4, "4\n");

	/* Take headers from the tx queue and try to stuff as
	   many as possible into the tx-msg */
	while (addmore == TRUE && object->tx_headerq != NULL) {

		h = object->tx_headerq->data;

		if (h->stream) {
			/* This is a streaming body */
			if (h->flags & OBEX_FL_SUSPEND)
				object->suspend = 1;
			actual = send_stream(self, h, txmsg, tx_left);
			if (actual < 0 )
				return -1;
			tx_left -= actual;
		} else if (h->hi == OBEX_HDR_BODY) {
			/* The body may be fragmented over several packets. */
			if (h->flags & OBEX_FL_SUSPEND)
				object->suspend = 1;
			tx_left -= send_body(object, h, txmsg, tx_left);
		} else if(h->hi == OBEX_HDR_EMPTY) {
			if (h->flags & OBEX_FL_SUSPEND)
				object->suspend = 1;
			object->tx_headerq = slist_remove(object->tx_headerq, h);
			free(h);
		} else if (h->length <= tx_left) {
			/* There is room for more data in tx msg */
			DEBUG(4, "Adding non-body header\n");
			buf_insert_end(txmsg, h->buf->data, h->length);
			tx_left -= h->length;
			if (h->flags & OBEX_FL_SUSPEND)
				object->suspend = 1;

			/* Remove from tx-queue */
			object->tx_headerq = slist_remove(object->tx_headerq, h);
			buf_free(h->buf);
			free(h);
		} else if (h->length > self->mtu_tx) {
			/* Header is bigger than MTU. This should not happen,
			   because OBEX_ObjectAddHeader() rejects headers
			   bigger than the MTU */

			DEBUG(0, "ERROR! header to big for MTU\n");
			return -1;
		} else {
			/* This header won't fit. */
			addmore = FALSE;
		}

		if (object->suspend)
			addmore = FALSE;

		if (tx_left == 0)
			addmore = FALSE;
	};

	/* Decide which command to use, and if to use final-bit */
	if (object->tx_headerq) {
		/* Have more headers (or body) to send */
		/* In server, final bit is always set.
		 * In client, final bit is set only when we finish sending.
		 * Jean II */
		if (forcefinalbit)
			real_opcode = object->opcode | OBEX_FINAL;
		else
			real_opcode = object->opcode;
		finished = 0;
	} else if (allowfinalcmd == FALSE) {
		/* Have no yet any headers to send, but not allowed to send
		 * final command (== server, receiving incomming request) */
		real_opcode = object->opcode | OBEX_FINAL;
		finished = 0;
	} else {
		/* Have no more headers to send, and allowed to send final
		 * command (== end data we are sending) */
		real_opcode = object->lastopcode | OBEX_FINAL;
		finished = 1;
	}

	DEBUG(4, "Sending package with opcode %d\n", real_opcode);
	actual = obex_data_request(self, txmsg, real_opcode);

	if (actual < 0) {
		DEBUG(4, "Send error\n");
		return actual;
	} else
		return finished;
}
예제 #22
0
/*
 * Function send_stream(object, header, txmsg, tx_left)
 *
 *  Send a streaming header.
 *
 */
static int send_stream(obex_t *self,
				struct obex_header_element *h,
				buf_t *txmsg, unsigned int tx_left)
{
	obex_object_t *object;
	struct obex_byte_stream_hdr *body_txh;
	int actual;	/* Number of bytes sent in this fragment */

	DEBUG(4, "\n");

	object = self->object;

	/* Fill in length and header type later, but reserve space for it */
	body_txh  = (struct obex_byte_stream_hdr*) buf_reserve_end(txmsg,
				sizeof(struct obex_byte_stream_hdr) );
	tx_left -= sizeof(struct obex_byte_stream_hdr);
	actual = sizeof(struct obex_byte_stream_hdr);

	do {
		if (object->s_len == 0) {
			/* Ask app for more data if no more */
			object->s_offset = 0;
			object->s_buf = NULL;
			obex_deliver_event(self, OBEX_EV_STREAMEMPTY, 0, 0, FALSE);
			DEBUG(4, "s_len=%d, s_stop = %d\n",
						object->s_len, object->s_stop);
			/* End of stream ?*/
			if (object->s_stop)
				break;

			/* User suspended and didn't provide any new data */
			if (object->suspend && object->s_buf == NULL)
				break;

			/* Error ?*/
			if (object->s_buf == NULL) {
				DEBUG(1, "Unexpected end-of-stream\n");
				return -1;
			}
		}

		if (tx_left < object->s_len) {
			/* There is more data left in buffer than tx_left */
			DEBUG(4, "More data than tx_left. Buffer will not be empty\n");

			buf_insert_end(txmsg, (uint8_t*) object->s_buf + object->s_offset, tx_left);
			object->s_len -= tx_left;
			object->s_offset += tx_left;
			actual += tx_left;
			tx_left = 0;
		} else {
			/* There less data in buffer than tx_left */
			DEBUG(4, "Less data that tx_left. Buffer will be empty\n");
			buf_insert_end(txmsg, (uint8_t*) object->s_buf + object->s_offset, object->s_len);
			tx_left -= object->s_len;
			object->s_offset += object->s_len;
			actual += object->s_len;
			object->s_len = 0;
			if (object->suspend)
				tx_left = 0;
		}
	} while (tx_left > 0);

	DEBUG(4, "txmsg full or no more stream-data. actual = %d\n", actual);
	body_txh->hi = OBEX_HDR_BODY;

	if (object->s_stop && object->s_len == 0) {
		/* We are done. Remove header from tx-queue */
		object->tx_headerq = slist_remove(object->tx_headerq, h);
		body_txh->hi = OBEX_HDR_BODY_END;
		buf_free(h->buf);
		free(h);
	}

	body_txh->hl = htons((uint16_t)actual);

	return actual;
}
예제 #23
0
파일: clients.c 프로젝트: gjz22cn/openwrt
int clients_add(clients_t* list, int fd, const tcp_endpoint_t remote_end, const tcp_endpoint_t source_end)
{
  if(!list)
    return -1;

  client_t* element = malloc(sizeof(client_t));
  if(!element) {
    close(fd);
    return -2;
  }

  int i;
  for(i = 0; i < 2; ++i) {
    element->write_buf_[i].buf_ = NULL;
    element->write_buf_[i].length_ = 0;
    element->write_buf_offset_[i] = 0;
  }
  element->state_ = CONNECTING;
  element->fd_[0] = fd;
  element->fd_[1] = socket(remote_end.addr_.ss_family, SOCK_STREAM, 0);
  if(element->fd_[1] < 0) {
    log_printf(INFO, "Error on socket(): %s, not adding client %d", strerror(errno), element->fd_[0]);
    close(element->fd_[0]);
    free(element);
    return -1;
  }

  int on = 1;
  if(setsockopt(element->fd_[0], IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) ||
     setsockopt(element->fd_[1], IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on))) {
    log_printf(ERROR, "Error on setsockopt(): %s", strerror(errno));
    close(element->fd_[0]);
    close(element->fd_[1]);
    free(element);
    return -1;
  }

  if(fcntl(element->fd_[0], F_SETFL, O_NONBLOCK) ||
     fcntl(element->fd_[1], F_SETFL, O_NONBLOCK)) {
    log_printf(ERROR, "Error on fcntl(): %s", strerror(errno));
    close(element->fd_[0]);
    close(element->fd_[1]);
    free(element);
    return -1;
  }

  if(source_end.addr_.ss_family != AF_UNSPEC) {
    if(bind(element->fd_[1], (struct sockaddr *)&(source_end.addr_), source_end.len_)==-1) {
      log_printf(INFO, "Error on bind(): %s, not adding client %d", strerror(errno), element->fd_[0]);
      close(element->fd_[0]);
      close(element->fd_[1]);
      free(element);
      return -1;
    }
  }

  if(slist_add(&(list->list_), element) == NULL) {
    close(element->fd_[0]);
    close(element->fd_[1]);
    free(element);
    return -2;
  }

  if(connect(element->fd_[1], (struct sockaddr *)&(remote_end.addr_), remote_end.len_)==-1) {
    if(errno == EINPROGRESS)
      return 0;

    log_printf(INFO, "Error on connect(): %s, not adding client %d", strerror(errno), element->fd_[0]);
    slist_remove(&(list->list_), element);
    return -1;
  }

  log_printf(DEBUG, "connect() for client %d returned immediatly", element->fd_[0]);

  int ret = handle_connect(element, list->buffer_size_);
  if(ret)
    slist_remove(&(list->list_), element);

  return ret;
}
예제 #24
0
static void
test_09()
{
	slist sl;
	slist *l = &sl;

	/*
	 * #1
	 */
	slist_init(l);
	slist_set_size(l, 3);
	slist_add(l, (void *)1);
	slist_add(l, (void *)2);
	slist_add(l, (void *)3);

	slist_itr_first(l);
	ASSERT((int)slist_itr_next(l) == 1);		/* 1 */
	ASSERT((int)slist_itr_next(l) == 2);		/* 2 */
	ASSERT((int)slist_itr_next(l) == 3);		/* 3 */
							/* reaches the last */
	slist_add(l, (void *)4);			/* add a new item */
	ASSERT(slist_itr_has_next(l));			/* iterates the new */
	ASSERT((int)slist_itr_next(l) == 4);
	slist_fini(l);


	/*
	 * #2
	 */
	slist_init(l);
	slist_set_size(l, 3);
	slist_add(l, (void *)1);
	slist_add(l, (void *)2);
	slist_add(l, (void *)3);

	slist_itr_first(l);
	ASSERT((int)slist_itr_next(l) == 1);		/* 1 */
	ASSERT((int)slist_itr_next(l) == 2);		/* 2 */
	ASSERT((int)slist_itr_next(l) == 3);		/* 3 */
							/* reaches the last */
	slist_itr_remove(l);				/* and remove the last*/
	slist_add(l, (void *)4);			/* add 4 (new last)*/
	ASSERT(slist_itr_has_next(l));			/* */
	ASSERT((int)slist_itr_next(l) == 4);		/* 4 */
	slist_fini(l);

	/*
	 * #3
	 */
	slist_init(l);
	slist_set_size(l, 3);
	slist_add(l, (void *)1);
	slist_add(l, (void *)2);
	slist_add(l, (void *)3);

	slist_itr_first(l);
	ASSERT((int)slist_itr_next(l) == 1);		/* 1 */
	ASSERT((int)slist_itr_next(l) == 2);		/* 2 */
	ASSERT((int)slist_itr_next(l) == 3);		/* 3 */
							/* reaches the last */
	slist_add(l, (void *)4);			/* add a new */
	slist_itr_remove(l);
	ASSERT(slist_itr_has_next(l));
	ASSERT((int)slist_itr_next(l) == 4);		/* 4 */
	slist_fini(l);

	/*
	 * #4 - remove iterator's next and it is the last
	 */
	slist_init(l);
	slist_set_size(l, 3);
	slist_add(l, (void *)1);
	slist_add(l, (void *)2);
	slist_add(l, (void *)3);

	slist_itr_first(l);
	ASSERT((int)slist_itr_next(l) == 1);		/* 1 */
	ASSERT((int)slist_itr_next(l) == 2);		/* 2 */
	slist_remove(l, 2);				/* remove the next */
	slist_add(l, (void *)4);			/* add the new next */
	ASSERT(slist_itr_has_next(l));			/* iterates the new */
	ASSERT((int)slist_itr_next(l) == 4);
	slist_fini(l);
}