authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-08-17 11:56:11+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-08-20 19:18:11+02:00
log07cc32b0041e5e12f72d682fd06a995fe904d556
tree00b5449a6e8a8faf3f7b4423c685c28b82609f61
parentd748cc9c12ba852ac02edf55eb418b06086d211c

wasi-libc: update to c89896107d7b57aef69dcadede47409ee4f702ee


124 files changed, 4219 insertions(+), 1637 deletions(-)

lib/libc/include/wasm-wasi-musl/__macro_PAGESIZE.h+11-3
...@@ -2,15 +2,23 @@...@@ -2,15 +2,23 @@
2#define __wasilibc___macro_PAGESIZE_h2#define __wasilibc___macro_PAGESIZE_h
33
4/*4/*
5 * The page size in WebAssembly is fixed at 64 KiB. If this ever changes,5 * Without custom-page-sizes proposal, the page size in WebAssembly
6 * it's expected that applications will need to opt in, so we can change6 * is fixed at 64 KiB.
7 * this.7 *
8 * The LLVM versions with a support of custom-page-sizes proposal
9 * provides __wasm_first_page_end global to allow page-size-agnostic
10 * objects.
8 *11 *
9 * If this ever needs to be a value outside the range of an `int`, the12 * If this ever needs to be a value outside the range of an `int`, the
10 * `getpagesize` function which returns this value will need special13 * `getpagesize` function which returns this value will need special
11 * consideration. POSIX has deprecated `getpagesize` in favor of14 * consideration. POSIX has deprecated `getpagesize` in favor of
12 * `sysconf(_SC_PAGESIZE)` which does not have this problem.15 * `sysconf(_SC_PAGESIZE)` which does not have this problem.
13 */16 */
17#if __clang_major__ >= 22
18extern char __wasm_first_page_end;
19#define PAGESIZE ((unsigned long)&__wasm_first_page_end)
20#else
14#define PAGESIZE (0x10000)21#define PAGESIZE (0x10000)
22#endif
1523
16#endif24#endif
lib/libc/include/wasm-wasi-musl/__wasi_snapshot.h+5
...@@ -0,0 +1,5 @@...@@ -0,0 +1,5 @@
1/* This file is (practically) empty by default. The Makefile will replace it
2 with a non-empty version that defines `__wasilibc_use_wasip2` if targeting
3 `wasm32-wasip2`.
4 */
5
lib/libc/include/wasm-wasi-musl/arpa/nameser.h deleted-455
...@@ -1,455 +0,0 @@
1#ifndef _ARPA_NAMESER_H
2#define _ARPA_NAMESER_H
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8#include <stddef.h>
9#include <stdint.h>
10
11#define __NAMESER 19991006
12#define NS_PACKETSZ 512
13#define NS_MAXDNAME 1025
14#define NS_MAXMSG 65535
15#define NS_MAXCDNAME 255
16#define NS_MAXLABEL 63
17#define NS_HFIXEDSZ 12
18#define NS_QFIXEDSZ 4
19#define NS_RRFIXEDSZ 10
20#define NS_INT32SZ 4
21#define NS_INT16SZ 2
22#define NS_INT8SZ 1
23#define NS_INADDRSZ 4
24#define NS_IN6ADDRSZ 16
25#define NS_CMPRSFLGS 0xc0
26#define NS_DEFAULTPORT 53
27
28typedef enum __ns_sect {
29 ns_s_qd = 0,
30 ns_s_zn = 0,
31 ns_s_an = 1,
32 ns_s_pr = 1,
33 ns_s_ns = 2,
34 ns_s_ud = 2,
35 ns_s_ar = 3,
36 ns_s_max = 4
37} ns_sect;
38
39typedef struct __ns_msg {
40 const unsigned char *_msg, *_eom;
41 uint16_t _id, _flags, _counts[ns_s_max];
42 const unsigned char *_sections[ns_s_max];
43 ns_sect _sect;
44 int _rrnum;
45 const unsigned char *_msg_ptr;
46} ns_msg;
47
48struct _ns_flagdata { int mask, shift; };
49extern const struct _ns_flagdata _ns_flagdata[];
50
51#define ns_msg_id(handle) ((handle)._id + 0)
52#define ns_msg_base(handle) ((handle)._msg + 0)
53#define ns_msg_end(handle) ((handle)._eom + 0)
54#define ns_msg_size(handle) ((handle)._eom - (handle)._msg)
55#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
56#define ns_msg_getflag(handle, flag) \
57 (((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift)
58
59typedef struct __ns_rr {
60 char name[NS_MAXDNAME];
61 uint16_t type;
62 uint16_t rr_class;
63 uint32_t ttl;
64 uint16_t rdlength;
65 const unsigned char *rdata;
66} ns_rr;
67
68#define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".")
69#define ns_rr_type(rr) ((ns_type)((rr).type + 0))
70#define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0))
71#define ns_rr_ttl(rr) ((rr).ttl + 0)
72#define ns_rr_rdlen(rr) ((rr).rdlength + 0)
73#define ns_rr_rdata(rr) ((rr).rdata + 0)
74
75typedef enum __ns_flag {
76 ns_f_qr,
77 ns_f_opcode,
78 ns_f_aa,
79 ns_f_tc,
80 ns_f_rd,
81 ns_f_ra,
82 ns_f_z,
83 ns_f_ad,
84 ns_f_cd,
85 ns_f_rcode,
86 ns_f_max
87} ns_flag;
88
89typedef enum __ns_opcode {
90 ns_o_query = 0,
91 ns_o_iquery = 1,
92 ns_o_status = 2,
93 ns_o_notify = 4,
94 ns_o_update = 5,
95 ns_o_max = 6
96} ns_opcode;
97
98typedef enum __ns_rcode {
99 ns_r_noerror = 0,
100 ns_r_formerr = 1,
101 ns_r_servfail = 2,
102 ns_r_nxdomain = 3,
103 ns_r_notimpl = 4,
104 ns_r_refused = 5,
105 ns_r_yxdomain = 6,
106 ns_r_yxrrset = 7,
107 ns_r_nxrrset = 8,
108 ns_r_notauth = 9,
109 ns_r_notzone = 10,
110 ns_r_max = 11,
111 ns_r_badvers = 16,
112 ns_r_badsig = 16,
113 ns_r_badkey = 17,
114 ns_r_badtime = 18
115} ns_rcode;
116
117typedef enum __ns_update_operation {
118 ns_uop_delete = 0,
119 ns_uop_add = 1,
120 ns_uop_max = 2
121} ns_update_operation;
122
123struct ns_tsig_key {
124 char name[NS_MAXDNAME], alg[NS_MAXDNAME];
125 unsigned char *data;
126 int len;
127};
128typedef struct ns_tsig_key ns_tsig_key;
129
130struct ns_tcp_tsig_state {
131 int counter;
132 struct dst_key *key;
133 void *ctx;
134 unsigned char sig[NS_PACKETSZ];
135 int siglen;
136};
137typedef struct ns_tcp_tsig_state ns_tcp_tsig_state;
138
139#define NS_TSIG_FUDGE 300
140#define NS_TSIG_TCP_COUNT 100
141#define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT"
142
143#define NS_TSIG_ERROR_NO_TSIG -10
144#define NS_TSIG_ERROR_NO_SPACE -11
145#define NS_TSIG_ERROR_FORMERR -12
146
147typedef enum __ns_type {
148 ns_t_invalid = 0,
149 ns_t_a = 1,
150 ns_t_ns = 2,
151 ns_t_md = 3,
152 ns_t_mf = 4,
153 ns_t_cname = 5,
154 ns_t_soa = 6,
155 ns_t_mb = 7,
156 ns_t_mg = 8,
157 ns_t_mr = 9,
158 ns_t_null = 10,
159 ns_t_wks = 11,
160 ns_t_ptr = 12,
161 ns_t_hinfo = 13,
162 ns_t_minfo = 14,
163 ns_t_mx = 15,
164 ns_t_txt = 16,
165 ns_t_rp = 17,
166 ns_t_afsdb = 18,
167 ns_t_x25 = 19,
168 ns_t_isdn = 20,
169 ns_t_rt = 21,
170 ns_t_nsap = 22,
171 ns_t_nsap_ptr = 23,
172 ns_t_sig = 24,
173 ns_t_key = 25,
174 ns_t_px = 26,
175 ns_t_gpos = 27,
176 ns_t_aaaa = 28,
177 ns_t_loc = 29,
178 ns_t_nxt = 30,
179 ns_t_eid = 31,
180 ns_t_nimloc = 32,
181 ns_t_srv = 33,
182 ns_t_atma = 34,
183 ns_t_naptr = 35,
184 ns_t_kx = 36,
185 ns_t_cert = 37,
186 ns_t_a6 = 38,
187 ns_t_dname = 39,
188 ns_t_sink = 40,
189 ns_t_opt = 41,
190 ns_t_apl = 42,
191 ns_t_tkey = 249,
192 ns_t_tsig = 250,
193 ns_t_ixfr = 251,
194 ns_t_axfr = 252,
195 ns_t_mailb = 253,
196 ns_t_maila = 254,
197 ns_t_any = 255,
198 ns_t_zxfr = 256,
199 ns_t_max = 65536
200} ns_type;
201
202#define ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \
203 (t) == ns_t_mailb || (t) == ns_t_maila)
204#define ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt)
205#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t))
206#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr)
207#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \
208 (t) == ns_t_zxfr)
209
210typedef enum __ns_class {
211 ns_c_invalid = 0,
212 ns_c_in = 1,
213 ns_c_2 = 2,
214 ns_c_chaos = 3,
215 ns_c_hs = 4,
216 ns_c_none = 254,
217 ns_c_any = 255,
218 ns_c_max = 65536
219} ns_class;
220
221typedef enum __ns_key_types {
222 ns_kt_rsa = 1,
223 ns_kt_dh = 2,
224 ns_kt_dsa = 3,
225 ns_kt_private = 254
226} ns_key_types;
227
228typedef enum __ns_cert_types {
229 cert_t_pkix = 1,
230 cert_t_spki = 2,
231 cert_t_pgp = 3,
232 cert_t_url = 253,
233 cert_t_oid = 254
234} ns_cert_types;
235
236#define NS_KEY_TYPEMASK 0xC000
237#define NS_KEY_TYPE_AUTH_CONF 0x0000
238#define NS_KEY_TYPE_CONF_ONLY 0x8000
239#define NS_KEY_TYPE_AUTH_ONLY 0x4000
240#define NS_KEY_TYPE_NO_KEY 0xC000
241#define NS_KEY_NO_AUTH 0x8000
242#define NS_KEY_NO_CONF 0x4000
243#define NS_KEY_RESERVED2 0x2000
244#define NS_KEY_EXTENDED_FLAGS 0x1000
245#define NS_KEY_RESERVED4 0x0800
246#define NS_KEY_RESERVED5 0x0400
247#define NS_KEY_NAME_TYPE 0x0300
248#define NS_KEY_NAME_USER 0x0000
249#define NS_KEY_NAME_ENTITY 0x0200
250#define NS_KEY_NAME_ZONE 0x0100
251#define NS_KEY_NAME_RESERVED 0x0300
252#define NS_KEY_RESERVED8 0x0080
253#define NS_KEY_RESERVED9 0x0040
254#define NS_KEY_RESERVED10 0x0020
255#define NS_KEY_RESERVED11 0x0010
256#define NS_KEY_SIGNATORYMASK 0x000F
257#define NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \
258 NS_KEY_RESERVED4 | \
259 NS_KEY_RESERVED5 | \
260 NS_KEY_RESERVED8 | \
261 NS_KEY_RESERVED9 | \
262 NS_KEY_RESERVED10 | \
263 NS_KEY_RESERVED11 )
264#define NS_KEY_RESERVED_BITMASK2 0xFFFF
265#define NS_ALG_MD5RSA 1
266#define NS_ALG_DH 2
267#define NS_ALG_DSA 3
268#define NS_ALG_DSS NS_ALG_DSA
269#define NS_ALG_EXPIRE_ONLY 253
270#define NS_ALG_PRIVATE_OID 254
271
272#define NS_KEY_PROT_TLS 1
273#define NS_KEY_PROT_EMAIL 2
274#define NS_KEY_PROT_DNSSEC 3
275#define NS_KEY_PROT_IPSEC 4
276#define NS_KEY_PROT_ANY 255
277
278#define NS_MD5RSA_MIN_BITS 512
279#define NS_MD5RSA_MAX_BITS 4096
280#define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS+7/8)*2+3)
281#define NS_MD5RSA_MAX_BASE64 (((NS_MD5RSA_MAX_BYTES+2)/3)*4)
282#define NS_MD5RSA_MIN_SIZE ((NS_MD5RSA_MIN_BITS+7)/8)
283#define NS_MD5RSA_MAX_SIZE ((NS_MD5RSA_MAX_BITS+7)/8)
284
285#define NS_DSA_SIG_SIZE 41
286#define NS_DSA_MIN_SIZE 213
287#define NS_DSA_MAX_BYTES 405
288
289#define NS_SIG_TYPE 0
290#define NS_SIG_ALG 2
291#define NS_SIG_LABELS 3
292#define NS_SIG_OTTL 4
293#define NS_SIG_EXPIR 8
294#define NS_SIG_SIGNED 12
295#define NS_SIG_FOOT 16
296#define NS_SIG_SIGNER 18
297#define NS_NXT_BITS 8
298#define NS_NXT_BIT_SET( n,p) (p[(n)/NS_NXT_BITS] |= (0x80>>((n)%NS_NXT_BITS)))
299#define NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS)))
300#define NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] & (0x80>>((n)%NS_NXT_BITS)))
301#define NS_NXT_MAX 127
302
303#define NS_OPT_DNSSEC_OK 0x8000U
304#define NS_OPT_NSID 3
305
306#define NS_GET16(s, cp) (void)((s) = ns_get16(((cp)+=2)-2))
307#define NS_GET32(l, cp) (void)((l) = ns_get32(((cp)+=4)-4))
308#define NS_PUT16(s, cp) ns_put16((s), ((cp)+=2)-2)
309#define NS_PUT32(l, cp) ns_put32((l), ((cp)+=4)-4)
310
311unsigned ns_get16(const unsigned char *);
312unsigned long ns_get32(const unsigned char *);
313void ns_put16(unsigned, unsigned char *);
314void ns_put32(unsigned long, unsigned char *);
315
316int ns_initparse(const unsigned char *, int, ns_msg *);
317int ns_parserr(ns_msg *, ns_sect, int, ns_rr *);
318int ns_skiprr(const unsigned char *, const unsigned char *, ns_sect, int);
319int ns_name_uncompress(const unsigned char *, const unsigned char *, const unsigned char *, char *, size_t);
320
321
322#define __BIND 19950621
323
324typedef struct {
325 unsigned id :16;
326#if __BYTE_ORDER == __BIG_ENDIAN
327 unsigned qr: 1;
328 unsigned opcode: 4;
329 unsigned aa: 1;
330 unsigned tc: 1;
331 unsigned rd: 1;
332 unsigned ra: 1;
333 unsigned unused :1;
334 unsigned ad: 1;
335 unsigned cd: 1;
336 unsigned rcode :4;
337#else
338 unsigned rd :1;
339 unsigned tc :1;
340 unsigned aa :1;
341 unsigned opcode :4;
342 unsigned qr :1;
343 unsigned rcode :4;
344 unsigned cd: 1;
345 unsigned ad: 1;
346 unsigned unused :1;
347 unsigned ra :1;
348#endif
349 unsigned qdcount :16;
350 unsigned ancount :16;
351 unsigned nscount :16;
352 unsigned arcount :16;
353} HEADER;
354
355#define PACKETSZ NS_PACKETSZ
356#define MAXDNAME NS_MAXDNAME
357#define MAXCDNAME NS_MAXCDNAME
358#define MAXLABEL NS_MAXLABEL
359#define HFIXEDSZ NS_HFIXEDSZ
360#define QFIXEDSZ NS_QFIXEDSZ
361#define RRFIXEDSZ NS_RRFIXEDSZ
362#define INT32SZ NS_INT32SZ
363#define INT16SZ NS_INT16SZ
364#define INT8SZ NS_INT8SZ
365#define INADDRSZ NS_INADDRSZ
366#define IN6ADDRSZ NS_IN6ADDRSZ
367#define INDIR_MASK NS_CMPRSFLGS
368#define NAMESERVER_PORT NS_DEFAULTPORT
369
370#define S_ZONE ns_s_zn
371#define S_PREREQ ns_s_pr
372#define S_UPDATE ns_s_ud
373#define S_ADDT ns_s_ar
374
375#define QUERY ns_o_query
376#define IQUERY ns_o_iquery
377#define STATUS ns_o_status
378#define NS_NOTIFY_OP ns_o_notify
379#define NS_UPDATE_OP ns_o_update
380
381#define NOERROR ns_r_noerror
382#define FORMERR ns_r_formerr
383#define SERVFAIL ns_r_servfail
384#define NXDOMAIN ns_r_nxdomain
385#define NOTIMP ns_r_notimpl
386#define REFUSED ns_r_refused
387#define YXDOMAIN ns_r_yxdomain
388#define YXRRSET ns_r_yxrrset
389#define NXRRSET ns_r_nxrrset
390#define NOTAUTH ns_r_notauth
391#define NOTZONE ns_r_notzone
392
393#define DELETE ns_uop_delete
394#define ADD ns_uop_add
395
396#define T_A ns_t_a
397#define T_NS ns_t_ns
398#define T_MD ns_t_md
399#define T_MF ns_t_mf
400#define T_CNAME ns_t_cname
401#define T_SOA ns_t_soa
402#define T_MB ns_t_mb
403#define T_MG ns_t_mg
404#define T_MR ns_t_mr
405#define T_NULL ns_t_null
406#define T_WKS ns_t_wks
407#define T_PTR ns_t_ptr
408#define T_HINFO ns_t_hinfo
409#define T_MINFO ns_t_minfo
410#define T_MX ns_t_mx
411#define T_TXT ns_t_txt
412#define T_RP ns_t_rp
413#define T_AFSDB ns_t_afsdb
414#define T_X25 ns_t_x25
415#define T_ISDN ns_t_isdn
416#define T_RT ns_t_rt
417#define T_NSAP ns_t_nsap
418#define T_NSAP_PTR ns_t_nsap_ptr
419#define T_SIG ns_t_sig
420#define T_KEY ns_t_key
421#define T_PX ns_t_px
422#define T_GPOS ns_t_gpos
423#define T_AAAA ns_t_aaaa
424#define T_LOC ns_t_loc
425#define T_NXT ns_t_nxt
426#define T_EID ns_t_eid
427#define T_NIMLOC ns_t_nimloc
428#define T_SRV ns_t_srv
429#define T_ATMA ns_t_atma
430#define T_NAPTR ns_t_naptr
431#define T_A6 ns_t_a6
432#define T_DNAME ns_t_dname
433#define T_TSIG ns_t_tsig
434#define T_IXFR ns_t_ixfr
435#define T_AXFR ns_t_axfr
436#define T_MAILB ns_t_mailb
437#define T_MAILA ns_t_maila
438#define T_ANY ns_t_any
439
440#define C_IN ns_c_in
441#define C_CHAOS ns_c_chaos
442#define C_HS ns_c_hs
443#define C_NONE ns_c_none
444#define C_ANY ns_c_any
445
446#define GETSHORT NS_GET16
447#define GETLONG NS_GET32
448#define PUTSHORT NS_PUT16
449#define PUTLONG NS_PUT32
450
451#ifdef __cplusplus
452}
453#endif
454
455#endif
lib/libc/include/wasm-wasi-musl/fcntl.h+5-1
...@@ -203,7 +203,6 @@ struct f_owner_ex {...@@ -203,7 +203,6 @@ struct f_owner_ex {
203#endif203#endif
204#ifdef __wasilibc_unmodified_upstream /* WASI has no fallocate */204#ifdef __wasilibc_unmodified_upstream /* WASI has no fallocate */
205int fallocate(int, int, off_t, off_t);205int fallocate(int, int, off_t, off_t);
206#define fallocate64 fallocate
207#endif206#endif
208#ifdef __wasilibc_unmodified_upstream /* WASI has no name_to_handle_at */207#ifdef __wasilibc_unmodified_upstream /* WASI has no name_to_handle_at */
209int name_to_handle_at(int, const char *, struct file_handle *, int *, int);208int name_to_handle_at(int, const char *, struct file_handle *, int *, int);
...@@ -237,6 +236,11 @@ ssize_t tee(int, int, size_t, unsigned);...@@ -237,6 +236,11 @@ ssize_t tee(int, int, size_t, unsigned);
237#define posix_fadvise64 posix_fadvise236#define posix_fadvise64 posix_fadvise
238#define posix_fallocate64 posix_fallocate237#define posix_fallocate64 posix_fallocate
239#define off64_t off_t238#define off64_t off_t
239#ifdef __wasilibc_unmodified_upstream /* WASI has no fallocate */
240#if defined(_GNU_SOURCE)
241#define fallocate64 fallocate
242#endif
243#endif
240#endif244#endif
241245
242#ifdef __cplusplus246#ifdef __cplusplus
lib/libc/include/wasm-wasi-musl/fts.h created+155
...@@ -0,0 +1,155 @@
1/* $NetBSD: fts.h,v 1.19 2009/08/16 19:33:38 christos Exp $ */
2
3/*
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * @(#)fts.h 8.3 (Berkeley) 8/14/94
32 */
33
34#ifndef _FTS_H_
35#define _FTS_H_
36
37#include <stdint.h>
38#include <sys/types.h>
39
40#ifndef __fts_stat_t
41#define __fts_stat_t struct stat
42#endif
43#ifndef __fts_nlink_t
44#define __fts_nlink_t nlink_t
45#endif
46#ifndef __fts_ino_t
47#define __fts_ino_t ino_t
48#endif
49#ifndef __fts_length_t
50#define __fts_length_t unsigned int
51#endif
52#ifndef __fts_number_t
53#define __fts_number_t int64_t
54#endif
55#ifndef __fts_dev_t
56#define __fts_dev_t dev_t
57#endif
58#ifndef __fts_level_t
59#define __fts_level_t int
60#endif
61
62typedef struct {
63 struct _ftsent *fts_cur; /* current node */
64 struct _ftsent *fts_child; /* linked list of children */
65 struct _ftsent **fts_array; /* sort array */
66 dev_t fts_dev; /* starting device # */
67 char *fts_path; /* path for this descent */
68 int fts_rfd; /* fd for root */
69 unsigned int fts_pathlen; /* sizeof(path) */
70 unsigned int fts_nitems; /* elements in the sort array */
71 int (*fts_compar) /* compare function */
72 (const struct _ftsent **, const struct _ftsent **);
73
74#define FTS_COMFOLLOW 0x001 /* follow command line symlinks */
75#define FTS_LOGICAL 0x002 /* logical walk */
76#define FTS_NOCHDIR 0x004 /* don't change directories */
77#define FTS_NOSTAT 0x008 /* don't get stat info */
78#define FTS_PHYSICAL 0x010 /* physical walk */
79#define FTS_SEEDOT 0x020 /* return dot and dot-dot */
80#define FTS_XDEV 0x040 /* don't cross devices */
81#define FTS_WHITEOUT 0x080 /* return whiteout information */
82#define FTS_OPTIONMASK 0x0ff /* valid user option mask */
83
84#define FTS_NAMEONLY 0x100 /* (private) child names only */
85#define FTS_STOP 0x200 /* (private) unrecoverable error */
86 int fts_options; /* fts_open options, global flags */
87} FTS;
88
89typedef struct _ftsent {
90 struct _ftsent *fts_cycle; /* cycle node */
91 struct _ftsent *fts_parent; /* parent directory */
92 struct _ftsent *fts_link; /* next file in directory */
93 __fts_number_t fts_number; /* local numeric value */
94 void *fts_pointer; /* local address value */
95 char *fts_accpath; /* access path */
96 char *fts_path; /* root path */
97 int fts_errno; /* errno for this node */
98 int fts_symfd; /* fd for symlink */
99 __fts_length_t fts_pathlen; /* strlen(fts_path) */
100 __fts_length_t fts_namelen; /* strlen(fts_name) */
101
102 __fts_ino_t fts_ino; /* inode */
103 __fts_dev_t fts_dev; /* device */
104 __fts_nlink_t fts_nlink; /* link count */
105
106#define FTS_ROOTPARENTLEVEL -1
107#define FTS_ROOTLEVEL 0
108 __fts_level_t fts_level; /* depth (-1 to N) */
109
110#define FTS_D 1 /* preorder directory */
111#define FTS_DC 2 /* directory that causes cycles */
112#define FTS_DEFAULT 3 /* none of the above */
113#define FTS_DNR 4 /* unreadable directory */
114#define FTS_DOT 5 /* dot or dot-dot */
115#define FTS_DP 6 /* postorder directory */
116#define FTS_ERR 7 /* error; errno is set */
117#define FTS_F 8 /* regular file */
118#define FTS_INIT 9 /* initialized only */
119#define FTS_NS 10 /* stat(2) failed */
120#define FTS_NSOK 11 /* no stat(2) requested */
121#define FTS_SL 12 /* symbolic link */
122#define FTS_SLNONE 13 /* symbolic link without target */
123#define FTS_W 14 /* whiteout object */
124 unsigned short fts_info; /* user flags for FTSENT structure */
125
126#define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */
127#define FTS_SYMFOLLOW 0x02 /* followed a symlink to get here */
128#define FTS_ISW 0x04 /* this is a whiteout object */
129 unsigned short fts_flags; /* private flags for FTSENT structure */
130
131#define FTS_AGAIN 1 /* read node again */
132#define FTS_FOLLOW 2 /* follow symbolic link */
133#define FTS_NOINSTR 3 /* no instructions */
134#define FTS_SKIP 4 /* discard node */
135 unsigned short fts_instr; /* fts_set() instructions */
136
137 __fts_stat_t *fts_statp; /* stat(2) information */
138 char fts_name[1]; /* file name */
139} FTSENT;
140
141#ifdef __cplusplus
142extern "C" {
143#endif
144FTSENT *fts_children(FTS *, int);
145int fts_close(FTS *);
146FTS *fts_open(char * const *, int,
147 int (*)(const FTSENT **, const FTSENT **));
148FTSENT *fts_read(FTS *);
149int fts_set(FTS *, FTSENT *, int);
150#ifdef __cplusplus
151}
152#endif
153
154
155#endif /* !_FTS_H_ */
lib/libc/include/wasm-wasi-musl/limits.h-2
...@@ -65,11 +65,9 @@...@@ -65,11 +65,9 @@
6565
66/* Implementation choices... */66/* Implementation choices... */
6767
68#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
69#define PTHREAD_KEYS_MAX 12868#define PTHREAD_KEYS_MAX 128
70#define PTHREAD_STACK_MIN 204869#define PTHREAD_STACK_MIN 2048
71#define PTHREAD_DESTRUCTOR_ITERATIONS 470#define PTHREAD_DESTRUCTOR_ITERATIONS 4
72#endif
73#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)71#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
74#define SEM_VALUE_MAX 0x7fffffff72#define SEM_VALUE_MAX 0x7fffffff
75#define SEM_NSEMS_MAX 25673#define SEM_NSEMS_MAX 256
lib/libc/include/wasm-wasi-musl/poll.h+2-2
...@@ -48,7 +48,7 @@ struct pollfd {...@@ -48,7 +48,7 @@ struct pollfd {
4848
49int poll (struct pollfd *, nfds_t, int);49int poll (struct pollfd *, nfds_t, int);
5050
51#ifdef _GNU_SOURCE51#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
52#define __NEED_time_t52#define __NEED_time_t
53#define __NEED_struct_timespec53#define __NEED_struct_timespec
54#define __NEED_sigset_t54#define __NEED_sigset_t
...@@ -57,7 +57,7 @@ int ppoll(struct pollfd *, nfds_t, const struct timespec *, const sigset_t *);...@@ -57,7 +57,7 @@ int ppoll(struct pollfd *, nfds_t, const struct timespec *, const sigset_t *);
57#endif57#endif
5858
59#if _REDIR_TIME6459#if _REDIR_TIME64
60#ifdef _GNU_SOURCE60#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
61__REDIR(ppoll, __ppoll_time64);61__REDIR(ppoll, __ppoll_time64);
62#endif62#endif
63#endif63#endif
lib/libc/include/wasm-wasi-musl/pthread.h created+267
...@@ -0,0 +1,267 @@
1#ifndef _PTHREAD_H
2#define _PTHREAD_H
3#ifdef __cplusplus
4extern "C" {
5#endif
6
7#include <features.h>
8
9#define __NEED_time_t
10#define __NEED_clockid_t
11#define __NEED_struct_timespec
12#define __NEED_sigset_t
13#define __NEED_pthread_t
14#define __NEED_pthread_attr_t
15#define __NEED_pthread_mutexattr_t
16#define __NEED_pthread_condattr_t
17#define __NEED_pthread_rwlockattr_t
18#define __NEED_pthread_barrierattr_t
19#define __NEED_pthread_mutex_t
20#define __NEED_pthread_cond_t
21#define __NEED_pthread_rwlock_t
22#define __NEED_pthread_barrier_t
23#define __NEED_pthread_spinlock_t
24#define __NEED_pthread_key_t
25#define __NEED_pthread_once_t
26#define __NEED_size_t
27
28#include <bits/alltypes.h>
29
30#include <sched.h>
31#include <time.h>
32
33#define PTHREAD_CREATE_JOINABLE 0
34#define PTHREAD_CREATE_DETACHED 1
35
36#define PTHREAD_MUTEX_NORMAL 0
37#define PTHREAD_MUTEX_DEFAULT 0
38#define PTHREAD_MUTEX_RECURSIVE 1
39#define PTHREAD_MUTEX_ERRORCHECK 2
40
41#define PTHREAD_MUTEX_STALLED 0
42#define PTHREAD_MUTEX_ROBUST 1
43
44#define PTHREAD_PRIO_NONE 0
45#define PTHREAD_PRIO_INHERIT 1
46#define PTHREAD_PRIO_PROTECT 2
47
48#define PTHREAD_INHERIT_SCHED 0
49#define PTHREAD_EXPLICIT_SCHED 1
50
51#define PTHREAD_SCOPE_SYSTEM 0
52#define PTHREAD_SCOPE_PROCESS 1
53
54#define PTHREAD_PROCESS_PRIVATE 0
55#define PTHREAD_PROCESS_SHARED 1
56
57
58#define PTHREAD_MUTEX_INITIALIZER {{{0}}}
59#define PTHREAD_RWLOCK_INITIALIZER {{{0}}}
60#define PTHREAD_COND_INITIALIZER {{{0}}}
61#define PTHREAD_ONCE_INIT 0
62
63
64#define PTHREAD_CANCEL_ENABLE 0
65#define PTHREAD_CANCEL_DISABLE 1
66#define PTHREAD_CANCEL_MASKED 2
67
68#define PTHREAD_CANCEL_DEFERRED 0
69#define PTHREAD_CANCEL_ASYNCHRONOUS 1
70
71#define PTHREAD_CANCELED ((void *)-1)
72
73
74#define PTHREAD_BARRIER_SERIAL_THREAD (-1)
75
76
77#define PTHREAD_NULL ((pthread_t)0)
78
79
80#ifdef __wasilibc_unmodified_upstream
81int pthread_create(pthread_t *__restrict, const pthread_attr_t *__restrict, void *(*)(void *), void *__restrict);
82int pthread_detach(pthread_t);
83_Noreturn void pthread_exit(void *);
84int pthread_join(pthread_t, void **);
85#else
86#if defined(_REENTRANT) || !defined(_WASI_STRICT_PTHREAD)
87int pthread_create(pthread_t *__restrict, const pthread_attr_t *__restrict, void *(*)(void *), void *__restrict);
88int pthread_detach(pthread_t);
89int pthread_join(pthread_t, void **);
90#else
91#define pthread_create(...) ({ _Static_assert(0, "This function is not available on a single-threaded target; switch to a multi-threaded target with -pthread or enable a stub implementation by undefining _WASI_STRICT_PTHREAD"); 0;})
92#define pthread_detach(...) ({ _Static_assert(0, "This function is not available on a single-threaded target; switch to a multi-threaded target with -pthread or enable a stub implementation by undefining _WASI_STRICT_PTHREAD"); 0;})
93#define pthread_join(...) ({ _Static_assert(0, "This function is not available on a single-threaded target; switch to a multi-threaded target with -pthread or enable a stub implementation by undefining _WASI_STRICT_PTHREAD"); 0;})
94#endif
95#endif
96
97#ifdef __GNUC__
98__attribute__((const))
99#endif
100pthread_t pthread_self(void);
101
102int pthread_equal(pthread_t, pthread_t);
103#ifndef __cplusplus
104#define pthread_equal(x,y) ((x)==(y))
105#endif
106
107int pthread_setcancelstate(int, int *);
108int pthread_setcanceltype(int, int *);
109void pthread_testcancel(void);
110#ifdef __wasilibc_unmodified_upstream /* WASI has no cancellation support. */
111int pthread_cancel(pthread_t);
112#endif
113
114#ifdef __wasilibc_unmodified_upstream /* WASI has no CPU scheduling support. */
115int pthread_getschedparam(pthread_t, int *__restrict, struct sched_param *__restrict);
116int pthread_setschedparam(pthread_t, int, const struct sched_param *);
117#endif
118int pthread_setschedprio(pthread_t, int);
119
120int pthread_once(pthread_once_t *, void (*)(void));
121
122int pthread_mutex_init(pthread_mutex_t *__restrict, const pthread_mutexattr_t *__restrict);
123int pthread_mutex_lock(pthread_mutex_t *);
124int pthread_mutex_unlock(pthread_mutex_t *);
125int pthread_mutex_trylock(pthread_mutex_t *);
126int pthread_mutex_timedlock(pthread_mutex_t *__restrict, const struct timespec *__restrict);
127int pthread_mutex_destroy(pthread_mutex_t *);
128int pthread_mutex_consistent(pthread_mutex_t *);
129
130int pthread_mutex_getprioceiling(const pthread_mutex_t *__restrict, int *__restrict);
131int pthread_mutex_setprioceiling(pthread_mutex_t *__restrict, int, int *__restrict);
132
133int pthread_cond_init(pthread_cond_t *__restrict, const pthread_condattr_t *__restrict);
134int pthread_cond_destroy(pthread_cond_t *);
135int pthread_cond_wait(pthread_cond_t *__restrict, pthread_mutex_t *__restrict);
136int pthread_cond_timedwait(pthread_cond_t *__restrict, pthread_mutex_t *__restrict, const struct timespec *__restrict);
137int pthread_cond_broadcast(pthread_cond_t *);
138int pthread_cond_signal(pthread_cond_t *);
139
140int pthread_rwlock_init(pthread_rwlock_t *__restrict, const pthread_rwlockattr_t *__restrict);
141int pthread_rwlock_destroy(pthread_rwlock_t *);
142int pthread_rwlock_rdlock(pthread_rwlock_t *);
143int pthread_rwlock_tryrdlock(pthread_rwlock_t *);
144int pthread_rwlock_timedrdlock(pthread_rwlock_t *__restrict, const struct timespec *__restrict);
145int pthread_rwlock_wrlock(pthread_rwlock_t *);
146int pthread_rwlock_trywrlock(pthread_rwlock_t *);
147int pthread_rwlock_timedwrlock(pthread_rwlock_t *__restrict, const struct timespec *__restrict);
148int pthread_rwlock_unlock(pthread_rwlock_t *);
149
150int pthread_spin_init(pthread_spinlock_t *, int);
151int pthread_spin_destroy(pthread_spinlock_t *);
152int pthread_spin_lock(pthread_spinlock_t *);
153int pthread_spin_trylock(pthread_spinlock_t *);
154int pthread_spin_unlock(pthread_spinlock_t *);
155
156int pthread_barrier_init(pthread_barrier_t *__restrict, const pthread_barrierattr_t *__restrict, unsigned);
157int pthread_barrier_destroy(pthread_barrier_t *);
158int pthread_barrier_wait(pthread_barrier_t *);
159
160int pthread_key_create(pthread_key_t *, void (*)(void *));
161int pthread_key_delete(pthread_key_t);
162void *pthread_getspecific(pthread_key_t);
163int pthread_setspecific(pthread_key_t, const void *);
164
165int pthread_attr_init(pthread_attr_t *);
166int pthread_attr_destroy(pthread_attr_t *);
167
168int pthread_attr_getguardsize(const pthread_attr_t *__restrict, size_t *__restrict);
169int pthread_attr_setguardsize(pthread_attr_t *, size_t);
170int pthread_attr_getstacksize(const pthread_attr_t *__restrict, size_t *__restrict);
171int pthread_attr_setstacksize(pthread_attr_t *, size_t);
172int pthread_attr_getdetachstate(const pthread_attr_t *, int *);
173int pthread_attr_setdetachstate(pthread_attr_t *, int);
174int pthread_attr_getstack(const pthread_attr_t *__restrict, void **__restrict, size_t *__restrict);
175int pthread_attr_setstack(pthread_attr_t *, void *, size_t);
176int pthread_attr_getscope(const pthread_attr_t *__restrict, int *__restrict);
177int pthread_attr_setscope(pthread_attr_t *, int);
178int pthread_attr_getschedpolicy(const pthread_attr_t *__restrict, int *__restrict);
179int pthread_attr_setschedpolicy(pthread_attr_t *, int);
180#ifdef __wasilibc_unmodified_upstream /* WASI has no CPU scheduling support. */
181int pthread_attr_getschedparam(const pthread_attr_t *__restrict, struct sched_param *__restrict);
182int pthread_attr_setschedparam(pthread_attr_t *__restrict, const struct sched_param *__restrict);
183#endif
184int pthread_attr_getinheritsched(const pthread_attr_t *__restrict, int *__restrict);
185int pthread_attr_setinheritsched(pthread_attr_t *, int);
186
187int pthread_mutexattr_destroy(pthread_mutexattr_t *);
188int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *__restrict, int *__restrict);
189int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *__restrict, int *__restrict);
190int pthread_mutexattr_getpshared(const pthread_mutexattr_t *__restrict, int *__restrict);
191int pthread_mutexattr_getrobust(const pthread_mutexattr_t *__restrict, int *__restrict);
192int pthread_mutexattr_gettype(const pthread_mutexattr_t *__restrict, int *__restrict);
193int pthread_mutexattr_init(pthread_mutexattr_t *);
194int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *, int);
195int pthread_mutexattr_setprotocol(pthread_mutexattr_t *, int);
196int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int);
197int pthread_mutexattr_setrobust(pthread_mutexattr_t *, int);
198int pthread_mutexattr_settype(pthread_mutexattr_t *, int);
199
200int pthread_condattr_init(pthread_condattr_t *);
201int pthread_condattr_destroy(pthread_condattr_t *);
202int pthread_condattr_setclock(pthread_condattr_t *, clockid_t);
203int pthread_condattr_setpshared(pthread_condattr_t *, int);
204int pthread_condattr_getclock(const pthread_condattr_t *__restrict, clockid_t *__restrict);
205int pthread_condattr_getpshared(const pthread_condattr_t *__restrict, int *__restrict);
206
207int pthread_rwlockattr_init(pthread_rwlockattr_t *);
208int pthread_rwlockattr_destroy(pthread_rwlockattr_t *);
209int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int);
210int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *__restrict, int *__restrict);
211
212int pthread_barrierattr_destroy(pthread_barrierattr_t *);
213int pthread_barrierattr_getpshared(const pthread_barrierattr_t *__restrict, int *__restrict);
214int pthread_barrierattr_init(pthread_barrierattr_t *);
215int pthread_barrierattr_setpshared(pthread_barrierattr_t *, int);
216
217int pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
218
219int pthread_getconcurrency(void);
220int pthread_setconcurrency(int);
221
222int pthread_getcpuclockid(pthread_t, clockid_t *);
223
224struct __ptcb {
225 void (*__f)(void *);
226 void *__x;
227 struct __ptcb *__next;
228};
229
230void _pthread_cleanup_push(struct __ptcb *, void (*)(void *), void *);
231void _pthread_cleanup_pop(struct __ptcb *, int);
232
233#define pthread_cleanup_push(f, x) do { struct __ptcb __cb; _pthread_cleanup_push(&__cb, f, x);
234#define pthread_cleanup_pop(r) _pthread_cleanup_pop(&__cb, (r)); } while(0)
235
236#ifdef _GNU_SOURCE
237struct cpu_set_t;
238int pthread_getaffinity_np(pthread_t, size_t, struct cpu_set_t *);
239int pthread_setaffinity_np(pthread_t, size_t, const struct cpu_set_t *);
240int pthread_getattr_np(pthread_t, pthread_attr_t *);
241int pthread_setname_np(pthread_t, const char *);
242int pthread_getname_np(pthread_t, char *, size_t);
243int pthread_getattr_default_np(pthread_attr_t *);
244int pthread_setattr_default_np(const pthread_attr_t *);
245#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT) || !defined(_WASI_STRICT_PTHREAD)
246int pthread_tryjoin_np(pthread_t, void **);
247int pthread_timedjoin_np(pthread_t, void **, const struct timespec *);
248#else
249#define pthread_tryjoin_np(...) ({ _Static_assert(0, "This function is not available on a single-threaded target; switch to a multi-threaded target with -pthread or enable a stub implementation by undefining _WASI_STRICT_PTHREAD"); 0;})
250#define pthread_timedjoin_np(...) ({ _Static_assert(0, "This function is not available on a single-threaded target; switch to a multi-threaded target with -pthread or enable a stub implementation by undefining _WASI_STRICT_PTHREAD"); 0;})
251#endif
252#endif
253
254#if _REDIR_TIME64
255__REDIR(pthread_mutex_timedlock, __pthread_mutex_timedlock_time64);
256__REDIR(pthread_cond_timedwait, __pthread_cond_timedwait_time64);
257__REDIR(pthread_rwlock_timedrdlock, __pthread_rwlock_timedrdlock_time64);
258__REDIR(pthread_rwlock_timedwrlock, __pthread_rwlock_timedwrlock_time64);
259#ifdef _GNU_SOURCE
260__REDIR(pthread_timedjoin_np, __pthread_timedjoin_np_time64);
261#endif
262#endif
263
264#ifdef __cplusplus
265}
266#endif
267#endif
lib/libc/include/wasm-wasi-musl/sched.h+2-2
...@@ -16,7 +16,6 @@ extern "C" {...@@ -16,7 +16,6 @@ extern "C" {
1616
17#include <bits/alltypes.h>17#include <bits/alltypes.h>
1818
19#ifdef __wasilibc_unmodified_upstream /* WASI has no CPU scheduling support. */
20struct sched_param {19struct sched_param {
21 int sched_priority;20 int sched_priority;
22 int __reserved1;21 int __reserved1;
...@@ -31,6 +30,7 @@ struct sched_param {...@@ -31,6 +30,7 @@ struct sched_param {
31 int __reserved3;30 int __reserved3;
32};31};
3332
33#ifdef __wasilibc_unmodified_upstream /* WASI has no CPU scheduling support. */
34int sched_get_priority_max(int);34int sched_get_priority_max(int);
35int sched_get_priority_min(int);35int sched_get_priority_min(int);
36int sched_getparam(pid_t, struct sched_param *);36int sched_getparam(pid_t, struct sched_param *);
...@@ -127,7 +127,7 @@ __CPU_op_func_S(XOR, ^)...@@ -127,7 +127,7 @@ __CPU_op_func_S(XOR, ^)
127#define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n)))127#define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n)))
128#define CPU_FREE(set) free(set)128#define CPU_FREE(set) free(set)
129129
130#define CPU_SETSIZE 128130#define CPU_SETSIZE 1024
131131
132#define CPU_SET(i, set) CPU_SET_S(i,sizeof(cpu_set_t),set)132#define CPU_SET(i, set) CPU_SET_S(i,sizeof(cpu_set_t),set)
133#define CPU_CLR(i, set) CPU_CLR_S(i,sizeof(cpu_set_t),set)133#define CPU_CLR(i, set) CPU_CLR_S(i,sizeof(cpu_set_t),set)
lib/libc/include/wasm-wasi-musl/stdc-predef.h deleted-13
...@@ -1,13 +0,0 @@
1#ifndef _STDC_PREDEF_H
2#define _STDC_PREDEF_H
3
4#define __STDC_ISO_10646__ 201206L
5
6#if !defined(__GCC_IEC_559) || __GCC_IEC_559 > 0
7#define __STDC_IEC_559__ 1
8#endif
9
10#define __STDC_UTF_16__ 1
11#define __STDC_UTF_32__ 1
12
13#endif
lib/libc/include/wasm-wasi-musl/stdlib.h+2-2
...@@ -108,7 +108,7 @@ size_t __ctype_get_mb_cur_max(void);...@@ -108,7 +108,7 @@ size_t __ctype_get_mb_cur_max(void);
108#define WTERMSIG(s) ((s) & 0x7f)108#define WTERMSIG(s) ((s) & 0x7f)
109#define WSTOPSIG(s) WEXITSTATUS(s)109#define WSTOPSIG(s) WEXITSTATUS(s)
110#define WIFEXITED(s) (!WTERMSIG(s))110#define WIFEXITED(s) (!WTERMSIG(s))
111#define WIFSTOPPED(s) ((short)((((s)&0xffff)*0x10001)>>8) > 0x7f00)111#define WIFSTOPPED(s) ((short)((((s)&0xffff)*0x10001U)>>8) > 0x7f00)
112#define WIFSIGNALED(s) (((s)&0xffff)-1U < 0xffu)112#define WIFSIGNALED(s) (((s)&0xffff)-1U < 0xffu)
113#endif113#endif
114114
...@@ -190,7 +190,7 @@ long double strtold_l(const char *__restrict, char **__restrict, struct __locale...@@ -190,7 +190,7 @@ long double strtold_l(const char *__restrict, char **__restrict, struct __locale
190#endif190#endif
191191
192#ifdef __wasilibc_unmodified_upstream /* WASI has no temp directories */192#ifdef __wasilibc_unmodified_upstream /* WASI has no temp directories */
193#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)193#if defined(_LARGEFILE64_SOURCE)
194#define mkstemp64 mkstemp194#define mkstemp64 mkstemp
195#define mkostemp64 mkostemp195#define mkostemp64 mkostemp
196#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)196#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
lib/libc/include/wasm-wasi-musl/string.h+1-6
...@@ -92,6 +92,7 @@ char *strsignal(int);...@@ -92,6 +92,7 @@ char *strsignal(int);
92char *strerror_l (int, locale_t);92char *strerror_l (int, locale_t);
93int strcoll_l (const char *, const char *, locale_t);93int strcoll_l (const char *, const char *, locale_t);
94size_t strxfrm_l (char *__restrict, const char *__restrict, size_t, locale_t);94size_t strxfrm_l (char *__restrict, const char *__restrict, size_t, locale_t);
95void *memmem(const void *, size_t, const void *, size_t);
95#endif96#endif
9697
97#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \98#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
...@@ -111,14 +112,8 @@ void explicit_bzero (void *, size_t);...@@ -111,14 +112,8 @@ void explicit_bzero (void *, size_t);
111int strverscmp (const char *, const char *);112int strverscmp (const char *, const char *);
112char *strchrnul(const char *, int);113char *strchrnul(const char *, int);
113char *strcasestr(const char *, const char *);114char *strcasestr(const char *, const char *);
114void *memmem(const void *, size_t, const void *, size_t);
115void *memrchr(const void *, int, size_t);115void *memrchr(const void *, int, size_t);
116void *mempcpy(void *, const void *, size_t);116void *mempcpy(void *, const void *, size_t);
117#ifdef __wasilibc_unmodified_upstream /* avoid unprototyped decls; use <libgen.h> */
118#ifndef __cplusplus
119char *basename();
120#endif
121#endif
122#endif117#endif
123118
124#ifdef __cplusplus119#ifdef __cplusplus
lib/libc/include/wasm-wasi-musl/strings.h deleted-39
...@@ -1,39 +0,0 @@
1#ifndef _STRINGS_H
2#define _STRINGS_H
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8
9#define __NEED_size_t
10#define __NEED_locale_t
11#include <bits/alltypes.h>
12
13#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_POSIX_SOURCE) \
14 || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE+0 < 200809L) \
15 || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700)
16int bcmp (const void *, const void *, size_t);
17void bcopy (const void *, void *, size_t);
18void bzero (void *, size_t);
19char *index (const char *, int);
20char *rindex (const char *, int);
21#endif
22
23#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
24int ffs (int);
25int ffsl (long);
26int ffsll (long long);
27#endif
28
29int strcasecmp (const char *, const char *);
30int strncasecmp (const char *, const char *, size_t);
31
32int strcasecmp_l (const char *, const char *, locale_t);
33int strncasecmp_l (const char *, const char *, size_t, locale_t);
34
35#ifdef __cplusplus
36}
37#endif
38
39#endif
lib/libc/include/wasm-wasi-musl/sys/stat.h+57
...@@ -18,6 +18,13 @@ extern "C" {...@@ -18,6 +18,13 @@ extern "C" {
18#define __NEED_blkcnt_t18#define __NEED_blkcnt_t
19#define __NEED_struct_timespec19#define __NEED_struct_timespec
2020
21#ifdef _GNU_SOURCE
22#define __NEED_int64_t
23#define __NEED_uint64_t
24#define __NEED_uint32_t
25#define __NEED_uint16_t
26#endif
27
21#include <bits/alltypes.h>28#include <bits/alltypes.h>
2229
23#include <bits/stat.h>30#include <bits/stat.h>
...@@ -112,6 +119,56 @@ int lchmod(const char *, mode_t);...@@ -112,6 +119,56 @@ int lchmod(const char *, mode_t);
112#define S_IEXEC S_IXUSR119#define S_IEXEC S_IXUSR
113#endif120#endif
114121
122#ifdef __wasilibc_unmodified_upstream /* WASI has no statx */
123#if defined(_GNU_SOURCE)
124#define STATX_TYPE 1U
125#define STATX_MODE 2U
126#define STATX_NLINK 4U
127#define STATX_UID 8U
128#define STATX_GID 0x10U
129#define STATX_ATIME 0x20U
130#define STATX_MTIME 0x40U
131#define STATX_CTIME 0x80U
132#define STATX_INO 0x100U
133#define STATX_SIZE 0x200U
134#define STATX_BLOCKS 0x400U
135#define STATX_BASIC_STATS 0x7ffU
136#define STATX_BTIME 0x800U
137#define STATX_ALL 0xfffU
138
139struct statx_timestamp {
140 int64_t tv_sec;
141 uint32_t tv_nsec, __pad;
142};
143
144struct statx {
145 uint32_t stx_mask;
146 uint32_t stx_blksize;
147 uint64_t stx_attributes;
148 uint32_t stx_nlink;
149 uint32_t stx_uid;
150 uint32_t stx_gid;
151 uint16_t stx_mode;
152 uint16_t __pad0[1];
153 uint64_t stx_ino;
154 uint64_t stx_size;
155 uint64_t stx_blocks;
156 uint64_t stx_attributes_mask;
157 struct statx_timestamp stx_atime;
158 struct statx_timestamp stx_btime;
159 struct statx_timestamp stx_ctime;
160 struct statx_timestamp stx_mtime;
161 uint32_t stx_rdev_major;
162 uint32_t stx_rdev_minor;
163 uint32_t stx_dev_major;
164 uint32_t stx_dev_minor;
165 uint64_t __pad1[14];
166};
167
168int statx(int, const char *__restrict, int, unsigned, struct statx *__restrict);
169#endif
170#endif
171
115#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)172#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
116#define stat64 stat173#define stat64 stat
117#define fstat64 fstat174#define fstat64 fstat
lib/libc/include/wasm-wasi-musl/sys/statvfs.h+2-1
...@@ -23,7 +23,8 @@ struct statvfs {...@@ -23,7 +23,8 @@ struct statvfs {
23 unsigned long f_fsid;23 unsigned long f_fsid;
24#endif24#endif
25 unsigned long f_flag, f_namemax;25 unsigned long f_flag, f_namemax;
26 int __reserved[6];26 unsigned int f_type;
27 int __reserved[5];
27};28};
2829
29int statvfs (const char *__restrict, struct statvfs *__restrict);30int statvfs (const char *__restrict, struct statvfs *__restrict);
lib/libc/include/wasm-wasi-musl/sys/uio.h+9
...@@ -36,9 +36,18 @@ ssize_t pwritev (int, const struct iovec *, int, off_t);...@@ -36,9 +36,18 @@ ssize_t pwritev (int, const struct iovec *, int, off_t);
36#endif36#endif
37#endif37#endif
3838
39#ifdef __wasilibc_unmodified_upstream // Wasm doesn't have these Linux-specific functions
39#ifdef _GNU_SOURCE40#ifdef _GNU_SOURCE
40ssize_t process_vm_writev(pid_t, const struct iovec *, unsigned long, const struct iovec *, unsigned long, unsigned long);41ssize_t process_vm_writev(pid_t, const struct iovec *, unsigned long, const struct iovec *, unsigned long, unsigned long);
41ssize_t process_vm_readv(pid_t, const struct iovec *, unsigned long, const struct iovec *, unsigned long, unsigned long);42ssize_t process_vm_readv(pid_t, const struct iovec *, unsigned long, const struct iovec *, unsigned long, unsigned long);
43ssize_t preadv2 (int, const struct iovec *, int, off_t, int);
44ssize_t pwritev2 (int, const struct iovec *, int, off_t, int);
45#define RWF_HIPRI 0x00000001
46#define RWF_DSYNC 0x00000002
47#define RWF_SYNC 0x00000004
48#define RWF_NOWAIT 0x00000008
49#define RWF_APPEND 0x00000010
50#endif
42#endif51#endif
4352
44#ifdef __cplusplus53#ifdef __cplusplus
lib/libc/include/wasm-wasi-musl/unistd.h+12-2
...@@ -336,15 +336,21 @@ pid_t gettid(void);...@@ -336,15 +336,21 @@ pid_t gettid(void);
336#endif336#endif
337#define _POSIX_VDISABLE 0337#define _POSIX_VDISABLE 0
338338
339#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)339#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT) || !defined(_WASI_STRICT_PTHREAD)
340#define _POSIX_THREADS _POSIX_VERSION340#define _POSIX_THREADS _POSIX_VERSION
341#endif
342#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION341#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION
343#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION342#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION
343#endif
344#if defined(__wasilibc_unmodified_upstream) /* wasi-libc doesn't provide pthread_attr_{get,set}stackaddr */
344#define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION345#define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION
346#endif
347#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT) || !defined(_WASI_STRICT_PTHREAD)
345#define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION348#define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION
349#endif
350#if defined(__wasilibc_unmodified_upstream) /* WASI has no scheduling control, and wasi-libc doesn't provide pthread_getcpuclockid */
346#define _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_VERSION351#define _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_VERSION
347#define _POSIX_THREAD_CPUTIME _POSIX_VERSION352#define _POSIX_THREAD_CPUTIME _POSIX_VERSION
353#endif
348#define _POSIX_TIMERS _POSIX_VERSION354#define _POSIX_TIMERS _POSIX_VERSION
349#define _POSIX_TIMEOUTS _POSIX_VERSION355#define _POSIX_TIMEOUTS _POSIX_VERSION
350#define _POSIX_MONOTONIC_CLOCK _POSIX_VERSION356#define _POSIX_MONOTONIC_CLOCK _POSIX_VERSION
...@@ -529,6 +535,8 @@ pid_t gettid(void);...@@ -529,6 +535,8 @@ pid_t gettid(void);
529#define _SC_XOPEN_STREAMS 246535#define _SC_XOPEN_STREAMS 246
530#define _SC_THREAD_ROBUST_PRIO_INHERIT 247536#define _SC_THREAD_ROBUST_PRIO_INHERIT 247
531#define _SC_THREAD_ROBUST_PRIO_PROTECT 248537#define _SC_THREAD_ROBUST_PRIO_PROTECT 248
538#define _SC_MINSIGSTKSZ 249
539#define _SC_SIGSTKSZ 250
532540
533#define _CS_PATH 0541#define _CS_PATH 0
534#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 1542#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 1
...@@ -571,6 +579,8 @@ pid_t gettid(void);...@@ -571,6 +579,8 @@ pid_t gettid(void);
571#define _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS 1147579#define _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS 1147
572#define _CS_V6_ENV 1148580#define _CS_V6_ENV 1148
573#define _CS_V7_ENV 1149581#define _CS_V7_ENV 1149
582#define _CS_POSIX_V7_THREADS_CFLAGS 1150
583#define _CS_POSIX_V7_THREADS_LDFLAGS 1151
574584
575#ifdef __cplusplus585#ifdef __cplusplus
576}586}
lib/libc/include/wasm-wasi-musl/wasi/libc-busywait.h created+15
...@@ -0,0 +1,15 @@
1#ifndef __wasi_libc_busywait_h
2#define __wasi_libc_busywait_h
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8/// Enable busywait in futex on current thread.
9void __wasilibc_enable_futex_busywait_on_current_thread(void);
10
11#ifdef __cplusplus
12}
13#endif
14
15#endif
lib/libc/include/wasm-wasi-musl/wasi/libc.h+8-4
...@@ -3,6 +3,7 @@...@@ -3,6 +3,7 @@
33
4#include <__typedef_off_t.h>4#include <__typedef_off_t.h>
5#include <__struct_timespec.h>5#include <__struct_timespec.h>
6#include <unistd.h>
67
7#ifdef __cplusplus8#ifdef __cplusplus
8extern "C" {9extern "C" {
...@@ -17,10 +18,6 @@ struct timespec;...@@ -17,10 +18,6 @@ struct timespec;
17/// afterward, you should call this before doing so.18/// afterward, you should call this before doing so.
18void __wasilibc_populate_preopens(void);19void __wasilibc_populate_preopens(void);
1920
20/// Reset the preopens table to an uninitialized state, forcing it to be
21/// reinitialized next time it is needed.
22void __wasilibc_reset_preopens(void);
23
24/// Register the given pre-opened file descriptor under the given path.21/// Register the given pre-opened file descriptor under the given path.
25///22///
26/// This function does not take ownership of `prefix` (it makes its own copy).23/// This function does not take ownership of `prefix` (it makes its own copy).
...@@ -68,6 +65,13 @@ int __wasilibc_rename_oldat(int olddirfd, const char *oldpath, const char *newpa...@@ -68,6 +65,13 @@ int __wasilibc_rename_oldat(int olddirfd, const char *oldpath, const char *newpa
68int __wasilibc_rename_newat(const char *oldpath, int newdirfd, const char *newpath)65int __wasilibc_rename_newat(const char *oldpath, int newdirfd, const char *newpath)
69 __attribute__((__warn_unused_result__));66 __attribute__((__warn_unused_result__));
7067
68/// Enable busywait in futex on current thread.
69void __wasilibc_enable_futex_busywait_on_current_thread(void);
70
71/// Fill a buffer with random bytes
72int __wasilibc_random(void* buffer, size_t len)
73 __attribute__((__warn_unused_result__));
74
71#ifdef __cplusplus75#ifdef __cplusplus
72}76}
73#endif77#endif
lib/libc/wasi/fts/config.h created+7
...@@ -0,0 +1,7 @@
1#define HAVE_DECL_MAX 1
2
3#define HAVE_DECL_UINTMAX_MAX 0
4
5#define HAVE_DIRFD 1
6
7#define HAVE_FCHDIR 0
lib/libc/wasi/fts/musl-fts/COPYING created+26
...@@ -0,0 +1,26 @@
1Copyright (c) 1989, 1993
2 The Regents of the University of California. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions
6are met:
71. Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
92. Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
123. Neither the name of the University nor the names of its contributors
13 may be used to endorse or promote products derived from this software
14 without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26SUCH DAMAGE.
lib/libc/wasi/fts/musl-fts/fts.c created+1279
...@@ -0,0 +1,1279 @@
1/* $NetBSD: fts.c,v 1.48 2015/01/29 15:55:21 manu Exp $ */
2
3/*-
4 * Copyright (c) 1990, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#if defined(LIBC_SCCS) && !defined(lint)
33#if 0
34static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94";
35#else
36__RCSID("$NetBSD: fts.c,v 1.48 2015/01/29 15:55:21 manu Exp $");
37#endif
38#endif /* LIBC_SCCS and not lint */
39
40#include "config.h"
41
42#include <sys/param.h>
43#include <sys/stat.h>
44
45#include <assert.h>
46#define _DIAGASSERT(e)
47#include <dirent.h>
48#include <errno.h>
49#include <fcntl.h>
50#include <fts.h>
51#include <stdlib.h>
52#include <string.h>
53#include <unistd.h>
54
55#if !defined(HAVE_DECL_MAX) || (HAVE_DECL_MAX==0)
56#define MAX(a,b) ((a)>(b)?(a):(b))
57#endif
58
59#if !defined(UINT_MAX) && (HAVE_DECL_UINTMAX_MAX==1)
60#define UINT_MAX UINTMAX_MAX
61#endif
62
63#if !defined(HAVE_DIRFD)
64#if defined(HAVE_DIR_DD_FD)
65#define dirfd(dirp) ((dirp)->dd_fd)
66#endif
67#if defined(HAVE_DIR_D_FD)
68#define dirfd(dirp) ((dirp)->d_fd)
69#endif
70#endif
71
72static FTSENT *fts_alloc(FTS *, const char *, size_t);
73static FTSENT *fts_build(FTS *, int);
74static void fts_free(FTSENT *);
75static void fts_lfree(FTSENT *);
76static void fts_load(FTS *, FTSENT *);
77static size_t fts_maxarglen(char * const *);
78static size_t fts_pow2(size_t);
79static int fts_palloc(FTS *, size_t);
80static void fts_padjust(FTS *, FTSENT *);
81static FTSENT *fts_sort(FTS *, FTSENT *, size_t);
82static unsigned short fts_stat(FTS *, FTSENT *, int);
83static int fts_safe_changedir(const FTS *, const FTSENT *, int,
84 const char *);
85
86#if defined(ALIGNBYTES) && defined(ALIGN)
87#define FTS_ALLOC_ALIGNED 1
88#else
89#undef FTS_ALLOC_ALIGNED
90#endif
91
92#ifndef ftsent_namelen_truncate
93#define ftsent_namelen_truncate(a) \
94 ((a) > UINT_MAX ? UINT_MAX : (unsigned int)(a))
95#endif
96#ifndef ftsent_pathlen_truncate
97#define ftsent_pathlen_truncate(a) \
98 ((a) > UINT_MAX ? UINT_MAX : (unsigned int)(a))
99#endif
100#ifndef fts_pathlen_truncate
101#define fts_pathlen_truncate(a) \
102 ((a) > UINT_MAX ? UINT_MAX : (unsigned int)(a))
103#endif
104#ifndef fts_nitems_truncate
105#define fts_nitems_truncate(a) \
106 ((a) > UINT_MAX ? UINT_MAX : (unsigned int)(a))
107#endif
108
109#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
110
111#define CLR(opt) (sp->fts_options &= ~(opt))
112#define ISSET(opt) (sp->fts_options & (opt))
113#define SET(opt) (sp->fts_options |= (opt))
114
115#if HAVE_FCHDIR
116#define CHDIR(sp, path) (!ISSET(FTS_NOCHDIR) && chdir(path))
117#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd))
118#else
119/* If we don't have fchdir, pretend that !ISSET(FTS_NOCHDIR) is always false in
120 * the above macros, and do not reference chdir or fchdir. */
121#define CHDIR(sp, path) 0
122#define FCHDIR(sp, fd) 0
123#endif
124
125/* fts_build flags */
126#define BCHILD 1 /* fts_children */
127#define BNAMES 2 /* fts_children, names only */
128#define BREAD 3 /* fts_read */
129
130#ifndef DTF_HIDEW
131#undef FTS_WHITEOUT
132#endif
133
134FTS *
135fts_open(char * const *argv, int options,
136 int (*compar)(const FTSENT **, const FTSENT **))
137{
138 FTS *sp;
139 FTSENT *p, *root;
140 size_t nitems;
141 FTSENT *parent, *tmp = NULL; /* pacify gcc */
142 size_t len;
143
144 _DIAGASSERT(argv != NULL);
145
146#if !HAVE_FCHDIR
147 /* If we don't have fchdir, pretend that FTS_NOCHDIR is always set. */
148 options |= FTS_NOCHDIR;
149#endif
150
151 /* Options check. */
152 if (options & ~FTS_OPTIONMASK) {
153 errno = EINVAL;
154 return (NULL);
155 }
156
157 /* Allocate/initialize the stream */
158 if ((sp = malloc(sizeof(FTS))) == NULL)
159 return (NULL);
160 memset(sp, 0, sizeof(FTS));
161 sp->fts_compar = compar;
162 sp->fts_options = options;
163
164 /* Logical walks turn on NOCHDIR; symbolic links are too hard. */
165 if (ISSET(FTS_LOGICAL))
166 SET(FTS_NOCHDIR);
167
168 /*
169 * Start out with 1K of path space, and enough, in any case,
170 * to hold the user's paths.
171 */
172 if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN)))
173 goto mem1;
174
175 /* Allocate/initialize root's parent. */
176 if ((parent = fts_alloc(sp, "", 0)) == NULL)
177 goto mem2;
178 parent->fts_level = FTS_ROOTPARENTLEVEL;
179
180 /* Allocate/initialize root(s). */
181 for (root = NULL, nitems = 0; *argv; ++argv, ++nitems) {
182 /* Don't allow zero-length paths. */
183 if ((len = strlen(*argv)) == 0) {
184 errno = ENOENT;
185 goto mem3;
186 }
187
188 if ((p = fts_alloc(sp, *argv, len)) == NULL)
189 goto mem3;
190 p->fts_level = FTS_ROOTLEVEL;
191 p->fts_parent = parent;
192 p->fts_accpath = p->fts_name;
193 p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW));
194
195 /* Command-line "." and ".." are real directories. */
196 if (p->fts_info == FTS_DOT)
197 p->fts_info = FTS_D;
198
199 /*
200 * If comparison routine supplied, traverse in sorted
201 * order; otherwise traverse in the order specified.
202 */
203 if (compar) {
204 p->fts_link = root;
205 root = p;
206 } else {
207 p->fts_link = NULL;
208 if (root == NULL)
209 tmp = root = p;
210 else {
211 tmp->fts_link = p;
212 tmp = p;
213 }
214 }
215 }
216 if (compar && nitems > 1)
217 root = fts_sort(sp, root, nitems);
218
219 /*
220 * Allocate a dummy pointer and make fts_read think that we've just
221 * finished the node before the root(s); set p->fts_info to FTS_INIT
222 * so that everything about the "current" node is ignored.
223 */
224 if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
225 goto mem3;
226 sp->fts_cur->fts_link = root;
227 sp->fts_cur->fts_info = FTS_INIT;
228
229 /*
230 * If using chdir(2), grab a file descriptor pointing to dot to ensure
231 * that we can get back here; this could be avoided for some paths,
232 * but almost certainly not worth the effort. Slashes, symbolic links,
233 * and ".." are all fairly nasty problems. Note, if we can't get the
234 * descriptor we run anyway, just more slowly.
235 */
236#ifndef O_CLOEXEC
237#define O_CLOEXEC 0
238#endif
239 if (!ISSET(FTS_NOCHDIR)) {
240 if ((sp->fts_rfd = open(".", O_RDONLY | O_CLOEXEC, 0)) == -1)
241 SET(FTS_NOCHDIR);
242 }
243
244 if (nitems == 0)
245 fts_free(parent);
246
247 return (sp);
248
249mem3: fts_lfree(root);
250 fts_free(parent);
251mem2: free(sp->fts_path);
252mem1: free(sp);
253 return (NULL);
254}
255
256static void
257fts_load(FTS *sp, FTSENT *p)
258{
259 size_t len;
260 char *cp;
261
262 _DIAGASSERT(sp != NULL);
263 _DIAGASSERT(p != NULL);
264
265 /*
266 * Load the stream structure for the next traversal. Since we don't
267 * actually enter the directory until after the preorder visit, set
268 * the fts_accpath field specially so the chdir gets done to the right
269 * place and the user can access the first node. From fts_open it's
270 * known that the path will fit.
271 */
272 len = p->fts_pathlen = p->fts_namelen;
273 memmove(sp->fts_path, p->fts_name, len + 1);
274 if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) {
275 len = strlen(++cp);
276 memmove(p->fts_name, cp, len + 1);
277 p->fts_namelen = ftsent_namelen_truncate(len);
278 }
279 p->fts_accpath = p->fts_path = sp->fts_path;
280 sp->fts_dev = p->fts_dev;
281}
282
283int
284fts_close(FTS *sp)
285{
286 FTSENT *freep, *p;
287 int saved_errno = 0;
288
289 _DIAGASSERT(sp != NULL);
290
291 /*
292 * This still works if we haven't read anything -- the dummy structure
293 * points to the root list, so we step through to the end of the root
294 * list which has a valid parent pointer.
295 */
296 if (sp->fts_cur) {
297 if (sp->fts_cur->fts_flags & FTS_SYMFOLLOW)
298 (void)close(sp->fts_cur->fts_symfd);
299 for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
300 freep = p;
301 p = p->fts_link ? p->fts_link : p->fts_parent;
302 fts_free(freep);
303 }
304 fts_free(p);
305 }
306
307 /* Free up child linked list, sort array, path buffer. */
308 if (sp->fts_child)
309 fts_lfree(sp->fts_child);
310 if (sp->fts_array)
311 free(sp->fts_array);
312 free(sp->fts_path);
313
314 #if HAVE_FCHDIR
315 /* Return to original directory, save errno if necessary. */
316 if (!ISSET(FTS_NOCHDIR)) {
317 if (fchdir(sp->fts_rfd) == -1)
318 saved_errno = errno;
319 (void)close(sp->fts_rfd);
320 }
321 #endif
322
323 /* Free up the stream pointer. */
324 free(sp);
325 if (saved_errno) {
326 errno = saved_errno;
327 return -1;
328 }
329
330 return 0;
331}
332
333#if !defined(__FTS_COMPAT_TAILINGSLASH)
334
335/*
336 * Special case of "/" at the end of the path so that slashes aren't
337 * appended which would cause paths to be written as "....//foo".
338 */
339#define NAPPEND(p) \
340 (p->fts_path[p->fts_pathlen - 1] == '/' \
341 ? p->fts_pathlen - 1 : p->fts_pathlen)
342
343#else /* !defined(__FTS_COMPAT_TAILINGSLASH) */
344
345/*
346 * compatibility with the old behaviour.
347 *
348 * Special case a root of "/" so that slashes aren't appended which would
349 * cause paths to be written as "//foo".
350 */
351
352#define NAPPEND(p) \
353 (p->fts_level == FTS_ROOTLEVEL && p->fts_pathlen == 1 && \
354 p->fts_path[0] == '/' ? 0 : p->fts_pathlen)
355
356#endif /* !defined(__FTS_COMPAT_TAILINGSLASH) */
357
358FTSENT *
359fts_read(FTS *sp)
360{
361 FTSENT *p, *tmp;
362 int instr;
363 char *t;
364 int saved_errno;
365
366 _DIAGASSERT(sp != NULL);
367
368 /* If finished or unrecoverable error, return NULL. */
369 if (sp->fts_cur == NULL || ISSET(FTS_STOP))
370 return (NULL);
371
372 /* Set current node pointer. */
373 p = sp->fts_cur;
374
375 /* Save and zero out user instructions. */
376 instr = p->fts_instr;
377 p->fts_instr = FTS_NOINSTR;
378
379 /* Any type of file may be re-visited; re-stat and re-turn. */
380 if (instr == FTS_AGAIN) {
381 p->fts_info = fts_stat(sp, p, 0);
382 return (p);
383 }
384
385 /*
386 * Following a symlink -- SLNONE test allows application to see
387 * SLNONE and recover. If indirecting through a symlink, have
388 * keep a pointer to current location. If unable to get that
389 * pointer, follow fails.
390 */
391 if (instr == FTS_FOLLOW &&
392 (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
393 p->fts_info = fts_stat(sp, p, 1);
394 if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
395 if ((p->fts_symfd = open(".", O_RDONLY | O_CLOEXEC, 0))
396 == -1) {
397 p->fts_errno = errno;
398 p->fts_info = FTS_ERR;
399 } else
400 p->fts_flags |= FTS_SYMFOLLOW;
401 }
402 return (p);
403 }
404
405 /* Directory in pre-order. */
406 if (p->fts_info == FTS_D) {
407 /* If skipped or crossed mount point, do post-order visit. */
408 if (instr == FTS_SKIP ||
409 (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) {
410 if (p->fts_flags & FTS_SYMFOLLOW)
411 (void)close(p->fts_symfd);
412 if (sp->fts_child) {
413 fts_lfree(sp->fts_child);
414 sp->fts_child = NULL;
415 }
416 p->fts_info = FTS_DP;
417 return (p);
418 }
419
420 /* Rebuild if only read the names and now traversing. */
421 if (sp->fts_child && ISSET(FTS_NAMEONLY)) {
422 CLR(FTS_NAMEONLY);
423 fts_lfree(sp->fts_child);
424 sp->fts_child = NULL;
425 }
426
427 /*
428 * Cd to the subdirectory.
429 *
430 * If have already read and now fail to chdir, whack the list
431 * to make the names come out right, and set the parent errno
432 * so the application will eventually get an error condition.
433 * Set the FTS_DONTCHDIR flag so that when we logically change
434 * directories back to the parent we don't do a chdir.
435 *
436 * If haven't read do so. If the read fails, fts_build sets
437 * FTS_STOP or the fts_info field of the node.
438 */
439 if (sp->fts_child) {
440 if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {
441 p->fts_errno = errno;
442 p->fts_flags |= FTS_DONTCHDIR;
443 for (p = sp->fts_child; p; p = p->fts_link)
444 p->fts_accpath =
445 p->fts_parent->fts_accpath;
446 }
447 } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) {
448 if (ISSET(FTS_STOP))
449 return (NULL);
450 return (p);
451 }
452 p = sp->fts_child;
453 sp->fts_child = NULL;
454 goto name;
455 }
456
457next:
458 /* Move to the next node on this level. */
459 tmp = p;
460
461 /*
462 * We are going to free sp->fts_cur, set it to NULL so
463 * that fts_close() does not attempt to free it again
464 * if we exit without setting it to a new value because
465 * FCHDIR() failed below.
466 */
467 assert(tmp == sp->fts_cur);
468 sp->fts_cur = NULL;
469
470 if ((p = p->fts_link) != NULL) {
471 fts_free(tmp);
472
473 /*
474 * If reached the top, return to the original directory, and
475 * load the paths for the next root.
476 */
477 if (p->fts_level == FTS_ROOTLEVEL) {
478 if (FCHDIR(sp, sp->fts_rfd)) {
479 SET(FTS_STOP);
480 return (NULL);
481 }
482 fts_load(sp, p);
483 return (sp->fts_cur = p);
484 }
485
486 /*
487 * User may have called fts_set on the node. If skipped,
488 * ignore. If followed, get a file descriptor so we can
489 * get back if necessary.
490 */
491 if (p->fts_instr == FTS_SKIP)
492 goto next;
493 if (p->fts_instr == FTS_FOLLOW) {
494 p->fts_info = fts_stat(sp, p, 1);
495 if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
496 if ((p->fts_symfd =
497 open(".", O_RDONLY | O_CLOEXEC, 0)) == -1) {
498 p->fts_errno = errno;
499 p->fts_info = FTS_ERR;
500 } else
501 p->fts_flags |= FTS_SYMFOLLOW;
502 }
503 p->fts_instr = FTS_NOINSTR;
504 }
505
506name: t = sp->fts_path + NAPPEND(p->fts_parent);
507 *t++ = '/';
508 memmove(t, p->fts_name, (size_t)(p->fts_namelen + 1));
509 return (sp->fts_cur = p);
510 }
511
512 /* Move up to the parent node. */
513 p = tmp->fts_parent;
514 fts_free(tmp);
515
516 if (p->fts_level == FTS_ROOTPARENTLEVEL) {
517 /*
518 * Done; free everything up and set errno to 0 so the user
519 * can distinguish between error and EOF.
520 */
521 fts_free(p);
522 errno = 0;
523 return (sp->fts_cur = NULL);
524 }
525
526 /* NUL terminate the pathname. */
527 sp->fts_path[p->fts_pathlen] = '\0';
528
529 /*
530 * Return to the parent directory. If at a root node or came through
531 * a symlink, go back through the file descriptor. Otherwise, cd up
532 * one directory.
533 */
534 if (p->fts_level == FTS_ROOTLEVEL) {
535 if (FCHDIR(sp, sp->fts_rfd)) {
536 SET(FTS_STOP);
537 return (NULL);
538 }
539 } else if (p->fts_flags & FTS_SYMFOLLOW) {
540 if (FCHDIR(sp, p->fts_symfd)) {
541 saved_errno = errno;
542 (void)close(p->fts_symfd);
543 errno = saved_errno;
544 SET(FTS_STOP);
545 return (NULL);
546 }
547 (void)close(p->fts_symfd);
548 } else if (!(p->fts_flags & FTS_DONTCHDIR) &&
549 fts_safe_changedir(sp, p->fts_parent, -1, "..")) {
550 SET(FTS_STOP);
551 return (NULL);
552 }
553 p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
554 return (sp->fts_cur = p);
555}
556
557/*
558 * Fts_set takes the stream as an argument although it's not used in this
559 * implementation; it would be necessary if anyone wanted to add global
560 * semantics to fts using fts_set. An error return is allowed for similar
561 * reasons.
562 */
563/* ARGSUSED */
564int
565fts_set(FTS *sp, FTSENT *p, int instr)
566{
567
568 _DIAGASSERT(sp != NULL);
569 _DIAGASSERT(p != NULL);
570
571 if (instr && instr != FTS_AGAIN && instr != FTS_FOLLOW &&
572 instr != FTS_NOINSTR && instr != FTS_SKIP) {
573 errno = EINVAL;
574 return (1);
575 }
576 p->fts_instr = instr;
577 return (0);
578}
579
580FTSENT *
581fts_children(FTS *sp, int instr)
582{
583 FTSENT *p;
584 int fd;
585
586 _DIAGASSERT(sp != NULL);
587
588 if (instr && instr != FTS_NAMEONLY) {
589 errno = EINVAL;
590 return (NULL);
591 }
592
593 /* Set current node pointer. */
594 p = sp->fts_cur;
595
596 /*
597 * Errno set to 0 so user can distinguish empty directory from
598 * an error.
599 */
600 errno = 0;
601
602 /* Fatal errors stop here. */
603 if (ISSET(FTS_STOP))
604 return (NULL);
605
606 /* Return logical hierarchy of user's arguments. */
607 if (p->fts_info == FTS_INIT)
608 return (p->fts_link);
609
610 /*
611 * If not a directory being visited in pre-order, stop here. Could
612 * allow FTS_DNR, assuming the user has fixed the problem, but the
613 * same effect is available with FTS_AGAIN.
614 */
615 if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */)
616 return (NULL);
617
618 /* Free up any previous child list. */
619 if (sp->fts_child)
620 fts_lfree(sp->fts_child);
621
622 if (instr == FTS_NAMEONLY) {
623 SET(FTS_NAMEONLY);
624 instr = BNAMES;
625 } else
626 instr = BCHILD;
627
628 #if HAVE_FCHDIR
629 /*
630 * If using chdir on a relative path and called BEFORE fts_read does
631 * its chdir to the root of a traversal, we can lose -- we need to
632 * chdir into the subdirectory, and we don't know where the current
633 * directory is, so we can't get back so that the upcoming chdir by
634 * fts_read will work.
635 */
636 if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' ||
637 ISSET(FTS_NOCHDIR))
638 return (sp->fts_child = fts_build(sp, instr));
639
640 if ((fd = open(".", O_RDONLY | O_CLOEXEC, 0)) == -1)
641 return (sp->fts_child = NULL);
642 sp->fts_child = fts_build(sp, instr);
643 if (fchdir(fd)) {
644 (void)close(fd);
645 return (NULL);
646 }
647 (void)close(fd);
648 return (sp->fts_child);
649 #else
650 /* If not using chdir, just build the list. */
651 return (sp->fts_child = fts_build(sp, instr));
652 #endif
653}
654
655/*
656 * This is the tricky part -- do not casually change *anything* in here. The
657 * idea is to build the linked list of entries that are used by fts_children
658 * and fts_read. There are lots of special cases.
659 *
660 * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is
661 * set and it's a physical walk (so that symbolic links can't be directories),
662 * we can do things quickly. First, if it's a 4.4BSD file system, the type
663 * of the file is in the directory entry. Otherwise, we assume that the number
664 * of subdirectories in a node is equal to the number of links to the parent.
665 * The former skips all stat calls. The latter skips stat calls in any leaf
666 * directories and for any files after the subdirectories in the directory have
667 * been found, cutting the stat calls by about 2/3.
668 */
669static FTSENT *
670fts_build(FTS *sp, int type)
671{
672 struct dirent *dp;
673 FTSENT *p, *head;
674 size_t nitems;
675 FTSENT *cur, *tail;
676 DIR *dirp;
677 void *oldaddr;
678 size_t dnamlen;
679 int cderrno, descend, level, nlinks, saved_errno, nostat, doadjust;
680 size_t len, maxlen;
681#ifdef FTS_WHITEOUT
682 int oflag;
683#endif
684 char *cp = NULL; /* pacify gcc */
685
686 _DIAGASSERT(sp != NULL);
687
688 /* Set current node pointer. */
689 cur = sp->fts_cur;
690
691 /*
692 * Open the directory for reading. If this fails, we're done.
693 * If being called from fts_read, set the fts_info field.
694 */
695#ifdef FTS_WHITEOUT
696 if (ISSET(FTS_WHITEOUT))
697 oflag = DTF_NODUP|DTF_REWIND;
698 else
699 oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND;
700#else
701#define __opendir2(path, flag) opendir(path)
702#endif
703 if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) {
704 if (type == BREAD) {
705 cur->fts_info = FTS_DNR;
706 cur->fts_errno = errno;
707 }
708 return (NULL);
709 }
710
711 /*
712 * Nlinks is the number of possible entries of type directory in the
713 * directory if we're cheating on stat calls, 0 if we're not doing
714 * any stat calls at all, -1 if we're doing stats on everything.
715 */
716 if (type == BNAMES) {
717 nlinks = 0;
718 nostat = 1;
719 } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
720 nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2);
721 nostat = 1;
722 } else {
723 nlinks = -1;
724 nostat = 0;
725 }
726
727#ifdef notdef
728 (void)printf("nlinks == %d (cur: %d)\n", nlinks, cur->fts_nlink);
729 (void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n",
730 ISSET(FTS_NOSTAT), ISSET(FTS_PHYSICAL), ISSET(FTS_SEEDOT));
731#endif
732 /*
733 * If we're going to need to stat anything or we want to descend
734 * and stay in the directory, chdir. If this fails we keep going,
735 * but set a flag so we don't chdir after the post-order visit.
736 * We won't be able to stat anything, but we can still return the
737 * names themselves. Note, that since fts_read won't be able to
738 * chdir into the directory, it will have to return different path
739 * names than before, i.e. "a/b" instead of "b". Since the node
740 * has already been visited in pre-order, have to wait until the
741 * post-order visit to return the error. There is a special case
742 * here, if there was nothing to stat then it's not an error to
743 * not be able to stat. This is all fairly nasty. If a program
744 * needed sorted entries or stat information, they had better be
745 * checking FTS_NS on the returned nodes.
746 */
747 cderrno = 0;
748 if (nlinks || type == BREAD) {
749 if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
750 if (nlinks && type == BREAD)
751 cur->fts_errno = errno;
752 cur->fts_flags |= FTS_DONTCHDIR;
753 descend = 0;
754 cderrno = errno;
755 } else
756 descend = 1;
757 } else
758 descend = 0;
759
760 /*
761 * Figure out the max file name length that can be stored in the
762 * current path -- the inner loop allocates more path as necessary.
763 * We really wouldn't have to do the maxlen calculations here, we
764 * could do them in fts_read before returning the path, but it's a
765 * lot easier here since the length is part of the dirent structure.
766 *
767 * If not changing directories set a pointer so that can just append
768 * each new name into the path.
769 */
770 len = NAPPEND(cur);
771 if (ISSET(FTS_NOCHDIR)) {
772 cp = sp->fts_path + len;
773 *cp++ = '/';
774 }
775 len++;
776 maxlen = sp->fts_pathlen - len;
777
778#if defined(__FTS_COMPAT_LEVEL)
779 if (cur->fts_level == SHRT_MAX) {
780 (void)closedir(dirp);
781 cur->fts_info = FTS_ERR;
782 SET(FTS_STOP);
783 errno = ENAMETOOLONG;
784 return (NULL);
785 }
786#endif
787
788 level = cur->fts_level + 1;
789
790 /* Read the directory, attaching each entry to the `link' pointer. */
791 doadjust = 0;
792 for (head = tail = NULL, nitems = 0; (dp = readdir(dirp)) != NULL;) {
793
794 if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
795 continue;
796
797#if defined(HAVE_STRUCT_DIRENT_D_NAMLEN)
798 dnamlen = dp->d_namlen;
799#else
800 dnamlen = strlen(dp->d_name);
801#endif
802 if ((p = fts_alloc(sp, dp->d_name, dnamlen)) == NULL)
803 goto mem1;
804 if (dnamlen >= maxlen) { /* include space for NUL */
805 oldaddr = sp->fts_path;
806 if (fts_palloc(sp, dnamlen + len + 1)) {
807 /*
808 * No more memory for path or structures. Save
809 * errno, free up the current structure and the
810 * structures already allocated.
811 */
812mem1: saved_errno = errno;
813 if (p)
814 fts_free(p);
815 fts_lfree(head);
816 (void)closedir(dirp);
817 errno = saved_errno;
818 cur->fts_info = FTS_ERR;
819 SET(FTS_STOP);
820 return (NULL);
821 }
822 /* Did realloc() change the pointer? */
823 if (oldaddr != sp->fts_path) {
824 doadjust = 1;
825 if (ISSET(FTS_NOCHDIR))
826 cp = sp->fts_path + len;
827 }
828 maxlen = sp->fts_pathlen - len;
829 }
830
831#if defined(__FTS_COMPAT_LENGTH)
832 if (len + dnamlen >= USHRT_MAX) {
833 /*
834 * In an FTSENT, fts_pathlen is an unsigned short
835 * so it is possible to wraparound here.
836 * If we do, free up the current structure and the
837 * structures already allocated, then error out
838 * with ENAMETOOLONG.
839 */
840 fts_free(p);
841 fts_lfree(head);
842 (void)closedir(dirp);
843 cur->fts_info = FTS_ERR;
844 SET(FTS_STOP);
845 errno = ENAMETOOLONG;
846 return (NULL);
847 }
848#endif
849 p->fts_level = level;
850 p->fts_pathlen = ftsent_pathlen_truncate(len + dnamlen);
851 p->fts_parent = sp->fts_cur;
852
853#ifdef FTS_WHITEOUT
854 if (dp->d_type == DT_WHT)
855 p->fts_flags |= FTS_ISW;
856#endif
857
858 if (cderrno) {
859 if (nlinks) {
860 p->fts_info = FTS_NS;
861 p->fts_errno = cderrno;
862 } else
863 p->fts_info = FTS_NSOK;
864 p->fts_accpath = cur->fts_accpath;
865 } else if (nlinks == 0
866#ifdef DT_DIR
867 || (nostat &&
868 dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
869#endif
870 ) {
871 p->fts_accpath =
872 ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
873 p->fts_info = FTS_NSOK;
874 } else {
875 /* Build a file name for fts_stat to stat. */
876 if (ISSET(FTS_NOCHDIR)) {
877 p->fts_accpath = p->fts_path;
878 memmove(cp, p->fts_name,
879 (size_t)(p->fts_namelen + 1));
880 } else
881 p->fts_accpath = p->fts_name;
882 /* Stat it. */
883 p->fts_info = fts_stat(sp, p, 0);
884
885 /* Decrement link count if applicable. */
886 if (nlinks > 0 && (p->fts_info == FTS_D ||
887 p->fts_info == FTS_DC || p->fts_info == FTS_DOT))
888 --nlinks;
889 }
890
891 /* We walk in directory order so "ls -f" doesn't get upset. */
892 p->fts_link = NULL;
893 if (head == NULL)
894 head = tail = p;
895 else {
896 tail->fts_link = p;
897 tail = p;
898 }
899 ++nitems;
900 }
901 (void)closedir(dirp);
902
903 /*
904 * If had to realloc the path, adjust the addresses for the rest
905 * of the tree.
906 */
907 if (doadjust)
908 fts_padjust(sp, head);
909
910 /*
911 * If not changing directories, reset the path back to original
912 * state.
913 */
914 if (ISSET(FTS_NOCHDIR)) {
915 if (len == sp->fts_pathlen || nitems == 0)
916 --cp;
917 *cp = '\0';
918 }
919
920 /*
921 * If descended after called from fts_children or after called from
922 * fts_read and nothing found, get back. At the root level we use
923 * the saved fd; if one of fts_open()'s arguments is a relative path
924 * to an empty directory, we wind up here with no other way back. If
925 * can't get back, we're done.
926 */
927 if (descend && (type == BCHILD || !nitems) &&
928 (cur->fts_level == FTS_ROOTLEVEL ?
929 FCHDIR(sp, sp->fts_rfd) :
930 fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) {
931 cur->fts_info = FTS_ERR;
932 SET(FTS_STOP);
933 return (NULL);
934 }
935
936 /* If didn't find anything, return NULL. */
937 if (!nitems) {
938 if (type == BREAD)
939 cur->fts_info = FTS_DP;
940 return (NULL);
941 }
942
943 /* Sort the entries. */
944 if (sp->fts_compar && nitems > 1)
945 head = fts_sort(sp, head, nitems);
946 return (head);
947}
948
949static unsigned short
950fts_stat(FTS *sp, FTSENT *p, int follow)
951{
952 FTSENT *t;
953 dev_t dev;
954 __fts_ino_t ino;
955 __fts_stat_t *sbp, sb;
956 int saved_errno;
957
958 _DIAGASSERT(sp != NULL);
959 _DIAGASSERT(p != NULL);
960
961 /* If user needs stat info, stat buffer already allocated. */
962 sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp;
963
964#ifdef FTS_WHITEOUT
965 /* check for whiteout */
966 if (p->fts_flags & FTS_ISW) {
967 if (sbp != &sb) {
968 memset(sbp, '\0', sizeof (*sbp));
969 sbp->st_mode = S_IFWHT;
970 }
971 return (FTS_W);
972 }
973#endif
974
975 /*
976 * If doing a logical walk, or application requested FTS_FOLLOW, do
977 * a stat(2). If that fails, check for a non-existent symlink. If
978 * fail, set the errno from the stat call.
979 */
980 if (ISSET(FTS_LOGICAL) || follow) {
981 if (stat(p->fts_accpath, sbp)) {
982 saved_errno = errno;
983 if (!lstat(p->fts_accpath, sbp)) {
984 errno = 0;
985 return (FTS_SLNONE);
986 }
987 p->fts_errno = saved_errno;
988 goto err;
989 }
990 } else if (lstat(p->fts_accpath, sbp)) {
991 p->fts_errno = errno;
992err: memset(sbp, 0, sizeof(*sbp));
993 return (FTS_NS);
994 }
995
996 if (S_ISDIR(sbp->st_mode)) {
997 /*
998 * Set the device/inode. Used to find cycles and check for
999 * crossing mount points. Also remember the link count, used
1000 * in fts_build to limit the number of stat calls. It is
1001 * understood that these fields are only referenced if fts_info
1002 * is set to FTS_D.
1003 */
1004 dev = p->fts_dev = sbp->st_dev;
1005 ino = p->fts_ino = sbp->st_ino;
1006 p->fts_nlink = sbp->st_nlink;
1007
1008 if (ISDOT(p->fts_name))
1009 return (FTS_DOT);
1010
1011 /*
1012 * Cycle detection is done by brute force when the directory
1013 * is first encountered. If the tree gets deep enough or the
1014 * number of symbolic links to directories is high enough,
1015 * something faster might be worthwhile.
1016 */
1017 for (t = p->fts_parent;
1018 t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)
1019 if (ino == t->fts_ino && dev == t->fts_dev) {
1020 p->fts_cycle = t;
1021 return (FTS_DC);
1022 }
1023 return (FTS_D);
1024 }
1025 if (S_ISLNK(sbp->st_mode))
1026 return (FTS_SL);
1027 if (S_ISREG(sbp->st_mode))
1028 return (FTS_F);
1029 return (FTS_DEFAULT);
1030}
1031
1032static FTSENT *
1033fts_sort(FTS *sp, FTSENT *head, size_t nitems)
1034{
1035 FTSENT **ap, *p;
1036
1037 _DIAGASSERT(sp != NULL);
1038 _DIAGASSERT(head != NULL);
1039
1040 /*
1041 * Construct an array of pointers to the structures and call qsort(3).
1042 * Reassemble the array in the order returned by qsort. If unable to
1043 * sort for memory reasons, return the directory entries in their
1044 * current order. Allocate enough space for the current needs plus
1045 * 40 so don't realloc one entry at a time.
1046 */
1047 if (nitems > sp->fts_nitems) {
1048 FTSENT **new;
1049
1050 new = realloc(sp->fts_array, sizeof(FTSENT *) * (nitems + 40));
1051 if (new == 0)
1052 return (head);
1053 sp->fts_array = new;
1054 sp->fts_nitems = fts_nitems_truncate(nitems + 40);
1055 }
1056 for (ap = sp->fts_array, p = head; p; p = p->fts_link)
1057 *ap++ = p;
1058 qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *),
1059 (int (*)(const void *, const void *))sp->fts_compar);
1060 for (head = *(ap = sp->fts_array); --nitems; ++ap)
1061 ap[0]->fts_link = ap[1];
1062 ap[0]->fts_link = NULL;
1063 return (head);
1064}
1065
1066static FTSENT *
1067fts_alloc(FTS *sp, const char *name, size_t namelen)
1068{
1069 FTSENT *p;
1070#if defined(FTS_ALLOC_ALIGNED)
1071 size_t len;
1072#endif
1073
1074 _DIAGASSERT(sp != NULL);
1075 _DIAGASSERT(name != NULL);
1076
1077#if defined(FTS_ALLOC_ALIGNED)
1078 /*
1079 * The file name is a variable length array and no stat structure is
1080 * necessary if the user has set the nostat bit. Allocate the FTSENT
1081 * structure, the file name and the stat structure in one chunk, but
1082 * be careful that the stat structure is reasonably aligned. Since the
1083 * fts_name field is declared to be of size 1, the fts_name pointer is
1084 * namelen + 2 before the first possible address of the stat structure.
1085 */
1086 len = sizeof(FTSENT) + namelen;
1087 if (!ISSET(FTS_NOSTAT))
1088 len += sizeof(*(p->fts_statp)) + ALIGNBYTES;
1089 if ((p = malloc(len)) == NULL)
1090 return (NULL);
1091
1092 if (!ISSET(FTS_NOSTAT))
1093 p->fts_statp = (__fts_stat_t *)ALIGN(
1094 (unsigned long)(p->fts_name + namelen + 2));
1095#else
1096 if ((p = malloc(sizeof(FTSENT) + namelen)) == NULL)
1097 return (NULL);
1098
1099 if (!ISSET(FTS_NOSTAT))
1100 if ((p->fts_statp = malloc(sizeof(*(p->fts_statp)))) == NULL) {
1101 free(p);
1102 return (NULL);
1103 }
1104#endif
1105
1106 if (ISSET(FTS_NOSTAT))
1107 p->fts_statp = NULL;
1108
1109 /* Copy the name plus the trailing NULL. */
1110 memmove(p->fts_name, name, namelen + 1);
1111
1112 p->fts_namelen = ftsent_namelen_truncate(namelen);
1113 p->fts_path = sp->fts_path;
1114 p->fts_errno = 0;
1115 p->fts_flags = 0;
1116 p->fts_instr = FTS_NOINSTR;
1117 p->fts_number = 0;
1118 p->fts_pointer = NULL;
1119 return (p);
1120}
1121
1122static void
1123fts_free(FTSENT *p)
1124{
1125#if !defined(FTS_ALLOC_ALIGNED)
1126 if (p->fts_statp)
1127 free(p->fts_statp);
1128#endif
1129 free(p);
1130}
1131
1132static void
1133fts_lfree(FTSENT *head)
1134{
1135 FTSENT *p;
1136
1137 /* XXX: head may be NULL ? */
1138
1139 /* Free a linked list of structures. */
1140 while ((p = head) != NULL) {
1141 head = head->fts_link;
1142 fts_free(p);
1143 }
1144}
1145
1146static size_t
1147fts_pow2(size_t x)
1148{
1149
1150 x--;
1151 x |= x>>1;
1152 x |= x>>2;
1153 x |= x>>4;
1154 x |= x>>8;
1155 x |= x>>16;
1156#if LONG_BIT > 32
1157 x |= x>>32;
1158#endif
1159#if LONG_BIT > 64
1160 x |= x>>64;
1161#endif
1162 x++;
1163 return (x);
1164}
1165
1166/*
1167 * Allow essentially unlimited paths; find, rm, ls should all work on any tree.
1168 * Most systems will allow creation of paths much longer than MAXPATHLEN, even
1169 * though the kernel won't resolve them. Round up the new size to a power of 2,
1170 * so we don't realloc the path 2 bytes at a time.
1171 */
1172static int
1173fts_palloc(FTS *sp, size_t size)
1174{
1175 char *new;
1176
1177 _DIAGASSERT(sp != NULL);
1178
1179#ifdef __FTS_COMPAT_LENGTH
1180 /* Protect against fts_pathlen overflow. */
1181 if (size > USHRT_MAX + 1) {
1182 errno = ENAMETOOLONG;
1183 return (1);
1184 }
1185#endif
1186 size = fts_pow2(size);
1187 new = realloc(sp->fts_path, size);
1188 if (new == 0)
1189 return (1);
1190 sp->fts_path = new;
1191 sp->fts_pathlen = fts_pathlen_truncate(size);
1192 return (0);
1193}
1194
1195/*
1196 * When the path is realloc'd, have to fix all of the pointers in structures
1197 * already returned.
1198 */
1199static void
1200fts_padjust(FTS *sp, FTSENT *head)
1201{
1202 FTSENT *p;
1203 char *addr;
1204
1205 _DIAGASSERT(sp != NULL);
1206
1207#define ADJUST(p) do { \
1208 if ((p)->fts_accpath != (p)->fts_name) \
1209 (p)->fts_accpath = \
1210 addr + ((p)->fts_accpath - (p)->fts_path); \
1211 (p)->fts_path = addr; \
1212} while (/*CONSTCOND*/0)
1213
1214 addr = sp->fts_path;
1215
1216 /* Adjust the current set of children. */
1217 for (p = sp->fts_child; p; p = p->fts_link)
1218 ADJUST(p);
1219
1220 /* Adjust the rest of the tree, including the current level. */
1221 for (p = head; p->fts_level >= FTS_ROOTLEVEL;) {
1222 ADJUST(p);
1223 p = p->fts_link ? p->fts_link : p->fts_parent;
1224 }
1225}
1226
1227static size_t
1228fts_maxarglen(char * const *argv)
1229{
1230 size_t len, max;
1231
1232 _DIAGASSERT(argv != NULL);
1233
1234 for (max = 0; *argv; ++argv)
1235 if ((len = strlen(*argv)) > max)
1236 max = len;
1237 return (max + 1);
1238}
1239
1240/*
1241 * Change to dir specified by fd or p->fts_accpath without getting
1242 * tricked by someone changing the world out from underneath us.
1243 * Assumes p->fts_dev and p->fts_ino are filled in.
1244 */
1245static int
1246fts_safe_changedir(const FTS *sp, const FTSENT *p, int fd, const char *path)
1247{
1248#if HAVE_FCHDIR
1249 int oldfd = fd, ret = -1;
1250 __fts_stat_t sb;
1251
1252 if (ISSET(FTS_NOCHDIR))
1253 return 0;
1254
1255 if (oldfd < 0 && (fd = open(path, O_RDONLY | O_CLOEXEC)) == -1)
1256 return -1;
1257
1258 if (fstat(fd, &sb) == -1)
1259 goto bail;
1260
1261 if (sb.st_ino != p->fts_ino || sb.st_dev != p->fts_dev) {
1262 errno = ENOENT;
1263 goto bail;
1264 }
1265
1266 ret = fchdir(fd);
1267
1268bail:
1269 if (oldfd < 0) {
1270 int save_errno = errno;
1271 (void)close(fd);
1272 errno = save_errno;
1273 }
1274 return ret;
1275#else
1276 /* If we can't do fchdir, pretend as if ISSET(FTS_NOCHDIR) is set. */
1277 return 0;
1278#endif
1279}
lib/libc/wasi/libc-bottom-half/clocks/times.c+2-1
...@@ -17,7 +17,8 @@ clock_t times(struct tms *buffer) {...@@ -17,7 +17,8 @@ clock_t times(struct tms *buffer) {
17 __wasi_timestamp_t user = __clock();17 __wasi_timestamp_t user = __clock();
18 *buffer = (struct tms){18 *buffer = (struct tms){
19 .tms_utime = user,19 .tms_utime = user,
20 .tms_cutime = user20 // WASI doesn't provide a way to spawn a new process, so always 0.
21 .tms_cutime = 0
21 };22 };
2223
23 __wasi_timestamp_t realtime = 0;24 __wasi_timestamp_t realtime = 0;
lib/libc/wasi/libc-bottom-half/cloudlibc/src/libc/stdlib/_Exit.c+9
...@@ -2,13 +2,22 @@...@@ -2,13 +2,22 @@
2//2//
3// SPDX-License-Identifier: BSD-2-Clause3// SPDX-License-Identifier: BSD-2-Clause
44
5#ifdef __wasilibc_use_wasip2
6#include <wasi/wasip2.h>
7#else
5#include <wasi/api.h>8#include <wasi/api.h>
9#endif
6#include <_/cdefs.h>10#include <_/cdefs.h>
7#include <stdnoreturn.h>11#include <stdnoreturn.h>
8#include <unistd.h>12#include <unistd.h>
913
10noreturn void _Exit(int status) {14noreturn void _Exit(int status) {
15#ifdef __wasilibc_use_wasip2
16 exit_result_void_void_t exit_status = { .is_err = status != 0 };
17 exit_exit(&exit_status);
18#else
11 __wasi_proc_exit(status);19 __wasi_proc_exit(status);
20#endif
12}21}
1322
14__strong_reference(_Exit, _exit);23__strong_reference(_Exit, _exit);
lib/libc/wasi/libc-bottom-half/crt/crt1-command.c+11
...@@ -2,7 +2,11 @@...@@ -2,7 +2,11 @@
2#include <stdatomic.h>2#include <stdatomic.h>
3extern void __wasi_init_tp(void);3extern void __wasi_init_tp(void);
4#endif4#endif
5#ifdef __wasilibc_use_wasip2
6#include <wasi/wasip2.h>
7#else
5#include <wasi/api.h>8#include <wasi/api.h>
9#endif
6extern void __wasm_call_ctors(void);10extern void __wasm_call_ctors(void);
7extern int __main_void(void);11extern int __main_void(void);
8extern void __wasm_call_dtors(void);12extern void __wasm_call_dtors(void);
...@@ -47,7 +51,14 @@ void _start(void) {...@@ -47,7 +51,14 @@ void _start(void) {
4751
48 // If main exited successfully, just return, otherwise call52 // If main exited successfully, just return, otherwise call
49 // `__wasi_proc_exit`.53 // `__wasi_proc_exit`.
54#ifdef __wasilibc_use_wasip2
55 if (r != 0) {
56 exit_result_void_void_t status = { .is_err = true };
57 exit_exit(&status);
58 }
59#else
50 if (r != 0) {60 if (r != 0) {
51 __wasi_proc_exit(r);61 __wasi_proc_exit(r);
52 }62 }
63#endif
53}64}
lib/libc/wasi/libc-bottom-half/headers/private/wasi/sockets_utils.h+14
...@@ -26,6 +26,17 @@ typedef struct {...@@ -26,6 +26,17 @@ typedef struct {
26 };26 };
27} output_sockaddr_t;27} output_sockaddr_t;
2828
29typedef struct {
30 char *s_name;
31 uint16_t port;
32 uint16_t protocol;
33} service_entry_t;
34
35typedef enum {
36 SERVICE_PROTOCOL_TCP = 1,
37 SERVICE_PROTOCOL_UDP = 2
38} service_protocol_e;
39
29network_borrow_network_t __wasi_sockets_utils__borrow_network();40network_borrow_network_t __wasi_sockets_utils__borrow_network();
30int __wasi_sockets_utils__map_error(network_error_code_t wasi_error);41int __wasi_sockets_utils__map_error(network_error_code_t wasi_error);
31bool __wasi_sockets_utils__parse_address(42bool __wasi_sockets_utils__parse_address(
...@@ -49,5 +60,8 @@ bool __wasi_sockets_utils__stream(udp_socket_t *socket,...@@ -49,5 +60,8 @@ bool __wasi_sockets_utils__stream(udp_socket_t *socket,
49 udp_socket_streams_t *result,60 udp_socket_streams_t *result,
50 network_error_code_t *error);61 network_error_code_t *error);
51void __wasi_sockets_utils__drop_streams(udp_socket_streams_t streams);62void __wasi_sockets_utils__drop_streams(udp_socket_streams_t streams);
63int __wasi_sockets_utils__parse_port(const char *port);
64const service_entry_t *__wasi_sockets_utils__get_service_entry_by_name(const char *name);
65const service_entry_t *__wasi_sockets_utils__get_service_entry_by_port(const uint16_t port);
5266
53#endif67#endif
lib/libc/wasi/libc-bottom-half/mman/mman.c+33
...@@ -9,6 +9,7 @@...@@ -9,6 +9,7 @@
9#include <errno.h>9#include <errno.h>
10#include <unistd.h>10#include <unistd.h>
11#include <string.h>11#include <string.h>
12#include <limits.h>
12#include <sys/mman.h>13#include <sys/mman.h>
13#include <sys/types.h>14#include <sys/types.h>
1415
...@@ -122,3 +123,35 @@ int munmap(void *addr, size_t length) {...@@ -122,3 +123,35 @@ int munmap(void *addr, size_t length) {
122 // Success!123 // Success!
123 return 0;124 return 0;
124}125}
126
127int mprotect(void *addr, size_t length, int prot) {
128 // Address must be page-aligned.
129 size_t begin = (size_t)addr;
130 if ((begin & (PAGESIZE - 1)) != 0) {
131 errno = EINVAL;
132 return -1;
133 }
134
135 // Length must not be big enough to wrap around.
136 size_t end;
137 if (__builtin_add_overflow(begin, length, &end)) {
138 errno = ENOMEM;
139 return -1;
140 }
141
142 // Range must be in bounds of linear memory.
143 size_t memory_size = __builtin_wasm_memory_size(0) * PAGESIZE;
144 if (end > memory_size) {
145 errno = ENOMEM;
146 return -1;
147 }
148
149 // Can only protect memory as read/write (which is a no-op).
150 if (prot != (PROT_READ | PROT_WRITE)) {
151 errno = ENOTSUP;
152 return -1;
153 }
154
155 // Success!
156 return 0;
157}
lib/libc/wasi/libc-bottom-half/sources/__main_void.c+47-6
...@@ -1,19 +1,19 @@...@@ -1,19 +1,19 @@
1#ifdef __wasilibc_use_wasip2
2#include <wasi/wasip2.h>
3#else
1#include <wasi/api.h>4#include <wasi/api.h>
5#endif
2#include <stdlib.h>6#include <stdlib.h>
3#include <sysexits.h>7#include <sysexits.h>
48
5int __wasilibc_main(int argc, char *argv[]) asm("main");
6
7// The user's `main` function, expecting arguments.9// The user's `main` function, expecting arguments.
8//10//
9// Note that we make this a weak symbol so that it will have a11// Note that we make this a weak symbol so that it will have a
10// `WASM_SYM_BINDING_WEAK` flag in libc.so, which tells the dynamic linker that12// `WASM_SYM_BINDING_WEAK` flag in libc.so, which tells the dynamic linker that
11// it need not be defined (e.g. in reactor-style apps with no main function).13// it need not be defined (e.g. in reactor-style apps with no main function).
12// See also the TODO comment on `__main_void` below.14// See also the TODO comment on `__main_void` below.
13__attribute__((__weak__, nodebug))15__attribute__((__weak__))
14int __main_argc_argv(int argc, char *argv[]) {16int __main_argc_argv(int argc, char *argv[]);
15 return __wasilibc_main(argc, argv);
16}
1717
18// If the user's `main` function expects arguments, the compiler will rename18// If the user's `main` function expects arguments, the compiler will rename
19// it to `__main_argc_argv`, and this version will get linked in, which19// it to `__main_argc_argv`, and this version will get linked in, which
...@@ -25,6 +25,46 @@ int __main_argc_argv(int argc, char *argv[]) {...@@ -25,6 +25,46 @@ int __main_argc_argv(int argc, char *argv[]) {
25// (e.g. crt0.o or crtend.o) and teach Clang to use it when needed.25// (e.g. crt0.o or crtend.o) and teach Clang to use it when needed.
26__attribute__((__weak__, nodebug))26__attribute__((__weak__, nodebug))
27int __main_void(void) {27int __main_void(void) {
28#ifdef __wasilibc_use_wasip2
29 wasip2_list_string_t argument_list;
30
31 environment_get_arguments(&argument_list);
32
33 // Add 1 for the NULL pointer to mark the end, and check for overflow.
34 size_t argc = argument_list.len;
35 size_t num_ptrs = argc + 1;
36 if (num_ptrs == 0) {
37 wasip2_list_string_free(&argument_list);
38 _Exit(EX_SOFTWARE);
39 }
40
41 // Allocate memory for the array of pointers. This uses `calloc` both to
42 // handle overflow and to initialize the NULL pointer at the end.
43 char **argv = calloc(num_ptrs, sizeof(char *));
44 if (argv == NULL) {
45 wasip2_list_string_free(&argument_list);
46 _Exit(EX_SOFTWARE);
47 }
48
49 // Copy the arguments
50 for (size_t i = 0; i < argc; i++) {
51 wasip2_string_t wasi_string = argument_list.ptr[i];
52 size_t len = wasi_string.len;
53 argv[i] = malloc(len + 1);
54 if (!argv[i]) {
55 wasip2_list_string_free(&argument_list);
56 _Exit(EX_SOFTWARE);
57 }
58 memcpy(argv[i], wasi_string.ptr, len);
59 argv[i][len] = '\0';
60 }
61
62 // Free the WASI argument list
63 wasip2_list_string_free(&argument_list);
64
65 // Call `__main_argc_argv` with the arguments!
66 return __main_argc_argv(argc, argv);
67#else
28 __wasi_errno_t err;68 __wasi_errno_t err;
2969
30 // Get the sizes of the arrays we'll have to create to copy in the args.70 // Get the sizes of the arrays we'll have to create to copy in the args.
...@@ -66,4 +106,5 @@ int __main_void(void) {...@@ -66,4 +106,5 @@ int __main_void(void) {
66106
67 // Call `__main_argc_argv` with the arguments!107 // Call `__main_argc_argv` with the arguments!
68 return __main_argc_argv(argc, argv);108 return __main_argc_argv(argc, argv);
109#endif
69}110}
lib/libc/wasi/libc-bottom-half/sources/__wasilibc_initialize_environ.c+54
...@@ -1,7 +1,11 @@...@@ -1,7 +1,11 @@
1#include <unistd.h>1#include <unistd.h>
2#include <stdlib.h>2#include <stdlib.h>
3#include <sysexits.h>3#include <sysexits.h>
4#ifdef __wasilibc_use_wasip2
5#include <wasi/wasip2.h>
6#else
4#include <wasi/api.h>7#include <wasi/api.h>
8#endif
5#include <wasi/libc.h>9#include <wasi/libc.h>
6#include <wasi/libc-environ.h>10#include <wasi/libc-environ.h>
711
...@@ -26,6 +30,55 @@ static char *empty_environ[1] = { NULL };...@@ -26,6 +30,55 @@ static char *empty_environ[1] = { NULL };
2630
27// See the comments in libc-environ.h.31// See the comments in libc-environ.h.
28void __wasilibc_initialize_environ(void) {32void __wasilibc_initialize_environ(void) {
33#ifdef __wasilibc_use_wasip2
34 // Get the environment
35 wasip2_list_tuple2_string_string_t wasi_environment;
36 environment_get_environment(&wasi_environment);
37
38 size_t environ_count = wasi_environment.len;
39 if (environ_count == 0) {
40 __wasilibc_environ = empty_environ;
41 return;
42 }
43
44 // Add 1 for the NULL pointer to mark the end, and check for overflow.
45 size_t num_ptrs = environ_count + 1;
46 if (num_ptrs == 0) {
47 goto software;
48 }
49
50 // Allocate memory for the array of pointers. This uses `calloc` both to
51 // handle overflow and to initialize the NULL pointer at the end.
52 char **environ_ptrs = calloc(num_ptrs, sizeof(char *));
53
54 // Copy the environment variables
55 for (size_t i = 0; i < environ_count; i++) {
56 wasip2_tuple2_string_string_t pair = wasi_environment.ptr[i];
57 // 1 extra character for the null terminator, 1 for the '=' character
58 environ_ptrs[i] = malloc(pair.f0.len + pair.f1.len + 2);
59 if (!environ_ptrs[i]) {
60 for (size_t j = 0; j < i; j++)
61 free(environ_ptrs[j]);
62 free(environ_ptrs);
63 goto software;
64 }
65 memcpy(environ_ptrs[i], pair.f0.ptr, pair.f0.len);
66 environ_ptrs[i][pair.f0.len] = '=';
67 memcpy(environ_ptrs[i] + pair.f0.len + 1, pair.f1.ptr, pair.f1.len);
68 environ_ptrs[i][pair.f0.len + pair.f1.len + 1] = '\0';
69 }
70
71 // Free the WASI environment list
72 wasip2_list_tuple2_string_string_free(&wasi_environment);
73
74 // Initialize the environment from the created array
75 __wasilibc_environ = environ_ptrs;
76 return;
77software:
78 wasip2_list_tuple2_string_string_free(&wasi_environment);
79 _Exit(EX_SOFTWARE);
80
81#else
29 // Get the sizes of the arrays we'll have to create to copy in the environment.82 // Get the sizes of the arrays we'll have to create to copy in the environment.
30 size_t environ_count;83 size_t environ_count;
31 size_t environ_buf_size;84 size_t environ_buf_size;
...@@ -74,6 +127,7 @@ oserr:...@@ -74,6 +127,7 @@ oserr:
74 _Exit(EX_OSERR);127 _Exit(EX_OSERR);
75software:128software:
76 _Exit(EX_SOFTWARE);129 _Exit(EX_SOFTWARE);
130#endif
77}131}
78132
79// See the comments in libc-environ.h.133// See the comments in libc-environ.h.
lib/libc/wasi/libc-bottom-half/sources/__wasilibc_random.c created+29
...@@ -0,0 +1,29 @@
1#include <errno.h>
2#include <unistd.h>
3#ifdef __wasilibc_use_wasip2
4#include <wasi/wasip2.h>
5#include <sysexits.h>
6
7int __wasilibc_random(void *buffer, size_t len) {
8
9 // Set up a WASI byte list to receive the results
10 wasip2_list_u8_t wasi_list;
11
12 // Get random bytes
13 random_get_random_bytes(len, &wasi_list);
14
15 // The spec for get-random-bytes specifies that wasi_list.len
16 // will be equal to len.
17 if (wasi_list.len != len)
18 _Exit(EX_OSERR);
19 else {
20 // Copy the result
21 memcpy(buffer, wasi_list.ptr, len);
22 }
23
24 // Free the WASI byte list
25 wasip2_list_u8_free(&wasi_list);
26
27 return 0;
28}
29#endif
lib/libc/wasi/libc-bottom-half/sources/getentropy.c+8-2
...@@ -1,6 +1,10 @@...@@ -1,6 +1,10 @@
1#include <errno.h>1#include <errno.h>
2#include <unistd.h>2#include <unistd.h>
3#ifdef __wasilibc_use_wasip2
4#include <wasi/libc.h>
5#else
3#include <wasi/api.h>6#include <wasi/api.h>
7#endif
48
5int __getentropy(void *buffer, size_t len) {9int __getentropy(void *buffer, size_t len) {
6 if (len > 256) {10 if (len > 256) {
...@@ -8,13 +12,15 @@ int __getentropy(void *buffer, size_t len) {...@@ -8,13 +12,15 @@ int __getentropy(void *buffer, size_t len) {
8 return -1;12 return -1;
9 }13 }
1014
15#ifdef __wasilibc_use_wasip2
16 int r = __wasilibc_random(buffer, len);
17#else
11 int r = __wasi_random_get(buffer, len);18 int r = __wasi_random_get(buffer, len);
1219#endif
13 if (r != 0) {20 if (r != 0) {
14 errno = r;21 errno = r;
15 return -1;22 return -1;
16 }23 }
17
18 return 0;24 return 0;
19}25}
20weak_alias(__getentropy, getentropy);26weak_alias(__getentropy, getentropy);
lib/libc/wasi/libc-bottom-half/sources/preopens.c+3-6
...@@ -59,7 +59,6 @@ static void assert_invariants(void) {...@@ -59,7 +59,6 @@ static void assert_invariants(void) {
5959
60/// Allocate space for more preopens. Returns 0 on success and -1 on failure.60/// Allocate space for more preopens. Returns 0 on success and -1 on failure.
61static int resize(void) {61static int resize(void) {
62 LOCK(lock);
63 size_t start_capacity = 4;62 size_t start_capacity = 4;
64 size_t old_capacity = preopen_capacity;63 size_t old_capacity = preopen_capacity;
65 size_t new_capacity = old_capacity == 0 ? start_capacity : old_capacity * 2;64 size_t new_capacity = old_capacity == 0 ? start_capacity : old_capacity * 2;
...@@ -67,7 +66,6 @@ static int resize(void) {...@@ -67,7 +66,6 @@ static int resize(void) {
67 preopen *old_preopens = preopens;66 preopen *old_preopens = preopens;
68 preopen *new_preopens = calloc(sizeof(preopen), new_capacity);67 preopen *new_preopens = calloc(sizeof(preopen), new_capacity);
69 if (new_preopens == NULL) {68 if (new_preopens == NULL) {
70 UNLOCK(lock);
71 return -1;69 return -1;
72 }70 }
7371
...@@ -77,7 +75,6 @@ static int resize(void) {...@@ -77,7 +75,6 @@ static int resize(void) {
77 free(old_preopens);75 free(old_preopens);
7876
79 assert_invariants();77 assert_invariants();
80 UNLOCK(lock);
81 return 0;78 return 0;
82}79}
8380
...@@ -101,8 +98,7 @@ static const char *strip_prefixes(const char *path) {...@@ -101,8 +98,7 @@ static const char *strip_prefixes(const char *path) {
101 return path;98 return path;
102}99}
103100
104/// Similar to `internal_register_preopened_fd_unlocked` but does not101/// Similar to `internal_register_preopened_fd` but does not take a lock.
105/// take a lock.
106static int internal_register_preopened_fd_unlocked(__wasi_fd_t fd, const char *relprefix) {102static int internal_register_preopened_fd_unlocked(__wasi_fd_t fd, const char *relprefix) {
107 // Check preconditions.103 // Check preconditions.
108 assert_invariants();104 assert_invariants();
...@@ -184,7 +180,7 @@ int __wasilibc_find_abspath(const char *path,...@@ -184,7 +180,7 @@ int __wasilibc_find_abspath(const char *path,
184 const char **relative_path) {180 const char **relative_path) {
185 __wasilibc_populate_preopens();181 __wasilibc_populate_preopens();
186182
187 // Strip leading `/` characters, the prefixes we're mataching won't have183 // Strip leading `/` characters, the prefixes we're matching won't have
188 // them.184 // them.
189 while (*path == '/')185 while (*path == '/')
190 path++;186 path++;
...@@ -231,6 +227,7 @@ int __wasilibc_find_abspath(const char *path,...@@ -231,6 +227,7 @@ int __wasilibc_find_abspath(const char *path,
231 return fd;227 return fd;
232}228}
233229
230/* zig patch: initialize preopens early so zig code doesn't have to call __wasilibc_populate_preopens */
234__attribute__((constructor(51)))231__attribute__((constructor(51)))
235void __wasilibc_populate_preopens(void) {232void __wasilibc_populate_preopens(void) {
236 // Fast path: If the preopens are already initialized, do nothing.233 // Fast path: If the preopens are already initialized, do nothing.
lib/libc/wasi/libc-top-half/musl/include/aio.h created+73
...@@ -0,0 +1,73 @@
1#ifndef _AIO_H
2#define _AIO_H
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8#include <features.h>
9#include <signal.h>
10#include <time.h>
11
12#define __NEED_ssize_t
13#define __NEED_off_t
14
15#include <bits/alltypes.h>
16
17struct aiocb {
18 int aio_fildes, aio_lio_opcode, aio_reqprio;
19 volatile void *aio_buf;
20 size_t aio_nbytes;
21 struct sigevent aio_sigevent;
22 void *__td;
23 int __lock[2];
24 volatile int __err;
25 ssize_t __ret;
26 off_t aio_offset;
27 void *__next, *__prev;
28 char __dummy4[32-2*sizeof(void *)];
29};
30
31#define AIO_CANCELED 0
32#define AIO_NOTCANCELED 1
33#define AIO_ALLDONE 2
34
35#define LIO_READ 0
36#define LIO_WRITE 1
37#define LIO_NOP 2
38
39#define LIO_WAIT 0
40#define LIO_NOWAIT 1
41
42int aio_read(struct aiocb *);
43int aio_write(struct aiocb *);
44int aio_error(const struct aiocb *);
45ssize_t aio_return(struct aiocb *);
46int aio_cancel(int, struct aiocb *);
47int aio_suspend(const struct aiocb *const [], int, const struct timespec *);
48int aio_fsync(int, struct aiocb *);
49
50int lio_listio(int, struct aiocb *__restrict const *__restrict, int, struct sigevent *__restrict);
51
52#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
53#define aiocb64 aiocb
54#define aio_read64 aio_read
55#define aio_write64 aio_write
56#define aio_error64 aio_error
57#define aio_return64 aio_return
58#define aio_cancel64 aio_cancel
59#define aio_suspend64 aio_suspend
60#define aio_fsync64 aio_fsync
61#define lio_listio64 lio_listio
62#define off64_t off_t
63#endif
64
65#if _REDIR_TIME64
66__REDIR(aio_suspend, __aio_suspend_time64);
67#endif
68
69#ifdef __cplusplus
70}
71#endif
72
73#endif
lib/libc/wasi/libc-top-half/musl/include/arpa/nameser.h deleted-455
...@@ -1,455 +0,0 @@
1#ifndef _ARPA_NAMESER_H
2#define _ARPA_NAMESER_H
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8#include <stddef.h>
9#include <stdint.h>
10
11#define __NAMESER 19991006
12#define NS_PACKETSZ 512
13#define NS_MAXDNAME 1025
14#define NS_MAXMSG 65535
15#define NS_MAXCDNAME 255
16#define NS_MAXLABEL 63
17#define NS_HFIXEDSZ 12
18#define NS_QFIXEDSZ 4
19#define NS_RRFIXEDSZ 10
20#define NS_INT32SZ 4
21#define NS_INT16SZ 2
22#define NS_INT8SZ 1
23#define NS_INADDRSZ 4
24#define NS_IN6ADDRSZ 16
25#define NS_CMPRSFLGS 0xc0
26#define NS_DEFAULTPORT 53
27
28typedef enum __ns_sect {
29 ns_s_qd = 0,
30 ns_s_zn = 0,
31 ns_s_an = 1,
32 ns_s_pr = 1,
33 ns_s_ns = 2,
34 ns_s_ud = 2,
35 ns_s_ar = 3,
36 ns_s_max = 4
37} ns_sect;
38
39typedef struct __ns_msg {
40 const unsigned char *_msg, *_eom;
41 uint16_t _id, _flags, _counts[ns_s_max];
42 const unsigned char *_sections[ns_s_max];
43 ns_sect _sect;
44 int _rrnum;
45 const unsigned char *_msg_ptr;
46} ns_msg;
47
48struct _ns_flagdata { int mask, shift; };
49extern const struct _ns_flagdata _ns_flagdata[];
50
51#define ns_msg_id(handle) ((handle)._id + 0)
52#define ns_msg_base(handle) ((handle)._msg + 0)
53#define ns_msg_end(handle) ((handle)._eom + 0)
54#define ns_msg_size(handle) ((handle)._eom - (handle)._msg)
55#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
56#define ns_msg_getflag(handle, flag) \
57 (((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift)
58
59typedef struct __ns_rr {
60 char name[NS_MAXDNAME];
61 uint16_t type;
62 uint16_t rr_class;
63 uint32_t ttl;
64 uint16_t rdlength;
65 const unsigned char *rdata;
66} ns_rr;
67
68#define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".")
69#define ns_rr_type(rr) ((ns_type)((rr).type + 0))
70#define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0))
71#define ns_rr_ttl(rr) ((rr).ttl + 0)
72#define ns_rr_rdlen(rr) ((rr).rdlength + 0)
73#define ns_rr_rdata(rr) ((rr).rdata + 0)
74
75typedef enum __ns_flag {
76 ns_f_qr,
77 ns_f_opcode,
78 ns_f_aa,
79 ns_f_tc,
80 ns_f_rd,
81 ns_f_ra,
82 ns_f_z,
83 ns_f_ad,
84 ns_f_cd,
85 ns_f_rcode,
86 ns_f_max
87} ns_flag;
88
89typedef enum __ns_opcode {
90 ns_o_query = 0,
91 ns_o_iquery = 1,
92 ns_o_status = 2,
93 ns_o_notify = 4,
94 ns_o_update = 5,
95 ns_o_max = 6
96} ns_opcode;
97
98typedef enum __ns_rcode {
99 ns_r_noerror = 0,
100 ns_r_formerr = 1,
101 ns_r_servfail = 2,
102 ns_r_nxdomain = 3,
103 ns_r_notimpl = 4,
104 ns_r_refused = 5,
105 ns_r_yxdomain = 6,
106 ns_r_yxrrset = 7,
107 ns_r_nxrrset = 8,
108 ns_r_notauth = 9,
109 ns_r_notzone = 10,
110 ns_r_max = 11,
111 ns_r_badvers = 16,
112 ns_r_badsig = 16,
113 ns_r_badkey = 17,
114 ns_r_badtime = 18
115} ns_rcode;
116
117typedef enum __ns_update_operation {
118 ns_uop_delete = 0,
119 ns_uop_add = 1,
120 ns_uop_max = 2
121} ns_update_operation;
122
123struct ns_tsig_key {
124 char name[NS_MAXDNAME], alg[NS_MAXDNAME];
125 unsigned char *data;
126 int len;
127};
128typedef struct ns_tsig_key ns_tsig_key;
129
130struct ns_tcp_tsig_state {
131 int counter;
132 struct dst_key *key;
133 void *ctx;
134 unsigned char sig[NS_PACKETSZ];
135 int siglen;
136};
137typedef struct ns_tcp_tsig_state ns_tcp_tsig_state;
138
139#define NS_TSIG_FUDGE 300
140#define NS_TSIG_TCP_COUNT 100
141#define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT"
142
143#define NS_TSIG_ERROR_NO_TSIG -10
144#define NS_TSIG_ERROR_NO_SPACE -11
145#define NS_TSIG_ERROR_FORMERR -12
146
147typedef enum __ns_type {
148 ns_t_invalid = 0,
149 ns_t_a = 1,
150 ns_t_ns = 2,
151 ns_t_md = 3,
152 ns_t_mf = 4,
153 ns_t_cname = 5,
154 ns_t_soa = 6,
155 ns_t_mb = 7,
156 ns_t_mg = 8,
157 ns_t_mr = 9,
158 ns_t_null = 10,
159 ns_t_wks = 11,
160 ns_t_ptr = 12,
161 ns_t_hinfo = 13,
162 ns_t_minfo = 14,
163 ns_t_mx = 15,
164 ns_t_txt = 16,
165 ns_t_rp = 17,
166 ns_t_afsdb = 18,
167 ns_t_x25 = 19,
168 ns_t_isdn = 20,
169 ns_t_rt = 21,
170 ns_t_nsap = 22,
171 ns_t_nsap_ptr = 23,
172 ns_t_sig = 24,
173 ns_t_key = 25,
174 ns_t_px = 26,
175 ns_t_gpos = 27,
176 ns_t_aaaa = 28,
177 ns_t_loc = 29,
178 ns_t_nxt = 30,
179 ns_t_eid = 31,
180 ns_t_nimloc = 32,
181 ns_t_srv = 33,
182 ns_t_atma = 34,
183 ns_t_naptr = 35,
184 ns_t_kx = 36,
185 ns_t_cert = 37,
186 ns_t_a6 = 38,
187 ns_t_dname = 39,
188 ns_t_sink = 40,
189 ns_t_opt = 41,
190 ns_t_apl = 42,
191 ns_t_tkey = 249,
192 ns_t_tsig = 250,
193 ns_t_ixfr = 251,
194 ns_t_axfr = 252,
195 ns_t_mailb = 253,
196 ns_t_maila = 254,
197 ns_t_any = 255,
198 ns_t_zxfr = 256,
199 ns_t_max = 65536
200} ns_type;
201
202#define ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \
203 (t) == ns_t_mailb || (t) == ns_t_maila)
204#define ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt)
205#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t))
206#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr)
207#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \
208 (t) == ns_t_zxfr)
209
210typedef enum __ns_class {
211 ns_c_invalid = 0,
212 ns_c_in = 1,
213 ns_c_2 = 2,
214 ns_c_chaos = 3,
215 ns_c_hs = 4,
216 ns_c_none = 254,
217 ns_c_any = 255,
218 ns_c_max = 65536
219} ns_class;
220
221typedef enum __ns_key_types {
222 ns_kt_rsa = 1,
223 ns_kt_dh = 2,
224 ns_kt_dsa = 3,
225 ns_kt_private = 254
226} ns_key_types;
227
228typedef enum __ns_cert_types {
229 cert_t_pkix = 1,
230 cert_t_spki = 2,
231 cert_t_pgp = 3,
232 cert_t_url = 253,
233 cert_t_oid = 254
234} ns_cert_types;
235
236#define NS_KEY_TYPEMASK 0xC000
237#define NS_KEY_TYPE_AUTH_CONF 0x0000
238#define NS_KEY_TYPE_CONF_ONLY 0x8000
239#define NS_KEY_TYPE_AUTH_ONLY 0x4000
240#define NS_KEY_TYPE_NO_KEY 0xC000
241#define NS_KEY_NO_AUTH 0x8000
242#define NS_KEY_NO_CONF 0x4000
243#define NS_KEY_RESERVED2 0x2000
244#define NS_KEY_EXTENDED_FLAGS 0x1000
245#define NS_KEY_RESERVED4 0x0800
246#define NS_KEY_RESERVED5 0x0400
247#define NS_KEY_NAME_TYPE 0x0300
248#define NS_KEY_NAME_USER 0x0000
249#define NS_KEY_NAME_ENTITY 0x0200
250#define NS_KEY_NAME_ZONE 0x0100
251#define NS_KEY_NAME_RESERVED 0x0300
252#define NS_KEY_RESERVED8 0x0080
253#define NS_KEY_RESERVED9 0x0040
254#define NS_KEY_RESERVED10 0x0020
255#define NS_KEY_RESERVED11 0x0010
256#define NS_KEY_SIGNATORYMASK 0x000F
257#define NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \
258 NS_KEY_RESERVED4 | \
259 NS_KEY_RESERVED5 | \
260 NS_KEY_RESERVED8 | \
261 NS_KEY_RESERVED9 | \
262 NS_KEY_RESERVED10 | \
263 NS_KEY_RESERVED11 )
264#define NS_KEY_RESERVED_BITMASK2 0xFFFF
265#define NS_ALG_MD5RSA 1
266#define NS_ALG_DH 2
267#define NS_ALG_DSA 3
268#define NS_ALG_DSS NS_ALG_DSA
269#define NS_ALG_EXPIRE_ONLY 253
270#define NS_ALG_PRIVATE_OID 254
271
272#define NS_KEY_PROT_TLS 1
273#define NS_KEY_PROT_EMAIL 2
274#define NS_KEY_PROT_DNSSEC 3
275#define NS_KEY_PROT_IPSEC 4
276#define NS_KEY_PROT_ANY 255
277
278#define NS_MD5RSA_MIN_BITS 512
279#define NS_MD5RSA_MAX_BITS 4096
280#define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS+7/8)*2+3)
281#define NS_MD5RSA_MAX_BASE64 (((NS_MD5RSA_MAX_BYTES+2)/3)*4)
282#define NS_MD5RSA_MIN_SIZE ((NS_MD5RSA_MIN_BITS+7)/8)
283#define NS_MD5RSA_MAX_SIZE ((NS_MD5RSA_MAX_BITS+7)/8)
284
285#define NS_DSA_SIG_SIZE 41
286#define NS_DSA_MIN_SIZE 213
287#define NS_DSA_MAX_BYTES 405
288
289#define NS_SIG_TYPE 0
290#define NS_SIG_ALG 2
291#define NS_SIG_LABELS 3
292#define NS_SIG_OTTL 4
293#define NS_SIG_EXPIR 8
294#define NS_SIG_SIGNED 12
295#define NS_SIG_FOOT 16
296#define NS_SIG_SIGNER 18
297#define NS_NXT_BITS 8
298#define NS_NXT_BIT_SET( n,p) (p[(n)/NS_NXT_BITS] |= (0x80>>((n)%NS_NXT_BITS)))
299#define NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS)))
300#define NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] & (0x80>>((n)%NS_NXT_BITS)))
301#define NS_NXT_MAX 127
302
303#define NS_OPT_DNSSEC_OK 0x8000U
304#define NS_OPT_NSID 3
305
306#define NS_GET16(s, cp) (void)((s) = ns_get16(((cp)+=2)-2))
307#define NS_GET32(l, cp) (void)((l) = ns_get32(((cp)+=4)-4))
308#define NS_PUT16(s, cp) ns_put16((s), ((cp)+=2)-2)
309#define NS_PUT32(l, cp) ns_put32((l), ((cp)+=4)-4)
310
311unsigned ns_get16(const unsigned char *);
312unsigned long ns_get32(const unsigned char *);
313void ns_put16(unsigned, unsigned char *);
314void ns_put32(unsigned long, unsigned char *);
315
316int ns_initparse(const unsigned char *, int, ns_msg *);
317int ns_parserr(ns_msg *, ns_sect, int, ns_rr *);
318int ns_skiprr(const unsigned char *, const unsigned char *, ns_sect, int);
319int ns_name_uncompress(const unsigned char *, const unsigned char *, const unsigned char *, char *, size_t);
320
321
322#define __BIND 19950621
323
324typedef struct {
325 unsigned id :16;
326#if __BYTE_ORDER == __BIG_ENDIAN
327 unsigned qr: 1;
328 unsigned opcode: 4;
329 unsigned aa: 1;
330 unsigned tc: 1;
331 unsigned rd: 1;
332 unsigned ra: 1;
333 unsigned unused :1;
334 unsigned ad: 1;
335 unsigned cd: 1;
336 unsigned rcode :4;
337#else
338 unsigned rd :1;
339 unsigned tc :1;
340 unsigned aa :1;
341 unsigned opcode :4;
342 unsigned qr :1;
343 unsigned rcode :4;
344 unsigned cd: 1;
345 unsigned ad: 1;
346 unsigned unused :1;
347 unsigned ra :1;
348#endif
349 unsigned qdcount :16;
350 unsigned ancount :16;
351 unsigned nscount :16;
352 unsigned arcount :16;
353} HEADER;
354
355#define PACKETSZ NS_PACKETSZ
356#define MAXDNAME NS_MAXDNAME
357#define MAXCDNAME NS_MAXCDNAME
358#define MAXLABEL NS_MAXLABEL
359#define HFIXEDSZ NS_HFIXEDSZ
360#define QFIXEDSZ NS_QFIXEDSZ
361#define RRFIXEDSZ NS_RRFIXEDSZ
362#define INT32SZ NS_INT32SZ
363#define INT16SZ NS_INT16SZ
364#define INT8SZ NS_INT8SZ
365#define INADDRSZ NS_INADDRSZ
366#define IN6ADDRSZ NS_IN6ADDRSZ
367#define INDIR_MASK NS_CMPRSFLGS
368#define NAMESERVER_PORT NS_DEFAULTPORT
369
370#define S_ZONE ns_s_zn
371#define S_PREREQ ns_s_pr
372#define S_UPDATE ns_s_ud
373#define S_ADDT ns_s_ar
374
375#define QUERY ns_o_query
376#define IQUERY ns_o_iquery
377#define STATUS ns_o_status
378#define NS_NOTIFY_OP ns_o_notify
379#define NS_UPDATE_OP ns_o_update
380
381#define NOERROR ns_r_noerror
382#define FORMERR ns_r_formerr
383#define SERVFAIL ns_r_servfail
384#define NXDOMAIN ns_r_nxdomain
385#define NOTIMP ns_r_notimpl
386#define REFUSED ns_r_refused
387#define YXDOMAIN ns_r_yxdomain
388#define YXRRSET ns_r_yxrrset
389#define NXRRSET ns_r_nxrrset
390#define NOTAUTH ns_r_notauth
391#define NOTZONE ns_r_notzone
392
393#define DELETE ns_uop_delete
394#define ADD ns_uop_add
395
396#define T_A ns_t_a
397#define T_NS ns_t_ns
398#define T_MD ns_t_md
399#define T_MF ns_t_mf
400#define T_CNAME ns_t_cname
401#define T_SOA ns_t_soa
402#define T_MB ns_t_mb
403#define T_MG ns_t_mg
404#define T_MR ns_t_mr
405#define T_NULL ns_t_null
406#define T_WKS ns_t_wks
407#define T_PTR ns_t_ptr
408#define T_HINFO ns_t_hinfo
409#define T_MINFO ns_t_minfo
410#define T_MX ns_t_mx
411#define T_TXT ns_t_txt
412#define T_RP ns_t_rp
413#define T_AFSDB ns_t_afsdb
414#define T_X25 ns_t_x25
415#define T_ISDN ns_t_isdn
416#define T_RT ns_t_rt
417#define T_NSAP ns_t_nsap
418#define T_NSAP_PTR ns_t_nsap_ptr
419#define T_SIG ns_t_sig
420#define T_KEY ns_t_key
421#define T_PX ns_t_px
422#define T_GPOS ns_t_gpos
423#define T_AAAA ns_t_aaaa
424#define T_LOC ns_t_loc
425#define T_NXT ns_t_nxt
426#define T_EID ns_t_eid
427#define T_NIMLOC ns_t_nimloc
428#define T_SRV ns_t_srv
429#define T_ATMA ns_t_atma
430#define T_NAPTR ns_t_naptr
431#define T_A6 ns_t_a6
432#define T_DNAME ns_t_dname
433#define T_TSIG ns_t_tsig
434#define T_IXFR ns_t_ixfr
435#define T_AXFR ns_t_axfr
436#define T_MAILB ns_t_mailb
437#define T_MAILA ns_t_maila
438#define T_ANY ns_t_any
439
440#define C_IN ns_c_in
441#define C_CHAOS ns_c_chaos
442#define C_HS ns_c_hs
443#define C_NONE ns_c_none
444#define C_ANY ns_c_any
445
446#define GETSHORT NS_GET16
447#define GETLONG NS_GET32
448#define PUTSHORT NS_PUT16
449#define PUTLONG NS_PUT32
450
451#ifdef __cplusplus
452}
453#endif
454
455#endif
lib/libc/wasi/libc-top-half/musl/include/fcntl.h+5-1
...@@ -203,7 +203,6 @@ struct f_owner_ex {...@@ -203,7 +203,6 @@ struct f_owner_ex {
203#endif203#endif
204#ifdef __wasilibc_unmodified_upstream /* WASI has no fallocate */204#ifdef __wasilibc_unmodified_upstream /* WASI has no fallocate */
205int fallocate(int, int, off_t, off_t);205int fallocate(int, int, off_t, off_t);
206#define fallocate64 fallocate
207#endif206#endif
208#ifdef __wasilibc_unmodified_upstream /* WASI has no name_to_handle_at */207#ifdef __wasilibc_unmodified_upstream /* WASI has no name_to_handle_at */
209int name_to_handle_at(int, const char *, struct file_handle *, int *, int);208int name_to_handle_at(int, const char *, struct file_handle *, int *, int);
...@@ -237,6 +236,11 @@ ssize_t tee(int, int, size_t, unsigned);...@@ -237,6 +236,11 @@ ssize_t tee(int, int, size_t, unsigned);
237#define posix_fadvise64 posix_fadvise236#define posix_fadvise64 posix_fadvise
238#define posix_fallocate64 posix_fallocate237#define posix_fallocate64 posix_fallocate
239#define off64_t off_t238#define off64_t off_t
239#ifdef __wasilibc_unmodified_upstream /* WASI has no fallocate */
240#if defined(_GNU_SOURCE)
241#define fallocate64 fallocate
242#endif
243#endif
240#endif244#endif
241245
242#ifdef __cplusplus246#ifdef __cplusplus
lib/libc/wasi/libc-top-half/musl/include/limits.h-2
...@@ -65,11 +65,9 @@...@@ -65,11 +65,9 @@
6565
66/* Implementation choices... */66/* Implementation choices... */
6767
68#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
69#define PTHREAD_KEYS_MAX 12868#define PTHREAD_KEYS_MAX 128
70#define PTHREAD_STACK_MIN 204869#define PTHREAD_STACK_MIN 2048
71#define PTHREAD_DESTRUCTOR_ITERATIONS 470#define PTHREAD_DESTRUCTOR_ITERATIONS 4
72#endif
73#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)71#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
74#define SEM_VALUE_MAX 0x7fffffff72#define SEM_VALUE_MAX 0x7fffffff
75#define SEM_NSEMS_MAX 25673#define SEM_NSEMS_MAX 256
lib/libc/wasi/libc-top-half/musl/include/netdb.h created+162
...@@ -0,0 +1,162 @@
1#ifndef _NETDB_H
2#define _NETDB_H
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8#include <features.h>
9#include <netinet/in.h>
10
11#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
12#define __NEED_size_t
13#include <bits/alltypes.h>
14#endif
15
16struct addrinfo {
17 int ai_flags;
18 int ai_family;
19 int ai_socktype;
20 int ai_protocol;
21 socklen_t ai_addrlen;
22 struct sockaddr *ai_addr;
23 char *ai_canonname;
24 struct addrinfo *ai_next;
25};
26
27#define AI_PASSIVE 0x01
28#define AI_CANONNAME 0x02
29#define AI_NUMERICHOST 0x04
30#define AI_V4MAPPED 0x08
31#define AI_ALL 0x10
32#define AI_ADDRCONFIG 0x20
33#define AI_NUMERICSERV 0x400
34
35
36#define NI_NUMERICHOST 0x01
37#define NI_NUMERICSERV 0x02
38#define NI_NOFQDN 0x04
39#define NI_NAMEREQD 0x08
40#define NI_DGRAM 0x10
41#define NI_NUMERICSCOPE 0x100
42
43#define EAI_BADFLAGS -1
44#define EAI_NONAME -2
45#define EAI_AGAIN -3
46#define EAI_FAIL -4
47#define EAI_NODATA -5
48#define EAI_FAMILY -6
49#define EAI_SOCKTYPE -7
50#define EAI_SERVICE -8
51#define EAI_MEMORY -10
52#define EAI_SYSTEM -11
53#define EAI_OVERFLOW -12
54
55int getaddrinfo (const char *__restrict, const char *__restrict, const struct addrinfo *__restrict, struct addrinfo **__restrict);
56void freeaddrinfo (struct addrinfo *);
57int getnameinfo (const struct sockaddr *__restrict, socklen_t, char *__restrict, socklen_t, char *__restrict, socklen_t, int);
58const char *gai_strerror(int);
59
60
61/* Legacy functions follow (marked OBsolete in SUS) */
62
63struct netent {
64 char *n_name;
65 char **n_aliases;
66 int n_addrtype;
67 uint32_t n_net;
68};
69
70struct hostent {
71 char *h_name;
72 char **h_aliases;
73 int h_addrtype;
74 int h_length;
75 char **h_addr_list;
76};
77#define h_addr h_addr_list[0]
78
79struct servent {
80 char *s_name;
81 char **s_aliases;
82 int s_port;
83 char *s_proto;
84};
85
86struct protoent {
87 char *p_name;
88 char **p_aliases;
89 int p_proto;
90};
91
92void sethostent (int);
93void endhostent (void);
94struct hostent *gethostent (void);
95
96void setnetent (int);
97void endnetent (void);
98struct netent *getnetent (void);
99struct netent *getnetbyaddr (uint32_t, int);
100struct netent *getnetbyname (const char *);
101
102void setservent (int);
103void endservent (void);
104struct servent *getservent (void);
105struct servent *getservbyname (const char *, const char *);
106struct servent *getservbyport (int, const char *);
107
108void setprotoent (int);
109void endprotoent (void);
110struct protoent *getprotoent (void);
111struct protoent *getprotobyname (const char *);
112struct protoent *getprotobynumber (int);
113
114#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_POSIX_SOURCE) \
115 || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE+0 < 200809L) \
116 || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700)
117struct hostent *gethostbyname (const char *);
118struct hostent *gethostbyaddr (const void *, socklen_t, int);
119#ifdef __GNUC__
120__attribute__((const))
121#endif
122#ifdef __wasilibc_unmodified_upstream
123int *__h_errno_location(void);
124#define h_errno (*__h_errno_location())
125#elif (defined __wasilibc_use_wasip2)
126extern _Thread_local int h_errno;
127#define h_errno h_errno
128#endif
129#define HOST_NOT_FOUND 1
130#define TRY_AGAIN 2
131#define NO_RECOVERY 3
132#define NO_DATA 4
133#define NO_ADDRESS NO_DATA
134#endif
135
136#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
137void herror(const char *);
138const char *hstrerror(int);
139int gethostbyname_r(const char *, struct hostent *, char *, size_t, struct hostent **, int *);
140int gethostbyname2_r(const char *, int, struct hostent *, char *, size_t, struct hostent **, int *);
141struct hostent *gethostbyname2(const char *, int);
142int gethostbyaddr_r(const void *, socklen_t, int, struct hostent *, char *, size_t, struct hostent **, int *);
143int getservbyport_r(int, const char *, struct servent *, char *, size_t, struct servent **);
144int getservbyname_r(const char *, const char *, struct servent *, char *, size_t, struct servent **);
145#define EAI_NODATA -5
146#define EAI_ADDRFAMILY -9
147#define EAI_INPROGRESS -100
148#define EAI_CANCELED -101
149#define EAI_NOTCANCELED -102
150#define EAI_ALLDONE -103
151#define EAI_INTR -104
152#define EAI_IDN_ENCODE -105
153#define NI_MAXHOST 255
154#define NI_MAXSERV 32
155#endif
156
157
158#ifdef __cplusplus
159}
160#endif
161
162#endif
lib/libc/wasi/libc-top-half/musl/include/poll.h+2-2
...@@ -48,7 +48,7 @@ struct pollfd {...@@ -48,7 +48,7 @@ struct pollfd {
4848
49int poll (struct pollfd *, nfds_t, int);49int poll (struct pollfd *, nfds_t, int);
5050
51#ifdef _GNU_SOURCE51#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
52#define __NEED_time_t52#define __NEED_time_t
53#define __NEED_struct_timespec53#define __NEED_struct_timespec
54#define __NEED_sigset_t54#define __NEED_sigset_t
...@@ -57,7 +57,7 @@ int ppoll(struct pollfd *, nfds_t, const struct timespec *, const sigset_t *);...@@ -57,7 +57,7 @@ int ppoll(struct pollfd *, nfds_t, const struct timespec *, const sigset_t *);
57#endif57#endif
5858
59#if _REDIR_TIME6459#if _REDIR_TIME64
60#ifdef _GNU_SOURCE60#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
61__REDIR(ppoll, __ppoll_time64);61__REDIR(ppoll, __ppoll_time64);
62#endif62#endif
63#endif63#endif
lib/libc/wasi/libc-top-half/musl/include/pthread.h created+267
...@@ -0,0 +1,267 @@
1#ifndef _PTHREAD_H
2#define _PTHREAD_H
3#ifdef __cplusplus
4extern "C" {
5#endif
6
7#include <features.h>
8
9#define __NEED_time_t
10#define __NEED_clockid_t
11#define __NEED_struct_timespec
12#define __NEED_sigset_t
13#define __NEED_pthread_t
14#define __NEED_pthread_attr_t
15#define __NEED_pthread_mutexattr_t
16#define __NEED_pthread_condattr_t
17#define __NEED_pthread_rwlockattr_t
18#define __NEED_pthread_barrierattr_t
19#define __NEED_pthread_mutex_t
20#define __NEED_pthread_cond_t
21#define __NEED_pthread_rwlock_t
22#define __NEED_pthread_barrier_t
23#define __NEED_pthread_spinlock_t
24#define __NEED_pthread_key_t
25#define __NEED_pthread_once_t
26#define __NEED_size_t
27
28#include <bits/alltypes.h>
29
30#include <sched.h>
31#include <time.h>
32
33#define PTHREAD_CREATE_JOINABLE 0
34#define PTHREAD_CREATE_DETACHED 1
35
36#define PTHREAD_MUTEX_NORMAL 0
37#define PTHREAD_MUTEX_DEFAULT 0
38#define PTHREAD_MUTEX_RECURSIVE 1
39#define PTHREAD_MUTEX_ERRORCHECK 2
40
41#define PTHREAD_MUTEX_STALLED 0
42#define PTHREAD_MUTEX_ROBUST 1
43
44#define PTHREAD_PRIO_NONE 0
45#define PTHREAD_PRIO_INHERIT 1
46#define PTHREAD_PRIO_PROTECT 2
47
48#define PTHREAD_INHERIT_SCHED 0
49#define PTHREAD_EXPLICIT_SCHED 1
50
51#define PTHREAD_SCOPE_SYSTEM 0
52#define PTHREAD_SCOPE_PROCESS 1
53
54#define PTHREAD_PROCESS_PRIVATE 0
55#define PTHREAD_PROCESS_SHARED 1
56
57
58#define PTHREAD_MUTEX_INITIALIZER {{{0}}}
59#define PTHREAD_RWLOCK_INITIALIZER {{{0}}}
60#define PTHREAD_COND_INITIALIZER {{{0}}}
61#define PTHREAD_ONCE_INIT 0
62
63
64#define PTHREAD_CANCEL_ENABLE 0
65#define PTHREAD_CANCEL_DISABLE 1
66#define PTHREAD_CANCEL_MASKED 2
67
68#define PTHREAD_CANCEL_DEFERRED 0
69#define PTHREAD_CANCEL_ASYNCHRONOUS 1
70
71#define PTHREAD_CANCELED ((void *)-1)
72
73
74#define PTHREAD_BARRIER_SERIAL_THREAD (-1)
75
76
77#define PTHREAD_NULL ((pthread_t)0)
78
79
80#ifdef __wasilibc_unmodified_upstream
81int pthread_create(pthread_t *__restrict, const pthread_attr_t *__restrict, void *(*)(void *), void *__restrict);
82int pthread_detach(pthread_t);
83_Noreturn void pthread_exit(void *);
84int pthread_join(pthread_t, void **);
85#else
86#if defined(_REENTRANT) || !defined(_WASI_STRICT_PTHREAD)
87int pthread_create(pthread_t *__restrict, const pthread_attr_t *__restrict, void *(*)(void *), void *__restrict);
88int pthread_detach(pthread_t);
89int pthread_join(pthread_t, void **);
90#else
91#define pthread_create(...) ({ _Static_assert(0, "This function is not available on a single-threaded target; switch to a multi-threaded target with -pthread or enable a stub implementation by undefining _WASI_STRICT_PTHREAD"); 0;})
92#define pthread_detach(...) ({ _Static_assert(0, "This function is not available on a single-threaded target; switch to a multi-threaded target with -pthread or enable a stub implementation by undefining _WASI_STRICT_PTHREAD"); 0;})
93#define pthread_join(...) ({ _Static_assert(0, "This function is not available on a single-threaded target; switch to a multi-threaded target with -pthread or enable a stub implementation by undefining _WASI_STRICT_PTHREAD"); 0;})
94#endif
95#endif
96
97#ifdef __GNUC__
98__attribute__((const))
99#endif
100pthread_t pthread_self(void);
101
102int pthread_equal(pthread_t, pthread_t);
103#ifndef __cplusplus
104#define pthread_equal(x,y) ((x)==(y))
105#endif
106
107int pthread_setcancelstate(int, int *);
108int pthread_setcanceltype(int, int *);
109void pthread_testcancel(void);
110#ifdef __wasilibc_unmodified_upstream /* WASI has no cancellation support. */
111int pthread_cancel(pthread_t);
112#endif
113
114#ifdef __wasilibc_unmodified_upstream /* WASI has no CPU scheduling support. */
115int pthread_getschedparam(pthread_t, int *__restrict, struct sched_param *__restrict);
116int pthread_setschedparam(pthread_t, int, const struct sched_param *);
117#endif
118int pthread_setschedprio(pthread_t, int);
119
120int pthread_once(pthread_once_t *, void (*)(void));
121
122int pthread_mutex_init(pthread_mutex_t *__restrict, const pthread_mutexattr_t *__restrict);
123int pthread_mutex_lock(pthread_mutex_t *);
124int pthread_mutex_unlock(pthread_mutex_t *);
125int pthread_mutex_trylock(pthread_mutex_t *);
126int pthread_mutex_timedlock(pthread_mutex_t *__restrict, const struct timespec *__restrict);
127int pthread_mutex_destroy(pthread_mutex_t *);
128int pthread_mutex_consistent(pthread_mutex_t *);
129
130int pthread_mutex_getprioceiling(const pthread_mutex_t *__restrict, int *__restrict);
131int pthread_mutex_setprioceiling(pthread_mutex_t *__restrict, int, int *__restrict);
132
133int pthread_cond_init(pthread_cond_t *__restrict, const pthread_condattr_t *__restrict);
134int pthread_cond_destroy(pthread_cond_t *);
135int pthread_cond_wait(pthread_cond_t *__restrict, pthread_mutex_t *__restrict);
136int pthread_cond_timedwait(pthread_cond_t *__restrict, pthread_mutex_t *__restrict, const struct timespec *__restrict);
137int pthread_cond_broadcast(pthread_cond_t *);
138int pthread_cond_signal(pthread_cond_t *);
139
140int pthread_rwlock_init(pthread_rwlock_t *__restrict, const pthread_rwlockattr_t *__restrict);
141int pthread_rwlock_destroy(pthread_rwlock_t *);
142int pthread_rwlock_rdlock(pthread_rwlock_t *);
143int pthread_rwlock_tryrdlock(pthread_rwlock_t *);
144int pthread_rwlock_timedrdlock(pthread_rwlock_t *__restrict, const struct timespec *__restrict);
145int pthread_rwlock_wrlock(pthread_rwlock_t *);
146int pthread_rwlock_trywrlock(pthread_rwlock_t *);
147int pthread_rwlock_timedwrlock(pthread_rwlock_t *__restrict, const struct timespec *__restrict);
148int pthread_rwlock_unlock(pthread_rwlock_t *);
149
150int pthread_spin_init(pthread_spinlock_t *, int);
151int pthread_spin_destroy(pthread_spinlock_t *);
152int pthread_spin_lock(pthread_spinlock_t *);
153int pthread_spin_trylock(pthread_spinlock_t *);
154int pthread_spin_unlock(pthread_spinlock_t *);
155
156int pthread_barrier_init(pthread_barrier_t *__restrict, const pthread_barrierattr_t *__restrict, unsigned);
157int pthread_barrier_destroy(pthread_barrier_t *);
158int pthread_barrier_wait(pthread_barrier_t *);
159
160int pthread_key_create(pthread_key_t *, void (*)(void *));
161int pthread_key_delete(pthread_key_t);
162void *pthread_getspecific(pthread_key_t);
163int pthread_setspecific(pthread_key_t, const void *);
164
165int pthread_attr_init(pthread_attr_t *);
166int pthread_attr_destroy(pthread_attr_t *);
167
168int pthread_attr_getguardsize(const pthread_attr_t *__restrict, size_t *__restrict);
169int pthread_attr_setguardsize(pthread_attr_t *, size_t);
170int pthread_attr_getstacksize(const pthread_attr_t *__restrict, size_t *__restrict);
171int pthread_attr_setstacksize(pthread_attr_t *, size_t);
172int pthread_attr_getdetachstate(const pthread_attr_t *, int *);
173int pthread_attr_setdetachstate(pthread_attr_t *, int);
174int pthread_attr_getstack(const pthread_attr_t *__restrict, void **__restrict, size_t *__restrict);
175int pthread_attr_setstack(pthread_attr_t *, void *, size_t);
176int pthread_attr_getscope(const pthread_attr_t *__restrict, int *__restrict);
177int pthread_attr_setscope(pthread_attr_t *, int);
178int pthread_attr_getschedpolicy(const pthread_attr_t *__restrict, int *__restrict);
179int pthread_attr_setschedpolicy(pthread_attr_t *, int);
180#ifdef __wasilibc_unmodified_upstream /* WASI has no CPU scheduling support. */
181int pthread_attr_getschedparam(const pthread_attr_t *__restrict, struct sched_param *__restrict);
182int pthread_attr_setschedparam(pthread_attr_t *__restrict, const struct sched_param *__restrict);
183#endif
184int pthread_attr_getinheritsched(const pthread_attr_t *__restrict, int *__restrict);
185int pthread_attr_setinheritsched(pthread_attr_t *, int);
186
187int pthread_mutexattr_destroy(pthread_mutexattr_t *);
188int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *__restrict, int *__restrict);
189int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *__restrict, int *__restrict);
190int pthread_mutexattr_getpshared(const pthread_mutexattr_t *__restrict, int *__restrict);
191int pthread_mutexattr_getrobust(const pthread_mutexattr_t *__restrict, int *__restrict);
192int pthread_mutexattr_gettype(const pthread_mutexattr_t *__restrict, int *__restrict);
193int pthread_mutexattr_init(pthread_mutexattr_t *);
194int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *, int);
195int pthread_mutexattr_setprotocol(pthread_mutexattr_t *, int);
196int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int);
197int pthread_mutexattr_setrobust(pthread_mutexattr_t *, int);
198int pthread_mutexattr_settype(pthread_mutexattr_t *, int);
199
200int pthread_condattr_init(pthread_condattr_t *);
201int pthread_condattr_destroy(pthread_condattr_t *);
202int pthread_condattr_setclock(pthread_condattr_t *, clockid_t);
203int pthread_condattr_setpshared(pthread_condattr_t *, int);
204int pthread_condattr_getclock(const pthread_condattr_t *__restrict, clockid_t *__restrict);
205int pthread_condattr_getpshared(const pthread_condattr_t *__restrict, int *__restrict);
206
207int pthread_rwlockattr_init(pthread_rwlockattr_t *);
208int pthread_rwlockattr_destroy(pthread_rwlockattr_t *);
209int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int);
210int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *__restrict, int *__restrict);
211
212int pthread_barrierattr_destroy(pthread_barrierattr_t *);
213int pthread_barrierattr_getpshared(const pthread_barrierattr_t *__restrict, int *__restrict);
214int pthread_barrierattr_init(pthread_barrierattr_t *);
215int pthread_barrierattr_setpshared(pthread_barrierattr_t *, int);
216
217int pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
218
219int pthread_getconcurrency(void);
220int pthread_setconcurrency(int);
221
222int pthread_getcpuclockid(pthread_t, clockid_t *);
223
224struct __ptcb {
225 void (*__f)(void *);
226 void *__x;
227 struct __ptcb *__next;
228};
229
230void _pthread_cleanup_push(struct __ptcb *, void (*)(void *), void *);
231void _pthread_cleanup_pop(struct __ptcb *, int);
232
233#define pthread_cleanup_push(f, x) do { struct __ptcb __cb; _pthread_cleanup_push(&__cb, f, x);
234#define pthread_cleanup_pop(r) _pthread_cleanup_pop(&__cb, (r)); } while(0)
235
236#ifdef _GNU_SOURCE
237struct cpu_set_t;
238int pthread_getaffinity_np(pthread_t, size_t, struct cpu_set_t *);
239int pthread_setaffinity_np(pthread_t, size_t, const struct cpu_set_t *);
240int pthread_getattr_np(pthread_t, pthread_attr_t *);
241int pthread_setname_np(pthread_t, const char *);
242int pthread_getname_np(pthread_t, char *, size_t);
243int pthread_getattr_default_np(pthread_attr_t *);
244int pthread_setattr_default_np(const pthread_attr_t *);
245#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT) || !defined(_WASI_STRICT_PTHREAD)
246int pthread_tryjoin_np(pthread_t, void **);
247int pthread_timedjoin_np(pthread_t, void **, const struct timespec *);
248#else
249#define pthread_tryjoin_np(...) ({ _Static_assert(0, "This function is not available on a single-threaded target; switch to a multi-threaded target with -pthread or enable a stub implementation by undefining _WASI_STRICT_PTHREAD"); 0;})
250#define pthread_timedjoin_np(...) ({ _Static_assert(0, "This function is not available on a single-threaded target; switch to a multi-threaded target with -pthread or enable a stub implementation by undefining _WASI_STRICT_PTHREAD"); 0;})
251#endif
252#endif
253
254#if _REDIR_TIME64
255__REDIR(pthread_mutex_timedlock, __pthread_mutex_timedlock_time64);
256__REDIR(pthread_cond_timedwait, __pthread_cond_timedwait_time64);
257__REDIR(pthread_rwlock_timedrdlock, __pthread_rwlock_timedrdlock_time64);
258__REDIR(pthread_rwlock_timedwrlock, __pthread_rwlock_timedwrlock_time64);
259#ifdef _GNU_SOURCE
260__REDIR(pthread_timedjoin_np, __pthread_timedjoin_np_time64);
261#endif
262#endif
263
264#ifdef __cplusplus
265}
266#endif
267#endif
lib/libc/wasi/libc-top-half/musl/include/sched.h+2-2
...@@ -16,7 +16,6 @@ extern "C" {...@@ -16,7 +16,6 @@ extern "C" {
1616
17#include <bits/alltypes.h>17#include <bits/alltypes.h>
1818
19#ifdef __wasilibc_unmodified_upstream /* WASI has no CPU scheduling support. */
20struct sched_param {19struct sched_param {
21 int sched_priority;20 int sched_priority;
22 int __reserved1;21 int __reserved1;
...@@ -31,6 +30,7 @@ struct sched_param {...@@ -31,6 +30,7 @@ struct sched_param {
31 int __reserved3;30 int __reserved3;
32};31};
3332
33#ifdef __wasilibc_unmodified_upstream /* WASI has no CPU scheduling support. */
34int sched_get_priority_max(int);34int sched_get_priority_max(int);
35int sched_get_priority_min(int);35int sched_get_priority_min(int);
36int sched_getparam(pid_t, struct sched_param *);36int sched_getparam(pid_t, struct sched_param *);
...@@ -127,7 +127,7 @@ __CPU_op_func_S(XOR, ^)...@@ -127,7 +127,7 @@ __CPU_op_func_S(XOR, ^)
127#define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n)))127#define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n)))
128#define CPU_FREE(set) free(set)128#define CPU_FREE(set) free(set)
129129
130#define CPU_SETSIZE 128130#define CPU_SETSIZE 1024
131131
132#define CPU_SET(i, set) CPU_SET_S(i,sizeof(cpu_set_t),set)132#define CPU_SET(i, set) CPU_SET_S(i,sizeof(cpu_set_t),set)
133#define CPU_CLR(i, set) CPU_CLR_S(i,sizeof(cpu_set_t),set)133#define CPU_CLR(i, set) CPU_CLR_S(i,sizeof(cpu_set_t),set)
lib/libc/wasi/libc-top-half/musl/include/stdc-predef.h deleted-13
...@@ -1,13 +0,0 @@
1#ifndef _STDC_PREDEF_H
2#define _STDC_PREDEF_H
3
4#define __STDC_ISO_10646__ 201206L
5
6#if !defined(__GCC_IEC_559) || __GCC_IEC_559 > 0
7#define __STDC_IEC_559__ 1
8#endif
9
10#define __STDC_UTF_16__ 1
11#define __STDC_UTF_32__ 1
12
13#endif
lib/libc/wasi/libc-top-half/musl/include/stdlib.h+2-2
...@@ -108,7 +108,7 @@ size_t __ctype_get_mb_cur_max(void);...@@ -108,7 +108,7 @@ size_t __ctype_get_mb_cur_max(void);
108#define WTERMSIG(s) ((s) & 0x7f)108#define WTERMSIG(s) ((s) & 0x7f)
109#define WSTOPSIG(s) WEXITSTATUS(s)109#define WSTOPSIG(s) WEXITSTATUS(s)
110#define WIFEXITED(s) (!WTERMSIG(s))110#define WIFEXITED(s) (!WTERMSIG(s))
111#define WIFSTOPPED(s) ((short)((((s)&0xffff)*0x10001)>>8) > 0x7f00)111#define WIFSTOPPED(s) ((short)((((s)&0xffff)*0x10001U)>>8) > 0x7f00)
112#define WIFSIGNALED(s) (((s)&0xffff)-1U < 0xffu)112#define WIFSIGNALED(s) (((s)&0xffff)-1U < 0xffu)
113#endif113#endif
114114
...@@ -190,7 +190,7 @@ long double strtold_l(const char *__restrict, char **__restrict, struct __locale...@@ -190,7 +190,7 @@ long double strtold_l(const char *__restrict, char **__restrict, struct __locale
190#endif190#endif
191191
192#ifdef __wasilibc_unmodified_upstream /* WASI has no temp directories */192#ifdef __wasilibc_unmodified_upstream /* WASI has no temp directories */
193#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)193#if defined(_LARGEFILE64_SOURCE)
194#define mkstemp64 mkstemp194#define mkstemp64 mkstemp
195#define mkostemp64 mkostemp195#define mkostemp64 mkostemp
196#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)196#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
lib/libc/wasi/libc-top-half/musl/include/string.h+1-6
...@@ -92,6 +92,7 @@ char *strsignal(int);...@@ -92,6 +92,7 @@ char *strsignal(int);
92char *strerror_l (int, locale_t);92char *strerror_l (int, locale_t);
93int strcoll_l (const char *, const char *, locale_t);93int strcoll_l (const char *, const char *, locale_t);
94size_t strxfrm_l (char *__restrict, const char *__restrict, size_t, locale_t);94size_t strxfrm_l (char *__restrict, const char *__restrict, size_t, locale_t);
95void *memmem(const void *, size_t, const void *, size_t);
95#endif96#endif
9697
97#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \98#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
...@@ -111,14 +112,8 @@ void explicit_bzero (void *, size_t);...@@ -111,14 +112,8 @@ void explicit_bzero (void *, size_t);
111int strverscmp (const char *, const char *);112int strverscmp (const char *, const char *);
112char *strchrnul(const char *, int);113char *strchrnul(const char *, int);
113char *strcasestr(const char *, const char *);114char *strcasestr(const char *, const char *);
114void *memmem(const void *, size_t, const void *, size_t);
115void *memrchr(const void *, int, size_t);115void *memrchr(const void *, int, size_t);
116void *mempcpy(void *, const void *, size_t);116void *mempcpy(void *, const void *, size_t);
117#ifdef __wasilibc_unmodified_upstream /* avoid unprototyped decls; use <libgen.h> */
118#ifndef __cplusplus
119char *basename();
120#endif
121#endif
122#endif117#endif
123118
124#ifdef __cplusplus119#ifdef __cplusplus
lib/libc/wasi/libc-top-half/musl/include/strings.h deleted-39
...@@ -1,39 +0,0 @@
1#ifndef _STRINGS_H
2#define _STRINGS_H
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8
9#define __NEED_size_t
10#define __NEED_locale_t
11#include <bits/alltypes.h>
12
13#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_POSIX_SOURCE) \
14 || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE+0 < 200809L) \
15 || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700)
16int bcmp (const void *, const void *, size_t);
17void bcopy (const void *, void *, size_t);
18void bzero (void *, size_t);
19char *index (const char *, int);
20char *rindex (const char *, int);
21#endif
22
23#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
24int ffs (int);
25int ffsl (long);
26int ffsll (long long);
27#endif
28
29int strcasecmp (const char *, const char *);
30int strncasecmp (const char *, const char *, size_t);
31
32int strcasecmp_l (const char *, const char *, locale_t);
33int strncasecmp_l (const char *, const char *, size_t, locale_t);
34
35#ifdef __cplusplus
36}
37#endif
38
39#endif
lib/libc/wasi/libc-top-half/musl/include/sys/sendfile.h created+22
...@@ -0,0 +1,22 @@
1#ifndef _SYS_SENDFILE_H
2#define _SYS_SENDFILE_H
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8#include <features.h>
9#include <unistd.h>
10
11ssize_t sendfile(int, int, off_t *, size_t);
12
13#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
14#define sendfile64 sendfile
15#define off64_t off_t
16#endif
17
18#ifdef __cplusplus
19}
20#endif
21
22#endif
lib/libc/wasi/libc-top-half/musl/include/sys/stat.h+57
...@@ -18,6 +18,13 @@ extern "C" {...@@ -18,6 +18,13 @@ extern "C" {
18#define __NEED_blkcnt_t18#define __NEED_blkcnt_t
19#define __NEED_struct_timespec19#define __NEED_struct_timespec
2020
21#ifdef _GNU_SOURCE
22#define __NEED_int64_t
23#define __NEED_uint64_t
24#define __NEED_uint32_t
25#define __NEED_uint16_t
26#endif
27
21#include <bits/alltypes.h>28#include <bits/alltypes.h>
2229
23#include <bits/stat.h>30#include <bits/stat.h>
...@@ -112,6 +119,56 @@ int lchmod(const char *, mode_t);...@@ -112,6 +119,56 @@ int lchmod(const char *, mode_t);
112#define S_IEXEC S_IXUSR119#define S_IEXEC S_IXUSR
113#endif120#endif
114121
122#ifdef __wasilibc_unmodified_upstream /* WASI has no statx */
123#if defined(_GNU_SOURCE)
124#define STATX_TYPE 1U
125#define STATX_MODE 2U
126#define STATX_NLINK 4U
127#define STATX_UID 8U
128#define STATX_GID 0x10U
129#define STATX_ATIME 0x20U
130#define STATX_MTIME 0x40U
131#define STATX_CTIME 0x80U
132#define STATX_INO 0x100U
133#define STATX_SIZE 0x200U
134#define STATX_BLOCKS 0x400U
135#define STATX_BASIC_STATS 0x7ffU
136#define STATX_BTIME 0x800U
137#define STATX_ALL 0xfffU
138
139struct statx_timestamp {
140 int64_t tv_sec;
141 uint32_t tv_nsec, __pad;
142};
143
144struct statx {
145 uint32_t stx_mask;
146 uint32_t stx_blksize;
147 uint64_t stx_attributes;
148 uint32_t stx_nlink;
149 uint32_t stx_uid;
150 uint32_t stx_gid;
151 uint16_t stx_mode;
152 uint16_t __pad0[1];
153 uint64_t stx_ino;
154 uint64_t stx_size;
155 uint64_t stx_blocks;
156 uint64_t stx_attributes_mask;
157 struct statx_timestamp stx_atime;
158 struct statx_timestamp stx_btime;
159 struct statx_timestamp stx_ctime;
160 struct statx_timestamp stx_mtime;
161 uint32_t stx_rdev_major;
162 uint32_t stx_rdev_minor;
163 uint32_t stx_dev_major;
164 uint32_t stx_dev_minor;
165 uint64_t __pad1[14];
166};
167
168int statx(int, const char *__restrict, int, unsigned, struct statx *__restrict);
169#endif
170#endif
171
115#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)172#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
116#define stat64 stat173#define stat64 stat
117#define fstat64 fstat174#define fstat64 fstat
lib/libc/wasi/libc-top-half/musl/include/sys/statfs.h created+32
...@@ -0,0 +1,32 @@
1#ifndef _SYS_STATFS_H
2#define _SYS_STATFS_H
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8#include <features.h>
9
10#include <sys/statvfs.h>
11
12typedef struct __fsid_t {
13 int __val[2];
14} fsid_t;
15
16#include <bits/statfs.h>
17
18int statfs (const char *, struct statfs *);
19int fstatfs (int, struct statfs *);
20
21#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
22#define statfs64 statfs
23#define fstatfs64 fstatfs
24#define fsblkcnt64_t fsblkcnt_t
25#define fsfilcnt64_t fsfilcnt_t
26#endif
27
28#ifdef __cplusplus
29}
30#endif
31
32#endif
lib/libc/wasi/libc-top-half/musl/include/sys/statvfs.h+2-1
...@@ -23,7 +23,8 @@ struct statvfs {...@@ -23,7 +23,8 @@ struct statvfs {
23 unsigned long f_fsid;23 unsigned long f_fsid;
24#endif24#endif
25 unsigned long f_flag, f_namemax;25 unsigned long f_flag, f_namemax;
26 int __reserved[6];26 unsigned int f_type;
27 int __reserved[5];
27};28};
2829
29int statvfs (const char *__restrict, struct statvfs *__restrict);30int statvfs (const char *__restrict, struct statvfs *__restrict);
lib/libc/wasi/libc-top-half/musl/include/sys/uio.h+9
...@@ -36,9 +36,18 @@ ssize_t pwritev (int, const struct iovec *, int, off_t);...@@ -36,9 +36,18 @@ ssize_t pwritev (int, const struct iovec *, int, off_t);
36#endif36#endif
37#endif37#endif
3838
39#ifdef __wasilibc_unmodified_upstream // Wasm doesn't have these Linux-specific functions
39#ifdef _GNU_SOURCE40#ifdef _GNU_SOURCE
40ssize_t process_vm_writev(pid_t, const struct iovec *, unsigned long, const struct iovec *, unsigned long, unsigned long);41ssize_t process_vm_writev(pid_t, const struct iovec *, unsigned long, const struct iovec *, unsigned long, unsigned long);
41ssize_t process_vm_readv(pid_t, const struct iovec *, unsigned long, const struct iovec *, unsigned long, unsigned long);42ssize_t process_vm_readv(pid_t, const struct iovec *, unsigned long, const struct iovec *, unsigned long, unsigned long);
43ssize_t preadv2 (int, const struct iovec *, int, off_t, int);
44ssize_t pwritev2 (int, const struct iovec *, int, off_t, int);
45#define RWF_HIPRI 0x00000001
46#define RWF_DSYNC 0x00000002
47#define RWF_SYNC 0x00000004
48#define RWF_NOWAIT 0x00000008
49#define RWF_APPEND 0x00000010
50#endif
42#endif51#endif
4352
44#ifdef __cplusplus53#ifdef __cplusplus
lib/libc/wasi/libc-top-half/musl/include/unistd.h+12-2
...@@ -336,15 +336,21 @@ pid_t gettid(void);...@@ -336,15 +336,21 @@ pid_t gettid(void);
336#endif336#endif
337#define _POSIX_VDISABLE 0337#define _POSIX_VDISABLE 0
338338
339#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)339#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT) || !defined(_WASI_STRICT_PTHREAD)
340#define _POSIX_THREADS _POSIX_VERSION340#define _POSIX_THREADS _POSIX_VERSION
341#endif
342#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION341#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION
343#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION342#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION
343#endif
344#if defined(__wasilibc_unmodified_upstream) /* wasi-libc doesn't provide pthread_attr_{get,set}stackaddr */
344#define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION345#define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION
346#endif
347#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT) || !defined(_WASI_STRICT_PTHREAD)
345#define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION348#define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION
349#endif
350#if defined(__wasilibc_unmodified_upstream) /* WASI has no scheduling control, and wasi-libc doesn't provide pthread_getcpuclockid */
346#define _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_VERSION351#define _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_VERSION
347#define _POSIX_THREAD_CPUTIME _POSIX_VERSION352#define _POSIX_THREAD_CPUTIME _POSIX_VERSION
353#endif
348#define _POSIX_TIMERS _POSIX_VERSION354#define _POSIX_TIMERS _POSIX_VERSION
349#define _POSIX_TIMEOUTS _POSIX_VERSION355#define _POSIX_TIMEOUTS _POSIX_VERSION
350#define _POSIX_MONOTONIC_CLOCK _POSIX_VERSION356#define _POSIX_MONOTONIC_CLOCK _POSIX_VERSION
...@@ -529,6 +535,8 @@ pid_t gettid(void);...@@ -529,6 +535,8 @@ pid_t gettid(void);
529#define _SC_XOPEN_STREAMS 246535#define _SC_XOPEN_STREAMS 246
530#define _SC_THREAD_ROBUST_PRIO_INHERIT 247536#define _SC_THREAD_ROBUST_PRIO_INHERIT 247
531#define _SC_THREAD_ROBUST_PRIO_PROTECT 248537#define _SC_THREAD_ROBUST_PRIO_PROTECT 248
538#define _SC_MINSIGSTKSZ 249
539#define _SC_SIGSTKSZ 250
532540
533#define _CS_PATH 0541#define _CS_PATH 0
534#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 1542#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 1
...@@ -571,6 +579,8 @@ pid_t gettid(void);...@@ -571,6 +579,8 @@ pid_t gettid(void);
571#define _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS 1147579#define _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS 1147
572#define _CS_V6_ENV 1148580#define _CS_V6_ENV 1148
573#define _CS_V7_ENV 1149581#define _CS_V7_ENV 1149
582#define _CS_POSIX_V7_THREADS_CFLAGS 1150
583#define _CS_POSIX_V7_THREADS_LDFLAGS 1151
574584
575#ifdef __cplusplus585#ifdef __cplusplus
576}586}
lib/libc/wasi/libc-top-half/musl/include/wasi/libc-busywait.h created+15
...@@ -0,0 +1,15 @@
1#ifndef __wasi_libc_busywait_h
2#define __wasi_libc_busywait_h
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8/// Enable busywait in futex on current thread.
9void __wasilibc_enable_futex_busywait_on_current_thread(void);
10
11#ifdef __cplusplus
12}
13#endif
14
15#endif
lib/libc/wasi/libc-top-half/musl/src/conf/confstr.c deleted-17
...@@ -1,17 +0,0 @@
1#include <unistd.h>
2#include <stdio.h>
3#include <errno.h>
4
5size_t confstr(int name, char *buf, size_t len)
6{
7 const char *s = "";
8 if (!name) {
9 s = "/bin:/usr/bin";
10 } else if ((name&~4U)!=1 && name-_CS_POSIX_V6_ILP32_OFF32_CFLAGS>33U) {
11 errno = EINVAL;
12 return 0;
13 }
14 // snprintf is overkill but avoid wasting code size to implement
15 // this completely useless function and its truncation semantics
16 return snprintf(buf, len, "%s", s) + 1;
17}
lib/libc/wasi/libc-top-half/musl/src/conf/sysconf.c+15
...@@ -9,6 +9,7 @@...@@ -9,6 +9,7 @@
9#endif9#endif
10#include <sys/sysinfo.h>10#include <sys/sysinfo.h>
11#ifdef __wasilibc_unmodified_upstream11#ifdef __wasilibc_unmodified_upstream
12#include <sys/auxv.h>
12#include "syscall.h"13#include "syscall.h"
13#endif14#endif
14#include "libc.h"15#include "libc.h"
...@@ -29,6 +30,8 @@...@@ -29,6 +30,8 @@
29#define JT_AVPHYS_PAGES JT(9)30#define JT_AVPHYS_PAGES JT(9)
30#define JT_ZERO JT(10)31#define JT_ZERO JT(10)
31#define JT_DELAYTIMER_MAX JT(11)32#define JT_DELAYTIMER_MAX JT(11)
33#define JT_MINSIGSTKSZ JT(12)
34#define JT_SIGSTKSZ JT(13)
3235
33#define RLIM(x) (-32768|(RLIMIT_ ## x))36#define RLIM(x) (-32768|(RLIMIT_ ## x))
3437
...@@ -211,6 +214,9 @@ long sysconf(int name)...@@ -211,6 +214,9 @@ long sysconf(int name)
211 [_SC_XOPEN_STREAMS] = JT_ZERO,214 [_SC_XOPEN_STREAMS] = JT_ZERO,
212 [_SC_THREAD_ROBUST_PRIO_INHERIT] = -1,215 [_SC_THREAD_ROBUST_PRIO_INHERIT] = -1,
213 [_SC_THREAD_ROBUST_PRIO_PROTECT] = -1,216 [_SC_THREAD_ROBUST_PRIO_PROTECT] = -1,
217
218 [_SC_MINSIGSTKSZ] = JT_MINSIGSTKSZ,
219 [_SC_SIGSTKSZ] = JT_SIGSTKSZ,
214 };220 };
215221
216 if (name >= sizeof(values)/sizeof(values[0]) || !values[name]) {222 if (name >= sizeof(values)/sizeof(values[0]) || !values[name]) {
...@@ -278,5 +284,14 @@ long sysconf(int name)...@@ -278,5 +284,14 @@ long sysconf(int name)
278 case JT_ZERO & 255:284 case JT_ZERO & 255:
279 return 0;285 return 0;
280 }286 }
287#ifdef __wasilibc_unmodified_upstream // WASI has no auxv
288 case JT_MINSIGSTKSZ & 255:
289 case JT_SIGSTKSZ & 255: ;
290 long val = __getauxval(AT_MINSIGSTKSZ);
291 if (val < MINSIGSTKSZ) val = MINSIGSTKSZ;
292 if (values[name] == JT_SIGSTKSZ)
293 val += SIGSTKSZ - MINSIGSTKSZ;
294 return val;
295#endif
281 return values[name];296 return values[name];
282}297}
lib/libc/wasi/libc-top-half/musl/src/env/__stack_chk_fail.c+10
...@@ -38,12 +38,22 @@ hidden void __stack_chk_fail_local(void);...@@ -38,12 +38,22 @@ hidden void __stack_chk_fail_local(void);
38weak_alias(__stack_chk_fail, __stack_chk_fail_local);38weak_alias(__stack_chk_fail, __stack_chk_fail_local);
3939
40#ifndef __wasilibc_unmodified_upstream40#ifndef __wasilibc_unmodified_upstream
41#ifdef __wasilibc_use_wasip2
42# include <wasi/libc.h>
43#else
41# include <wasi/api.h>44# include <wasi/api.h>
45#endif
4246
43__attribute__((constructor(60)))47__attribute__((constructor(60)))
44static void __wasilibc_init_ssp(void) {48static void __wasilibc_init_ssp(void) {
45 uintptr_t entropy;49 uintptr_t entropy;
50#ifdef __wasilibc_use_wasip2
51 int len = sizeof(uintptr_t);
52
53 int r = __wasilibc_random(&entropy, len);
54#else
46 int r = __wasi_random_get((uint8_t *)&entropy, sizeof(uintptr_t));55 int r = __wasi_random_get((uint8_t *)&entropy, sizeof(uintptr_t));
56#endif
47 __init_ssp(r ? NULL : &entropy);57 __init_ssp(r ? NULL : &entropy);
48}58}
49#endif59#endif
lib/libc/wasi/libc-top-half/musl/src/include/pthread.h created+31
...@@ -0,0 +1,31 @@
1#ifndef PTHREAD_H
2#define PTHREAD_H
3
4#include "../../include/pthread.h"
5
6hidden int __pthread_once(pthread_once_t *, void (*)(void));
7hidden void __pthread_testcancel(void);
8hidden int __pthread_setcancelstate(int, int *);
9hidden int __pthread_create(pthread_t *restrict, const pthread_attr_t *restrict, void *(*)(void *), void *restrict);
10#ifdef __wasilibc_unmodified_upstream
11hidden _Noreturn void __pthread_exit(void *);
12#endif
13hidden int __pthread_join(pthread_t, void **);
14hidden int __pthread_mutex_lock(pthread_mutex_t *);
15hidden int __pthread_mutex_trylock(pthread_mutex_t *);
16hidden int __pthread_mutex_trylock_owner(pthread_mutex_t *);
17hidden int __pthread_mutex_timedlock(pthread_mutex_t *restrict, const struct timespec *restrict);
18hidden int __pthread_mutex_unlock(pthread_mutex_t *);
19hidden int __private_cond_signal(pthread_cond_t *, int);
20hidden int __pthread_cond_timedwait(pthread_cond_t *restrict, pthread_mutex_t *restrict, const struct timespec *restrict);
21hidden int __pthread_key_create(pthread_key_t *, void (*)(void *));
22hidden int __pthread_key_delete(pthread_key_t);
23hidden int __pthread_rwlock_rdlock(pthread_rwlock_t *);
24hidden int __pthread_rwlock_tryrdlock(pthread_rwlock_t *);
25hidden int __pthread_rwlock_timedrdlock(pthread_rwlock_t *__restrict, const struct timespec *__restrict);
26hidden int __pthread_rwlock_wrlock(pthread_rwlock_t *);
27hidden int __pthread_rwlock_trywrlock(pthread_rwlock_t *);
28hidden int __pthread_rwlock_timedwrlock(pthread_rwlock_t *__restrict, const struct timespec *__restrict);
29hidden int __pthread_rwlock_unlock(pthread_rwlock_t *);
30
31#endif
lib/libc/wasi/libc-top-half/musl/src/include/time.h created+15
...@@ -0,0 +1,15 @@
1#ifndef TIME_H
2#define TIME_H
3
4#include "../../include/time.h"
5
6hidden int __clock_gettime(clockid_t, struct timespec *);
7hidden int __clock_nanosleep(clockid_t, int, const struct timespec *, struct timespec *);
8
9hidden char *__asctime_r(const struct tm *, char *);
10hidden struct tm *__gmtime_r(const time_t *restrict, struct tm *restrict);
11hidden struct tm *__localtime_r(const time_t *restrict, struct tm *restrict);
12
13hidden size_t __strftime_l(char *restrict, size_t, const char *restrict, const struct tm *restrict, locale_t);
14
15#endif
lib/libc/wasi/libc-top-half/musl/src/internal/fork_impl.h+3-1
...@@ -3,7 +3,6 @@...@@ -3,7 +3,6 @@
3#ifdef __wasilibc_unmodified_upstream3#ifdef __wasilibc_unmodified_upstream
4extern hidden volatile int *const __at_quick_exit_lockptr;4extern hidden volatile int *const __at_quick_exit_lockptr;
5extern hidden volatile int *const __atexit_lockptr;5extern hidden volatile int *const __atexit_lockptr;
6extern hidden volatile int *const __dlerror_lockptr;
7extern hidden volatile int *const __gettext_lockptr;6extern hidden volatile int *const __gettext_lockptr;
8extern hidden volatile int *const __locale_lockptr;7extern hidden volatile int *const __locale_lockptr;
9extern hidden volatile int *const __random_lockptr;8extern hidden volatile int *const __random_lockptr;
...@@ -18,4 +17,7 @@ extern hidden volatile int *const __vmlock_lockptr;...@@ -18,4 +17,7 @@ extern hidden volatile int *const __vmlock_lockptr;
1817
19hidden void __malloc_atfork(int);18hidden void __malloc_atfork(int);
20hidden void __ldso_atfork(int);19hidden void __ldso_atfork(int);
20hidden void __pthread_key_atfork(int);
21
22hidden void __post_Fork(int);
21#endif23#endif
lib/libc/wasi/libc-top-half/musl/src/internal/ksigaction.h deleted-13
...@@ -1,13 +0,0 @@
1#include <features.h>
2
3/* This is the structure used for the rt_sigaction syscall on most archs,
4 * but it can be overridden by a file with the same name in the top-level
5 * arch dir for a given arch, if necessary. */
6struct k_sigaction {
7 void (*handler)(int);
8 unsigned long flags;
9 void (*restorer)(void);
10 unsigned mask[2];
11};
12
13hidden void __restore(), __restore_rt();
lib/libc/wasi/libc-top-half/musl/src/internal/locale_impl.h+1-1
...@@ -64,7 +64,7 @@ hidden char *__gettextdomain(void);...@@ -64,7 +64,7 @@ hidden char *__gettextdomain(void);
64 &libc.current_locale; \64 &libc.current_locale; \
65 }))65 }))
6666
67#define CURRENT_UTF8 (!!libc.global_locale.cat[LC_CTYPE])67#define CURRENT_UTF8 (!!CURRENT_LOCALE->cat[LC_CTYPE])
68#endif68#endif
6969
70#undef MB_CUR_MAX70#undef MB_CUR_MAX
lib/libc/wasi/libc-top-half/musl/src/internal/pthread_impl.h+2
...@@ -186,8 +186,10 @@ static inline void __wake(volatile void *addr, int cnt, int priv)...@@ -186,8 +186,10 @@ static inline void __wake(volatile void *addr, int cnt, int priv)
186 __syscall(SYS_futex, addr, FUTEX_WAKE|priv, cnt) != -ENOSYS ||186 __syscall(SYS_futex, addr, FUTEX_WAKE|priv, cnt) != -ENOSYS ||
187 __syscall(SYS_futex, addr, FUTEX_WAKE, cnt);187 __syscall(SYS_futex, addr, FUTEX_WAKE, cnt);
188#else188#else
189#ifdef _REENTRANT
189 __builtin_wasm_memory_atomic_notify((int*)addr, cnt);190 __builtin_wasm_memory_atomic_notify((int*)addr, cnt);
190#endif191#endif
192#endif
191}193}
192static inline void __futexwait(volatile void *addr, int val, int priv)194static inline void __futexwait(volatile void *addr, int val, int priv)
193{195{
lib/libc/wasi/libc-top-half/musl/src/internal/syscall.h+25-13
...@@ -59,7 +59,7 @@ hidden long __syscall_ret(unsigned long),...@@ -59,7 +59,7 @@ hidden long __syscall_ret(unsigned long),
59#define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__)59#define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__)
60#define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__))60#define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__))
6161
62static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, long c, long d, long e, long f)62static inline long __alt_socketcall(int sys, int sock, int cp, syscall_arg_t a, syscall_arg_t b, syscall_arg_t c, syscall_arg_t d, syscall_arg_t e, syscall_arg_t f)
63{63{
64 long r;64 long r;
65 if (cp) r = __syscall_cp(sys, a, b, c, d, e, f);65 if (cp) r = __syscall_cp(sys, a, b, c, d, e, f);
...@@ -72,9 +72,9 @@ static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, l...@@ -72,9 +72,9 @@ static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, l
72 return r;72 return r;
73}73}
74#define __socketcall(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 0, \74#define __socketcall(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 0, \
75 (long)(a), (long)(b), (long)(c), (long)(d), (long)(e), (long)(f))75 __scc(a), __scc(b), __scc(c), __scc(d), __scc(e), __scc(f))
76#define __socketcall_cp(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 1, \76#define __socketcall_cp(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 1, \
77 (long)(a), (long)(b), (long)(c), (long)(d), (long)(e), (long)(f))77 __scc(a), __scc(b), __scc(c), __scc(d), __scc(e), __scc(f))
7878
79/* fixup legacy 16-bit junk */79/* fixup legacy 16-bit junk */
8080
...@@ -202,43 +202,43 @@ static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, l...@@ -202,43 +202,43 @@ static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, l
202#define SYS_sendfile SYS_sendfile64202#define SYS_sendfile SYS_sendfile64
203#endif203#endif
204204
205#ifndef SYS_timer_settime205#ifdef SYS_timer_settime32
206#define SYS_timer_settime SYS_timer_settime32206#define SYS_timer_settime SYS_timer_settime32
207#endif207#endif
208208
209#ifndef SYS_timer_gettime209#ifdef SYS_timer_gettime32
210#define SYS_timer_gettime SYS_timer_gettime32210#define SYS_timer_gettime SYS_timer_gettime32
211#endif211#endif
212212
213#ifndef SYS_timerfd_settime213#ifdef SYS_timerfd_settime32
214#define SYS_timerfd_settime SYS_timerfd_settime32214#define SYS_timerfd_settime SYS_timerfd_settime32
215#endif215#endif
216216
217#ifndef SYS_timerfd_gettime217#ifdef SYS_timerfd_gettime32
218#define SYS_timerfd_gettime SYS_timerfd_gettime32218#define SYS_timerfd_gettime SYS_timerfd_gettime32
219#endif219#endif
220220
221#ifndef SYS_clock_settime221#ifdef SYS_clock_settime32
222#define SYS_clock_settime SYS_clock_settime32222#define SYS_clock_settime SYS_clock_settime32
223#endif223#endif
224224
225#ifndef SYS_clock_gettime225#ifdef SYS_clock_gettime32
226#define SYS_clock_gettime SYS_clock_gettime32226#define SYS_clock_gettime SYS_clock_gettime32
227#endif227#endif
228228
229#ifndef SYS_clock_getres229#ifdef SYS_clock_getres_time32
230#define SYS_clock_getres SYS_clock_getres_time32230#define SYS_clock_getres SYS_clock_getres_time32
231#endif231#endif
232232
233#ifndef SYS_clock_nanosleep233#ifdef SYS_clock_nanosleep_time32
234#define SYS_clock_nanosleep SYS_clock_nanosleep_time32234#define SYS_clock_nanosleep SYS_clock_nanosleep_time32
235#endif235#endif
236236
237#ifndef SYS_gettimeofday237#ifdef SYS_gettimeofday_time32
238#define SYS_gettimeofday SYS_gettimeofday_time32238#define SYS_gettimeofday SYS_gettimeofday_time32
239#endif239#endif
240240
241#ifndef SYS_settimeofday241#ifdef SYS_settimeofday_time32
242#define SYS_settimeofday SYS_settimeofday_time32242#define SYS_settimeofday SYS_settimeofday_time32
243#endif243#endif
244244
...@@ -392,6 +392,18 @@ static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, l...@@ -392,6 +392,18 @@ static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, l
392#define __sys_open_cp(...) __SYSCALL_DISP(__sys_open_cp,,__VA_ARGS__)392#define __sys_open_cp(...) __SYSCALL_DISP(__sys_open_cp,,__VA_ARGS__)
393#define sys_open_cp(...) __syscall_ret(__sys_open_cp(__VA_ARGS__))393#define sys_open_cp(...) __syscall_ret(__sys_open_cp(__VA_ARGS__))
394394
395#ifdef SYS_wait4
396#define __sys_wait4(a,b,c,d) __syscall(SYS_wait4,a,b,c,d)
397#define __sys_wait4_cp(a,b,c,d) __syscall_cp(SYS_wait4,a,b,c,d)
398#else
399hidden long __emulate_wait4(int, int *, int, void *, int);
400#define __sys_wait4(a,b,c,d) __emulate_wait4(a,b,c,d,0)
401#define __sys_wait4_cp(a,b,c,d) __emulate_wait4(a,b,c,d,1)
402#endif
403
404#define sys_wait4(a,b,c,d) __syscall_ret(__sys_wait4(a,b,c,d))
405#define sys_wait4_cp(a,b,c,d) __syscall_ret(__sys_wait4_cp(a,b,c,d))
406
395hidden void __procfdname(char __buf[static 15+3*sizeof(int)], unsigned);407hidden void __procfdname(char __buf[static 15+3*sizeof(int)], unsigned);
396408
397hidden void *__vdsosym(const char *, const char *);409hidden void *__vdsosym(const char *, const char *);
lib/libc/wasi/libc-top-half/musl/src/math/powl.c+21-13
...@@ -216,25 +216,33 @@ long double powl(long double x, long double y)...@@ -216,25 +216,33 @@ long double powl(long double x, long double y)
216 }216 }
217 if (x == 1.0)217 if (x == 1.0)
218 return 1.0; /* 1**y = 1, even if y is nan */218 return 1.0; /* 1**y = 1, even if y is nan */
219 if (x == -1.0 && !isfinite(y))
220 return 1.0; /* -1**inf = 1 */
221 if (y == 0.0)219 if (y == 0.0)
222 return 1.0; /* x**0 = 1, even if x is nan */220 return 1.0; /* x**0 = 1, even if x is nan */
223 if (y == 1.0)221 if (y == 1.0)
224 return x;222 return x;
225 if (y >= LDBL_MAX) {223 /* if y*log2(x) < log2(LDBL_TRUE_MIN)-1 then x^y uflows to 0
226 if (x > 1.0 || x < -1.0)224 if y*log2(x) > -log2(LDBL_TRUE_MIN)+1 > LDBL_MAX_EXP then x^y oflows
227 return INFINITY;225 if |x|!=1 then |log2(x)| > |log(x)| > LDBL_EPSILON/2 so
228 if (x != 0.0)226 x^y oflows/uflows if |y|*LDBL_EPSILON/2 > -log2(LDBL_TRUE_MIN)+1 */
229 return 0.0;227 if (fabsl(y) > 2*(-LDBL_MIN_EXP+LDBL_MANT_DIG+1)/LDBL_EPSILON) {
230 }228 /* y is not an odd int */
231 if (y <= -LDBL_MAX) {229 if (x == -1.0)
232 if (x > 1.0 || x < -1.0)230 return 1.0;
231 if (y == INFINITY) {
232 if (x > 1.0 || x < -1.0)
233 return INFINITY;
233 return 0.0;234 return 0.0;
234 if (x != 0.0 || y == -INFINITY)235 }
236 if (y == -INFINITY) {
237 if (x > 1.0 || x < -1.0)
238 return 0.0;
235 return INFINITY;239 return INFINITY;
240 }
241 if ((x > 1.0 || x < -1.0) == (y > 0))
242 return huge * huge;
243 return twom10000 * twom10000;
236 }244 }
237 if (x >= LDBL_MAX) {245 if (x == INFINITY) {
238 if (y > 0.0)246 if (y > 0.0)
239 return INFINITY;247 return INFINITY;
240 return 0.0;248 return 0.0;
...@@ -257,7 +265,7 @@ long double powl(long double x, long double y)...@@ -257,7 +265,7 @@ long double powl(long double x, long double y)
257 yoddint = 1;265 yoddint = 1;
258 }266 }
259267
260 if (x <= -LDBL_MAX) {268 if (x == -INFINITY) {
261 if (y > 0.0) {269 if (y > 0.0) {
262 if (yoddint)270 if (yoddint)
263 return -INFINITY;271 return -INFINITY;
lib/libc/wasi/libc-top-half/musl/src/misc/nftw.c+3-1
...@@ -33,6 +33,8 @@ static int do_nftw(char *path, int (*fn)(const char *, const struct stat *, int,...@@ -33,6 +33,8 @@ static int do_nftw(char *path, int (*fn)(const char *, const struct stat *, int,
33 int err;33 int err;
34 struct FTW lev;34 struct FTW lev;
3535
36 st.st_dev = st.st_ino = 0;
37
36 if ((flags & FTW_PHYS) ? lstat(path, &st) : stat(path, &st) < 0) {38 if ((flags & FTW_PHYS) ? lstat(path, &st) : stat(path, &st) < 0) {
37 if (!(flags & FTW_PHYS) && errno==ENOENT && !lstat(path, &st))39 if (!(flags & FTW_PHYS) && errno==ENOENT && !lstat(path, &st))
38 type = FTW_SLN;40 type = FTW_SLN;
...@@ -48,7 +50,7 @@ static int do_nftw(char *path, int (*fn)(const char *, const struct stat *, int,...@@ -48,7 +50,7 @@ static int do_nftw(char *path, int (*fn)(const char *, const struct stat *, int,
48 type = FTW_F;50 type = FTW_F;
49 }51 }
5052
51 if ((flags & FTW_MOUNT) && h && st.st_dev != h->dev)53 if ((flags & FTW_MOUNT) && h && type != FTW_NS && st.st_dev != h->dev)
52 return 0;54 return 0;
53 55
54 new.chain = h;56 new.chain = h;
lib/libc/wasi/libc-top-half/musl/src/regex/glob.c+1-1
...@@ -271,7 +271,7 @@ int glob(const char *restrict pat, int flags, int (*errfunc)(const char *path, i...@@ -271,7 +271,7 @@ int glob(const char *restrict pat, int flags, int (*errfunc)(const char *path, i
271 if (append(&tail, pat, strlen(pat), 0))271 if (append(&tail, pat, strlen(pat), 0))
272 return GLOB_NOSPACE;272 return GLOB_NOSPACE;
273 cnt++;273 cnt++;
274 } else274 } else if (!error)
275 return GLOB_NOMATCH;275 return GLOB_NOMATCH;
276 }276 }
277277
lib/libc/wasi/libc-top-half/musl/src/setjmp/wasm32/rt.c created+83
...@@ -0,0 +1,83 @@
1/*
2 * a runtime implementation for
3 * https://github.com/llvm/llvm-project/pull/84137
4 * https://docs.google.com/document/d/1ZvTPT36K5jjiedF8MCXbEmYjULJjI723aOAks1IdLLg/edit
5 */
6
7#include <stddef.h>
8#include <stdint.h>
9
10/*
11 * function prototypes
12 */
13void __wasm_setjmp(void *env, uint32_t label, void *func_invocation_id);
14uint32_t __wasm_setjmp_test(void *env, void *func_invocation_id);
15void __wasm_longjmp(void *env, int val);
16
17/*
18 * jmp_buf should have large enough size and alignment to contain
19 * this structure.
20 */
21struct jmp_buf_impl {
22 void *func_invocation_id;
23 uint32_t label;
24
25 /*
26 * this is a temorary storage used by the communication between
27 * __wasm_sjlj_longjmp and WebAssemblyLowerEmscriptenEHSjL-generated
28 * logic.
29 * ideally, this can be replaced with multivalue.
30 */
31 struct arg {
32 void *env;
33 int val;
34 } arg;
35};
36
37void
38__wasm_setjmp(void *env, uint32_t label, void *func_invocation_id)
39{
40 struct jmp_buf_impl *jb = env;
41 if (label == 0) { /* ABI contract */
42 __builtin_trap();
43 }
44 if (func_invocation_id == NULL) { /* sanity check */
45 __builtin_trap();
46 }
47 jb->func_invocation_id = func_invocation_id;
48 jb->label = label;
49}
50
51uint32_t
52__wasm_setjmp_test(void *env, void *func_invocation_id)
53{
54 struct jmp_buf_impl *jb = env;
55 if (jb->label == 0) { /* ABI contract */
56 __builtin_trap();
57 }
58 if (func_invocation_id == NULL) { /* sanity check */
59 __builtin_trap();
60 }
61 if (jb->func_invocation_id == func_invocation_id) {
62 return jb->label;
63 }
64 return 0;
65}
66
67void
68__wasm_longjmp(void *env, int val)
69{
70 struct jmp_buf_impl *jb = env;
71 struct arg *arg = &jb->arg;
72 /*
73 * C standard says:
74 * The longjmp function cannot cause the setjmp macro to return
75 * the value 0; if val is 0, the setjmp macro returns the value 1.
76 */
77 if (val == 0) {
78 val = 1;
79 }
80 arg->env = env;
81 arg->val = val;
82 __builtin_wasm_throw(1, arg); /* 1 == C_LONGJMP */
83}
lib/libc/wasi/libc-top-half/musl/src/stdio/freopen.c+2
...@@ -67,6 +67,8 @@ FILE *freopen(const char *restrict filename, const char *restrict mode, FILE *re...@@ -67,6 +67,8 @@ FILE *freopen(const char *restrict filename, const char *restrict mode, FILE *re
67 fclose(f2);67 fclose(f2);
68 }68 }
6969
70 f->mode = 0;
71 f->locale = 0;
70 FUNLOCK(f);72 FUNLOCK(f);
71 return f;73 return f;
7274
lib/libc/wasi/libc-top-half/musl/src/stdio/open_wmemstream.c+5-1
...@@ -48,8 +48,12 @@ fail:...@@ -48,8 +48,12 @@ fail:
48static size_t wms_write(FILE *f, const unsigned char *buf, size_t len)48static size_t wms_write(FILE *f, const unsigned char *buf, size_t len)
49{49{
50 struct cookie *c = f->cookie;50 struct cookie *c = f->cookie;
51 size_t len2;51 size_t len2 = f->wpos - f->wbase;
52 wchar_t *newbuf;52 wchar_t *newbuf;
53 if (len2) {
54 f->wpos = f->wbase;
55 if (wms_write(f, f->wbase, len2) < len2) return 0;
56 }
53 if (len + c->pos >= c->space) {57 if (len + c->pos >= c->space) {
54 len2 = 2*c->space+1 | c->pos+len+1;58 len2 = 2*c->space+1 | c->pos+len+1;
55 if (len2 > SSIZE_MAX/4) return 0;59 if (len2 > SSIZE_MAX/4) return 0;
lib/libc/wasi/libc-top-half/musl/src/stdio/ungetc.c deleted-20
...@@ -1,20 +0,0 @@
1#include "stdio_impl.h"
2
3int ungetc(int c, FILE *f)
4{
5 if (c == EOF) return c;
6
7 FLOCK(f);
8
9 if (!f->rpos) __toread(f);
10 if (!f->rpos || f->rpos <= f->buf - UNGET) {
11 FUNLOCK(f);
12 return EOF;
13 }
14
15 *--f->rpos = c;
16 f->flags &= ~F_EOF;
17
18 FUNLOCK(f);
19 return (unsigned char)c;
20}
lib/libc/wasi/libc-top-half/musl/src/stdio/vfprintf.c+19-12
...@@ -56,7 +56,7 @@ static const unsigned char states[]['z'-'A'+1] = {...@@ -56,7 +56,7 @@ static const unsigned char states[]['z'-'A'+1] = {
56 S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,56 S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
57 S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,57 S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
58 S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,58 S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
59 S('c') = CHAR, S('C') = INT,59 S('c') = INT, S('C') = UINT,
60 S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,60 S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
61 S('m') = NOARG,61 S('m') = NOARG,
62 S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,62 S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
...@@ -66,7 +66,7 @@ static const unsigned char states[]['z'-'A'+1] = {...@@ -66,7 +66,7 @@ static const unsigned char states[]['z'-'A'+1] = {
66 S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,66 S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
67 S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,67 S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
68 S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,68 S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
69 S('c') = INT, S('s') = PTR, S('n') = PTR,69 S('c') = UINT, S('s') = PTR, S('n') = PTR,
70 S('l') = LLPRE,70 S('l') = LLPRE,
71 }, { /* 2: ll-prefixed */71 }, { /* 2: ll-prefixed */
72 S('d') = LLONG, S('i') = LLONG,72 S('d') = LLONG, S('i') = LLONG,
...@@ -152,7 +152,7 @@ static void pop_arg(union arg *arg, int type, va_list *ap)...@@ -152,7 +152,7 @@ static void pop_arg(union arg *arg, int type, va_list *ap)
152152
153static void out(FILE *f, const char *s, size_t l)153static void out(FILE *f, const char *s, size_t l)
154{154{
155 if (!(f->flags & F_ERR)) __fwritex((void *)s, l, f);155 if (!ferror(f)) __fwritex((void *)s, l, f);
156}156}
157157
158static void pad(FILE *f, char c, int w, int l, int fl)158static void pad(FILE *f, char c, int w, int l, int fl)
...@@ -476,7 +476,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,...@@ -476,7 +476,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
476 unsigned st, ps;476 unsigned st, ps;
477 int cnt=0, l=0;477 int cnt=0, l=0;
478 size_t i;478 size_t i;
479 char buf[sizeof(uintmax_t)*3+3+LDBL_MANT_DIG/4];479 char buf[sizeof(uintmax_t)*3];
480 const char *prefix;480 const char *prefix;
481 int t, pl;481 int t, pl;
482 wchar_t wc[2], *ws;482 wchar_t wc[2], *ws;
...@@ -517,8 +517,8 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,...@@ -517,8 +517,8 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
517 if (*s=='*') {517 if (*s=='*') {
518 if (isdigit(s[1]) && s[2]=='$') {518 if (isdigit(s[1]) && s[2]=='$') {
519 l10n=1;519 l10n=1;
520 nl_type[s[1]-'0'] = INT;520 if (!f) nl_type[s[1]-'0'] = INT, w = 0;
521 w = nl_arg[s[1]-'0'].i;521 else w = nl_arg[s[1]-'0'].i;
522 s+=3;522 s+=3;
523 } else if (!l10n) {523 } else if (!l10n) {
524 w = f ? va_arg(*ap, int) : 0;524 w = f ? va_arg(*ap, int) : 0;
...@@ -530,8 +530,8 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,...@@ -530,8 +530,8 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
530 /* Read precision */530 /* Read precision */
531 if (*s=='.' && s[1]=='*') {531 if (*s=='.' && s[1]=='*') {
532 if (isdigit(s[2]) && s[3]=='$') {532 if (isdigit(s[2]) && s[3]=='$') {
533 nl_type[s[2]-'0'] = INT;533 if (!f) nl_type[s[2]-'0'] = INT, p = 0;
534 p = nl_arg[s[2]-'0'].i;534 else p = nl_arg[s[2]-'0'].i;
535 s+=4;535 s+=4;
536 } else if (!l10n) {536 } else if (!l10n) {
537 p = f ? va_arg(*ap, int) : 0;537 p = f ? va_arg(*ap, int) : 0;
...@@ -560,13 +560,18 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,...@@ -560,13 +560,18 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
560 if (st==NOARG) {560 if (st==NOARG) {
561 if (argpos>=0) goto inval;561 if (argpos>=0) goto inval;
562 } else {562 } else {
563 if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos];563 if (argpos>=0) {
564 else if (f) pop_arg(&arg, st, ap);564 if (!f) nl_type[argpos]=st;
565 else arg=nl_arg[argpos];
566 } else if (f) pop_arg(&arg, st, ap);
565 else return 0;567 else return 0;
566 }568 }
567569
568 if (!f) continue;570 if (!f) continue;
569571
572 /* Do not process any new directives once in error state. */
573 if (ferror(f)) return -1;
574
570 z = buf + sizeof(buf);575 z = buf + sizeof(buf);
571 prefix = "-+ 0X0x";576 prefix = "-+ 0X0x";
572 pl = 0;577 pl = 0;
...@@ -622,6 +627,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,...@@ -622,6 +627,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
622 }627 }
623 p = MAX(p, z-a + !arg.i);628 p = MAX(p, z-a + !arg.i);
624 break;629 break;
630 narrow_c:
625 case 'c':631 case 'c':
626 *(a=z-(p=1))=arg.i;632 *(a=z-(p=1))=arg.i;
627 fl &= ~ZERO_PAD;633 fl &= ~ZERO_PAD;
...@@ -636,6 +642,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,...@@ -636,6 +642,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg,
636 fl &= ~ZERO_PAD;642 fl &= ~ZERO_PAD;
637 break;643 break;
638 case 'C':644 case 'C':
645 if (!arg.i) goto narrow_c;
639 wc[0] = arg.i;646 wc[0] = arg.i;
640 wc[1] = 0;647 wc[1] = 0;
641 arg.p = wc;648 arg.p = wc;
...@@ -713,7 +720,7 @@ int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap)...@@ -713,7 +720,7 @@ int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap)
713720
714 FLOCK(f);721 FLOCK(f);
715 olderr = f->flags & F_ERR;722 olderr = f->flags & F_ERR;
716 if (f->mode < 1) f->flags &= ~F_ERR;723 f->flags &= ~F_ERR;
717 if (!f->buf_size) {724 if (!f->buf_size) {
718 saved_buf = f->buf;725 saved_buf = f->buf;
719 f->buf = internal_buf;726 f->buf = internal_buf;
...@@ -729,7 +736,7 @@ int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap)...@@ -729,7 +736,7 @@ int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap)
729 f->buf_size = 0;736 f->buf_size = 0;
730 f->wpos = f->wbase = f->wend = 0;737 f->wpos = f->wbase = f->wend = 0;
731 }738 }
732 if (f->flags & F_ERR) ret = -1;739 if (ferror(f)) ret = -1;
733 f->flags |= olderr;740 f->flags |= olderr;
734 FUNLOCK(f);741 FUNLOCK(f);
735 va_end(ap2);742 va_end(ap2);
lib/libc/wasi/libc-top-half/musl/src/stdio/vfwprintf.c+25-18
...@@ -49,7 +49,7 @@ static const unsigned char states[]['z'-'A'+1] = {...@@ -49,7 +49,7 @@ static const unsigned char states[]['z'-'A'+1] = {
49 S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,49 S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
50 S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,50 S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
51 S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,51 S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
52 S('c') = CHAR, S('C') = INT,52 S('c') = INT, S('C') = UINT,
53 S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,53 S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
54 S('m') = NOARG,54 S('m') = NOARG,
55 S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,55 S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
...@@ -59,7 +59,7 @@ static const unsigned char states[]['z'-'A'+1] = {...@@ -59,7 +59,7 @@ static const unsigned char states[]['z'-'A'+1] = {
59 S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,59 S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
60 S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,60 S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
61 S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,61 S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
62 S('c') = INT, S('s') = PTR, S('n') = PTR,62 S('c') = UINT, S('s') = PTR, S('n') = PTR,
63 S('l') = LLPRE,63 S('l') = LLPRE,
64 }, { /* 2: ll-prefixed */64 }, { /* 2: ll-prefixed */
65 S('d') = LLONG, S('i') = LLONG,65 S('d') = LLONG, S('i') = LLONG,
...@@ -144,7 +144,13 @@ static void pop_arg(union arg *arg, int type, va_list *ap)...@@ -144,7 +144,13 @@ static void pop_arg(union arg *arg, int type, va_list *ap)
144144
145static void out(FILE *f, const wchar_t *s, size_t l)145static void out(FILE *f, const wchar_t *s, size_t l)
146{146{
147 while (l-- && !(f->flags & F_ERR)) fputwc(*s++, f);147 while (l-- && !ferror(f)) fputwc(*s++, f);
148}
149
150static void pad(FILE *f, int n, int fl)
151{
152 if ((fl & LEFT_ADJ) || !n || ferror(f)) return;
153 fprintf(f, "%*s", n, "");
148}154}
149155
150static int getint(wchar_t **s) {156static int getint(wchar_t **s) {
...@@ -261,6 +267,10 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_...@@ -261,6 +267,10 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_
261 }267 }
262268
263 if (!f) continue;269 if (!f) continue;
270
271 /* Do not process any new directives once in error state. */
272 if (ferror(f)) return -1;
273
264 t = s[-1];274 t = s[-1];
265 if (ps && (t&15)==3) t&=~32;275 if (ps && (t&15)==3) t&=~32;
266276
...@@ -277,25 +287,22 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_...@@ -277,25 +287,22 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_
277 }287 }
278 continue;288 continue;
279 case 'c':289 case 'c':
290 case 'C':
280 if (w<1) w=1;291 if (w<1) w=1;
281 if (w>1 && !(fl&LEFT_ADJ)) fprintf(f, "%*s", w-1, "");292 pad(f, w-1, fl);
282 fputwc(btowc(arg.i), f);293 out(f, &(wchar_t){t=='C' ? arg.i : btowc(arg.i)}, 1);
283 if (w>1 && (fl&LEFT_ADJ)) fprintf(f, "%*s", w-1, "");294 pad(f, w-1, fl^LEFT_ADJ);
284 l = w;295 l = w;
285 continue;296 continue;
286 case 'C':
287 fputwc(arg.i, f);
288 l = 1;
289 continue;
290 case 'S':297 case 'S':
291 a = arg.p;298 a = arg.p;
292 z = a + wcsnlen(a, p<0 ? INT_MAX : p);299 z = a + wcsnlen(a, p<0 ? INT_MAX : p);
293 if (p<0 && *z) goto overflow;300 if (p<0 && *z) goto overflow;
294 p = z-a;301 p = z-a;
295 if (w<p) w=p;302 if (w<p) w=p;
296 if (!(fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, "");303 pad(f, w-p, fl);
297 out(f, a, p);304 out(f, a, p);
298 if ((fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, "");305 pad(f, w-p, fl^LEFT_ADJ);
299 l=w;306 l=w;
300 continue;307 continue;
301 case 'm':308 case 'm':
...@@ -308,14 +315,14 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_...@@ -308,14 +315,14 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_
308 if (p<0 && *bs) goto overflow;315 if (p<0 && *bs) goto overflow;
309 p=l;316 p=l;
310 if (w<p) w=p;317 if (w<p) w=p;
311 if (!(fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, "");318 pad(f, w-p, fl);
312 bs = arg.p;319 bs = arg.p;
313 while (l--) {320 while (l--) {
314 i=mbtowc(&wc, bs, MB_LEN_MAX);321 i=mbtowc(&wc, bs, MB_LEN_MAX);
315 bs+=i;322 bs+=i;
316 fputwc(wc, f);323 out(f, &wc, 1);
317 }324 }
318 if ((fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, "");325 pad(f, w-p, fl^LEFT_ADJ);
319 l=w;326 l=w;
320 continue;327 continue;
321 }328 }
...@@ -389,8 +396,8 @@ overflow:...@@ -389,8 +396,8 @@ overflow:
389int vfwprintf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)396int vfwprintf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)
390{397{
391 va_list ap2;398 va_list ap2;
392 int nl_type[NL_ARGMAX] = {0};399 int nl_type[NL_ARGMAX+1] = {0};
393 union arg nl_arg[NL_ARGMAX];400 union arg nl_arg[NL_ARGMAX+1];
394 int olderr;401 int olderr;
395 int ret;402 int ret;
396403
...@@ -406,7 +413,7 @@ int vfwprintf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)...@@ -406,7 +413,7 @@ int vfwprintf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)
406 olderr = f->flags & F_ERR;413 olderr = f->flags & F_ERR;
407 f->flags &= ~F_ERR;414 f->flags &= ~F_ERR;
408 ret = wprintf_core(f, fmt, &ap2, nl_arg, nl_type);415 ret = wprintf_core(f, fmt, &ap2, nl_arg, nl_type);
409 if (f->flags & F_ERR) ret = -1;416 if (ferror(f)) ret = -1;
410 f->flags |= olderr;417 f->flags |= olderr;
411 FUNLOCK(f);418 FUNLOCK(f);
412 va_end(ap2);419 va_end(ap2);
lib/libc/wasi/libc-top-half/musl/src/stdio/vfwscanf.c deleted-332
...@@ -1,332 +0,0 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <stdarg.h>
4#include <ctype.h>
5#include <wchar.h>
6#include <wctype.h>
7#include <limits.h>
8#include <string.h>
9
10#include "stdio_impl.h"
11#include "shgetc.h"
12#include "intscan.h"
13#include "floatscan.h"
14
15#define SIZE_hh -2
16#define SIZE_h -1
17#define SIZE_def 0
18#define SIZE_l 1
19#define SIZE_L 2
20#define SIZE_ll 3
21
22static void store_int(void *dest, int size, unsigned long long i)
23{
24 if (!dest) return;
25 switch (size) {
26 case SIZE_hh:
27 *(char *)dest = i;
28 break;
29 case SIZE_h:
30 *(short *)dest = i;
31 break;
32 case SIZE_def:
33 *(int *)dest = i;
34 break;
35 case SIZE_l:
36 *(long *)dest = i;
37 break;
38 case SIZE_ll:
39 *(long long *)dest = i;
40 break;
41 }
42}
43
44static void *arg_n(va_list ap, unsigned int n)
45{
46 void *p;
47 unsigned int i;
48 va_list ap2;
49 va_copy(ap2, ap);
50 for (i=n; i>1; i--) va_arg(ap2, void *);
51 p = va_arg(ap2, void *);
52 va_end(ap2);
53 return p;
54}
55
56static int in_set(const wchar_t *set, int c)
57{
58 int j;
59 const wchar_t *p = set;
60 if (*p == '-') {
61 if (c=='-') return 1;
62 p++;
63 } else if (*p == ']') {
64 if (c==']') return 1;
65 p++;
66 }
67 for (; *p && *p != ']'; p++) {
68 if (*p=='-' && p[1] && p[1] != ']')
69 for (j=p++[-1]; j<*p; j++)
70 if (c==j) return 1;
71 if (c==*p) return 1;
72 }
73 return 0;
74}
75
76#if 1
77#undef getwc
78#define getwc(f) \
79 ((f)->rpos != (f)->rend && *(f)->rpos < 128 ? *(f)->rpos++ : (getwc)(f))
80
81#undef ungetwc
82#define ungetwc(c,f) \
83 ((f)->rend && (c)<128U ? *--(f)->rpos : ungetwc((c),(f)))
84#endif
85
86int vfwscanf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)
87{
88 int width;
89 int size;
90 int alloc;
91 const wchar_t *p;
92 int c, t;
93 char *s;
94 wchar_t *wcs;
95 void *dest=NULL;
96 int invert;
97 int matches=0;
98 off_t pos = 0, cnt;
99 static const char size_pfx[][3] = { "hh", "h", "", "l", "L", "ll" };
100 char tmp[3*sizeof(int)+10];
101 const wchar_t *set;
102 size_t i, k;
103
104 FLOCK(f);
105
106 fwide(f, 1);
107
108 for (p=fmt; *p; p++) {
109
110 alloc = 0;
111
112 if (iswspace(*p)) {
113 while (iswspace(p[1])) p++;
114 while (iswspace((c=getwc(f)))) pos++;
115 ungetwc(c, f);
116 continue;
117 }
118 if (*p != '%' || p[1] == '%') {
119 if (*p == '%') {
120 p++;
121 while (iswspace((c=getwc(f)))) pos++;
122 } else {
123 c = getwc(f);
124 }
125 if (c!=*p) {
126 ungetwc(c, f);
127 if (c<0) goto input_fail;
128 goto match_fail;
129 }
130 pos++;
131 continue;
132 }
133
134 p++;
135 if (*p=='*') {
136 dest = 0; p++;
137 } else if (iswdigit(*p) && p[1]=='$') {
138 dest = arg_n(ap, *p-'0'); p+=2;
139 } else {
140 dest = va_arg(ap, void *);
141 }
142
143 for (width=0; iswdigit(*p); p++) {
144 width = 10*width + *p - '0';
145 }
146
147 if (*p=='m') {
148 wcs = 0;
149 s = 0;
150 alloc = !!dest;
151 p++;
152 } else {
153 alloc = 0;
154 }
155
156 size = SIZE_def;
157 switch (*p++) {
158 case 'h':
159 if (*p == 'h') p++, size = SIZE_hh;
160 else size = SIZE_h;
161 break;
162 case 'l':
163 if (*p == 'l') p++, size = SIZE_ll;
164 else size = SIZE_l;
165 break;
166 case 'j':
167 size = SIZE_ll;
168 break;
169 case 'z':
170 case 't':
171 size = SIZE_l;
172 break;
173 case 'L':
174 size = SIZE_L;
175 break;
176 case 'd': case 'i': case 'o': case 'u': case 'x':
177 case 'a': case 'e': case 'f': case 'g':
178 case 'A': case 'E': case 'F': case 'G': case 'X':
179 case 's': case 'c': case '[':
180 case 'S': case 'C':
181 case 'p': case 'n':
182 p--;
183 break;
184 default:
185 goto fmt_fail;
186 }
187
188 t = *p;
189
190 /* Transform S,C -> ls,lc */
191 if ((t&0x2f)==3) {
192 size = SIZE_l;
193 t |= 32;
194 }
195
196 if (t != 'n') {
197 if (t != '[' && (t|32) != 'c')
198 while (iswspace((c=getwc(f)))) pos++;
199 else
200 c=getwc(f);
201 if (c < 0) goto input_fail;
202 ungetwc(c, f);
203 }
204
205 switch (t) {
206 case 'n':
207 store_int(dest, size, pos);
208 /* do not increment match count, etc! */
209 continue;
210
211 case 's':
212 case 'c':
213 case '[':
214 if (t == 'c') {
215 if (width<1) width = 1;
216 invert = 1;
217 set = L"";
218 } else if (t == 's') {
219 invert = 1;
220 static const wchar_t spaces[] = {
221 ' ', '\t', '\n', '\r', 11, 12, 0x0085,
222 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005,
223 0x2006, 0x2008, 0x2009, 0x200a,
224 0x2028, 0x2029, 0x205f, 0x3000, 0 };
225 set = spaces;
226 } else {
227 if (*++p == '^') p++, invert = 1;
228 else invert = 0;
229 set = p;
230 if (*p==']') p++;
231 while (*p!=']') {
232 if (!*p) goto fmt_fail;
233 p++;
234 }
235 }
236
237 s = (size == SIZE_def) ? dest : 0;
238 wcs = (size == SIZE_l) ? dest : 0;
239
240 int gotmatch = 0;
241
242 if (width < 1) width = -1;
243
244 i = 0;
245 if (alloc) {
246 k = t=='c' ? width+1U : 31;
247 if (size == SIZE_l) {
248 wcs = malloc(k*sizeof(wchar_t));
249 if (!wcs) goto alloc_fail;
250 } else {
251 s = malloc(k);
252 if (!s) goto alloc_fail;
253 }
254 }
255 while (width) {
256 if ((c=getwc(f))<0) break;
257 if (in_set(set, c) == invert)
258 break;
259 if (wcs) {
260 wcs[i++] = c;
261 if (alloc && i==k) {
262 k += k+1;
263 wchar_t *tmp = realloc(wcs, k*sizeof(wchar_t));
264 if (!tmp) goto alloc_fail;
265 wcs = tmp;
266 }
267 } else if (size != SIZE_l) {
268 int l = wctomb(s?s+i:tmp, c);
269 if (l<0) goto input_fail;
270 i += l;
271 if (alloc && i > k-4) {
272 k += k+1;
273 char *tmp = realloc(s, k);
274 if (!tmp) goto alloc_fail;
275 s = tmp;
276 }
277 }
278 pos++;
279 width-=(width>0);
280 gotmatch=1;
281 }
282 if (width) {
283 ungetwc(c, f);
284 if (t == 'c' || !gotmatch) goto match_fail;
285 }
286
287 if (alloc) {
288 if (size == SIZE_l) *(wchar_t **)dest = wcs;
289 else *(char **)dest = s;
290 }
291 if (t != 'c') {
292 if (wcs) wcs[i] = 0;
293 if (s) s[i] = 0;
294 }
295 break;
296
297 case 'd': case 'i': case 'o': case 'u': case 'x':
298 case 'a': case 'e': case 'f': case 'g':
299 case 'A': case 'E': case 'F': case 'G': case 'X':
300 case 'p':
301 if (width < 1) width = 0;
302 snprintf(tmp, sizeof tmp, "%.*s%.0d%s%c%%lln",
303 1+!dest, "%*", width, size_pfx[size+2], t);
304 cnt = 0;
305 if (fscanf(f, tmp, dest?dest:&cnt, &cnt) == -1)
306 goto input_fail;
307 else if (!cnt)
308 goto match_fail;
309 pos += cnt;
310 break;
311 default:
312 goto fmt_fail;
313 }
314
315 if (dest) matches++;
316 }
317 if (0) {
318fmt_fail:
319alloc_fail:
320input_fail:
321 if (!matches) matches--;
322match_fail:
323 if (alloc) {
324 free(s);
325 free(wcs);
326 }
327 }
328 FUNLOCK(f);
329 return matches;
330}
331
332weak_alias(vfwscanf,__isoc99_vfwscanf);
lib/libc/wasi/libc-top-half/musl/src/stdio/vsnprintf.c-5
...@@ -47,11 +47,6 @@ int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap)...@@ -47,11 +47,6 @@ int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap)
47 .cookie = &c,47 .cookie = &c,
48 };48 };
4949
50 if (n > INT_MAX) {
51 errno = EOVERFLOW;
52 return -1;
53 }
54
55 *c.s = 0;50 *c.s = 0;
56 return vfprintf(&f, fmt, ap);51 return vfprintf(&f, fmt, ap);
57}52}
lib/libc/wasi/libc-top-half/musl/src/stdio/vswprintf.c+1-3
...@@ -18,6 +18,7 @@ static size_t sw_write(FILE *f, const unsigned char *s, size_t l)...@@ -18,6 +18,7 @@ static size_t sw_write(FILE *f, const unsigned char *s, size_t l)
18 if (s!=f->wbase && sw_write(f, f->wbase, f->wpos-f->wbase)==-1)18 if (s!=f->wbase && sw_write(f, f->wbase, f->wpos-f->wbase)==-1)
19 return -1;19 return -1;
20 while (c->l && l && (i=mbtowc(c->ws, (void *)s, l))>=0) {20 while (c->l && l && (i=mbtowc(c->ws, (void *)s, l))>=0) {
21 if (!i) i=1;
21 s+=i;22 s+=i;
22 l-=i;23 l-=i;
23 c->l--;24 c->l--;
...@@ -52,9 +53,6 @@ int vswprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, va_lis...@@ -52,9 +53,6 @@ int vswprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, va_lis
5253
53 if (!n) {54 if (!n) {
54 return -1;55 return -1;
55 } else if (n > INT_MAX) {
56 errno = EOVERFLOW;
57 return -1;
58 }56 }
59 r = vfwprintf(&f, fmt, ap);57 r = vfwprintf(&f, fmt, ap);
60 sw_write(&f, 0, 0);58 sw_write(&f, 0, 0);
lib/libc/wasi/libc-top-half/musl/src/stdlib/strtol.c deleted-56
...@@ -1,56 +0,0 @@
1#include "stdio_impl.h"
2#include "intscan.h"
3#include "shgetc.h"
4#include <inttypes.h>
5#include <limits.h>
6#include <ctype.h>
7
8static unsigned long long strtox(const char *s, char **p, int base, unsigned long long lim)
9{
10 FILE f;
11 sh_fromstring(&f, s);
12 shlim(&f, 0);
13 unsigned long long y = __intscan(&f, base, 1, lim);
14 if (p) {
15 size_t cnt = shcnt(&f);
16 *p = (char *)s + cnt;
17 }
18 return y;
19}
20
21unsigned long long strtoull(const char *restrict s, char **restrict p, int base)
22{
23 return strtox(s, p, base, ULLONG_MAX);
24}
25
26long long strtoll(const char *restrict s, char **restrict p, int base)
27{
28 return strtox(s, p, base, LLONG_MIN);
29}
30
31unsigned long strtoul(const char *restrict s, char **restrict p, int base)
32{
33 return strtox(s, p, base, ULONG_MAX);
34}
35
36long strtol(const char *restrict s, char **restrict p, int base)
37{
38 return strtox(s, p, base, 0UL+LONG_MIN);
39}
40
41intmax_t strtoimax(const char *restrict s, char **restrict p, int base)
42{
43 return strtoll(s, p, base);
44}
45
46uintmax_t strtoumax(const char *restrict s, char **restrict p, int base)
47{
48 return strtoull(s, p, base);
49}
50
51weak_alias(strtol, __strtol_internal);
52weak_alias(strtoul, __strtoul_internal);
53weak_alias(strtoll, __strtoll_internal);
54weak_alias(strtoull, __strtoull_internal);
55weak_alias(strtoimax, __strtoimax_internal);
56weak_alias(strtoumax, __strtoumax_internal);
lib/libc/wasi/libc-top-half/musl/src/string/memchr.c created+89
...@@ -0,0 +1,89 @@
1#include <string.h>
2#include <stdint.h>
3#include <limits.h>
4
5#ifdef __wasm_simd128__
6#include <wasm_simd128.h>
7#endif
8
9#define SS (sizeof(size_t))
10#define ALIGN (sizeof(size_t)-1)
11#define ONES ((size_t)-1/UCHAR_MAX)
12#define HIGHS (ONES * (UCHAR_MAX/2+1))
13#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
14
15void *memchr(const void *src, int c, size_t n)
16{
17#if defined(__wasm_simd128__) && defined(__wasilibc_simd_string)
18 // Skip Clang 19 and Clang 20 which have a bug (llvm/llvm-project#146574)
19 // which results in an ICE when inline assembly is used with a vector result.
20#if __clang_major__ != 19 && __clang_major__ != 20
21 // When n is zero, a function that locates a character finds no occurrence.
22 // Otherwise, decrement n to ensure sub_overflow overflows
23 // when n would go equal-to-or-below zero.
24 if (!n--) {
25 return NULL;
26 }
27
28 // Note that reading before/after the allocation of a pointer is UB in
29 // C, so inline assembly is used to generate the exact machine
30 // instruction we want with opaque semantics to the compiler to avoid
31 // the UB.
32 uintptr_t align = (uintptr_t)src % sizeof(v128_t);
33 uintptr_t addr = (uintptr_t)src - align;
34 v128_t vc = wasm_i8x16_splat(c);
35
36 for (;;) {
37 v128_t v;
38 __asm__ (
39 "local.get %1\n"
40 "v128.load 0\n"
41 "local.set %0\n"
42 : "=r"(v)
43 : "r"(addr)
44 : "memory");
45 v128_t cmp = wasm_i8x16_eq(v, vc);
46 // Bitmask is slow on AArch64, any_true is much faster.
47 if (wasm_v128_any_true(cmp)) {
48 // Clear the bits corresponding to align (little-endian)
49 // so we can count trailing zeros.
50 int mask = wasm_i8x16_bitmask(cmp) >> align << align;
51 // At least one bit will be set, unless align cleared them.
52 // Knowing this helps the compiler if it unrolls the loop.
53 __builtin_assume(mask || align);
54 // If the mask became zero because of align,
55 // it's as if we didn't find anything.
56 if (mask) {
57 // Find the offset of the first one bit (little-endian).
58 // That's a match, unless it is beyond the end of the object.
59 // Recall that we decremented n, so less-than-or-equal-to is correct.
60 size_t ctz = __builtin_ctz(mask);
61 return ctz - align <= n ? (char *)src + (addr + ctz - (uintptr_t)src)
62 : NULL;
63 }
64 }
65 // Decrement n; if it overflows we're done.
66 if (__builtin_sub_overflow(n, sizeof(v128_t) - align, &n)) {
67 return NULL;
68 }
69 align = 0;
70 addr += sizeof(v128_t);
71 }
72#endif
73#endif
74
75 const unsigned char *s = src;
76 c = (unsigned char)c;
77#ifdef __GNUC__
78 for (; ((uintptr_t)s & ALIGN) && n && *s != c; s++, n--);
79 if (n && *s != c) {
80 typedef size_t __attribute__((__may_alias__)) word;
81 const word *w;
82 size_t k = ONES * c;
83 for (w = (const void *)s; n>=SS && !HASZERO(*w^k); w++, n-=SS);
84 s = (const void *)w;
85 }
86#endif
87 for (; n && *s != c; s++, n--);
88 return n ? (void *)s : 0;
89}
lib/libc/wasi/libc-top-half/musl/src/string/memcmp.c created+43
...@@ -0,0 +1,43 @@
1#include <string.h>
2
3#ifdef __wasm_simd128__
4#include <wasm_simd128.h>
5#endif
6
7int memcmp(const void *vl, const void *vr, size_t n)
8{
9#if defined(__wasm_simd128__) && defined(__wasilibc_simd_string)
10 if (n >= sizeof(v128_t)) {
11 // memcmp is allowed to read up to n bytes from each object.
12 // Find the first different character in the objects.
13 // Unaligned loads handle the case where the objects
14 // have mismatching alignments.
15 const v128_t *v1 = (v128_t *)vl;
16 const v128_t *v2 = (v128_t *)vr;
17 while (n) {
18 const v128_t cmp = wasm_i8x16_eq(wasm_v128_load(v1), wasm_v128_load(v2));
19 // Bitmask is slow on AArch64, all_true is much faster.
20 if (!wasm_i8x16_all_true(cmp)) {
21 // Find the offset of the first zero bit (little-endian).
22 size_t ctz = __builtin_ctz(~wasm_i8x16_bitmask(cmp));
23 const unsigned char *u1 = (unsigned char *)v1 + ctz;
24 const unsigned char *u2 = (unsigned char *)v2 + ctz;
25 // This may help the compiler if the function is inlined.
26 __builtin_assume(*u1 - *u2 != 0);
27 return *u1 - *u2;
28 }
29 // This makes n a multiple of sizeof(v128_t)
30 // for every iteration except the first.
31 size_t align = (n - 1) % sizeof(v128_t) + 1;
32 v1 = (v128_t *)((char *)v1 + align);
33 v2 = (v128_t *)((char *)v2 + align);
34 n -= align;
35 }
36 return 0;
37 }
38#endif
39
40 const unsigned char *l=vl, *r=vr;
41 for (; n && *l == *r; n--, l++, r++);
42 return n ? *l-*r : 0;
43}
lib/libc/wasi/libc-top-half/musl/src/string/memrchr.c created+33
...@@ -0,0 +1,33 @@
1#include <string.h>
2
3#ifdef __wasm_simd128__
4#include <wasm_simd128.h>
5#endif
6
7void *__memrchr(const void *m, int c, size_t n)
8{
9#if defined(__wasm_simd128__) && defined(__wasilibc_simd_string)
10 // memrchr is allowed to read up to n bytes from the object.
11 // Search backward for the last matching character.
12 const v128_t *v = (v128_t *)((char *)m + n);
13 const v128_t vc = wasm_i8x16_splat(c);
14 for (; n >= sizeof(v128_t); n -= sizeof(v128_t)) {
15 const v128_t cmp = wasm_i8x16_eq(wasm_v128_load(--v), vc);
16 // Bitmask is slow on AArch64, any_true is much faster.
17 if (wasm_v128_any_true(cmp)) {
18 // Find the offset of the last one bit (little-endian).
19 // The leading 16 bits of the bitmask are always zero,
20 // and to be ignored.
21 size_t clz = __builtin_clz(wasm_i8x16_bitmask(cmp)) - 16;
22 return (char *)(v + 1) - (clz + 1);
23 }
24 }
25#endif
26
27 const unsigned char *s = m;
28 c = (unsigned char)c;
29 while (n--) if (s[n]==c) return (void *)(s+n);
30 return 0;
31}
32
33weak_alias(__memrchr, memrchr);
lib/libc/wasi/libc-top-half/musl/src/string/strchrnul.c created+75
...@@ -0,0 +1,75 @@
1#include <string.h>
2#include <stdint.h>
3#include <limits.h>
4
5#ifdef __wasm_simd128__
6#include <wasm_simd128.h>
7#endif
8
9#define ALIGN (sizeof(size_t))
10#define ONES ((size_t)-1/UCHAR_MAX)
11#define HIGHS (ONES * (UCHAR_MAX/2+1))
12#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
13
14char *__strchrnul(const char *s, int c)
15{
16 c = (unsigned char)c;
17 if (!c) return (char *)s + strlen(s);
18
19#if defined(__wasm_simd128__) && defined(__wasilibc_simd_string)
20 // Skip Clang 19 and Clang 20 which have a bug (llvm/llvm-project#146574)
21 // which results in an ICE when inline assembly is used with a vector result.
22#if __clang_major__ != 19 && __clang_major__ != 20
23 // Note that reading before/after the allocation of a pointer is UB in
24 // C, so inline assembly is used to generate the exact machine
25 // instruction we want with opaque semantics to the compiler to avoid
26 // the UB.
27 uintptr_t align = (uintptr_t)s % sizeof(v128_t);
28 uintptr_t addr = (uintptr_t)s - align;
29 v128_t vc = wasm_i8x16_splat(c);
30
31 for (;;) {
32 v128_t v;
33 __asm__ (
34 "local.get %1\n"
35 "v128.load 0\n"
36 "local.set %0\n"
37 : "=r"(v)
38 : "r"(addr)
39 : "memory");
40 const v128_t cmp = wasm_i8x16_eq(v, (v128_t){}) | wasm_i8x16_eq(v, vc);
41 // Bitmask is slow on AArch64, any_true is much faster.
42 if (wasm_v128_any_true(cmp)) {
43 // Clear the bits corresponding to align (little-endian)
44 // so we can count trailing zeros.
45 int mask = wasm_i8x16_bitmask(cmp) >> align << align;
46 // At least one bit will be set, unless align cleared them.
47 // Knowing this helps the compiler if it unrolls the loop.
48 __builtin_assume(mask || align);
49 // If the mask became zero because of align,
50 // it's as if we didn't find anything.
51 if (mask) {
52 // Find the offset of the first one bit (little-endian).
53 return (char *)s + (addr - (uintptr_t)s + __builtin_ctz(mask));
54 }
55 }
56 align = 0;
57 addr += sizeof(v128_t);
58 }
59#endif
60#endif
61
62#ifdef __GNUC__
63 typedef size_t __attribute__((__may_alias__)) word;
64 const word *w;
65 for (; (uintptr_t)s % ALIGN; s++)
66 if (!*s || *(unsigned char *)s == c) return (char *)s;
67 size_t k = ONES * c;
68 for (w = (void *)s; !HASZERO(*w) && !HASZERO(*w^k); w++);
69 s = (void *)w;
70#endif
71 for (; *s && *(unsigned char *)s != c; s++);
72 return (char *)s;
73}
74
75weak_alias(__strchrnul, strchrnul);
lib/libc/wasi/libc-top-half/musl/src/thread/pthread_attr_get.c created+121
...@@ -0,0 +1,121 @@
1#include "pthread_impl.h"
2
3#ifndef __wasilibc_unmodified_upstream
4#include <common/clock.h>
5#endif
6
7int pthread_attr_getdetachstate(const pthread_attr_t *a, int *state)
8{
9 *state = a->_a_detach;
10 return 0;
11}
12int pthread_attr_getguardsize(const pthread_attr_t *restrict a, size_t *restrict size)
13{
14 *size = a->_a_guardsize;
15 return 0;
16}
17
18#ifdef __wasilibc_unmodified_upstream /* WASI has no CPU scheduling support. */
19int pthread_attr_getinheritsched(const pthread_attr_t *restrict a, int *restrict inherit)
20{
21 *inherit = a->_a_sched;
22 return 0;
23}
24
25int pthread_attr_getschedparam(const pthread_attr_t *restrict a, struct sched_param *restrict param)
26{
27 param->sched_priority = a->_a_prio;
28 return 0;
29}
30
31int pthread_attr_getschedpolicy(const pthread_attr_t *restrict a, int *restrict policy)
32{
33 *policy = a->_a_policy;
34 return 0;
35}
36
37int pthread_attr_getscope(const pthread_attr_t *restrict a, int *restrict scope)
38{
39 *scope = PTHREAD_SCOPE_SYSTEM;
40 return 0;
41}
42#else
43int pthread_attr_getschedparam(const pthread_attr_t *restrict a, struct sched_param *restrict param)
44{
45 param->sched_priority = 0;
46 return 0;
47}
48#endif
49
50int pthread_attr_getstack(const pthread_attr_t *restrict a, void **restrict addr, size_t *restrict size)
51{
52 if (!a->_a_stackaddr)
53 return EINVAL;
54 *size = a->_a_stacksize;
55 *addr = (void *)(a->_a_stackaddr - *size);
56 return 0;
57}
58
59int pthread_attr_getstacksize(const pthread_attr_t *restrict a, size_t *restrict size)
60{
61 *size = a->_a_stacksize;
62 return 0;
63}
64
65int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict a, int *restrict pshared)
66{
67 *pshared = !!a->__attr;
68 return 0;
69}
70
71#ifdef __wasilibc_unmodified_upstream /* Forward declaration of WASI's `__clockid` type. */
72int pthread_condattr_getclock(const pthread_condattr_t *restrict a, clockid_t *restrict clk)
73{
74 *clk = a->__attr & 0x7fffffff;
75 return 0;
76}
77#else
78int pthread_condattr_getclock(const pthread_condattr_t *restrict a, clockid_t *restrict clk)
79{
80 if (a->__attr & 0x7fffffff == __WASI_CLOCKID_REALTIME)
81 *clk = CLOCK_REALTIME;
82 if (a->__attr & 0x7fffffff == __WASI_CLOCKID_MONOTONIC)
83 *clk = CLOCK_MONOTONIC;
84 return 0;
85}
86#endif
87
88int pthread_condattr_getpshared(const pthread_condattr_t *restrict a, int *restrict pshared)
89{
90 *pshared = a->__attr>>31;
91 return 0;
92}
93
94int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *restrict a, int *restrict protocol)
95{
96 *protocol = a->__attr / 8U % 2;
97 return 0;
98}
99int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict a, int *restrict pshared)
100{
101 *pshared = a->__attr / 128U % 2;
102 return 0;
103}
104
105int pthread_mutexattr_getrobust(const pthread_mutexattr_t *restrict a, int *restrict robust)
106{
107 *robust = a->__attr / 4U % 2;
108 return 0;
109}
110
111int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict a, int *restrict type)
112{
113 *type = a->__attr & 3;
114 return 0;
115}
116
117int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict a, int *restrict pshared)
118{
119 *pshared = a->__attr[0];
120 return 0;
121}
lib/libc/wasi/libc-top-half/musl/src/thread/pthread_attr_setguardsize.c created+13
...@@ -0,0 +1,13 @@
1#include "pthread_impl.h"
2
3int pthread_attr_setguardsize(pthread_attr_t *a, size_t size)
4{
5#ifdef __wasilibc_unmodified_upstream
6 if (size > SIZE_MAX/8) return EINVAL;
7#else
8 /* WASI doesn't have memory protection required for stack guards. */
9 if (size > 0) return EINVAL;
10#endif
11 a->_a_guardsize = size;
12 return 0;
13}
lib/libc/wasi/libc-top-half/musl/src/thread/pthread_attr_setschedparam.c created+11
...@@ -0,0 +1,11 @@
1#include "pthread_impl.h"
2
3int pthread_attr_setschedparam(pthread_attr_t *restrict a, const struct sched_param *restrict param)
4{
5#ifdef __wasilibc_unmodified_upstream
6 a->_a_prio = param->sched_priority;
7#else
8 if (param->sched_priority != 0) return ENOTSUP;
9#endif
10 return 0;
11}
lib/libc/wasi/libc-top-half/musl/src/thread/pthread_cancel.c created+113
...@@ -0,0 +1,113 @@
1#define _GNU_SOURCE
2#include <string.h>
3#include "pthread_impl.h"
4#include "syscall.h"
5
6#ifdef __wasilibc_unmodified_upstream
7hidden long __cancel(), __syscall_cp_asm(), __syscall_cp_c();
8
9long __cancel()
10{
11 pthread_t self = __pthread_self();
12 if (self->canceldisable == PTHREAD_CANCEL_ENABLE || self->cancelasync)
13 pthread_exit(PTHREAD_CANCELED);
14 self->canceldisable = PTHREAD_CANCEL_DISABLE;
15 return -ECANCELED;
16}
17
18long __syscall_cp_asm(volatile void *, syscall_arg_t,
19 syscall_arg_t, syscall_arg_t, syscall_arg_t,
20 syscall_arg_t, syscall_arg_t, syscall_arg_t);
21
22long __syscall_cp_c(syscall_arg_t nr,
23 syscall_arg_t u, syscall_arg_t v, syscall_arg_t w,
24 syscall_arg_t x, syscall_arg_t y, syscall_arg_t z)
25{
26 pthread_t self;
27 long r;
28 int st;
29
30 if ((st=(self=__pthread_self())->canceldisable)
31 && (st==PTHREAD_CANCEL_DISABLE || nr==SYS_close))
32 return __syscall(nr, u, v, w, x, y, z);
33
34 r = __syscall_cp_asm(&self->cancel, nr, u, v, w, x, y, z);
35 if (r==-EINTR && nr!=SYS_close && self->cancel &&
36 self->canceldisable != PTHREAD_CANCEL_DISABLE)
37 r = __cancel();
38 return r;
39}
40
41static void _sigaddset(sigset_t *set, int sig)
42{
43 unsigned s = sig-1;
44 set->__bits[s/8/sizeof *set->__bits] |= 1UL<<(s&8*sizeof *set->__bits-1);
45}
46
47extern hidden const char __cp_begin[1], __cp_end[1], __cp_cancel[1];
48
49static void cancel_handler(int sig, siginfo_t *si, void *ctx)
50{
51 pthread_t self = __pthread_self();
52 ucontext_t *uc = ctx;
53 uintptr_t pc = uc->uc_mcontext.MC_PC;
54
55 a_barrier();
56 if (!self->cancel || self->canceldisable == PTHREAD_CANCEL_DISABLE) return;
57
58 _sigaddset(&uc->uc_sigmask, SIGCANCEL);
59
60 if (self->cancelasync) {
61 pthread_sigmask(SIG_SETMASK, &uc->uc_sigmask, 0);
62 __cancel();
63 }
64
65 if (pc >= (uintptr_t)__cp_begin && pc < (uintptr_t)__cp_end) {
66 uc->uc_mcontext.MC_PC = (uintptr_t)__cp_cancel;
67#ifdef CANCEL_GOT
68 uc->uc_mcontext.MC_GOT = CANCEL_GOT;
69#endif
70 return;
71 }
72
73 __syscall(SYS_tkill, self->tid, SIGCANCEL);
74}
75
76void __testcancel()
77{
78 pthread_t self = __pthread_self();
79 if (self->cancel && !self->canceldisable)
80 __cancel();
81}
82
83static void init_cancellation()
84{
85 struct sigaction sa = {
86 .sa_flags = SA_SIGINFO | SA_RESTART | SA_ONSTACK,
87 .sa_sigaction = cancel_handler
88 };
89 memset(&sa.sa_mask, -1, _NSIG/8);
90 __libc_sigaction(SIGCANCEL, &sa, 0);
91}
92
93int pthread_cancel(pthread_t t)
94{
95 static int init;
96 if (!init) {
97 init_cancellation();
98 init = 1;
99 }
100 a_store(&t->cancel, 1);
101 if (t == pthread_self()) {
102 if (t->canceldisable == PTHREAD_CANCEL_ENABLE && t->cancelasync)
103 pthread_exit(PTHREAD_CANCELED);
104 return 0;
105 }
106 return pthread_kill(t, SIGCANCEL);
107}
108#else
109int pthread_cancel(pthread_t t)
110{
111 return ENOTSUP;
112}
113#endif
lib/libc/wasi/libc-top-half/musl/src/thread/pthread_condattr_setclock.c created+21
...@@ -0,0 +1,21 @@
1#include "pthread_impl.h"
2
3#ifndef __wasilibc_unmodified_upstream
4#include <common/clock.h>
5#endif
6
7int pthread_condattr_setclock(pthread_condattr_t *a, clockid_t clk)
8{
9#ifdef __wasilibc_unmodified_upstream
10 if (clk < 0 || clk-2U < 2) return EINVAL;
11#else
12 if (clk->id < 0 || clk->id-2U < 2) return EINVAL;
13#endif
14 a->__attr &= 0x80000000;
15#ifdef __wasilibc_unmodified_upstream
16 a->__attr |= clk;
17#else
18 a->__attr |= clk->id;
19#endif
20 return 0;
21}
lib/libc/wasi/libc-top-half/musl/src/thread/pthread_key_create.c created+105
...@@ -0,0 +1,105 @@
1#include "pthread_impl.h"
2#include "fork_impl.h"
3
4volatile size_t __pthread_tsd_size = sizeof(void *) * PTHREAD_KEYS_MAX;
5void *__pthread_tsd_main[PTHREAD_KEYS_MAX] = { 0 };
6
7static void (*keys[PTHREAD_KEYS_MAX])(void *);
8
9static pthread_rwlock_t key_lock = PTHREAD_RWLOCK_INITIALIZER;
10
11static pthread_key_t next_key;
12
13static void nodtor(void *dummy)
14{
15}
16
17static void dummy_0(void)
18{
19}
20
21weak_alias(dummy_0, __tl_lock);
22weak_alias(dummy_0, __tl_unlock);
23
24#ifdef __wasilibc_unmodified_upstream // WASI lacks fork
25void __pthread_key_atfork(int who)
26{
27 if (who<0) __pthread_rwlock_rdlock(&key_lock);
28 else if (!who) __pthread_rwlock_unlock(&key_lock);
29 else key_lock = (pthread_rwlock_t)PTHREAD_RWLOCK_INITIALIZER;
30}
31#endif
32
33int __pthread_key_create(pthread_key_t *k, void (*dtor)(void *))
34{
35 pthread_t self = __pthread_self();
36
37 /* This can only happen in the main thread before
38 * pthread_create has been called. */
39 if (!self->tsd) self->tsd = __pthread_tsd_main;
40
41 /* Purely a sentinel value since null means slot is free. */
42 if (!dtor) dtor = nodtor;
43
44 __pthread_rwlock_wrlock(&key_lock);
45 pthread_key_t j = next_key;
46 do {
47 if (!keys[j]) {
48 keys[next_key = *k = j] = dtor;
49 __pthread_rwlock_unlock(&key_lock);
50 return 0;
51 }
52 } while ((j=(j+1)%PTHREAD_KEYS_MAX) != next_key);
53
54 __pthread_rwlock_unlock(&key_lock);
55 return EAGAIN;
56}
57
58int __pthread_key_delete(pthread_key_t k)
59{
60 sigset_t set;
61 pthread_t self = __pthread_self(), td=self;
62
63#ifdef __wasilibc_unmodified_upstream
64 __block_app_sigs(&set);
65#endif
66 __pthread_rwlock_wrlock(&key_lock);
67
68 __tl_lock();
69 do td->tsd[k] = 0;
70 while ((td=td->next)!=self);
71 __tl_unlock();
72
73 keys[k] = 0;
74
75 __pthread_rwlock_unlock(&key_lock);
76#ifdef __wasilibc_unmodified_upstream
77 __restore_sigs(&set);
78#endif
79
80 return 0;
81}
82
83void __pthread_tsd_run_dtors()
84{
85 pthread_t self = __pthread_self();
86 int i, j;
87 for (j=0; self->tsd_used && j<PTHREAD_DESTRUCTOR_ITERATIONS; j++) {
88 __pthread_rwlock_rdlock(&key_lock);
89 self->tsd_used = 0;
90 for (i=0; i<PTHREAD_KEYS_MAX; i++) {
91 void *val = self->tsd[i];
92 void (*dtor)(void *) = keys[i];
93 self->tsd[i] = 0;
94 if (val && dtor && dtor != nodtor) {
95 __pthread_rwlock_unlock(&key_lock);
96 dtor(val);
97 __pthread_rwlock_rdlock(&key_lock);
98 }
99 }
100 __pthread_rwlock_unlock(&key_lock);
101 }
102}
103
104weak_alias(__pthread_key_create, pthread_key_create);
105weak_alias(__pthread_key_delete, pthread_key_delete);
lib/libc/wasi/libc-top-half/musl/src/thread/pthread_mutex_destroy.c created+18
...@@ -0,0 +1,18 @@
1#include "pthread_impl.h"
2
3int pthread_mutex_destroy(pthread_mutex_t *mutex)
4{
5#ifdef __wasilibc_unmodified_upstream
6 /* If the mutex being destroyed is process-shared and has nontrivial
7 * type (tracking ownership), it might be in the pending slot of a
8 * robust_list; wait for quiescence. */
9 if (mutex->_m_type > 128) __vm_wait();
10#else
11 /* For now, wasi-libc chooses to avoid implementing robust mutex support
12 * though this could be added later. The error code indicates that the
13 * mutex was an invalid type, but it would be more accurate as
14 * "unimplemented". */
15 if (mutex->_m_type > 128) return EINVAL;
16#endif
17 return 0;
18}
lib/libc/wasi/libc-top-half/musl/src/thread/pthread_mutexattr_setprotocol.c created+32
...@@ -0,0 +1,32 @@
1#include "pthread_impl.h"
2#include "syscall.h"
3
4static volatile int check_pi_result = -1;
5
6int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int protocol)
7{
8 int r;
9 switch (protocol) {
10 case PTHREAD_PRIO_NONE:
11 a->__attr &= ~8;
12 return 0;
13 case PTHREAD_PRIO_INHERIT:
14#ifdef __wasilibc_unmodified_upstream
15 r = check_pi_result;
16 if (r < 0) {
17 volatile int lk = 0;
18 r = -__syscall(SYS_futex, &lk, FUTEX_LOCK_PI, 0, 0);
19 a_store(&check_pi_result, r);
20 }
21 if (r) return r;
22 a->__attr |= 8;
23 return 0;
24#else
25 return ENOTSUP;
26#endif
27 case PTHREAD_PRIO_PROTECT:
28 return ENOTSUP;
29 default:
30 return EINVAL;
31 }
32}
lib/libc/wasi/libc-top-half/musl/src/thread/pthread_mutexattr_setrobust.c created+28
...@@ -0,0 +1,28 @@
1#include "pthread_impl.h"
2#include "syscall.h"
3
4static volatile int check_robust_result = -1;
5
6int pthread_mutexattr_setrobust(pthread_mutexattr_t *a, int robust)
7{
8#ifdef __wasilibc_unmodified_upstream
9 if (robust > 1U) return EINVAL;
10 if (robust) {
11 int r = check_robust_result;
12 if (r < 0) {
13 void *p;
14 size_t l;
15 r = -__syscall(SYS_get_robust_list, 0, &p, &l);
16 a_store(&check_robust_result, r);
17 }
18 if (r) return r;
19 a->__attr |= 4;
20 return 0;
21 }
22 a->__attr &= ~4;
23 return 0;
24#else
25 if (robust) return EINVAL;
26 return 0;
27#endif
28}
lib/libc/wasi/libc-top-half/musl/src/thread/pthread_self.c created+14
...@@ -0,0 +1,14 @@
1#include "pthread_impl.h"
2#include <threads.h>
3
4#if !defined(__wasilibc_unmodified_upstream) && defined(__wasm__)
5_Thread_local struct pthread __wasilibc_pthread_self;
6#endif
7
8static pthread_t __pthread_self_internal()
9{
10 return __pthread_self();
11}
12
13weak_alias(__pthread_self_internal, pthread_self);
14weak_alias(__pthread_self_internal, thrd_current);
lib/libc/wasi/libc-top-half/musl/src/time/__tz.c+8-4
...@@ -434,10 +434,14 @@ weak_alias(__tzset, tzset);...@@ -434,10 +434,14 @@ weak_alias(__tzset, tzset);
434void __secs_to_zone(long long t, int local, int *isdst, int *offset, long *oppoff, const char **zonename)434void __secs_to_zone(long long t, int local, int *isdst, int *offset, long *oppoff, const char **zonename)
435{435{
436 // Minimalist implementation for now.436 // Minimalist implementation for now.
437 *isdst = 0;437 if (isdst)
438 *offset = 0;438 *isdst = 0;
439 *oppoff = 0;439 if (offset)
440 *zonename = __utc;440 *offset = 0;
441 if (oppoff)
442 *oppoff = 0;
443 if (zonename)
444 *zonename = __utc;
441}445}
442#endif446#endif
443447
lib/libc/wasi/libc-top-half/musl/src/time/strftime.c+7-1
...@@ -3,6 +3,7 @@...@@ -3,6 +3,7 @@
3#include <string.h>3#include <string.h>
4#include <langinfo.h>4#include <langinfo.h>
5#include <locale.h>5#include <locale.h>
6#include <ctype.h>
6#include <time.h>7#include <time.h>
7#include <limits.h>8#include <limits.h>
8#include "locale_impl.h"9#include "locale_impl.h"
...@@ -237,7 +238,12 @@ size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const st...@@ -237,7 +238,12 @@ size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const st
237 pad = 0;238 pad = 0;
238 if (*f == '-' || *f == '_' || *f == '0') pad = *f++;239 if (*f == '-' || *f == '_' || *f == '0') pad = *f++;
239 if ((plus = (*f == '+'))) f++;240 if ((plus = (*f == '+'))) f++;
240 width = strtoul(f, &p, 10);241 if (isdigit(*f)) {
242 width = strtoul(f, &p, 10);
243 } else {
244 width = 0;
245 p = (void *)f;
246 }
241 if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') {247 if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') {
242 if (!width && p!=f) width = 1;248 if (!width && p!=f) width = 1;
243 } else {249 } else {
lib/libc/wasi/thread-stub/pthread_barrier_destroy.c created+6
...@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_barrier_destroy(pthread_barrier_t *b)
4{
5 return 0;
6}
lib/libc/wasi/thread-stub/pthread_barrier_init.c created+8
...@@ -0,0 +1,8 @@
1#include "pthread_impl.h"
2
3int pthread_barrier_init(pthread_barrier_t *restrict b, const pthread_barrierattr_t *restrict a, unsigned count)
4{
5 if (count-1 > INT_MAX-1) return EINVAL;
6 *b = (pthread_barrier_t){ ._b_limit = count-1 };
7 return 0;
8}
lib/libc/wasi/thread-stub/pthread_barrier_wait.c created+7
...@@ -0,0 +1,7 @@
1#include "pthread_impl.h"
2
3int pthread_barrier_wait(pthread_barrier_t *b)
4{
5 if (!b->_b_limit) return PTHREAD_BARRIER_SERIAL_THREAD;
6 __builtin_trap();
7}
lib/libc/wasi/thread-stub/pthread_cond_broadcast.c created+6
...@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_cond_broadcast(pthread_cond_t *c)
4{
5 return 0;
6}
lib/libc/wasi/thread-stub/pthread_cond_destroy.c created+6
...@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_cond_destroy(pthread_cond_t *c)
4{
5 return 0;
6}
lib/libc/wasi/thread-stub/pthread_cond_init.c created+6
...@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_cond_init(pthread_cond_t *restrict c, const pthread_condattr_t *restrict a)
4{
5 return 0;
6}
lib/libc/wasi/thread-stub/pthread_cond_signal.c created+6
...@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_cond_signal(pthread_cond_t *c)
4{
5 return 0;
6}
lib/libc/wasi/thread-stub/pthread_cond_timedwait.c created+13
...@@ -0,0 +1,13 @@
1#include "pthread_impl.h"
2
3int __pthread_cond_timedwait(pthread_cond_t *restrict c, pthread_mutex_t *restrict m, const struct timespec *restrict ts)
4{
5 /* Error check mutexes must detect if they're not locked (UB for others) */
6 if (!m->_m_count) return EPERM;
7 int ret = clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, ts, 0);
8 if (ret == 0) return ETIMEDOUT;
9 if (ret != EINTR) return ret;
10 return 0;
11}
12
13weak_alias(__pthread_cond_timedwait, pthread_cond_timedwait);
lib/libc/wasi/thread-stub/pthread_cond_wait.c created+9
...@@ -0,0 +1,9 @@
1#include "pthread_impl.h"
2
3int pthread_cond_wait(pthread_cond_t *restrict c, pthread_mutex_t *restrict m)
4{
5 /* Because there is no other thread that can signal us, this is a deadlock immediately.
6 The other possible choice is to return immediately (spurious wakeup), but that is likely to
7 just result in the program spinning forever on a condition that cannot become true. */
8 __builtin_trap();
9}
lib/libc/wasi/thread-stub/pthread_create.c created+19
...@@ -0,0 +1,19 @@
1#include "pthread_impl.h"
2
3static void dummy_0()
4{
5}
6weak_alias(dummy_0, __acquire_ptc);
7weak_alias(dummy_0, __release_ptc);
8
9int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp, void *(*entry)(void *), void *restrict arg)
10{
11 /*
12 "The system lacked the necessary resources to create another thread,
13 or the system-imposed limit on the total number of threads in a process
14 {PTHREAD_THREADS_MAX} would be exceeded."
15 */
16 return EAGAIN;
17}
18
19weak_alias(__pthread_create, pthread_create);
lib/libc/wasi/thread-stub/pthread_detach.c created+13
...@@ -0,0 +1,13 @@
1#include "pthread_impl.h"
2
3static int __pthread_detach(pthread_t t)
4{
5 /*
6 If we are the only thread, when we exit the whole process exits.
7 So the storage will be reclaimed no matter what.
8 */
9 return 0;
10}
11
12weak_alias(__pthread_detach, pthread_detach);
13weak_alias(__pthread_detach, thrd_detach);
lib/libc/wasi/thread-stub/pthread_getattr_np.c created+11
...@@ -0,0 +1,11 @@
1#include "pthread_impl.h"
2
3int pthread_getattr_np(pthread_t t, pthread_attr_t *a)
4{
5 *a = (pthread_attr_t){0};
6 /* Can't join main thread. */
7 a->_a_detach = PTHREAD_CREATE_DETACHED;
8 /* WASI doesn't have memory protection required for stack guards. */
9 a->_a_guardsize = 0;
10 return 0;
11}
lib/libc/wasi/thread-stub/pthread_join.c created+32
...@@ -0,0 +1,32 @@
1#include "pthread_impl.h"
2
3static int __pthread_tryjoin_np(pthread_t t, void **res)
4{
5 /*
6 "The behavior is undefined if the value specified by the thread argument
7 to pthread_join() refers to the calling thread."
8 */
9 return 0;
10}
11
12static int __pthread_timedjoin_np(pthread_t t, void **res, const struct timespec *at)
13{
14 /*
15 "The behavior is undefined if the value specified by the thread argument
16 to pthread_join() refers to the calling thread."
17 */
18 return 0;
19}
20
21int __pthread_join(pthread_t t, void **res)
22{
23 /*
24 "The behavior is undefined if the value specified by the thread argument
25 to pthread_join() refers to the calling thread."
26 */
27 return 0;
28}
29
30weak_alias(__pthread_tryjoin_np, pthread_tryjoin_np);
31weak_alias(__pthread_timedjoin_np, pthread_timedjoin_np);
32weak_alias(__pthread_join, pthread_join);
lib/libc/wasi/thread-stub/pthread_mutex_consistent.c created+8
...@@ -0,0 +1,8 @@
1#include "pthread_impl.h"
2
3int pthread_mutex_consistent(pthread_mutex_t *m)
4{
5 /* cannot be a robust mutex, as they're entirely unsupported in WASI */
6 return EINVAL;
7
8}
lib/libc/wasi/thread-stub/pthread_mutex_getprioceiling.c created+6
...@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_mutex_getprioceiling(const pthread_mutex_t *restrict m, int *restrict ceiling)
4{
5 return EINVAL;
6}
lib/libc/wasi/thread-stub/pthread_mutex_lock.c created+21
...@@ -0,0 +1,21 @@
1#include "pthread_impl.h"
2
3int __pthread_mutex_lock(pthread_mutex_t *m)
4{
5 /*
6 _m_type[1:0] - type
7 0 - normal
8 1 - recursive
9 2 - errorcheck
10 */
11 if (m->_m_type&3 != PTHREAD_MUTEX_RECURSIVE) {
12 if (m->_m_count) return EDEADLK;
13 m->_m_count = 1;
14 } else {
15 if ((unsigned)m->_m_count >= INT_MAX) return EAGAIN;
16 m->_m_count++;
17 }
18 return 0;
19}
20
21weak_alias(__pthread_mutex_lock, pthread_mutex_lock);
lib/libc/wasi/thread-stub/pthread_mutex_timedlock.c created+10
...@@ -0,0 +1,10 @@
1#include "pthread_impl.h"
2
3int __pthread_mutex_timedlock(pthread_mutex_t *restrict m, const struct timespec *restrict at)
4{
5 /* "The pthread_mutex_timedlock() function may fail if: A deadlock condition was detected." */
6 /* This means that we don't have to wait and then return timeout, we can just detect deadlock. */
7 return pthread_mutex_lock(m);
8}
9
10weak_alias(__pthread_mutex_timedlock, pthread_mutex_timedlock);
lib/libc/wasi/thread-stub/pthread_mutex_trylock.c created+21
...@@ -0,0 +1,21 @@
1#include "pthread_impl.h"
2
3int __pthread_mutex_trylock(pthread_mutex_t *m)
4{
5 /*
6 _m_type[1:0] - type
7 0 - normal
8 1 - recursive
9 2 - errorcheck
10 */
11 if (m->_m_type&3 != PTHREAD_MUTEX_RECURSIVE) {
12 if (m->_m_count) return EBUSY;
13 m->_m_count = 1;
14 } else {
15 if ((unsigned)m->_m_count >= INT_MAX) return EAGAIN;
16 m->_m_count++;
17 }
18 return 0;
19}
20
21weak_alias(__pthread_mutex_trylock, pthread_mutex_trylock);
lib/libc/wasi/thread-stub/pthread_mutex_unlock.c created+10
...@@ -0,0 +1,10 @@
1#include "pthread_impl.h"
2
3int __pthread_mutex_unlock(pthread_mutex_t *m)
4{
5 if (!m->_m_count) return EPERM;
6 m->_m_count--;
7 return 0;
8}
9
10weak_alias(__pthread_mutex_unlock, pthread_mutex_unlock);
lib/libc/wasi/thread-stub/pthread_once.c created+12
...@@ -0,0 +1,12 @@
1#include "pthread_impl.h"
2
3int __pthread_once(pthread_once_t *control, void (*init)(void))
4{
5 if (!*control) {
6 init();
7 *control = 1;
8 }
9 return 0;
10}
11
12weak_alias(__pthread_once, pthread_once);
lib/libc/wasi/thread-stub/pthread_rwlock_rdlock.c created+11
...@@ -0,0 +1,11 @@
1#include "pthread_impl.h"
2
3int __pthread_rwlock_rdlock(pthread_rwlock_t *rw)
4{
5 if (rw->_rw_lock == 0x7fffffff) return EDEADLK;
6 if (rw->_rw_lock == 0x7ffffffe) return EAGAIN;
7 rw->_rw_lock++;
8 return 0;
9}
10
11weak_alias(__pthread_rwlock_rdlock, pthread_rwlock_rdlock);
lib/libc/wasi/thread-stub/pthread_rwlock_timedrdlock.c created+8
...@@ -0,0 +1,8 @@
1#include "pthread_impl.h"
2
3int __pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict rw, const struct timespec *restrict at)
4{
5 return pthread_rwlock_rdlock(rw);
6}
7
8weak_alias(__pthread_rwlock_timedrdlock, pthread_rwlock_timedrdlock);
lib/libc/wasi/thread-stub/pthread_rwlock_timedwrlock.c created+8
...@@ -0,0 +1,8 @@
1#include "pthread_impl.h"
2
3int __pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rw, const struct timespec *restrict at)
4{
5 return pthread_rwlock_wrlock(rw);
6}
7
8weak_alias(__pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock);
lib/libc/wasi/thread-stub/pthread_rwlock_tryrdlock.c created+11
...@@ -0,0 +1,11 @@
1#include "pthread_impl.h"
2
3int __pthread_rwlock_tryrdlock(pthread_rwlock_t *rw)
4{
5 if (rw->_rw_lock == 0x7fffffff) return EBUSY;
6 if (rw->_rw_lock == 0x7ffffffe) return EAGAIN;
7 rw->_rw_lock++;
8 return 0;
9}
10
11weak_alias(__pthread_rwlock_tryrdlock, pthread_rwlock_tryrdlock);
lib/libc/wasi/thread-stub/pthread_rwlock_trywrlock.c created+10
...@@ -0,0 +1,10 @@
1#include "pthread_impl.h"
2
3int __pthread_rwlock_trywrlock(pthread_rwlock_t *rw)
4{
5 if (rw->_rw_lock) return EBUSY;
6 rw->_rw_lock = 0x7fffffff;
7 return 0;
8}
9
10weak_alias(__pthread_rwlock_trywrlock, pthread_rwlock_trywrlock);
lib/libc/wasi/thread-stub/pthread_rwlock_unlock.c created+12
...@@ -0,0 +1,12 @@
1#include "pthread_impl.h"
2
3int __pthread_rwlock_unlock(pthread_rwlock_t *rw)
4{
5 if (rw->_rw_lock == 0x7fffffff)
6 rw->_rw_lock = 0;
7 else
8 rw->_rw_lock--;
9 return 0;
10}
11
12weak_alias(__pthread_rwlock_unlock, pthread_rwlock_unlock);
lib/libc/wasi/thread-stub/pthread_rwlock_wrlock.c created+10
...@@ -0,0 +1,10 @@
1#include "pthread_impl.h"
2
3int __pthread_rwlock_wrlock(pthread_rwlock_t *rw)
4{
5 if (rw->_rw_lock) return EDEADLK;
6 rw->_rw_lock = 0x7fffffff;
7 return 0;
8}
9
10weak_alias(__pthread_rwlock_wrlock, pthread_rwlock_wrlock);
lib/libc/wasi/thread-stub/pthread_spin_lock.c created+8
...@@ -0,0 +1,8 @@
1#include "pthread_impl.h"
2
3int pthread_spin_lock(pthread_spinlock_t *s)
4{
5 if (*s) return EDEADLK;
6 *s = 1;
7 return 0;
8}
lib/libc/wasi/thread-stub/pthread_spin_trylock.c created+8
...@@ -0,0 +1,8 @@
1#include "pthread_impl.h"
2
3int pthread_spin_trylock(pthread_spinlock_t *s)
4{
5 if (*s) return EBUSY;
6 *s = 1;
7 return 0;
8}
lib/libc/wasi/thread-stub/pthread_spin_unlock.c created+7
...@@ -0,0 +1,7 @@
1#include "pthread_impl.h"
2
3int pthread_spin_unlock(pthread_spinlock_t *s)
4{
5 *s = 0;
6 return 0;
7}
lib/std/start.zig+1-1
...@@ -57,7 +57,7 @@ comptime {...@@ -57,7 +57,7 @@ comptime {
57 } else if (builtin.output_mode == .Exe or @hasDecl(root, "main")) {57 } else if (builtin.output_mode == .Exe or @hasDecl(root, "main")) {
58 if (builtin.link_libc and @hasDecl(root, "main")) {58 if (builtin.link_libc and @hasDecl(root, "main")) {
59 if (native_arch.isWasm()) {59 if (native_arch.isWasm()) {
60 @export(&mainWithoutEnv, .{ .name = "main" });60 @export(&mainWithoutEnv, .{ .name = "__main_argc_argv" });
61 } else if (!@typeInfo(@TypeOf(root.main)).@"fn".calling_convention.eql(.c)) {61 } else if (!@typeInfo(@TypeOf(root.main)).@"fn".calling_convention.eql(.c)) {
62 @export(&main, .{ .name = "main" });62 @export(&main, .{ .name = "main" });
63 }63 }
lib/std/zig/target.zig+2
...@@ -361,6 +361,8 @@ pub fn isLibCLibName(target: *const std.Target, name: []const u8) bool {...@@ -361,6 +361,8 @@ pub fn isLibCLibName(target: *const std.Target, name: []const u8) bool {
361 return true;361 return true;
362362
363 if (target.os.tag == .wasi) {363 if (target.os.tag == .wasi) {
364 if (eqlIgnoreCase(ignore_case, name, "setjmp"))
365 return true;
364 if (eqlIgnoreCase(ignore_case, name, "wasi-emulated-getpid"))366 if (eqlIgnoreCase(ignore_case, name, "wasi-emulated-getpid"))
365 return true;367 return true;
366 if (eqlIgnoreCase(ignore_case, name, "wasi-emulated-mman"))368 if (eqlIgnoreCase(ignore_case, name, "wasi-emulated-mman"))
src/Compilation.zig-5
...@@ -1426,11 +1426,6 @@ pub const MiscTask = enum {...@@ -1426,11 +1426,6 @@ pub const MiscTask = enum {
1426 @"wasi crt1-reactor.o",1426 @"wasi crt1-reactor.o",
1427 @"wasi crt1-command.o",1427 @"wasi crt1-command.o",
1428 @"wasi libc.a",1428 @"wasi libc.a",
1429 @"wasi libdl.a",
1430 @"libwasi-emulated-process-clocks.a",
1431 @"libwasi-emulated-getpid.a",
1432 @"libwasi-emulated-mman.a",
1433 @"libwasi-emulated-signal.a",
14341429
1435 @"glibc Scrt1.o",1430 @"glibc Scrt1.o",
1436 @"glibc libc_nonshared.a",1431 @"glibc libc_nonshared.a",
src/libs/wasi_libc.zig+162-47
...@@ -44,6 +44,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre...@@ -44,6 +44,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
44 var args = std.array_list.Managed([]const u8).init(arena);44 var args = std.array_list.Managed([]const u8).init(arena);
45 try addCCArgs(comp, arena, &args, .{});45 try addCCArgs(comp, arena, &args, .{});
46 try addLibcBottomHalfIncludes(comp, arena, &args);46 try addLibcBottomHalfIncludes(comp, arena, &args);
47
47 var files = [_]Compilation.CSourceFile{48 var files = [_]Compilation.CSourceFile{
48 .{49 .{
49 .src_path = try comp.dirs.zig_lib.join(arena, &.{50 .src_path = try comp.dirs.zig_lib.join(arena, &.{
...@@ -53,12 +54,14 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre...@@ -53,12 +54,14 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
53 .owner = undefined,54 .owner = undefined,
54 },55 },
55 };56 };
57
56 return comp.build_crt_file("crt1-reactor", .Obj, .@"wasi crt1-reactor.o", prog_node, &files, .{});58 return comp.build_crt_file("crt1-reactor", .Obj, .@"wasi crt1-reactor.o", prog_node, &files, .{});
57 },59 },
58 .crt1_command_o => {60 .crt1_command_o => {
59 var args = std.array_list.Managed([]const u8).init(arena);61 var args = std.array_list.Managed([]const u8).init(arena);
60 try addCCArgs(comp, arena, &args, .{});62 try addCCArgs(comp, arena, &args, .{});
61 try addLibcBottomHalfIncludes(comp, arena, &args);63 try addLibcBottomHalfIncludes(comp, arena, &args);
64
62 var files = [_]Compilation.CSourceFile{65 var files = [_]Compilation.CSourceFile{
63 .{66 .{
64 .src_path = try comp.dirs.zig_lib.join(arena, &.{67 .src_path = try comp.dirs.zig_lib.join(arena, &.{
...@@ -68,6 +71,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre...@@ -68,6 +71,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
68 .owner = undefined,71 .owner = undefined,
69 },72 },
70 };73 };
74
71 return comp.build_crt_file("crt1-command", .Obj, .@"wasi crt1-command.o", prog_node, &files, .{});75 return comp.build_crt_file("crt1-command", .Obj, .@"wasi crt1-command.o", prog_node, &files, .{});
72 },76 },
73 .libc_a => {77 .libc_a => {
...@@ -77,6 +81,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre...@@ -77,6 +81,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
77 // Compile emmalloc.81 // Compile emmalloc.
78 var args = std.array_list.Managed([]const u8).init(arena);82 var args = std.array_list.Managed([]const u8).init(arena);
79 try addCCArgs(comp, arena, &args, .{ .want_O3 = true, .no_strict_aliasing = true });83 try addCCArgs(comp, arena, &args, .{ .want_O3 = true, .no_strict_aliasing = true });
84
80 for (emmalloc_src_files) |file_path| {85 for (emmalloc_src_files) |file_path| {
81 try libc_sources.append(.{86 try libc_sources.append(.{
82 .src_path = try comp.dirs.zig_lib.join(arena, &.{87 .src_path = try comp.dirs.zig_lib.join(arena, &.{
...@@ -122,11 +127,52 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre...@@ -122,11 +127,52 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
122 }127 }
123 }128 }
124129
130 {
131 // Compile musl-fts.
132 var args = std.array_list.Managed([]const u8).init(arena);
133 try addCCArgs(comp, arena, &args, .{ .want_O3 = true });
134 try args.appendSlice(&[_][]const u8{
135 "-I",
136 try comp.dirs.zig_lib.join(arena, &.{
137 "libc",
138 "wasi",
139 "fts",
140 }),
141 });
142
143 for (fts_src_files) |file_path| {
144 try libc_sources.append(.{
145 .src_path = try comp.dirs.zig_lib.join(arena, &.{
146 "libc", try sanitize(arena, file_path),
147 }),
148 .extra_flags = args.items,
149 .owner = undefined,
150 });
151 }
152 }
153
154 if (comp.getTarget().cpu.has(.wasm, .exception_handling)) {
155 // Compile libsetjmp.
156 var args = std.array_list.Managed([]const u8).init(arena);
157 try addCCArgs(comp, arena, &args, .{ .want_O3 = true });
158 try addLibcTopHalfIncludes(comp, arena, &args);
159
160 for (setjmp_src_files) |file_path| {
161 try libc_sources.append(.{
162 .src_path = try comp.dirs.zig_lib.join(arena, &.{
163 "libc", try sanitize(arena, file_path),
164 }),
165 .extra_flags = args.items,
166 .owner = undefined,
167 });
168 }
169 }
170
125 {171 {
126 // Compile libdl.172 // Compile libdl.
127 var args = std.array_list.Managed([]const u8).init(arena);173 var args = std.array_list.Managed([]const u8).init(arena);
128 try addCCArgs(comp, arena, &args, .{ .want_O3 = true });174 try addCCArgs(comp, arena, &args, .{ .want_O3 = true });
129 try addLibcBottomHalfIncludes(comp, arena, &args);175 try addLibcTopHalfIncludes(comp, arena, &args);
130176
131 for (emulated_dl_src_files) |file_path| {177 for (emulated_dl_src_files) |file_path| {
132 try libc_sources.append(.{178 try libc_sources.append(.{
...@@ -143,16 +189,6 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre...@@ -143,16 +189,6 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
143 // Compile libwasi-emulated-process-clocks.189 // Compile libwasi-emulated-process-clocks.
144 var args = std.array_list.Managed([]const u8).init(arena);190 var args = std.array_list.Managed([]const u8).init(arena);
145 try addCCArgs(comp, arena, &args, .{ .want_O3 = true });191 try addCCArgs(comp, arena, &args, .{ .want_O3 = true });
146 try args.appendSlice(&.{
147 "-I",
148 try comp.dirs.zig_lib.join(arena, &.{
149 "libc",
150 "wasi",
151 "libc-bottom-half",
152 "cloudlibc",
153 "src",
154 }),
155 });
156192
157 for (emulated_process_clocks_src_files) |file_path| {193 for (emulated_process_clocks_src_files) |file_path| {
158 try libc_sources.append(.{194 try libc_sources.append(.{
...@@ -169,7 +205,6 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre...@@ -169,7 +205,6 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
169 // Compile libwasi-emulated-getpid.205 // Compile libwasi-emulated-getpid.
170 var args = std.array_list.Managed([]const u8).init(arena);206 var args = std.array_list.Managed([]const u8).init(arena);
171 try addCCArgs(comp, arena, &args, .{ .want_O3 = true });207 try addCCArgs(comp, arena, &args, .{ .want_O3 = true });
172 try addLibcBottomHalfIncludes(comp, arena, &args);
173208
174 for (emulated_getpid_src_files) |file_path| {209 for (emulated_getpid_src_files) |file_path| {
175 try libc_sources.append(.{210 try libc_sources.append(.{
...@@ -186,7 +221,6 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre...@@ -186,7 +221,6 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
186 // Compile libwasi-emulated-mman.221 // Compile libwasi-emulated-mman.
187 var args = std.array_list.Managed([]const u8).init(arena);222 var args = std.array_list.Managed([]const u8).init(arena);
188 try addCCArgs(comp, arena, &args, .{ .want_O3 = true });223 try addCCArgs(comp, arena, &args, .{ .want_O3 = true });
189 try addLibcBottomHalfIncludes(comp, arena, &args);
190224
191 for (emulated_mman_src_files) |file_path| {225 for (emulated_mman_src_files) |file_path| {
192 try libc_sources.append(.{226 try libc_sources.append(.{
...@@ -278,13 +312,18 @@ fn addCCArgs(...@@ -278,13 +312,18 @@ fn addCCArgs(
278 "-mthread-model",312 "-mthread-model",
279 "single",313 "single",
280314
281 "-isysroot",315 "-I",
282 "/",316 try comp.dirs.zig_lib.join(arena, &.{
317 "libc",
318 "wasi",
319 "libc-bottom-half",
320 "cloudlibc",
321 "src",
322 }),
283323
284 "-iwithsysroot",324 "-isystem",
285 try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", triple }),325 try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", triple }),
286326 "-isystem",
287 "-iwithsysroot",
288 try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", "generic-musl" }),327 try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", "generic-musl" }),
289328
290 "-DBULK_MEMORY_THRESHOLD=32",329 "-DBULK_MEMORY_THRESHOLD=32",
...@@ -338,7 +377,6 @@ fn addLibcBottomHalfIncludes(...@@ -338,7 +377,6 @@ fn addLibcBottomHalfIncludes(
338 "src",377 "src",
339 "include",378 "include",
340 }),379 }),
341
342 "-I",380 "-I",
343 try comp.dirs.zig_lib.join(arena, &.{381 try comp.dirs.zig_lib.join(arena, &.{
344 "libc",382 "libc",
...@@ -346,8 +384,8 @@ fn addLibcBottomHalfIncludes(...@@ -346,8 +384,8 @@ fn addLibcBottomHalfIncludes(
346 "src",384 "src",
347 "include",385 "include",
348 }),386 }),
349
350 "-I",387 "-I",
388
351 try comp.dirs.zig_lib.join(arena, &.{389 try comp.dirs.zig_lib.join(arena, &.{
352 "libc",390 "libc",
353 "wasi",391 "wasi",
...@@ -356,7 +394,6 @@ fn addLibcBottomHalfIncludes(...@@ -356,7 +394,6 @@ fn addLibcBottomHalfIncludes(
356 "src",394 "src",
357 "internal",395 "internal",
358 }),396 }),
359
360 "-I",397 "-I",
361 try comp.dirs.zig_lib.join(arena, &.{398 try comp.dirs.zig_lib.join(arena, &.{
362 "libc",399 "libc",
...@@ -382,7 +419,6 @@ fn addLibcTopHalfIncludes(...@@ -382,7 +419,6 @@ fn addLibcTopHalfIncludes(
382 "src",419 "src",
383 "include",420 "include",
384 }),421 }),
385
386 "-I",422 "-I",
387 try comp.dirs.zig_lib.join(arena, &.{423 try comp.dirs.zig_lib.join(arena, &.{
388 "libc",424 "libc",
...@@ -400,7 +436,6 @@ fn addLibcTopHalfIncludes(...@@ -400,7 +436,6 @@ fn addLibcTopHalfIncludes(
400 "src",436 "src",
401 "internal",437 "internal",
402 }),438 }),
403
404 "-I",439 "-I",
405 try comp.dirs.zig_lib.join(arena, &.{440 try comp.dirs.zig_lib.join(arena, &.{
406 "libc",441 "libc",
...@@ -418,7 +453,6 @@ fn addLibcTopHalfIncludes(...@@ -418,7 +453,6 @@ fn addLibcTopHalfIncludes(
418 "arch",453 "arch",
419 "wasm32",454 "wasm32",
420 }),455 }),
421
422 "-I",456 "-I",
423 try comp.dirs.zig_lib.join(arena, &.{457 try comp.dirs.zig_lib.join(arena, &.{
424 "libc",458 "libc",
...@@ -469,8 +503,8 @@ const libc_bottom_half_src_files = [_][]const u8{...@@ -469,8 +503,8 @@ const libc_bottom_half_src_files = [_][]const u8{
469 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/socket/recv.c",503 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/socket/recv.c",
470 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/socket/send.c",504 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/socket/send.c",
471 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/socket/shutdown.c",505 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/socket/shutdown.c",
472 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/stat/fstat.c",
473 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/stat/fstatat.c",506 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/stat/fstatat.c",
507 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/stat/fstat.c",
474 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/stat/futimens.c",508 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/stat/futimens.c",
475 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/stat/mkdirat.c",509 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/stat/mkdirat.c",
476 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/stat/utimensat.c",510 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/stat/utimensat.c",
...@@ -479,11 +513,11 @@ const libc_bottom_half_src_files = [_][]const u8{...@@ -479,11 +513,11 @@ const libc_bottom_half_src_files = [_][]const u8{
479 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/uio/pwritev.c",513 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/uio/pwritev.c",
480 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/uio/readv.c",514 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/uio/readv.c",
481 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/uio/writev.c",515 "wasi/libc-bottom-half/cloudlibc/src/libc/sys/uio/writev.c",
482 "wasi/libc-bottom-half/cloudlibc/src/libc/time/CLOCK_MONOTONIC.c",
483 "wasi/libc-bottom-half/cloudlibc/src/libc/time/CLOCK_REALTIME.c",
484 "wasi/libc-bottom-half/cloudlibc/src/libc/time/clock_getres.c",516 "wasi/libc-bottom-half/cloudlibc/src/libc/time/clock_getres.c",
485 "wasi/libc-bottom-half/cloudlibc/src/libc/time/clock_gettime.c",517 "wasi/libc-bottom-half/cloudlibc/src/libc/time/clock_gettime.c",
518 "wasi/libc-bottom-half/cloudlibc/src/libc/time/CLOCK_MONOTONIC.c",
486 "wasi/libc-bottom-half/cloudlibc/src/libc/time/clock_nanosleep.c",519 "wasi/libc-bottom-half/cloudlibc/src/libc/time/clock_nanosleep.c",
520 "wasi/libc-bottom-half/cloudlibc/src/libc/time/CLOCK_REALTIME.c",
487 "wasi/libc-bottom-half/cloudlibc/src/libc/time/nanosleep.c",521 "wasi/libc-bottom-half/cloudlibc/src/libc/time/nanosleep.c",
488 "wasi/libc-bottom-half/cloudlibc/src/libc/time/time.c",522 "wasi/libc-bottom-half/cloudlibc/src/libc/time/time.c",
489 "wasi/libc-bottom-half/cloudlibc/src/libc/unistd/faccessat.c",523 "wasi/libc-bottom-half/cloudlibc/src/libc/unistd/faccessat.c",
...@@ -501,25 +535,18 @@ const libc_bottom_half_src_files = [_][]const u8{...@@ -501,25 +535,18 @@ const libc_bottom_half_src_files = [_][]const u8{
501 "wasi/libc-bottom-half/cloudlibc/src/libc/unistd/unlinkat.c",535 "wasi/libc-bottom-half/cloudlibc/src/libc/unistd/unlinkat.c",
502 "wasi/libc-bottom-half/cloudlibc/src/libc/unistd/usleep.c",536 "wasi/libc-bottom-half/cloudlibc/src/libc/unistd/usleep.c",
503 "wasi/libc-bottom-half/cloudlibc/src/libc/unistd/write.c",537 "wasi/libc-bottom-half/cloudlibc/src/libc/unistd/write.c",
504 "wasi/libc-bottom-half/sources/__errno_location.c",
505 "wasi/libc-bottom-half/sources/__main_void.c",
506 "wasi/libc-bottom-half/sources/__wasilibc_dt.c",
507 "wasi/libc-bottom-half/sources/__wasilibc_environ.c",
508 "wasi/libc-bottom-half/sources/__wasilibc_fd_renumber.c",
509 "wasi/libc-bottom-half/sources/__wasilibc_initialize_environ.c",
510 "wasi/libc-bottom-half/sources/__wasilibc_real.c",
511 "wasi/libc-bottom-half/sources/__wasilibc_rmdirat.c",
512 "wasi/libc-bottom-half/sources/__wasilibc_tell.c",
513 "wasi/libc-bottom-half/sources/__wasilibc_unlinkat.c",
514 "wasi/libc-bottom-half/sources/abort.c",538 "wasi/libc-bottom-half/sources/abort.c",
515 "wasi/libc-bottom-half/sources/accept-wasip1.c",539 "wasi/libc-bottom-half/sources/accept-wasip1.c",
516 "wasi/libc-bottom-half/sources/at_fdcwd.c",540 "wasi/libc-bottom-half/sources/at_fdcwd.c",
541 "wasi/libc-bottom-half/sources/chdir.c",
517 "wasi/libc-bottom-half/sources/complex-builtins.c",542 "wasi/libc-bottom-half/sources/complex-builtins.c",
518 "wasi/libc-bottom-half/sources/environ.c",543 "wasi/libc-bottom-half/sources/environ.c",
519 "wasi/libc-bottom-half/sources/errno.c",544 "wasi/libc-bottom-half/sources/errno.c",
545 "wasi/libc-bottom-half/sources/__errno_location.c",
520 "wasi/libc-bottom-half/sources/getcwd.c",546 "wasi/libc-bottom-half/sources/getcwd.c",
521 "wasi/libc-bottom-half/sources/getentropy.c",547 "wasi/libc-bottom-half/sources/getentropy.c",
522 "wasi/libc-bottom-half/sources/isatty.c",548 "wasi/libc-bottom-half/sources/isatty.c",
549 "wasi/libc-bottom-half/sources/__main_void.c",
523 "wasi/libc-bottom-half/sources/math/fmin-fmax.c",550 "wasi/libc-bottom-half/sources/math/fmin-fmax.c",
524 "wasi/libc-bottom-half/sources/math/math-builtins.c",551 "wasi/libc-bottom-half/sources/math/math-builtins.c",
525 "wasi/libc-bottom-half/sources/posix.c",552 "wasi/libc-bottom-half/sources/posix.c",
...@@ -527,7 +554,15 @@ const libc_bottom_half_src_files = [_][]const u8{...@@ -527,7 +554,15 @@ const libc_bottom_half_src_files = [_][]const u8{
527 "wasi/libc-bottom-half/sources/reallocarray.c",554 "wasi/libc-bottom-half/sources/reallocarray.c",
528 "wasi/libc-bottom-half/sources/sbrk.c",555 "wasi/libc-bottom-half/sources/sbrk.c",
529 "wasi/libc-bottom-half/sources/truncate.c",556 "wasi/libc-bottom-half/sources/truncate.c",
530 "wasi/libc-bottom-half/sources/chdir.c",557 "wasi/libc-bottom-half/sources/__wasilibc_dt.c",
558 "wasi/libc-bottom-half/sources/__wasilibc_environ.c",
559 "wasi/libc-bottom-half/sources/__wasilibc_fd_renumber.c",
560 "wasi/libc-bottom-half/sources/__wasilibc_initialize_environ.c",
561 "wasi/libc-bottom-half/sources/__wasilibc_random.c",
562 "wasi/libc-bottom-half/sources/__wasilibc_real.c",
563 "wasi/libc-bottom-half/sources/__wasilibc_rmdirat.c",
564 "wasi/libc-bottom-half/sources/__wasilibc_tell.c",
565 "wasi/libc-bottom-half/sources/__wasilibc_unlinkat.c",
531};566};
532567
533const libc_top_half_src_files = [_][]const u8{568const libc_top_half_src_files = [_][]const u8{
...@@ -593,6 +628,7 @@ const libc_top_half_src_files = [_][]const u8{...@@ -593,6 +628,7 @@ const libc_top_half_src_files = [_][]const u8{
593 "musl/src/complex/ctanhf.c",628 "musl/src/complex/ctanhf.c",
594 "musl/src/complex/ctanhl.c",629 "musl/src/complex/ctanhl.c",
595 "musl/src/complex/ctanl.c",630 "musl/src/complex/ctanl.c",
631 "musl/src/conf/confstr.c",
596 "musl/src/conf/legacy.c",632 "musl/src/conf/legacy.c",
597 "musl/src/conf/pathconf.c",633 "musl/src/conf/pathconf.c",
598 "musl/src/crypt/crypt_blowfish.c",634 "musl/src/crypt/crypt_blowfish.c",
...@@ -971,8 +1007,10 @@ const libc_top_half_src_files = [_][]const u8{...@@ -971,8 +1007,10 @@ const libc_top_half_src_files = [_][]const u8{
971 "musl/src/stdio/__toread.c",1007 "musl/src/stdio/__toread.c",
972 "musl/src/stdio/__towrite.c",1008 "musl/src/stdio/__towrite.c",
973 "musl/src/stdio/__uflow.c",1009 "musl/src/stdio/__uflow.c",
1010 "musl/src/stdio/ungetc.c",
974 "musl/src/stdio/ungetwc.c",1011 "musl/src/stdio/ungetwc.c",
975 "musl/src/stdio/vasprintf.c",1012 "musl/src/stdio/vasprintf.c",
1013 "musl/src/stdio/vfwscanf.c",
976 "musl/src/stdio/vprintf.c",1014 "musl/src/stdio/vprintf.c",
977 "musl/src/stdio/vscanf.c",1015 "musl/src/stdio/vscanf.c",
978 "musl/src/stdio/vsprintf.c",1016 "musl/src/stdio/vsprintf.c",
...@@ -994,23 +1032,20 @@ const libc_top_half_src_files = [_][]const u8{...@@ -994,23 +1032,20 @@ const libc_top_half_src_files = [_][]const u8{
994 "musl/src/stdlib/lldiv.c",1032 "musl/src/stdlib/lldiv.c",
995 "musl/src/stdlib/qsort.c",1033 "musl/src/stdlib/qsort.c",
996 "musl/src/stdlib/qsort_nr.c",1034 "musl/src/stdlib/qsort_nr.c",
1035 "musl/src/stdlib/strtol.c",
997 "musl/src/string/bcmp.c",1036 "musl/src/string/bcmp.c",
998 "musl/src/string/bcopy.c",1037 "musl/src/string/bcopy.c",
999 "musl/src/string/explicit_bzero.c",1038 "musl/src/string/explicit_bzero.c",
1000 "musl/src/string/index.c",1039 "musl/src/string/index.c",
1001 "musl/src/string/memccpy.c",1040 "musl/src/string/memccpy.c",
1002 "musl/src/string/memchr.c",
1003 "musl/src/string/memcmp.c",
1004 "musl/src/string/memmem.c",1041 "musl/src/string/memmem.c",
1005 "musl/src/string/mempcpy.c",1042 "musl/src/string/mempcpy.c",
1006 "musl/src/string/memrchr.c",
1007 "musl/src/string/rindex.c",1043 "musl/src/string/rindex.c",
1008 "musl/src/string/stpcpy.c",1044 "musl/src/string/stpcpy.c",
1009 "musl/src/string/stpncpy.c",1045 "musl/src/string/stpncpy.c",
1010 "musl/src/string/strcasestr.c",1046 "musl/src/string/strcasestr.c",
1011 "musl/src/string/strcat.c",1047 "musl/src/string/strcat.c",
1012 "musl/src/string/strchr.c",1048 "musl/src/string/strchr.c",
1013 "musl/src/string/strchrnul.c",
1014 "musl/src/string/strcpy.c",1049 "musl/src/string/strcpy.c",
1015 "musl/src/string/strcspn.c",1050 "musl/src/string/strcspn.c",
1016 "musl/src/string/strdup.c",1051 "musl/src/string/strdup.c",
...@@ -1058,6 +1093,37 @@ const libc_top_half_src_files = [_][]const u8{...@@ -1058,6 +1093,37 @@ const libc_top_half_src_files = [_][]const u8{
1058 "musl/src/string/wmemcpy.c",1093 "musl/src/string/wmemcpy.c",
1059 "musl/src/string/wmemmove.c",1094 "musl/src/string/wmemmove.c",
1060 "musl/src/string/wmemset.c",1095 "musl/src/string/wmemset.c",
1096 "musl/src/thread/default_attr.c",
1097 "musl/src/thread/pthread_attr_destroy.c",
1098 "musl/src/thread/pthread_attr_init.c",
1099 "musl/src/thread/pthread_attr_setdetachstate.c",
1100 "musl/src/thread/pthread_attr_setstack.c",
1101 "musl/src/thread/pthread_attr_setstacksize.c",
1102 "musl/src/thread/pthread_barrierattr_destroy.c",
1103 "musl/src/thread/pthread_barrierattr_init.c",
1104 "musl/src/thread/pthread_barrierattr_setpshared.c",
1105 "musl/src/thread/pthread_cleanup_push.c",
1106 "musl/src/thread/pthread_condattr_destroy.c",
1107 "musl/src/thread/pthread_condattr_init.c",
1108 "musl/src/thread/pthread_condattr_setpshared.c",
1109 "musl/src/thread/pthread_equal.c",
1110 "musl/src/thread/pthread_getspecific.c",
1111 "musl/src/thread/pthread_mutexattr_destroy.c",
1112 "musl/src/thread/pthread_mutexattr_init.c",
1113 "musl/src/thread/pthread_mutexattr_setpshared.c",
1114 "musl/src/thread/pthread_mutexattr_settype.c",
1115 "musl/src/thread/pthread_mutex_init.c",
1116 "musl/src/thread/pthread_rwlockattr_destroy.c",
1117 "musl/src/thread/pthread_rwlockattr_init.c",
1118 "musl/src/thread/pthread_rwlockattr_setpshared.c",
1119 "musl/src/thread/pthread_rwlock_destroy.c",
1120 "musl/src/thread/pthread_rwlock_init.c",
1121 "musl/src/thread/pthread_setcancelstate.c",
1122 "musl/src/thread/pthread_setcanceltype.c",
1123 "musl/src/thread/pthread_setspecific.c",
1124 "musl/src/thread/pthread_spin_destroy.c",
1125 "musl/src/thread/pthread_spin_init.c",
1126 "musl/src/thread/pthread_testcancel.c",
1061 "musl/src/thread/thrd_sleep.c",1127 "musl/src/thread/thrd_sleep.c",
1062 "musl/src/time/asctime.c",1128 "musl/src/time/asctime.c",
1063 "musl/src/time/asctime_r.c",1129 "musl/src/time/asctime_r.c",
...@@ -1071,7 +1137,6 @@ const libc_top_half_src_files = [_][]const u8{...@@ -1071,7 +1137,6 @@ const libc_top_half_src_files = [_][]const u8{
1071 "musl/src/time/__year_to_secs.c",1137 "musl/src/time/__year_to_secs.c",
1072 "musl/src/unistd/posix_close.c",1138 "musl/src/unistd/posix_close.c",
10731139
1074 "wasi/libc-top-half/musl/src/conf/confstr.c",
1075 "wasi/libc-top-half/musl/src/conf/fpathconf.c",1140 "wasi/libc-top-half/musl/src/conf/fpathconf.c",
1076 "wasi/libc-top-half/musl/src/conf/sysconf.c",1141 "wasi/libc-top-half/musl/src/conf/sysconf.c",
1077 "wasi/libc-top-half/musl/src/dirent/alphasort.c",1142 "wasi/libc-top-half/musl/src/dirent/alphasort.c",
...@@ -1112,9 +1177,9 @@ const libc_top_half_src_files = [_][]const u8{...@@ -1112,9 +1177,9 @@ const libc_top_half_src_files = [_][]const u8{
1112 "wasi/libc-top-half/musl/src/misc/nftw.c",1177 "wasi/libc-top-half/musl/src/misc/nftw.c",
1113 "wasi/libc-top-half/musl/src/misc/uname.c",1178 "wasi/libc-top-half/musl/src/misc/uname.c",
1114 "wasi/libc-top-half/musl/src/prng/random.c",1179 "wasi/libc-top-half/musl/src/prng/random.c",
1180 "wasi/libc-top-half/musl/src/regex/glob.c",
1115 "wasi/libc-top-half/musl/src/regex/regcomp.c",1181 "wasi/libc-top-half/musl/src/regex/regcomp.c",
1116 "wasi/libc-top-half/musl/src/regex/regexec.c",1182 "wasi/libc-top-half/musl/src/regex/regexec.c",
1117 "wasi/libc-top-half/musl/src/regex/glob.c",
1118 "wasi/libc-top-half/musl/src/regex/tre-mem.c",1183 "wasi/libc-top-half/musl/src/regex/tre-mem.c",
1119 "wasi/libc-top-half/musl/src/stat/futimesat.c",1184 "wasi/libc-top-half/musl/src/stat/futimesat.c",
1120 "wasi/libc-top-half/musl/src/stdio/__fdopen.c",1185 "wasi/libc-top-half/musl/src/stdio/__fdopen.c",
...@@ -1144,21 +1209,32 @@ const libc_top_half_src_files = [_][]const u8{...@@ -1144,21 +1209,32 @@ const libc_top_half_src_files = [_][]const u8{
1144 "wasi/libc-top-half/musl/src/stdio/__stdio_write.c",1209 "wasi/libc-top-half/musl/src/stdio/__stdio_write.c",
1145 "wasi/libc-top-half/musl/src/stdio/stdout.c",1210 "wasi/libc-top-half/musl/src/stdio/stdout.c",
1146 "wasi/libc-top-half/musl/src/stdio/__stdout_write.c",1211 "wasi/libc-top-half/musl/src/stdio/__stdout_write.c",
1147 "wasi/libc-top-half/musl/src/stdio/ungetc.c",
1148 "wasi/libc-top-half/musl/src/stdio/vdprintf.c",1212 "wasi/libc-top-half/musl/src/stdio/vdprintf.c",
1149 "wasi/libc-top-half/musl/src/stdio/vfprintf.c",1213 "wasi/libc-top-half/musl/src/stdio/vfprintf.c",
1150 "wasi/libc-top-half/musl/src/stdio/vfscanf.c",1214 "wasi/libc-top-half/musl/src/stdio/vfscanf.c",
1151 "wasi/libc-top-half/musl/src/stdio/vfwprintf.c",1215 "wasi/libc-top-half/musl/src/stdio/vfwprintf.c",
1152 "wasi/libc-top-half/musl/src/stdio/vfwscanf.c",
1153 "wasi/libc-top-half/musl/src/stdio/vsnprintf.c",1216 "wasi/libc-top-half/musl/src/stdio/vsnprintf.c",
1154 "wasi/libc-top-half/musl/src/stdio/vsscanf.c",1217 "wasi/libc-top-half/musl/src/stdio/vsscanf.c",
1155 "wasi/libc-top-half/musl/src/stdio/vswprintf.c",1218 "wasi/libc-top-half/musl/src/stdio/vswprintf.c",
1156 "wasi/libc-top-half/musl/src/stdio/vswscanf.c",1219 "wasi/libc-top-half/musl/src/stdio/vswscanf.c",
1157 "wasi/libc-top-half/musl/src/stdlib/strtod.c",1220 "wasi/libc-top-half/musl/src/stdlib/strtod.c",
1158 "wasi/libc-top-half/musl/src/stdlib/strtol.c",
1159 "wasi/libc-top-half/musl/src/stdlib/wcstod.c",1221 "wasi/libc-top-half/musl/src/stdlib/wcstod.c",
1160 "wasi/libc-top-half/musl/src/stdlib/wcstol.c",1222 "wasi/libc-top-half/musl/src/stdlib/wcstol.c",
1223 "wasi/libc-top-half/musl/src/string/memchr.c",
1224 "wasi/libc-top-half/musl/src/string/memcmp.c",
1225 "wasi/libc-top-half/musl/src/string/memrchr.c",
1161 "wasi/libc-top-half/musl/src/string/memset.c",1226 "wasi/libc-top-half/musl/src/string/memset.c",
1227 "wasi/libc-top-half/musl/src/string/strchrnul.c",
1228 "wasi/libc-top-half/musl/src/thread/pthread_attr_get.c",
1229 "wasi/libc-top-half/musl/src/thread/pthread_attr_setguardsize.c",
1230 "wasi/libc-top-half/musl/src/thread/pthread_attr_setschedparam.c",
1231 "wasi/libc-top-half/musl/src/thread/pthread_cancel.c",
1232 "wasi/libc-top-half/musl/src/thread/pthread_condattr_setclock.c",
1233 "wasi/libc-top-half/musl/src/thread/pthread_key_create.c",
1234 "wasi/libc-top-half/musl/src/thread/pthread_mutexattr_setprotocol.c",
1235 "wasi/libc-top-half/musl/src/thread/pthread_mutexattr_setrobust.c",
1236 "wasi/libc-top-half/musl/src/thread/pthread_mutex_destroy.c",
1237 "wasi/libc-top-half/musl/src/thread/pthread_self.c",
1162 "wasi/libc-top-half/musl/src/time/getdate.c",1238 "wasi/libc-top-half/musl/src/time/getdate.c",
1163 "wasi/libc-top-half/musl/src/time/gmtime.c",1239 "wasi/libc-top-half/musl/src/time/gmtime.c",
1164 "wasi/libc-top-half/musl/src/time/gmtime_r.c",1240 "wasi/libc-top-half/musl/src/time/gmtime_r.c",
...@@ -1173,11 +1249,50 @@ const libc_top_half_src_files = [_][]const u8{...@@ -1173,11 +1249,50 @@ const libc_top_half_src_files = [_][]const u8{
1173 "wasi/libc-top-half/musl/src/time/wcsftime.c",1249 "wasi/libc-top-half/musl/src/time/wcsftime.c",
11741250
1175 "wasi/libc-top-half/sources/arc4random.c",1251 "wasi/libc-top-half/sources/arc4random.c",
1252
1253 "wasi/thread-stub/pthread_barrier_destroy.c",
1254 "wasi/thread-stub/pthread_barrier_init.c",
1255 "wasi/thread-stub/pthread_barrier_wait.c",
1256 "wasi/thread-stub/pthread_cond_broadcast.c",
1257 "wasi/thread-stub/pthread_cond_destroy.c",
1258 "wasi/thread-stub/pthread_cond_init.c",
1259 "wasi/thread-stub/pthread_cond_signal.c",
1260 "wasi/thread-stub/pthread_cond_timedwait.c",
1261 "wasi/thread-stub/pthread_cond_wait.c",
1262 "wasi/thread-stub/pthread_create.c",
1263 "wasi/thread-stub/pthread_detach.c",
1264 "wasi/thread-stub/pthread_getattr_np.c",
1265 "wasi/thread-stub/pthread_join.c",
1266 "wasi/thread-stub/pthread_mutex_consistent.c",
1267 "wasi/thread-stub/pthread_mutex_getprioceiling.c",
1268 "wasi/thread-stub/pthread_mutex_lock.c",
1269 "wasi/thread-stub/pthread_mutex_timedlock.c",
1270 "wasi/thread-stub/pthread_mutex_trylock.c",
1271 "wasi/thread-stub/pthread_mutex_unlock.c",
1272 "wasi/thread-stub/pthread_once.c",
1273 "wasi/thread-stub/pthread_rwlock_rdlock.c",
1274 "wasi/thread-stub/pthread_rwlock_timedrdlock.c",
1275 "wasi/thread-stub/pthread_rwlock_timedwrlock.c",
1276 "wasi/thread-stub/pthread_rwlock_tryrdlock.c",
1277 "wasi/thread-stub/pthread_rwlock_trywrlock.c",
1278 "wasi/thread-stub/pthread_rwlock_unlock.c",
1279 "wasi/thread-stub/pthread_rwlock_wrlock.c",
1280 "wasi/thread-stub/pthread_spin_lock.c",
1281 "wasi/thread-stub/pthread_spin_trylock.c",
1282 "wasi/thread-stub/pthread_spin_unlock.c",
1176};1283};
11771284
1178const crt1_command_src_file = "wasi/libc-bottom-half/crt/crt1-command.c";1285const crt1_command_src_file = "wasi/libc-bottom-half/crt/crt1-command.c";
1179const crt1_reactor_src_file = "wasi/libc-bottom-half/crt/crt1-reactor.c";1286const crt1_reactor_src_file = "wasi/libc-bottom-half/crt/crt1-reactor.c";
11801287
1288const fts_src_files = &[_][]const u8{
1289 "wasi/fts/musl-fts/fts.c",
1290};
1291
1292const setjmp_src_files = &[_][]const u8{
1293 "wasi/libc-top-half/musl/src/setjmp/wasm32/rt.c",
1294};
1295
1181const emulated_dl_src_files = &[_][]const u8{1296const emulated_dl_src_files = &[_][]const u8{
1182 "wasi/libc-top-half/musl/src/misc/dl.c",1297 "wasi/libc-top-half/musl/src/misc/dl.c",
1183};1298};