home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume20 / etherlib / part01 / src / etherreadv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-24  |  1.6 KB  |  75 lines

  1. /* $Id: etherreadv.c,v 2.1 89/10/23 15:42:42 dupuy Exp $ */
  2.  
  3. #include <sys/types.h>            /* iovec (caddr_t) */
  4. #include <sys/uio.h>            /* iovec */
  5.  
  6. #include <errno.h>            /* EWOULDBLOCK/EMSGSIZE */
  7.  
  8. extern int errno;
  9.  
  10. #include "libether.h"
  11.  
  12. #ifdef __GNUC__
  13. #define alloca __builtin_alloca
  14. #else
  15. #ifdef lint
  16. extern double *dalloca ();
  17. #define alloca dalloca
  18. #else
  19. #ifdef sparc
  20. #include <alloca.h>
  21. #endif
  22. extern char *alloca ();
  23. #endif
  24. #endif
  25.  
  26. #define HEADER    0
  27. #define USER    1
  28. #define WASTE    (count - 1)
  29.  
  30. /*
  31.  * Reads and returns a single packet, filling in all fields.  Reads on the
  32.  * ethernet packet filter device always return one packet.  Streams must be in
  33.  * RMSGD mode for reads to return one packet at a time
  34.  */
  35.  
  36. int
  37. ether_readv (fd, packet)
  38. int fd;
  39. ether_vec *packet;
  40. {
  41.     char waste[ETHER_MAX];
  42.     int count = 2 + packet->iovcnt;
  43.     struct iovec *iov =
  44.     (struct iovec *) alloca (sizeof (struct iovec) * count);
  45.  
  46.     iov[HEADER].iov_len = ETHER_PKT;
  47.     iov[HEADER].iov_base = (char *) packet;
  48.  
  49.     (void) bcopy ((char *) packet->iov, (char *) &iov[USER],
  50.           (int) packet->iovcnt * sizeof (struct iovec));
  51.  
  52.     iov[WASTE].iov_len = sizeof (waste);
  53.     iov[WASTE].iov_base = waste;
  54.  
  55.     if ((count = readv (fd, iov, count)) <= 0)
  56.     {                    /* enet returns EOF (0) */
  57. #ifndef EBADMSG                /* a stream will return EAGAIN */
  58.     if (count == 0 || errno == EWOULDBLOCK)
  59.         errno = EAGAIN;
  60. #endif
  61.     return (-1);
  62.     }
  63.  
  64.     if ((count -= ETHER_PKT) < 0)
  65.     {
  66. #ifdef EBADMSG
  67.     errno = EBADMSG;        /* XXX readv() can also return this */
  68. #else
  69.     errno = EMSGSIZE;        /* XXX message isn't really too long */
  70. #endif
  71.     }
  72.  
  73.     return (count);
  74. }
  75.