static int write_test_file(size_t file_size) { char *page_buffer; ssize_t len; static size_t current_file_size = 0; if (file_size == current_file_size) return (0); else if (file_size < current_file_size) { if (ftruncate(file_fd, file_size) != 0) FAIL_ERR("ftruncate"); current_file_size = file_size; return (0); } page_buffer = malloc(file_size); if (page_buffer == NULL) FAIL_ERR("malloc") bzero(page_buffer, file_size); len = write(file_fd, page_buffer, file_size); if (len < 0) FAIL_ERR("write") len = lseek(file_fd, 0, SEEK_SET); if (len < 0) FAIL_ERR("lseek") if (len != 0) FAIL("len != 0") free(page_buffer); current_file_size = file_size; return (0); }
static int new_test_socket(int *connect_socket) { struct sockaddr_in sin; int rc = 0; *connect_socket = socket(PF_INET, SOCK_STREAM, 0); if (*connect_socket < 0) FAIL_ERR("socket") bzero(&sin, sizeof(sin)); sin.sin_len = sizeof(sin); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); sin.sin_port = htons(TEST_PORT); if (connect(*connect_socket, (struct sockaddr *)&sin, sizeof(sin)) < 0) FAIL_ERR("connect") return (rc); }
static int write_test_file(size_t file_size) { char *page_buffer; ssize_t len; static size_t current_file_size = 0; if (file_size == current_file_size) return (0); else if (file_size < current_file_size) { if (ftruncate(file_fd, file_size) != 0) FAIL_ERR("ftruncate"); current_file_size = file_size; return (0); } page_buffer = malloc(file_size);
static int receive_test(void) { uint32_t header_length, offset, length, counter; struct test_header th; ssize_t len; char buf[10240]; MD5_CTX md5ctx; char *rxmd5; len = read(accept_socket, &th, sizeof(th)); if (len < 0 || (size_t)len < sizeof(th)) FAIL_ERR("read") if (test_th(&th, &header_length, &offset, &length) != 0) return (-1); MD5Init(&md5ctx); counter = 0; while (1) { len = read(accept_socket, buf, sizeof(buf)); if (len < 0 || len == 0) break; counter += len; MD5Update(&md5ctx, buf, len); } rxmd5 = MD5End(&md5ctx, NULL); if ((counter != header_length+length) || memcmp(th.th_md5, rxmd5, 33) != 0) FAIL("receive length mismatch") free(rxmd5); return (0); }
static int send_test(int connect_socket, struct sendfile_test test) { struct test_header th; struct sf_hdtr hdtr, *hdtrp; struct iovec headers; char *header; ssize_t len; int length; off_t off; len = lseek(file_fd, 0, SEEK_SET); if (len != 0) FAIL_ERR("lseek") struct stat st; if (fstat(file_fd, &st) < 0) FAIL_ERR("fstat") length = st.st_size - test.offset; if (test.length > 0 && test.length < (uint32_t)length) length = test.length; init_th(&th, test.hdr_length, test.offset, length); len = write(connect_socket, &th, sizeof(th)); if (len != sizeof(th)) return (-1); if (test.hdr_length != 0) { header = malloc(test.hdr_length); if (header == NULL) FAIL_ERR("malloc") hdtrp = &hdtr; bzero(&headers, sizeof(headers)); headers.iov_base = header; headers.iov_len = test.hdr_length; bzero(&hdtr, sizeof(hdtr)); hdtr.headers = &headers; hdtr.hdr_cnt = 1; hdtr.trailers = NULL; hdtr.trl_cnt = 0; } else { hdtrp = NULL; header = NULL; } if (sendfile(file_fd, connect_socket, test.offset, test.length, hdtrp, &off, 0) < 0) { if (header != NULL) free(header); FAIL_ERR("sendfile") } if (length == 0) { struct stat sb; if (fstat(file_fd, &sb) == 0) length = sb.st_size - test.offset; } if (header != NULL) free(header); if (off != length) FAIL("offset != length") return (0); }