Statistics
| Branch: | Revision:

fifo / fifo.c @ db97be63

History | View | Annotate | Download (2.51 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
#include <unistd.h>
13
#include <fcntl.h>
14

    
15
#define MAX(a,b) ((a>b) ? a : b)
16
#define MIN(a,b) ((a>b) ? b : a)
17

    
18
size_t bufsize = 1024*1024;
19
size_t readsize = 1024 * 32;
20

    
21
void *buf, *rpos, *wpos;
22

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

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

    
37
        exit(-1);
38
    }
39
  }
40
}
41

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

    
49
  cmdline_parse(argc, argv);
50

    
51
  flags = fcntl(0, F_GETFL, 0);
52
  fcntl(0, F_SETFL, flags | O_NONBLOCK);
53

    
54
  flags = fcntl(1, F_GETFL, 0);
55
  fcntl(1, F_SETFL, flags | O_NONBLOCK);
56

    
57
  buf = rpos = wpos = malloc(bufsize);
58
  if (!buf) {
59
    fprintf(stderr, "Error: can't allocate buffer of %lu bytes\n", bufsize);
60
    exit(EXIT_SUCCESS);
61
  }
62

    
63
  while(1) {
64

    
65
    /* Watch stdin (fd 0) to see when it has input. */
66
    FD_ZERO(&rfds);
67
    if (!reof && rpos != wpos-1 && rpos-bufsize != wpos-1 ) FD_SET(0, &rfds);
68

    
69
    /* Watch stdout (fd 1) to see when it can be written. */
70
    FD_ZERO(&wfds);
71
    if (rpos != wpos) FD_SET(1, &wfds);
72

    
73
    retval = select(2, &rfds, &wfds, NULL, NULL);
74

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