Statistics
| Branch: | Revision:

fifo / fifo.c @ c0e5c5ce

History | View | Annotate | Download (2.27 KB)

1
/*
2
 *  Copyright (c) 2010 Csaba Kiraly
3
 *
4
 *  This is free software; see gpl-3.0.txt
5
 */
6

    
7
#include <stdio.h>
8
#include <stdlib.h>
9
#include <sys/time.h>
10
#include <sys/types.h>
11
#include <unistd.h>
12

    
13
#define MAX(a,b) ((a>b) ? a : b)
14
#define MIN(a,b) ((a>b) ? b : a)
15

    
16
size_t bufsize = 1024*1024;
17
size_t readsize = 1024 * 32;
18

    
19
void *buf, *rpos, *wpos;
20

    
21
static void cmdline_parse(int argc, char *argv[])
22
{
23
  int o;
24

    
25
  while ((o = getopt(argc, argv, "b:r:")) != -1) {
26
    switch(o) {
27
      case 'b':
28
        bufsize = atol(optarg);
29
      case 'r':
30
        readsize = atol(optarg);
31
        break;
32
      default:
33
        fprintf(stderr, "Error: unknown option %c\n", o);
34

    
35
        exit(-1);
36
    }
37
  }
38
}
39

    
40
int main(int argc, char *argv[])
41
{
42
  fd_set rfds, wfds;
43
  int reof = 0;
44
  int retval;
45

    
46
  cmdline_parse(argc, argv);
47

    
48
  buf = rpos = wpos = malloc(bufsize);
49
  if (!buf) {
50
    fprintf(stderr, "Error: can't allocate buffer of %lu bytes\n", bufsize);
51
    exit(EXIT_SUCCESS);
52
  }
53

    
54
  while(1) {
55

    
56
    /* Watch stdin (fd 0) to see when it has input. */
57
    FD_ZERO(&rfds);
58
    if (!reof && rpos != wpos-1 && rpos-bufsize != wpos-1 ) FD_SET(0, &rfds);
59

    
60
    /* Watch stdout (fd 1) to see when it can be written. */
61
    FD_ZERO(&wfds);
62
    if (rpos != wpos) FD_SET(1, &wfds);
63

    
64
    retval = select(2, &rfds, &wfds, NULL, NULL);
65

    
66
    if (retval == -1) {
67
      break;
68
    } else {
69
      if (FD_ISSET(0, &rfds)) {
70
        ssize_t size;
71
        size_t rmax;
72
        rmax = MIN(MIN(readsize, buf + bufsize - rpos), (wpos+bufsize-rpos-1) % bufsize);
73
        size = read(0, rpos, rmax);
74
//fprintf(stderr,"reading %lu bytes, read %ld bytes\n", rmax, size);
75
        if (size < 0) {
76
          break;
77
        } else if (size == 0)  {
78
          reof = 1;
79
        } else {
80
          rpos += size;
81
          if (rpos >= buf + bufsize) rpos -= bufsize;
82
        }
83
      }
84
      if (FD_ISSET(1, &wfds)) {
85
        ssize_t size;
86
        size_t wmax;
87
        wmax = (wpos > rpos) ? (buf + bufsize) - wpos  : rpos - wpos;
88
        size = write(1, wpos, wmax);
89
//fprintf(stderr,"writing %lu bytes, written %ld bytes\n", wmax, size);
90
        if (size < 0) {
91
          break;
92
        } else {
93
          wpos += size;
94
          if (wpos >= buf + bufsize) wpos -= bufsize;
95
        }
96
      }
97
    }
98
    if (reof && rpos == wpos) break;
99
  }
100
  free(buf);
101
  exit(EXIT_SUCCESS);
102
}