projects
/
splice.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Fix various compile warnings
[splice.git]
/
vmsplice.c
diff --git
a/vmsplice.c
b/vmsplice.c
index 7a037b1b4862ef612d29811685c27765f5ba899a..2cfe6b29b1e544b609aec6b4d27a34320043fa7e 100644
(file)
--- a/
vmsplice.c
+++ b/
vmsplice.c
@@
-8,35
+8,35
@@
#include <limits.h>
#include <string.h>
#include <getopt.h>
#include <limits.h>
#include <string.h>
#include <getopt.h>
+#include <fcntl.h>
#include <sys/poll.h>
#include <sys/poll.h>
-#include <sys/stat.h>
#include <sys/types.h>
#include "splice.h"
#include <sys/types.h>
#include "splice.h"
-#define ALIGN_BUF
-
-#ifdef ALIGN_BUF
-#define ALIGN_MASK (65535) /* 64k-1, should just be PAGE_SIZE - 1 */
-#define ALIGN(buf) (void *) (((unsigned long) (buf) + ALIGN_MASK) & ~ALIGN_MASK)
-#else
-#define ALIGN_MASK (0)
-#define ALIGN(buf) (buf)
-#endif
+#define ALIGN(buf) (void *) (((unsigned long) (buf) + align_mask) & ~align_mask)
static int do_clear;
static int do_clear;
+static int align_mask = 65535;
+static int force_unalign;
+static int splice_flags;
-int do_vmsplice(int fd, void *b
uffer
, int len)
+int do_vmsplice(int fd, void *b
1, void *b2
, int len)
{
struct pollfd pfd = { .fd = fd, .events = POLLOUT, };
{
struct pollfd pfd = { .fd = fd, .events = POLLOUT, };
- int written;
+ struct iovec iov[] = {
+ {
+ .iov_base = b1,
+ .iov_len = len / 2,
+ },
+ {
+ .iov_base = b2,
+ .iov_len = len / 2,
+ },
+ };
+ int written, idx = 0;
while (len) {
while (len) {
- struct iovec iov = {
- .iov_base = buffer,
- .iov_len = min(SPLICE_SIZE, len),
- };
-
/*
* in a real app you'd be more clever with poll of course,
* here we are basically just blocking on output room and
/*
* in a real app you'd be more clever with poll of course,
* here we are basically just blocking on output room and
@@
-45,13
+45,22
@@
int do_vmsplice(int fd, void *buffer, int len)
if (poll(&pfd, 1, -1) < 0)
return error("poll");
if (poll(&pfd, 1, -1) < 0)
return error("poll");
- written =
vmsplice(fd, &iov, 1, 0
);
+ written =
svmsplice(fd, &iov[idx], 2 - idx, splice_flags
);
if (written <= 0)
return error("vmsplice");
len -= written;
if (written <= 0)
return error("vmsplice");
len -= written;
- buffer += written;
+ if ((size_t) written >= iov[idx].iov_len) {
+ int extra = written - iov[idx].iov_len;
+
+ idx++;
+ iov[idx].iov_len -= extra;
+ iov[idx].iov_base += extra;
+ } else {
+ iov[idx].iov_len -= written;
+ iov[idx].iov_base += written;
+ }
}
return 0;
}
return 0;
@@
-59,7
+68,7
@@
int do_vmsplice(int fd, void *buffer, int len)
static int usage(char *name)
{
static int usage(char *name)
{
- fprintf(stderr, "%s: [-c
]
\n", name);
+ fprintf(stderr, "%s: [-c
(lear)] [-u(nalign)] [-g(ift)]| ...
\n", name);
return 1;
}
return 1;
}
@@
-67,12
+76,20
@@
static int parse_options(int argc, char *argv[])
{
int c, index = 1;
{
int c, index = 1;
- while ((c = getopt(argc, argv, "c")) != -1) {
+ while ((c = getopt(argc, argv, "c
ug
")) != -1) {
switch (c) {
case 'c':
do_clear = 1;
index++;
break;
switch (c) {
case 'c':
do_clear = 1;
index++;
break;
+ case 'u':
+ force_unalign = 1;
+ index++;
+ break;
+ case 'g':
+ splice_flags = SPLICE_F_GIFT;
+ index++;
+ break;
default:
return -1;
}
default:
return -1;
}
@@
-83,29
+100,32
@@
static int parse_options(int argc, char *argv[])
int main(int argc, char *argv[])
{
int main(int argc, char *argv[])
{
- unsigned char *buffer;
- struct stat sb;
- int i;
+ unsigned char *b1, *b2;
if (parse_options(argc, argv) < 0)
return usage(argv[0]);
if (parse_options(argc, argv) < 0)
return usage(argv[0]);
- if (fstat(STDOUT_FILENO, &sb) < 0)
- return error("stat");
- if (!S_ISFIFO(sb.st_mode)) {
- fprintf(stderr, "stdout must be a pipe\n");
- return 1;
+ if (check_output_pipe())
+ return usage(argv[0]);
+
+ b1 = ALIGN(malloc(SPLICE_SIZE + align_mask));
+ b2 = ALIGN(malloc(SPLICE_SIZE + align_mask));
+
+ if (force_unalign) {
+ b1 += 1024;
+ b2 += 1024;
}
}
- buffer = ALIGN(malloc(2 * SPLICE_SIZE + ALIGN_MASK));
- for (i = 0; i < 2 * SPLICE_SIZE; i++)
- buffer[i] = (i & 0xff);
+ memset(b1, 0xaa, SPLICE_SIZE);
+ memset(b2, 0xbb, SPLICE_SIZE);
do {
do {
+ int half = SPLICE_SIZE / 2;
+
/*
* vmsplice the first half of the buffer into the pipe
*/
/*
* vmsplice the first half of the buffer into the pipe
*/
- if (do_vmsplice(STDOUT_FILENO, b
uffer
, SPLICE_SIZE))
+ if (do_vmsplice(STDOUT_FILENO, b
1, b2
, SPLICE_SIZE))
break;
/*
break;
/*
@@
-116,7
+136,7
@@
int main(int argc, char *argv[])
/*
* vmsplice second half
*/
/*
* vmsplice second half
*/
- if (do_vmsplice(STDOUT_FILENO, b
uffer + SPLICE_SIZE
, SPLICE_SIZE))
+ if (do_vmsplice(STDOUT_FILENO, b
1 + half, b2 + half
, SPLICE_SIZE))
break;
/*
break;
/*
@@
-129,9
+149,10
@@
int main(int argc, char *argv[])
* Test option - clear the first half of the buffer, should
* be safe now
*/
* Test option - clear the first half of the buffer, should
* be safe now
*/
- if (do_clear)
- memset(buffer, 0x00, SPLICE_SIZE);
-
+ if (do_clear) {
+ memset(b1, 0x00, SPLICE_SIZE);
+ memset(b2, 0x00, SPLICE_SIZE);
+ }
} while (0);
return 0;
} while (0);
return 0;