⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 suio.c.svn-base

📁 SFS是一个完全分散控制的的网路档案系统。sfslite 用于简化事件驱动网络编程的有用组件。
💻 SVN-BASE
字号:
/* $Id$ *//* * * Copyright (C) 1998 David Mazieres (dm@uun.org) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * */#include "suio.h"#ifdef DMALLOCconst char *suiocheck_file;int suiocheck_line;struct memsum {  struct iovec iov;  u_int16_t sum;  int line;  const char *file;};/* Simple, IP-like checksum */u_int16_tcksum (void *_data, int len){  u_char *data = (u_char *) _data;  union {    u_char b[2];    u_int16_t w;  } bwu;  u_int32_t sum;  u_char *end;  if (!len)    return 0;  bwu.w = 0;  if ((u_long) data & 1) {    bwu.b[0] = *data;    sum = cksum ((char *) data + 1, len - 1);    sum = ((sum >> 8) & 0xff) | ((sum & 0xff) << 8);    sum += bwu.w;    len = 1;  }  else    sum = 0;  end = data + (len & ~1);  while (data < end) {    sum += *(u_int16_t*) data;    data += sizeof (u_int16_t);  }  if (len & 1) {    bwu.b[0] = *data;    sum += bwu.w;  }  return ~sum;}static voidmemsum_check (void *_ms){  struct memsum *ms = (struct memsum *) _ms;  if (cksum (ms->iov.iov_base, ms->iov.iov_len) != ms->sum) {    fprintf (stderr, "%s:%d: data in uio subesquently changed!\n",	     ms->file, ms->line);    abort ();  }  xfree (ms);}void__suio_check (const char *file, int line, struct suio *uio,	      const void *base, size_t len){  if (uio->uio_iovcnt > 0) {    struct memsum *ms = (struct memsum *) xmalloc (sizeof (*ms));    ms->iov.iov_base = (iovbase_t) base;    ms->iov.iov_len = len;    ms->sum = cksum (ms->iov.iov_base, ms->iov.iov_len);    if (suiocheck_file) {      ms->file = suiocheck_file;      ms->line = suiocheck_line;    }    else {      ms->file = file;      ms->line = line;    }    uio->uio_endp = NULL;    suio_callback (uio, memsum_check, ms);  }}#define xxmalloc xmalloc#else /* !DMALLOC */void *xxmalloc (size_t n){  void *r = malloc (n);  if (!r) {    const char msg[] = "malloc failed\n";    write (2, msg, sizeof (msg) - 1);    abort ();  }  return r;}#endif /* DMALLOC */static inline void__suio_init (struct suio *uio){  bzero (uio, offsetof (struct suio, uio_defbuf.b_data));  uio->uio_mem = uio->uio_iov = uio->uio_defiov;  uio->uio_buf1 = uio->uio_bufp = &uio->uio_defbuf;  uio->uio_dp = uio->uio_defbuf.b_data;  uio->uio_dspace = SBUFSIZ;  uio->uio_iovmax = NDEFIOV;  TAILQ_INIT (&uio->uio_cb);}voidsuio_construct (struct suio *uio){  __suio_init (uio);}static inline void__suio_freemem (struct suio *uio){  struct s_buf *b, *n;  struct iovcb *cb1, *cb2;  for (cb1 = uio->uio_cb.tqh_first; cb1; cb1 = cb2) {    cb2 = cb1->cb_link.tqe_next;    cb1->cb_fn (cb1->cb_arg);    xfree (cb1);  }  for (b = uio->uio_buf1; b; b = n) {    n = b->b_next;    if (b != &uio->uio_defbuf)      xfree (b);  }  if (uio->uio_memalloced)    xfree (uio->uio_mem);}voidsuio_destruct (struct suio *uio){  __suio_freemem (uio);}static inline void__suio_bfree (struct suio *uio, struct s_buf *b){    if (b == &uio->uio_defbuf)      uio->uio_defbfree = 1;    else      xfree (b);}struct suio *#ifndef DMALLOCsuio_alloc (void)#else /* DMALLOC */__suio_alloc (const char *file, int line)#endif /* DMALLOC */{  struct suio *uio;#ifndef DMALLOC  uio = (struct suio *) xxmalloc (sizeof (*uio));#else /* DMALLOC */  uio = (struct suio *) _xmalloc_leap (file, line, sizeof (*uio));#endif /* DMALLOC */  __suio_init (uio);  return (uio);}voidsuio_free (struct suio *uio){  __suio_freemem (uio);  xfree (uio);}voidsuio_rembytes (struct suio *uio, u_int nbytes){  u_int64_t niov, iovn;  struct s_buf *b;  struct iovcb *cb1;  assert (nbytes <= uio->uio_resid);#if 0  /* Blow away everything if we are asked to remove all bytes */  if (nbytes == uio->uio_resid) {    niov = uio->uio_nremiov + uio->uio_iovcnt;    __suio_freemem (uio);    __suio_init (uio);    uio->uio_nremiov = niov;    return;  }  /* Actually, the above is potentially race-prone of a bad idea in   * the presence of arbirary callbacks. */#endif  /* Adjust byte count */  uio->uio_resid -= nbytes;  if (uio->uio_resid) {    /* Count IOV's that are consumed in their entirety, with nbytes of     * last IOV left over */    for (niov = 0; nbytes >= uio->uio_iov[niov].iov_len; niov++)      nbytes -= uio->uio_iov[niov].iov_len;    /* Adjust IOV pointers and counts in last IOV */    uio->uio_nremiov += niov;    uio->uio_iov += niov;    uio->uio_iovcnt -= niov;    uio->uio_iovmax -= niov;    if (nbytes) {      uio->uio_iov[0].iov_len -= nbytes;      uio->uio_iov[0].iov_base =	(iovbase_t) ((char *) uio->uio_iov[0].iov_base + nbytes);    }  }  else {    /* All IOV's have been consumed, so we might as well start over at     * uio_mem. */    niov = uio->uio_iovcnt;    uio->uio_nremiov += niov;    uio->uio_iovcnt = 0;    uio->uio_iovmax += uio->uio_mem - uio->uio_iov;    uio->uio_iov = uio->uio_mem;    /* No more last IOV to append onto. */    uio->uio_endp = NULL;  }  /* Free any dynamically allocated s_buf's no longer needed */  b = uio->uio_buf1;  while (b->b_next && (u_int) b->b_uiono <= niov) {    struct s_buf *n;    niov -= b->b_uiono;    n = b->b_next;    __suio_bfree (uio, b);    b = n;  }  uio->uio_buf1 = b;  /* make any necessary callbaks */  iovn = uio->uio_nremiov;  while ((cb1 = uio->uio_cb.tqh_first) && iovn >= cb1->cb_niov) {    TAILQ_REMOVE (&uio->uio_cb, cb1, cb_link);    cb1->cb_fn (cb1->cb_arg);    xfree (cb1);  }}#ifndef DMALLOCchar *suio_flatten (const struct suio *uio)#else /* DMALLOC */char *__suio_flatten (const struct suio *uio, const char *file, int line)#endif /* DMALLOC */{  struct iovec *iovp = uio->uio_iov;  struct iovec *lastiov = uio->uio_iov + uio->uio_iovcnt;#ifndef DMALLOC  char *buf = (char *) xxmalloc (uio->uio_resid);#else /* DMALLOC */  char *buf = (char *) _xmalloc_leap (file, line, uio->uio_resid);#endif /* DMALLOC */  char *cp = buf;  while (iovp < lastiov) {    int n = iovp->iov_len;    memcpy (cp, iovp->iov_base, n);    cp += n;    iovp++;  }  return buf;}char *__suio_newbuf (struct suio *uio){  struct s_buf *b;  if (uio->uio_defbfree) {    b = &uio->uio_defbuf;    uio->uio_defbfree = 0;  }  else    b = (struct s_buf *) xxmalloc (sizeof (*b));  uio->uio_bufp->b_next = b;  uio->uio_bufp = b;  uio->uio_dp = b->b_data;  uio->uio_dspace = SBUFSIZ;  b->b_next = NULL;  b->b_uiono = 0;  return (b->b_data);}void__suio_newiov (struct suio *uio){  u_int n;  struct iovec *newiov;  n = uio->uio_iov - uio->uio_mem;  /* Wasted slots below uio_iov */  if (n >= uio->uio_iovmax) {    memmove (uio->uio_mem, uio->uio_iov,	     uio->uio_iovcnt * sizeof (struct iovec));    uio->uio_iov = uio->uio_mem;    uio->uio_iovmax += n;    return;  }  n = 2 * (n + uio->uio_iovmax);  /* Allocate twice the number of old slots */  newiov = (struct iovec *) xxmalloc (n * sizeof (struct iovec));  memcpy (newiov, uio->uio_iov, uio->uio_iovcnt * sizeof (struct iovec));  if (uio->uio_memalloced)    xfree (uio->uio_mem);  uio->uio_iov = uio->uio_mem = newiov;  uio->uio_memalloced = 1;  uio->uio_iovmax = n;}void__suio_copy (struct suio *uio, const char *data, u_int len){  char *dp;  u_int n;  if (len > SBUFSIZ) {    dp = (char *) xxmalloc (len);    memcpy (dp, data, len);    __suio_addiov (uio, dp, len);    suio_callfree (uio, dp);    return;  }  dp = uio->uio_dp;  n = len < (u_int) uio->uio_dspace ? len : (u_int) uio->uio_dspace;  memcpy (dp, data, n);  __suio_addiov (uio, dp, n);   while (len - n >= SBUFSIZ) {    dp = __suio_newbuf (uio);    memcpy (dp, data + n, SBUFSIZ);    __suio_addiov (uio, dp, SBUFSIZ);    n += SBUFSIZ;  }  if (len > n) {    dp = __suio_newbuf (uio);    memcpy (dp, data + n, len - n);    __suio_addiov (uio, dp, len - n);  }  uio->uio_dp = uio->uio_endp;  uio->uio_dspace = SBUFSIZ - (uio->uio_dp - uio->uio_bufp->b_data);}void__suio_fill (struct suio *uio, char c, u_int n){  char *base;  base = __suio_newbuf (uio);  memset (base, c, SBUFSIZ);  while (n > SBUFSIZ) {    suio_print (uio, base, SBUFSIZ);    n -= SBUFSIZ;  }  if (n > 0)    suio_print (uio, base, n);}voidsuio_cat (struct suio *dst, const struct suio *src){  u_int i;  for (i = 0; i < src->uio_iovcnt; i++) {    if (dst->uio_iovcnt >= dst->uio_iovmax)      __suio_newiov (dst);    dst->uio_resid += src->uio_iov[i].iov_len;    dst->uio_iov[dst->uio_iovcnt++] = src->uio_iov[i];  }}voidsuio_move (struct suio *dst, struct suio *src){  struct iovcb *cb, *ocb;  cb = src->uio_cb.tqh_first;  TAILQ_INIT (&src->uio_cb);  while (src->uio_iovcnt) {    if ((char *) src->uio_iov->iov_base >= src->uio_buf1->b_data	&& (char *) src->uio_iov->iov_base < src->uio_buf1->b_data + SBUFSIZ)      suio_copy (dst, src->uio_iov->iov_base, src->uio_iov->iov_len);    else      __suio_addiov (dst, src->uio_iov->iov_base, src->uio_iov->iov_len);    suio_rembytes (src, src->uio_iov->iov_len);    while (cb && src->uio_nremiov >= cb->cb_niov) {      ocb = cb;      cb = cb->cb_link.tqe_next;      ocb->cb_niov = dst->uio_nremiov + dst->uio_iovcnt;      TAILQ_INSERT_TAIL (&dst->uio_cb, ocb, cb_link);    }  }  assert (!cb);}voidsuio_copyv (struct suio *uio, const struct iovec *iov, int cnt, u_int skip){  u_int size = iovsize (iov, cnt);  u_int n;  const struct iovec *iovp;  char *buf;  char *cp;  assert (skip <= size);  size -= skip;  n = size;  iovp = iov + cnt;  if (!size)    return;  buf = (char *) xxmalloc (size);  cp = buf + size;  while (iovp-- > iov && iovp->iov_len <= n) {    n -= iovp->iov_len;    cp -= iovp->iov_len;    memcpy (cp, iovp->iov_base, iovp->iov_len);  }  assert (cp - buf == (int) n && n <= size);  if (n > 0) {    assert (iovp > iov);    memcpy (buf, (char *) iovp->iov_base + iovp->iov_len - n, n);  }#if 0  {    size_t nc = 0;    for (int i = 0; i < cnt; i++) {      u_char *p = (u_char *) iov[i].iov_base;      u_char *e = p + iov[i].iov_len;      while (p < e) {	if (nc > size + skip)	  panic ("suio_copyv: calculated size was wrong\n");	if (nc >= skip && buf[nc - skip] != *p)	  panic ("suio_copyv: wrong byte\n");	nc++;	p++;      }    }  }#endif  suio_print (uio, buf, size);  suio_callfree (uio, buf);}#undef MIN3#undef MIN2#define MIN3(a, b, c) \  ((a) < (b) ? ((a) < (c) ? (a) : (c)) : ((b) < (c) ? (b) : (c)))#define MIN2(a, b) ((a) < (b) ? (a) : (b))#ifndef _KERNELintsuio_output (struct suio *uio, int fd, int cnt){  ssize_t n = 0;  if (cnt < 0)    while (uio->uio_resid	   && (n = writev (fd, uio->uio_iov,			   MIN2 (uio->uio_iovcnt, UIO_MAXIOV))) > 0)      suio_rembytes (uio, n);  else {    u_int64_t maxiovno = uio->uio_nremiov + cnt;    while (uio->uio_resid && uio->uio_nremiov < maxiovno	   && (n = writev (fd, uio->uio_iov,			   MIN2((int) (maxiovno - uio->uio_nremiov),				UIO_MAXIOV))) > 0)      suio_rembytes (uio, n);  }  if (n > 0)    return 1;  if (n == 0 || errno == EAGAIN)    return 0;  return -1;}#endif /* !_KERNEL */size_tiovsize (const struct iovec *iov, int cnt){  const struct iovec *end;  size_t size = 0;  for (end = iov + cnt; iov < end; iov++)    size += iov->iov_len;  return size;}#ifdef __cplusplusstatic inline void__makecbv (void *_cb){  callback<void>::ref &cb = *static_cast<callback<void>::ref *> (_cb);  (*cb) ();  delete &cb;}#endif /* __cplusplus */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -