sendfile
/* receive e-mail */ | |
void receive_mail(char *filename, int sock_fd) | |
{ | |
/* file descriptor for destination file */ | |
int destination_fd; | |
/* byte offset used by sendfile */ | |
off_t offset = 0; | |
size_t total_bytes_sent = 0; | |
struct stat stat_buf; | |
/* open destination file */ | |
destination_fd = open(filename, O_WRONLY | O_CREAT); | |
/* checking for "open" errors */ | |
if (destination_fd < 0) | |
{ exit(EXIT_FAILURE); } | |
fstat(destination_fd, &stat_buf); | |
(void)fprintf(stdout, "File size: %jd\n", (intmax_t)stat_buf.st_size); | |
/* receive file */ | |
total_bytes_sent = do_recvfile(1, sock_fd, offset, /* HERE I NEED THE FILE SIZE: ON SERVER-SIDE IT IS UNKNOWN */); | |
(void)fprintf(stdout, "Total bytes sent: %d\n", total_bytes_sent); | |
close(destination_fd); | |
} | |
/* receive file */ | |
ssize_t do_recvfile(int output_fd, int sock_fd, off_t offset, size_t count) | |
{ | |
ssize_t bytes; | |
ssize_t bytes_sent; | |
ssize_t bytes_in_pipe; | |
size_t total_bytes_sent = 0; | |
/* pipe */ | |
int pipefd[2]; | |
/* setup the pipe */ | |
if (pipe(pipefd) < 0) | |
{ | |
err_num = errno; | |
(void)fprintf(stderr, "\"pipe\" error:%s\n", strerror(err_num)); | |
exit(EXIT_FAILURE); | |
} | |
/* splice the data from "sock_fd" into the pipe */ | |
while (total_bytes_sent < count) | |
{ | |
if ((bytes_sent = splice(sock_fd, NULL, pipefd[1], NULL, | |
MIN(count - total_bytes_sent, 16384), | |
SPLICE_F_MORE | SPLICE_F_MOVE)) <= 0) { | |
if (errno == EINTR || errno == EAGAIN) | |
{ continue; } | |
err_num = errno; | |
(void)fprintf(stderr, "\"splice\" error (bytes_sent): %s\n", strerror(err_num)); | |
return (-1); | |
} | |
bytes_in_pipe = bytes_sent; | |
while (bytes_in_pipe > 0) | |
{ | |
if ((bytes = splice(pipefd[0], NULL, output_fd, &offset, bytes_in_pipe, SPLICE_F_MORE | SPLICE_F_MOVE)) <= 0) | |
{ | |
if (errno == EINTR || errno == EAGAIN) | |
{ continue; } | |
err_num = errno; | |
(void)fprintf(stderr, "\"splice\" error (bytes): %s\n", strerror(err_num)); | |
return (-1); | |
} | |
bytes_in_pipe -= bytes; | |
} | |
total_bytes_sent += bytes_sent; | |
} | |
return (total_bytes_sent); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment