#include "splice.h"
+#define PAGE_SIZE 4096
+#define PAGE_MASK (PAGE_SIZE - 1)
+#define ALIGN(buf) (void *) (((unsigned long) (buf) + PAGE_MASK) & ~PAGE_MASK)
+
static int alloc_stack;
+static int cross_page;
int do_vmsplice(int fd, struct iovec *iov, unsigned long nr_vecs)
{
static int usage(char *name)
{
- fprintf(stderr, "%s [-s(tack)] | ...\n", name);
+ fprintf(stderr, "%s [-s(tack)] [-c(ross page)]| ...\n", name);
return 1;
}
{
int c, index = 1;
- while ((c = getopt(argc, argv, "s")) != -1) {
+ while ((c = getopt(argc, argv, "sc")) != -1) {
switch (c) {
case 's':
alloc_stack = 1;
index++;
break;
+ case 'c':
+ cross_page = 1;
+ index++;
+ break;
default:
return -1;
}
}
+ if (alloc_stack && cross_page)
+ fprintf(stderr, "Stack alloc and cross page are mutually exclusive\n");
+
return index;
}
b = S2;
f = S3;
} else {
- h = strdup(S1);
- b = strdup(S2);
- f = strdup(S3);
+ if (cross_page) {
+ void *ptr;
+
+ ptr = ALIGN(malloc(2 * PAGE_SIZE));
+ h = ptr - (strlen(S1) / 2);
+ strcpy(h, S1);
+
+ ptr = ALIGN(malloc(2 * PAGE_SIZE));
+ b = ptr - (strlen(S2) / 2);
+ strcpy(b, S2);
+
+ ptr = ALIGN(malloc(2 * PAGE_SIZE));
+ f = ptr - (strlen(S3) / 2);
+ strcpy(f, S3);
+ } else {
+ h = strdup(S1);
+ b = strdup(S2);
+ f = strdup(S3);
+ }
}
vecs[0].iov_base = h;