[PATCH] Formalize input/output pipe checking
[splice.git] / splice.h
1 #ifndef SPLICE_H
2 #define SPLICE_H
3
4 #include <sys/uio.h>
5 #include <sys/stat.h>
6
7 #if defined(__i386__)
8 #define __NR_splice     313
9 #define __NR_tee        315
10 #define __NR_vmsplice   316
11 #elif defined(__x86_64__)
12 #define __NR_splice     275
13 #define __NR_tee        276
14 #define __NR_vmsplice   278
15 #elif defined(__powerpc__) || defined(__powerpc64__)
16 #define __NR_splice     283
17 #define __NR_tee        284
18 #define __NR_vmsplice   285
19 #elif defined(__ia64__)
20 #define __NR_splice     1297
21 #define __NR_tee        1301
22 #define __NR_vmsplice   1301
23 #else
24 #error unsupported arch
25 #endif
26
27 #ifndef F_SETPSZ
28 #define F_SETPSZ        15
29 #define F_GETPSZ        16
30 #endif
31
32 #define SPLICE_F_MOVE   (0x01)  /* move pages instead of copying */
33 #define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */
34                                  /* we may still block on the fd we splice */
35                                  /* from/to, of course */
36 #define SPLICE_F_MORE   (0x04)  /* expect more data */
37
38 static inline int splice(int fdin, loff_t *off_in, int fdout, loff_t *off_out,
39                          size_t len, unsigned long flags)
40 {
41         return syscall(__NR_splice, fdin, off_in, fdout, off_out, len, flags);
42
43 }
44
45 static inline int tee(int fdin, int fdout, size_t len, unsigned int flags)
46 {
47         return syscall(__NR_tee, fdin, fdout, len, flags);
48 }
49
50 static inline int vmsplice(int fd, const struct iovec *iov,
51                            unsigned long nr_segs, unsigned int flags)
52 {
53         return syscall(__NR_vmsplice, fd, iov, nr_segs, flags);
54 }
55
56 #define SPLICE_SIZE     (64*1024)
57
58 #define BUG_ON(c) assert(!(c))
59
60 #define min(x,y) ({ \
61         typeof(x) _x = (x);     \
62         typeof(y) _y = (y);     \
63         (void) (&_x == &_y);            \
64         _x < _y ? _x : _y; })
65
66 #define max(x,y) ({ \
67         typeof(x) _x = (x);     \
68         typeof(y) _y = (y);     \
69         (void) (&_x == &_y);            \
70         _x > _y ? _x : _y; })
71
72 static inline int error(const char *n)
73 {
74         perror(n);
75         return -1;
76 }
77
78 static int __check_pipe(int pfd)
79 {
80         struct stat sb;
81
82         if (fstat(pfd, &sb) < 0)
83                 return error("stat");
84         if (!S_ISFIFO(sb.st_mode))
85                 return 1;
86
87         return 0;
88 }
89
90 static inline int check_input_pipe(void)
91 {
92         if (!__check_pipe(STDIN_FILENO))
93                 return 0;
94
95         fprintf(stderr, "stdin must be a pipe\n");
96         return 1;
97 }
98
99 static inline int check_output_pipe(void)
100 {
101         if (!__check_pipe(STDOUT_FILENO))
102                 return 0;
103
104         fprintf(stderr, "stdout must be a pipe\n");
105         return 1;
106 }
107
108 #endif