mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-03 07:29:23 +00:00
Slightly optimize iovec on Windows
This commit is contained in:
parent
774c67fcd3
commit
65e425fbca
4 changed files with 136 additions and 8 deletions
|
@ -29,15 +29,21 @@
|
|||
*/
|
||||
textwindows size_t __iovec2nt(struct NtIovec iovnt[hasatleast 16],
|
||||
const struct iovec *iov, size_t iovlen) {
|
||||
size_t i, limit;
|
||||
for (limit = 0x7ffff000, i = 0; i < MIN(16, iovlen); ++i) {
|
||||
iovnt[i].buf = iov[i].iov_base;
|
||||
size_t i, j, limit = 0x7ffff000;
|
||||
for (j = i = 0; i < iovlen; ++i) {
|
||||
if (!iov[i].iov_len)
|
||||
continue;
|
||||
if (j == 16)
|
||||
break;
|
||||
iovnt[j].buf = iov[i].iov_base;
|
||||
if (iov[i].iov_len < limit) {
|
||||
limit -= (iovnt[i].len = iov[i].iov_len);
|
||||
limit -= (iovnt[j].len = iov[i].iov_len);
|
||||
++j;
|
||||
} else {
|
||||
iovnt[i].len = limit;
|
||||
iovnt[j].len = limit;
|
||||
++j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
return j;
|
||||
}
|
||||
|
|
|
@ -2044,7 +2044,7 @@ syscon misc IF_NAMESIZE 0x10 0x10 0x10 0x10 0x10 0x10 0x10 0
|
|||
syscon misc INTERMEDIATE_C_GOOD 10 10 0 0 0 0 0 0
|
||||
syscon misc INTERMEDIATE_GOOD 8 8 0 0 0 0 0 0
|
||||
|
||||
syscon misc IOV_MAX 0x0400 0x0400 0x0400 0x0400 0x0400 0x0400 0x0400 16 # unix consensus & MSG_MAXIOVLEN
|
||||
syscon misc IOV_MAX 1024 1024 1024 1024 1024 1024 1024 16 # unix consensus & MSG_MAXIOVLEN
|
||||
syscon misc LINE_MAX 0x0800 0x0800 0x0800 0x0800 0x0800 0x0800 0x0800 0 # unix consensus
|
||||
syscon misc LINKED_CMD_COMPLETE 10 10 0 0 0 0 0 0
|
||||
syscon misc LINKED_FLG_CMD_COMPLETE 11 11 0 0 0 0 0 0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon misc,IOV_MAX,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,16
|
||||
.syscon misc,IOV_MAX,1024,1024,1024,1024,1024,1024,1024,16
|
||||
|
|
122
test/posix/writev_test.c
Normal file
122
test/posix/writev_test.c
Normal file
|
@ -0,0 +1,122 @@
|
|||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main() {
|
||||
int sockfd, newsockfd, clientfd;
|
||||
struct sockaddr_in serv_addr, cli_addr;
|
||||
socklen_t clilen;
|
||||
struct iovec iov[2];
|
||||
char buffer[256];
|
||||
ssize_t n;
|
||||
const char *str1 = "";
|
||||
const char *str2 = "Hello from server!\n";
|
||||
const char *str3 = "Hello from client!\n";
|
||||
|
||||
// Create server socket
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sockfd < 0) {
|
||||
perror("socket");
|
||||
return 18;
|
||||
}
|
||||
|
||||
// Bind server socket to localhost:PORT
|
||||
memset(&serv_addr, 0, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); // localhost
|
||||
serv_addr.sin_port = 0;
|
||||
if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
|
||||
perror("bind");
|
||||
close(sockfd);
|
||||
return 19;
|
||||
}
|
||||
uint32_t addrsize = sizeof(serv_addr);
|
||||
if (getsockname(sockfd, (struct sockaddr *)&serv_addr, &addrsize)) {
|
||||
perror("getsockname");
|
||||
return 20;
|
||||
}
|
||||
|
||||
// Listen for incoming connections
|
||||
if (listen(sockfd, 1) < 0) {
|
||||
perror("listen");
|
||||
close(sockfd);
|
||||
return 21;
|
||||
}
|
||||
|
||||
// Create client socket
|
||||
clientfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (clientfd < 0) {
|
||||
perror("socket");
|
||||
close(sockfd);
|
||||
return 22;
|
||||
}
|
||||
|
||||
// Connect client socket to server
|
||||
if (connect(clientfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
|
||||
perror("connect");
|
||||
close(sockfd);
|
||||
close(clientfd);
|
||||
return 23;
|
||||
}
|
||||
|
||||
// Accept connection on server side
|
||||
clilen = sizeof(cli_addr);
|
||||
newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
|
||||
if (newsockfd < 0) {
|
||||
perror("accept");
|
||||
close(sockfd);
|
||||
close(clientfd);
|
||||
return 34;
|
||||
}
|
||||
|
||||
// Server writes to client using writev with zero-length iovec
|
||||
iov[0].iov_base = (void *)str1;
|
||||
iov[0].iov_len = 0; // Zero-length iovec
|
||||
iov[1].iov_base = (void *)str2;
|
||||
iov[1].iov_len = strlen(str2);
|
||||
|
||||
n = writev(newsockfd, iov, 2);
|
||||
if (n != 19)
|
||||
return 13;
|
||||
|
||||
// Client reads data from server
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
n = read(clientfd, buffer, sizeof(buffer) - 1);
|
||||
if (n < 0) {
|
||||
perror("read");
|
||||
return 14;
|
||||
} else {
|
||||
if (n != 19)
|
||||
return 8;
|
||||
}
|
||||
|
||||
// Client writes to server using writev with zero-length iovec
|
||||
iov[0].iov_base = (void *)str1;
|
||||
iov[0].iov_len = 0; // Zero-length iovec
|
||||
iov[1].iov_base = (void *)str3;
|
||||
iov[1].iov_len = strlen(str3);
|
||||
|
||||
n = writev(clientfd, iov, 2);
|
||||
if (n != 19)
|
||||
return 9;
|
||||
|
||||
// Server reads data from client
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
n = read(newsockfd, buffer, sizeof(buffer) - 1);
|
||||
if (n < 0) {
|
||||
perror("ERROR reading from client");
|
||||
return 10;
|
||||
} else if (n != 19) {
|
||||
return 11;
|
||||
}
|
||||
|
||||
// Close all sockets
|
||||
close(newsockfd);
|
||||
close(clientfd);
|
||||
close(sockfd);
|
||||
}
|
Loading…
Add table
Reference in a new issue