Skip to content

Commit f44d887

Browse files
committed
Workaround sendfile() bug in WSL
1 parent fc96af0 commit f44d887

File tree

4 files changed

+59
-1
lines changed

4 files changed

+59
-1
lines changed

libc/intrin/__is_wsl.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
2+
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
3+
╞══════════════════════════════════════════════════════════════════════════════╡
4+
│ Copyright 2022 Justine Alexandra Roberts Tunney │
5+
│ │
6+
│ Permission to use, copy, modify, and/or distribute this software for │
7+
│ any purpose with or without fee is hereby granted, provided that the │
8+
│ above copyright notice and this permission notice appear in all copies. │
9+
│ │
10+
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
11+
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
12+
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
13+
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
14+
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
15+
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
16+
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
17+
│ PERFORMANCE OF THIS SOFTWARE. │
18+
╚─────────────────────────────────────────────────────────────────────────────*/
19+
#include "libc/calls/calls.h"
20+
#include "libc/calls/syscall-sysv.internal.h"
21+
#include "libc/dce.h"
22+
#include "libc/errno.h"
23+
#include "libc/runtime/internal.h"
24+
#include "libc/sysv/consts/map.h"
25+
#include "libc/sysv/consts/prot.h"
26+
27+
#define MAP_GROWSDOWN_linux 0x00000100
28+
#define MAP_ANONYMOUS_linux 0x00000020
29+
30+
/**
31+
* Returns true if host platform is WSL.
32+
*/
33+
bool __is_wsl(void) {
34+
int e;
35+
void *p;
36+
bool res;
37+
if (!IsLinux()) return false;
38+
e = errno;
39+
p = __sys_mmap(0, 4096, PROT_READ | PROT_WRITE,
40+
MAP_PRIVATE | MAP_ANONYMOUS_linux | MAP_GROWSDOWN_linux, -1, 0,
41+
0);
42+
if (p != MAP_FAILED) {
43+
__sys_munmap(p, 4096);
44+
return false;
45+
}
46+
res = errno == ENOTSUP;
47+
errno = e;
48+
return res;
49+
}

libc/runtime/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ extern unsigned char _tls_size[];
2929
extern unsigned char _tls_content[];
3030

3131
void _init(void) hidden;
32+
bool __is_wsl(void);
3233
void __morph_tls(void);
3334
void __enable_tls(void);
3435
void __enable_threads(void) hidden;

test/libc/calls/fcntl_test.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ TEST(fcntl, getfd) {
8787
ASSERT_SYS(0, 0, fcntl(3, F_GETFD));
8888
ASSERT_SYS(0, 4, open("/dev/null", O_RDWR | O_CLOEXEC));
8989
ASSERT_SYS(0, FD_CLOEXEC, fcntl(4, F_GETFD));
90+
ASSERT_SYS(0, 0, fcntl(4, F_SETFD, FD_CLOEXEC));
91+
ASSERT_SYS(0, FD_CLOEXEC, fcntl(4, F_GETFD));
92+
ASSERT_SYS(0, 0, fcntl(4, F_SETFD, 0));
93+
ASSERT_SYS(0, 0, fcntl(4, F_GETFD));
9094
ASSERT_SYS(0, 0, close(4));
9195
ASSERT_SYS(0, 0, close(3));
9296
}

test/libc/sock/sendfile_test.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "libc/limits.h"
2525
#include "libc/mem/gc.internal.h"
2626
#include "libc/mem/mem.h"
27+
#include "libc/runtime/internal.h"
2728
#include "libc/runtime/runtime.h"
2829
#include "libc/sock/sock.h"
2930
#include "libc/sock/struct/sockaddr.h"
@@ -125,7 +126,10 @@ TEST(sendfile, testPositioning) {
125126
ASSERT_EQ(-1, sendfile(4, 5, 0, 6));
126127
ASSERT_TRUE(errno == EINVAL || errno == EPIPE);
127128
errno = 0;
128-
ASSERT_EQ(12, GetFileOffset(5));
129+
// XXX: WSL clobbers file offset on failure!
130+
if (!__is_wsl()) {
131+
ASSERT_EQ(12, GetFileOffset(5));
132+
}
129133
_Exit(0);
130134
}
131135
ASSERT_SYS(0, 0, close(3));

0 commit comments

Comments
 (0)