Viewing: sendfile.c
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
*/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <lustre/lustreapi.h>
#define syserr(str) { perror(str); exit(-1); }
int main(int argc, char *argv[])
{
char *sfile, *tfile;
struct stat stbuf;
int size;
unsigned long bufsize = 1024 * 1024;
int infd, outfd;
int sd[2];
int rc;
char *buf;
char cmd[1024];
loff_t pos;
if (argc < 3) {
fprintf(stderr, "%s <source file> <dest file>\n", argv[0]);
exit(-1);
}
sfile = argv[1];
tfile = argv[2];
if (stat(sfile, &stbuf) < 0) {
if (errno == ENOENT) {
/* assume doing non-object file testing */
infd = open(sfile,
O_LOV_DELAY_CREATE | O_CREAT | O_RDWR,
0644);
if (infd < 0)
syserr("open source file:");
size = random() % (1 * 1024 * 1024) + 1024;
if (ftruncate(infd, (off_t)size) < 0)
syserr("truncate file error:");
} else {
syserr("stat file: ");
}
} else if (S_ISREG(stbuf.st_mode)) {
size = (int)stbuf.st_size;
infd = open(sfile, O_RDONLY, 0644);
if (infd < 0)
syserr("Open an existing file error:");
} else {
fprintf(stderr, "%s is not a regular file\n", sfile);
exit(-1);
}
outfd = open(tfile, O_WRONLY | O_TRUNC | O_CREAT, 0666);
if (outfd < 0)
syserr("open dest file:");
rc = socketpair(AF_LOCAL, SOCK_STREAM, 0, sd);
if (rc < 0)
syserr("socketpair");
rc = fcntl(sd[0], F_SETFL, O_NONBLOCK);
if (rc < 0)
syserr("fcntl");
rc = setsockopt(sd[0], SOL_SOCKET, SO_SNDBUF,
&bufsize, sizeof(bufsize));
if (rc)
syserr("setsockopt");
srandom(time(NULL));
pos = 0;
while (size > 0) {
int rc2;
size_t seg_size;
seg_size = random() % bufsize + 1;
if (seg_size > size)
seg_size = size;
while (seg_size) {
rc = sendfile(sd[0], infd, &pos, seg_size);
if (rc < 0)
syserr("sendfile:");
seg_size -= rc;
size -= rc;
if (size == 0)
close(sd[0]);
buf = malloc(rc);
if (read(sd[1], buf, rc) < 0)
syserr("read from socket:");
rc2 = write(outfd, buf, rc);
if (rc2 != rc)
syserr("write dest file error:");
free(buf);
}
}
close(sd[1]), close(infd), close(outfd);
snprintf(cmd, sizeof(cmd), "cmp %s %s\n", sfile, tfile);
return system(cmd);
}