home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v941.tgz / icon.v941src.tar / icon.v941src / ipl / cfuncs / fpoll.c < prev    next >
C/C++ Source or Header  |  2001-11-27  |  3KB  |  100 lines

  1. /*
  2. ############################################################################
  3. #
  4. #    File:     fpoll.c
  5. #
  6. #    Subject:  Function to poll file for input
  7. #
  8. #    Author:   Gregg M. Townsend
  9. #
  10. #    Date:     November 27, 2001
  11. #
  12. ############################################################################
  13. #
  14. #   This file is in the public domain.
  15. #
  16. ############################################################################
  17. #
  18. #  fpoll(f, msec) waits until data is available for input from file f,
  19. #  and then returns.  It also returns when end-of-file is reached.
  20. #  If msec is specified, and no data is available after waiting that
  21. #  many milliseconds, then fpoll fails.  If msec is omitted, fpoll
  22. #  waits indefinitely.
  23. #
  24. ############################################################################
  25. #
  26. #  Requires:  UNIX, dynamic loading
  27. #
  28. ############################################################################
  29. */
  30.  
  31. #include <stdio.h>
  32. #include <sys/types.h>
  33. #include <sys/time.h>
  34.  
  35. #include "icall.h"
  36.  
  37. int fpoll(int argc, descriptor *argv)    /*: await data from file */
  38.    {
  39.    FILE *f;
  40.    int msec, r;
  41.    fd_set fds;
  42.    struct timeval tv, *tvp;
  43.  
  44.    /* check arguments */
  45.    if (argc < 1)
  46.       Error(105);
  47.    if ((IconType(argv[1]) != 'f') || (FileStat(argv[1]) & Fs_Window))
  48.       ArgError(1, 105);
  49.    if (!(FileStat(argv[1]) & Fs_Read))
  50.       ArgError(1, 212);
  51.    f = FileVal(argv[1]);
  52.  
  53.    if (argc < 2)
  54.       msec = -1;
  55.    else {
  56.       ArgInteger(2);
  57.       msec = IntegerVal(argv[2]);
  58.       }
  59.  
  60.    /* check for data already in buffer */
  61.    /* there's no legal way to do this in C; we cheat */
  62. #if defined(__GLIBC__) && defined(_STDIO_USES_IOSTREAM)
  63.    if (f->_IO_read_ptr < f->_IO_read_end)
  64.       RetArg(1);
  65. #elif defined(__GLIBC__)
  66.    if (f->__bufp < f->__get_limit)
  67.       RetArg(1);
  68. #elif __bsdi__ || __FreeBSD__ || __NetBSD__ || __OpenBSD__
  69.    if (f->_r > 0)
  70.       RetArg(1);
  71. #else
  72.    if (f->_cnt > 0)
  73.       RetArg(1);
  74. #endif
  75.  
  76.    /* set up select(2) structure */
  77.    FD_ZERO(&fds);            /* clear file bits */
  78.    FD_SET(fileno(f), &fds);        /* set bit of interest */
  79.  
  80.    /* set up timeout and pointer */
  81.    if (msec < 0)
  82.       tvp = NULL;
  83.    else {
  84.       tv.tv_sec = msec / 1000;
  85.       tv.tv_usec = (msec % 1000) * 1000;
  86.       tvp = &tv;
  87.       }
  88.  
  89.    /* poll the file using select(2) */
  90.    r = select(fileno(f) + 1, &fds, (fd_set*)NULL, (fd_set*)NULL, tvp);
  91.  
  92.    if (r > 0)
  93.       RetArg(1);            /* success */
  94.    else if (r == 0)            
  95.       Fail;                /* timeout */
  96.    else
  97.       ArgError(1, 214);            /* I/O error */
  98.  
  99. }
  100.