File: cloudabi.rs

package info (click to toggle)
rust-cloudabi 0.0.3-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster, sid
  • size: 164 kB
  • sloc: makefile: 2
file content (2847 lines) | stat: -rw-r--r-- 96,698 bytes parent folder | download | duplicates (25)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
// Copyright (c) 2016-2017 Nuxi (https://nuxi.nl/) and contributors.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
// This file is automatically generated. Do not edit.
//
// Source: https://github.com/NuxiNL/cloudabi

// Appease Rust's tidy.
// ignore-license
// ignore-tidy-linelength

//! **PLEASE NOTE: This entire crate including this
//! documentation is automatically generated from
//! [`cloudabi.txt`](https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt)**
//!
//! # Nuxi CloudABI
//!
//! CloudABI is what you get if you take POSIX, add capability-based
//! security, and remove everything that's incompatible with that. The
//! result is a minimal ABI consisting of only 49 syscalls.
//!
//! CloudABI doesn't have its own kernel, but instead is implemented in existing
//! kernels: FreeBSD has CloudABI support for x86-64 and arm64, and [a patch-set
//! for NetBSD](https://github.com/NuxiNL/netbsd) and [a patch-set for
//! Linux](https://github.com/NuxiNL/linux) are available as well. This means that
//! CloudABI binaries can be executed on different operating systems, without any
//! modification.
//!
//! ## Capability-Based Security
//!
//! Capability-based security means that processes can only perform
//! actions that have no global impact. Processes cannot open files by
//! their absolute path, cannot open network connections, and cannot
//! observe global system state such as the process table.
//!
//! The capabilities of a process are fully determined by its set of open
//! file descriptors (fds). For example, files can only be opened if the
//! process already has a file descriptor to a directory the file is in.
//!
//! Unlike in POSIX, where processes are normally started with file
//! descriptors 0, 1, and 2 reserved for standard input, output, and
//! error, CloudABI does not reserve any file descriptor numbers for
//! specific purposes.
//!
//! In CloudABI, a process depends on its parent process to launch it with
//! the right set of resources, since the process will not be able to open
//! any new resources. For example, a simple static web server would need
//! to be started with a file descriptor to a [TCP
//! listener](https://github.com/NuxiNL/flower), and a file descriptor to
//! the directory for which to serve files. The web server will then be
//! unable to do anything other than reading files in that directory, and
//! process incoming network connections.
//!
//! So, unknown CloudABI binaries can safely be executed without the need
//! for containers, virtual machines, or other sandboxing technologies.
//!
//! Watch [Ed Schouten's Talk at
//! 32C3](https://www.youtube.com/watch?v=3N29vrPoDv8) for more
//! information about what capability-based security for UNIX means.
//!
//! ## Cloudlibc
//!
//! [Cloudlibc](https://github.com/NuxiNL/cloudlibc) is an implementation
//! of the C standard library, without all CloudABI-incompatible
//! functions. For example, Cloudlibc does not have `printf`, but does
//! have `fprintf`. It does not have `open`, but does have `openat`.
//!
//! ## CloudABI-Ports
//!
//! [CloudABI-Ports](https://github.com/NuxiNL/cloudabi-ports) is a
//! collection of ports of commonly used libraries and applications to
//! CloudABI. It contains software such as `zlib`, `libpng`, `boost`,
//! `memcached`, and much more. The software is patched to not depend on
//! any global state, such as files in `/etc` or `/dev`, using `open()`,
//! etc.
//!
//! ## Using CloudABI
//!
//! Instructions for using CloudABI (including kernel modules/patches,
//! toolchain, and ports) are available for several operating systems:
//!
//! - [Arch Linux](https://nuxi.nl/cloudabi/archlinux/)
//! - [Debian, Ubuntu, and other Debian derivatives](https://nuxi.nl/cloudabi/debian/)
//! - [FreeBSD, PC-BSD and DragonFly BSD](https://nuxi.nl/cloudabi/freebsd/)
//! - [Mac OS X](https://nuxi.nl/cloudabi/mac/)
//! - [NetBSD](https://nuxi.nl/cloudabi/netbsd/)
//!
//! ## Specification of the ABI
//!
//! The entire ABI is specified in a a file called
//! [`cloudabi.txt`](https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt),
//! from which all
//! [headers](https://github.com/NuxiNL/cloudabi/tree/master/headers)
//! and documentation (including the one you're reading now) is generated.

#![no_std]
#![allow(non_camel_case_types)]

include!("bitflags.rs");

/// File or memory access pattern advisory information.
#[repr(u8)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum advice {
  /// The application expects that it will not access the
  /// specified data in the near future.
  DONTNEED   = 1,
  /// The application expects to access the specified data
  /// once and then not reuse it thereafter.
  NOREUSE    = 2,
  /// The application has no advice to give on its behavior
  /// with respect to the specified data.
  NORMAL     = 3,
  /// The application expects to access the specified data
  /// in a random order.
  RANDOM     = 4,
  /// The application expects to access the specified data
  /// sequentially from lower offsets to higher offsets.
  SEQUENTIAL = 5,
  /// The application expects to access the specified data
  /// in the near future.
  WILLNEED   = 6,
  #[doc(hidden)] _NonExhaustive = -1 as isize as u8,
}

/// Enumeration describing the kind of value stored in [`auxv`](struct.auxv.html).
#[repr(u32)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum auxtype {
  /// Base address of the binary argument data provided to
  /// [`proc_exec()`](fn.proc_exec.html).
  ARGDATA      = 256,
  /// Length of the binary argument data provided to
  /// [`proc_exec()`](fn.proc_exec.html).
  ARGDATALEN   = 257,
  /// Base address at which the executable is placed in
  /// memory.
  BASE         =   7,
  /// Base address of a buffer of random data that may be
  /// used for non-cryptographic purposes, for example as a
  /// canary for stack smashing protection.
  CANARY       = 258,
  /// Length of a buffer of random data that may be used
  /// for non-cryptographic purposes, for example as a
  /// canary for stack smashing protection.
  CANARYLEN    = 259,
  /// Number of CPUs that the system this process is running
  /// on has.
  NCPUS        = 260,
  /// Terminator of the auxiliary vector.
  NULL         =   0,
  /// Smallest memory object size for which individual
  /// memory protection controls can be configured.
  PAGESZ       =   6,
  /// Address of the first ELF program header of the
  /// executable.
  PHDR         =   3,
  /// Number of ELF program headers of the executable.
  PHNUM        =   4,
  /// Identifier of the process.
  ///
  /// This environment does not provide any simple numerical
  /// process identifiers, for the reason that these are not
  /// useful in distributed contexts. Instead, processes are
  /// identified by a UUID.
  ///
  /// This record should point to sixteen bytes of binary
  /// data, containing a version 4 UUID (fully random).
  PID          = 263,
  /// Address of the ELF header of the vDSO.
  ///
  /// The vDSO is a shared library that is mapped in the
  /// address space of the process. It provides entry points
  /// for every system call supported by the environment,
  /// all having a corresponding symbol that is prefixed
  /// with `cloudabi_sys_`. System calls should be invoked
  /// through these entry points.
  ///
  /// The first advantage of letting processes call into a
  /// vDSO to perform system calls instead of raising
  /// hardware traps is that it allows for easy emulation of
  /// executables on top of existing operating systems. The
  /// second advantage is that in cases where an operating
  /// system provides native support for CloudABI executables,
  /// it may still implement partial userspace
  /// implementations of these system calls to improve
  /// performance (e.g., [`clock_time_get()`](fn.clock_time_get.html)). It also provides
  /// a more dynamic way of adding, removing or replacing
  /// system calls.
  SYSINFO_EHDR = 262,
  /// Thread ID of the initial thread of the process.
  TID          = 261,
  #[doc(hidden)] _NonExhaustive = -1 as isize as u32,
}

/// Identifiers for clocks.
#[repr(u32)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum clockid {
  /// The system-wide monotonic clock, which is defined as a
  /// clock measuring real time, whose value cannot be
  /// adjusted and which cannot have negative clock jumps.
  ///
  /// The epoch of this clock is undefined. The absolute
  /// time value of this clock therefore has no meaning.
  MONOTONIC          = 1,
  /// The CPU-time clock associated with the current
  /// process.
  PROCESS_CPUTIME_ID = 2,
  /// The system-wide clock measuring real time. Time value
  /// zero corresponds with 1970-01-01T00:00:00Z.
  REALTIME           = 3,
  /// The CPU-time clock associated with the current thread.
  THREAD_CPUTIME_ID  = 4,
  #[doc(hidden)] _NonExhaustive = -1 as isize as u32,
}

/// A userspace condition variable.
#[repr(C)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct condvar(pub u32);
/// The condition variable is in its initial state. There
/// are no threads waiting to be woken up. If the
/// condition variable has any other value, the kernel
/// must be called to wake up any sleeping threads.
pub const CONDVAR_HAS_NO_WAITERS: condvar = condvar(0);

/// Identifier for a device containing a file system. Can be used
/// in combination with [`inode`](struct.inode.html) to uniquely identify a file on the
/// local system.
#[repr(C)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct device(pub u64);

/// A reference to the offset of a directory entry.
#[repr(C)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct dircookie(pub u64);
/// Permanent reference to the first directory entry
/// within a directory.
pub const DIRCOOKIE_START: dircookie = dircookie(0);

/// Error codes returned by system calls.
///
/// Not all of these error codes are returned by the system calls
/// provided by this environment, but are either used in userspace
/// exclusively or merely provided for alignment with POSIX.
#[repr(u16)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum errno {
  /// No error occurred. System call completed successfully.
  SUCCESS        =  0,
  /// Argument list too long.
  TOOBIG         =  1,
  /// Permission denied.
  ACCES          =  2,
  /// Address in use.
  ADDRINUSE      =  3,
  /// Address not available.
  ADDRNOTAVAIL   =  4,
  /// Address family not supported.
  AFNOSUPPORT    =  5,
  /// Resource unavailable, or operation would block.
  AGAIN          =  6,
  /// Connection already in progress.
  ALREADY        =  7,
  /// Bad file descriptor.
  BADF           =  8,
  /// Bad message.
  BADMSG         =  9,
  /// Device or resource busy.
  BUSY           = 10,
  /// Operation canceled.
  CANCELED       = 11,
  /// No child processes.
  CHILD          = 12,
  /// Connection aborted.
  CONNABORTED    = 13,
  /// Connection refused.
  CONNREFUSED    = 14,
  /// Connection reset.
  CONNRESET      = 15,
  /// Resource deadlock would occur.
  DEADLK         = 16,
  /// Destination address required.
  DESTADDRREQ    = 17,
  /// Mathematics argument out of domain of function.
  DOM            = 18,
  /// Reserved.
  DQUOT          = 19,
  /// File exists.
  EXIST          = 20,
  /// Bad address.
  FAULT          = 21,
  /// File too large.
  FBIG           = 22,
  /// Host is unreachable.
  HOSTUNREACH    = 23,
  /// Identifier removed.
  IDRM           = 24,
  /// Illegal byte sequence.
  ILSEQ          = 25,
  /// Operation in progress.
  INPROGRESS     = 26,
  /// Interrupted function.
  INTR           = 27,
  /// Invalid argument.
  INVAL          = 28,
  /// I/O error.
  IO             = 29,
  /// Socket is connected.
  ISCONN         = 30,
  /// Is a directory.
  ISDIR          = 31,
  /// Too many levels of symbolic links.
  LOOP           = 32,
  /// File descriptor value too large.
  MFILE          = 33,
  /// Too many links.
  MLINK          = 34,
  /// Message too large.
  MSGSIZE        = 35,
  /// Reserved.
  MULTIHOP       = 36,
  /// Filename too long.
  NAMETOOLONG    = 37,
  /// Network is down.
  NETDOWN        = 38,
  /// Connection aborted by network.
  NETRESET       = 39,
  /// Network unreachable.
  NETUNREACH     = 40,
  /// Too many files open in system.
  NFILE          = 41,
  /// No buffer space available.
  NOBUFS         = 42,
  /// No such device.
  NODEV          = 43,
  /// No such file or directory.
  NOENT          = 44,
  /// Executable file format error.
  NOEXEC         = 45,
  /// No locks available.
  NOLCK          = 46,
  /// Reserved.
  NOLINK         = 47,
  /// Not enough space.
  NOMEM          = 48,
  /// No message of the desired type.
  NOMSG          = 49,
  /// Protocol not available.
  NOPROTOOPT     = 50,
  /// No space left on device.
  NOSPC          = 51,
  /// Function not supported.
  NOSYS          = 52,
  /// The socket is not connected.
  NOTCONN        = 53,
  /// Not a directory or a symbolic link to a directory.
  NOTDIR         = 54,
  /// Directory not empty.
  NOTEMPTY       = 55,
  /// State not recoverable.
  NOTRECOVERABLE = 56,
  /// Not a socket.
  NOTSOCK        = 57,
  /// Not supported, or operation not supported on socket.
  NOTSUP         = 58,
  /// Inappropriate I/O control operation.
  NOTTY          = 59,
  /// No such device or address.
  NXIO           = 60,
  /// Value too large to be stored in data type.
  OVERFLOW       = 61,
  /// Previous owner died.
  OWNERDEAD      = 62,
  /// Operation not permitted.
  PERM           = 63,
  /// Broken pipe.
  PIPE           = 64,
  /// Protocol error.
  PROTO          = 65,
  /// Protocol not supported.
  PROTONOSUPPORT = 66,
  /// Protocol wrong type for socket.
  PROTOTYPE      = 67,
  /// Result too large.
  RANGE          = 68,
  /// Read-only file system.
  ROFS           = 69,
  /// Invalid seek.
  SPIPE          = 70,
  /// No such process.
  SRCH           = 71,
  /// Reserved.
  STALE          = 72,
  /// Connection timed out.
  TIMEDOUT       = 73,
  /// Text file busy.
  TXTBSY         = 74,
  /// Cross-device link.
  XDEV           = 75,
  /// Extension: Capabilities insufficient.
  NOTCAPABLE     = 76,
  #[doc(hidden)] _NonExhaustive = -1 as isize as u16,
}

bitflags! {
  /// The state of the file descriptor subscribed to with
  /// [`FD_READ`](enum.eventtype.html#variant.FD_READ) or [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
  #[repr(C)]
  pub struct eventrwflags: u16 {
    /// The peer of this socket has closed or disconnected.
    const HANGUP = 0x0001;
  }
}

/// Type of a subscription to an event or its occurrence.
#[repr(u8)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum eventtype {
  /// The time value of clock [`subscription.union.clock.clock_id`](struct.subscription_clock.html#structfield.clock_id)
  /// has reached timestamp [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout).
  CLOCK          = 1,
  /// Condition variable [`subscription.union.condvar.condvar`](struct.subscription_condvar.html#structfield.condvar) has
  /// been woken up and [`subscription.union.condvar.lock`](struct.subscription_condvar.html#structfield.lock) has been
  /// acquired for writing.
  CONDVAR        = 2,
  /// File descriptor [`subscription.union.fd_readwrite.fd`](struct.subscription_fd_readwrite.html#structfield.fd) has
  /// data available for reading. This event always triggers
  /// for regular files.
  FD_READ        = 3,
  /// File descriptor [`subscription.union.fd_readwrite.fd`](struct.subscription_fd_readwrite.html#structfield.fd) has
  /// capacity available for writing. This event always
  /// triggers for regular files.
  FD_WRITE       = 4,
  /// Lock [`subscription.union.lock.lock`](struct.subscription_lock.html#structfield.lock) has been acquired for
  /// reading.
  LOCK_RDLOCK    = 5,
  /// Lock [`subscription.union.lock.lock`](struct.subscription_lock.html#structfield.lock) has been acquired for
  /// writing.
  LOCK_WRLOCK    = 6,
  /// The process associated with process descriptor
  /// [`subscription.union.proc_terminate.fd`](struct.subscription_proc_terminate.html#structfield.fd) has terminated.
  PROC_TERMINATE = 7,
  #[doc(hidden)] _NonExhaustive = -1 as isize as u8,
}

/// Exit code generated by a process when exiting.
pub type exitcode = u32;

/// A file descriptor number.
///
/// Unlike on POSIX-compliant systems, none of the file descriptor
/// numbers are reserved for a purpose (e.g., stdin, stdout,
/// stderr). Operating systems are not required to allocate new
/// file descriptors in ascending order.
#[repr(C)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct fd(pub u32);
/// Returned to the child process by [`proc_fork()`](fn.proc_fork.html).
pub const PROCESS_CHILD: fd = fd(0xffffffff);
/// Passed to [`mem_map()`](fn.mem_map.html) when creating a mapping to
/// anonymous memory.
pub const MAP_ANON_FD  : fd = fd(0xffffffff);

bitflags! {
  /// File descriptor flags.
  #[repr(C)]
  pub struct fdflags: u16 {
    /// Append mode: Data written to the file is always
    /// appended to the file's end.
    const APPEND   = 0x0001;
    /// Write according to synchronized I/O data integrity
    /// completion. Only the data stored in the file is
    /// synchronized.
    const DSYNC    = 0x0002;
    /// Non-blocking mode.
    const NONBLOCK = 0x0004;
    /// Synchronized read I/O operations.
    const RSYNC    = 0x0008;
    /// Write according to synchronized I/O file integrity
    /// completion. In addition to synchronizing the data
    /// stored in the file, the system may also synchronously
    /// update the file's metadata.
    const SYNC     = 0x0010;
  }
}

bitflags! {
  /// Which file descriptor attributes to adjust.
  #[repr(C)]
  pub struct fdsflags: u16 {
    /// Adjust the file descriptor flags stored in
    /// [`fdstat.fs_flags`](struct.fdstat.html#structfield.fs_flags).
    const FLAGS  = 0x0001;
    /// Restrict the rights of the file descriptor to the
    /// rights stored in [`fdstat.fs_rights_base`](struct.fdstat.html#structfield.fs_rights_base) and
    /// [`fdstat.fs_rights_inheriting`](struct.fdstat.html#structfield.fs_rights_inheriting).
    const RIGHTS = 0x0002;
  }
}

/// Relative offset within a file.
pub type filedelta = i64;

/// Non-negative file size or length of a region within a file.
pub type filesize = u64;

/// The type of a file descriptor or file.
#[repr(u8)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum filetype {
  /// The type of the file descriptor or file is unknown or
  /// is different from any of the other types specified.
  UNKNOWN          =   0,
  /// The file descriptor or file refers to a block device
  /// inode.
  BLOCK_DEVICE     =  16,
  /// The file descriptor or file refers to a character
  /// device inode.
  CHARACTER_DEVICE =  17,
  /// The file descriptor or file refers to a directory
  /// inode.
  DIRECTORY        =  32,
  /// The file descriptor refers to a process handle.
  PROCESS          =  80,
  /// The file descriptor or file refers to a regular file
  /// inode.
  REGULAR_FILE     =  96,
  /// The file descriptor refers to a shared memory object.
  SHARED_MEMORY    = 112,
  /// The file descriptor or file refers to a datagram
  /// socket.
  SOCKET_DGRAM     = 128,
  /// The file descriptor or file refers to a byte-stream
  /// socket.
  SOCKET_STREAM    = 130,
  /// The file refers to a symbolic link inode.
  SYMBOLIC_LINK    = 144,
  #[doc(hidden)] _NonExhaustive = -1 as isize as u8,
}

bitflags! {
  /// Which file attributes to adjust.
  #[repr(C)]
  pub struct fsflags: u16 {
    /// Adjust the last data access timestamp to the value
    /// stored in [`filestat.st_atim`](struct.filestat.html#structfield.st_atim).
    const ATIM     = 0x0001;
    /// Adjust the last data access timestamp to the time
    /// of clock [`REALTIME`](enum.clockid.html#variant.REALTIME).
    const ATIM_NOW = 0x0002;
    /// Adjust the last data modification timestamp to the
    /// value stored in [`filestat.st_mtim`](struct.filestat.html#structfield.st_mtim).
    const MTIM     = 0x0004;
    /// Adjust the last data modification timestamp to the
    /// time of clock [`REALTIME`](enum.clockid.html#variant.REALTIME).
    const MTIM_NOW = 0x0008;
    /// Truncate or extend the file to the size stored in
    /// [`filestat.st_size`](struct.filestat.html#structfield.st_size).
    const SIZE     = 0x0010;
  }
}

/// File serial number that is unique within its file system.
#[repr(C)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct inode(pub u64);

/// Number of hard links to an inode.
pub type linkcount = u32;

/// A userspace read-recursive readers-writer lock, similar to a
/// Linux futex or a FreeBSD umtx.
#[repr(C)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct lock(pub u32);
/// Value indicating that the lock is in its initial
/// unlocked state.
pub const LOCK_UNLOCKED      : lock = lock(0x00000000);
/// Bitmask indicating that the lock is write-locked. If
/// set, the lower 30 bits of the lock contain the
/// identifier of the thread that owns the write lock.
/// Otherwise, the lower 30 bits of the lock contain the
/// number of acquired read locks.
pub const LOCK_WRLOCKED      : lock = lock(0x40000000);
/// Bitmask indicating that the lock is either read locked
/// or write locked, and that one or more threads have
/// their execution suspended, waiting to acquire the
/// lock. The last owner of the lock must call the
/// kernel to unlock.
///
/// When the lock is acquired for reading and this bit is
/// set, it means that one or more threads are attempting
/// to acquire this lock for writing. In that case, other
/// threads should only acquire additional read locks if
/// suspending execution would cause a deadlock. It is
/// preferred to suspend execution, as this prevents
/// starvation of writers.
pub const LOCK_KERNEL_MANAGED: lock = lock(0x80000000);
/// Value indicating that the lock is in an incorrect
/// state. A lock cannot be in its initial unlocked state,
/// while also managed by the kernel.
pub const LOCK_BOGUS         : lock = lock(0x80000000);

bitflags! {
  /// Flags determining the method of how paths are resolved.
  #[repr(C)]
  pub struct lookupflags: u32 {
    /// As long as the resolved path corresponds to a symbolic
    /// link, it is expanded.
    const SYMLINK_FOLLOW = 0x00000001;
  }
}

bitflags! {
  /// Memory mapping flags.
  #[repr(C)]
  pub struct mflags: u8 {
    /// Instead of mapping the contents of the file provided,
    /// create a mapping to anonymous memory. The file
    /// descriptor argument must be set to [`MAP_ANON_FD`](constant.MAP_ANON_FD.html),
    /// and the offset must be set to zero.
    const ANON    = 0x01;
    /// Require that the mapping is performed at the base
    /// address provided.
    const FIXED   = 0x02;
    /// Changes are private.
    const PRIVATE = 0x04;
    /// Changes are shared.
    const SHARED  = 0x08;
  }
}

bitflags! {
  /// Memory page protection options.
  ///
  /// This implementation enforces the `W^X` property: Pages cannot be
  /// mapped for execution while also mapped for writing.
  #[repr(C)]
  pub struct mprot: u8 {
    /// Page can be executed.
    const EXEC  = 0x01;
    /// Page can be written.
    const WRITE = 0x02;
    /// Page can be read.
    const READ  = 0x04;
  }
}

bitflags! {
  /// Methods of synchronizing memory with physical storage.
  #[repr(C)]
  pub struct msflags: u8 {
    /// Perform asynchronous writes.
    const ASYNC      = 0x01;
    /// Invalidate cached data.
    const INVALIDATE = 0x02;
    /// Perform synchronous writes.
    const SYNC       = 0x04;
  }
}

/// Specifies the number of threads sleeping on a condition
/// variable that should be woken up.
pub type nthreads = u32;

bitflags! {
  /// Open flags used by [`file_open()`](fn.file_open.html).
  #[repr(C)]
  pub struct oflags: u16 {
    /// Create file if it does not exist.
    const CREAT     = 0x0001;
    /// Fail if not a directory.
    const DIRECTORY = 0x0002;
    /// Fail if file already exists.
    const EXCL      = 0x0004;
    /// Truncate file to size 0.
    const TRUNC     = 0x0008;
  }
}

bitflags! {
  /// Flags provided to [`sock_recv()`](fn.sock_recv.html).
  #[repr(C)]
  pub struct riflags: u16 {
    /// Returns the message without removing it from the
    /// socket's receive queue.
    const PEEK    = 0x0004;
    /// On byte-stream sockets, block until the full amount
    /// of data can be returned.
    const WAITALL = 0x0010;
  }
}

bitflags! {
  /// File descriptor rights, determining which actions may be
  /// performed.
  #[repr(C)]
  pub struct rights: u64 {
    /// The right to invoke [`fd_datasync()`](fn.fd_datasync.html).
    ///
    /// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, includes the right to
    /// invoke [`file_open()`](fn.file_open.html) with [`DSYNC`](struct.fdflags.html#associatedconstant.DSYNC).
    const FD_DATASYNC           = 0x0000000000000001;
    /// The right to invoke [`fd_read()`](fn.fd_read.html) and [`sock_recv()`](fn.sock_recv.html).
    ///
    /// If [`MEM_MAP`](struct.rights.html#associatedconstant.MEM_MAP) is set, includes the right to
    /// invoke [`mem_map()`](fn.mem_map.html) with memory protection option
    /// [`READ`](struct.mprot.html#associatedconstant.READ).
    ///
    /// If [`FD_SEEK`](struct.rights.html#associatedconstant.FD_SEEK) is set, includes the right to invoke
    /// [`fd_pread()`](fn.fd_pread.html).
    const FD_READ               = 0x0000000000000002;
    /// The right to invoke [`fd_seek()`](fn.fd_seek.html). This flag implies
    /// [`FD_TELL`](struct.rights.html#associatedconstant.FD_TELL).
    const FD_SEEK               = 0x0000000000000004;
    /// The right to invoke [`fd_stat_put()`](fn.fd_stat_put.html) with
    /// [`FLAGS`](struct.fdsflags.html#associatedconstant.FLAGS).
    const FD_STAT_PUT_FLAGS     = 0x0000000000000008;
    /// The right to invoke [`fd_sync()`](fn.fd_sync.html).
    ///
    /// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, includes the right to
    /// invoke [`file_open()`](fn.file_open.html) with [`RSYNC`](struct.fdflags.html#associatedconstant.RSYNC) and
    /// [`DSYNC`](struct.fdflags.html#associatedconstant.DSYNC).
    const FD_SYNC               = 0x0000000000000010;
    /// The right to invoke [`fd_seek()`](fn.fd_seek.html) in such a way that the
    /// file offset remains unaltered (i.e., [`CUR`](enum.whence.html#variant.CUR) with
    /// offset zero).
    const FD_TELL               = 0x0000000000000020;
    /// The right to invoke [`fd_write()`](fn.fd_write.html) and [`sock_send()`](fn.sock_send.html).
    ///
    /// If [`MEM_MAP`](struct.rights.html#associatedconstant.MEM_MAP) is set, includes the right to
    /// invoke [`mem_map()`](fn.mem_map.html) with memory protection option
    /// [`WRITE`](struct.mprot.html#associatedconstant.WRITE).
    ///
    /// If [`FD_SEEK`](struct.rights.html#associatedconstant.FD_SEEK) is set, includes the right to
    /// invoke [`fd_pwrite()`](fn.fd_pwrite.html).
    const FD_WRITE              = 0x0000000000000040;
    /// The right to invoke [`file_advise()`](fn.file_advise.html).
    const FILE_ADVISE           = 0x0000000000000080;
    /// The right to invoke [`file_allocate()`](fn.file_allocate.html).
    const FILE_ALLOCATE         = 0x0000000000000100;
    /// The right to invoke [`file_create()`](fn.file_create.html) with
    /// [`DIRECTORY`](enum.filetype.html#variant.DIRECTORY).
    const FILE_CREATE_DIRECTORY = 0x0000000000000200;
    /// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, the right to invoke
    /// [`file_open()`](fn.file_open.html) with [`CREAT`](struct.oflags.html#associatedconstant.CREAT).
    const FILE_CREATE_FILE      = 0x0000000000000400;
    /// The right to invoke [`file_link()`](fn.file_link.html) with the file
    /// descriptor as the source directory.
    const FILE_LINK_SOURCE      = 0x0000000000001000;
    /// The right to invoke [`file_link()`](fn.file_link.html) with the file
    /// descriptor as the target directory.
    const FILE_LINK_TARGET      = 0x0000000000002000;
    /// The right to invoke [`file_open()`](fn.file_open.html).
    const FILE_OPEN             = 0x0000000000004000;
    /// The right to invoke [`file_readdir()`](fn.file_readdir.html).
    const FILE_READDIR          = 0x0000000000008000;
    /// The right to invoke [`file_readlink()`](fn.file_readlink.html).
    const FILE_READLINK         = 0x0000000000010000;
    /// The right to invoke [`file_rename()`](fn.file_rename.html) with the file
    /// descriptor as the source directory.
    const FILE_RENAME_SOURCE    = 0x0000000000020000;
    /// The right to invoke [`file_rename()`](fn.file_rename.html) with the file
    /// descriptor as the target directory.
    const FILE_RENAME_TARGET    = 0x0000000000040000;
    /// The right to invoke [`file_stat_fget()`](fn.file_stat_fget.html).
    const FILE_STAT_FGET        = 0x0000000000080000;
    /// The right to invoke [`file_stat_fput()`](fn.file_stat_fput.html) with
    /// [`SIZE`](struct.fsflags.html#associatedconstant.SIZE).
    ///
    /// If [`FILE_OPEN`](struct.rights.html#associatedconstant.FILE_OPEN) is set, includes the right to
    /// invoke [`file_open()`](fn.file_open.html) with [`TRUNC`](struct.oflags.html#associatedconstant.TRUNC).
    const FILE_STAT_FPUT_SIZE   = 0x0000000000100000;
    /// The right to invoke [`file_stat_fput()`](fn.file_stat_fput.html) with
    /// [`ATIM`](struct.fsflags.html#associatedconstant.ATIM), [`ATIM_NOW`](struct.fsflags.html#associatedconstant.ATIM_NOW), [`MTIM`](struct.fsflags.html#associatedconstant.MTIM),
    /// and [`MTIM_NOW`](struct.fsflags.html#associatedconstant.MTIM_NOW).
    const FILE_STAT_FPUT_TIMES  = 0x0000000000200000;
    /// The right to invoke [`file_stat_get()`](fn.file_stat_get.html).
    const FILE_STAT_GET         = 0x0000000000400000;
    /// The right to invoke [`file_stat_put()`](fn.file_stat_put.html) with
    /// [`ATIM`](struct.fsflags.html#associatedconstant.ATIM), [`ATIM_NOW`](struct.fsflags.html#associatedconstant.ATIM_NOW), [`MTIM`](struct.fsflags.html#associatedconstant.MTIM),
    /// and [`MTIM_NOW`](struct.fsflags.html#associatedconstant.MTIM_NOW).
    const FILE_STAT_PUT_TIMES   = 0x0000000000800000;
    /// The right to invoke [`file_symlink()`](fn.file_symlink.html).
    const FILE_SYMLINK          = 0x0000000001000000;
    /// The right to invoke [`file_unlink()`](fn.file_unlink.html).
    const FILE_UNLINK           = 0x0000000002000000;
    /// The right to invoke [`mem_map()`](fn.mem_map.html) with [`mprot`](struct.mprot.html) set to
    /// zero.
    const MEM_MAP               = 0x0000000004000000;
    /// If [`MEM_MAP`](struct.rights.html#associatedconstant.MEM_MAP) is set, the right to invoke
    /// [`mem_map()`](fn.mem_map.html) with [`EXEC`](struct.mprot.html#associatedconstant.EXEC).
    const MEM_MAP_EXEC          = 0x0000000008000000;
    /// If [`FD_READ`](struct.rights.html#associatedconstant.FD_READ) is set, includes the right to
    /// invoke [`poll()`](fn.poll.html) to subscribe to [`FD_READ`](enum.eventtype.html#variant.FD_READ).
    ///
    /// If [`FD_WRITE`](struct.rights.html#associatedconstant.FD_WRITE) is set, includes the right to
    /// invoke [`poll()`](fn.poll.html) to subscribe to [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
    const POLL_FD_READWRITE     = 0x0000000010000000;
    /// The right to invoke [`poll()`](fn.poll.html) to subscribe to
    /// [`PROC_TERMINATE`](enum.eventtype.html#variant.PROC_TERMINATE).
    const POLL_PROC_TERMINATE   = 0x0000000040000000;
    /// The right to invoke [`proc_exec()`](fn.proc_exec.html).
    const PROC_EXEC             = 0x0000000100000000;
    /// The right to invoke [`sock_shutdown()`](fn.sock_shutdown.html).
    const SOCK_SHUTDOWN         = 0x0000008000000000;
  }
}

bitflags! {
  /// Flags returned by [`sock_recv()`](fn.sock_recv.html).
  #[repr(C)]
  pub struct roflags: u16 {
    /// Returned by [`sock_recv()`](fn.sock_recv.html): List of file descriptors
    /// has been truncated.
    const FDS_TRUNCATED  = 0x0001;
    /// Returned by [`sock_recv()`](fn.sock_recv.html): Message data has been
    /// truncated.
    const DATA_TRUNCATED = 0x0008;
  }
}

/// Indicates whether an object is stored in private or shared
/// memory.
#[repr(u8)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum scope {
  /// The object is stored in private memory.
  PRIVATE = 4,
  /// The object is stored in shared memory.
  SHARED  = 8,
  #[doc(hidden)] _NonExhaustive = -1 as isize as u8,
}

bitflags! {
  /// Which channels on a socket need to be shut down.
  #[repr(C)]
  pub struct sdflags: u8 {
    /// Disables further receive operations.
    const RD = 0x01;
    /// Disables further send operations.
    const WR = 0x02;
  }
}

bitflags! {
  /// Flags provided to [`sock_send()`](fn.sock_send.html). As there are currently no flags
  /// defined, it must be set to zero.
  #[repr(C)]
  pub struct siflags: u16 {
    const DEFAULT = 0;
  }
}

/// Signal condition.
#[repr(u8)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum signal {
  /// Process abort signal.
  ///
  /// Action: Terminates the process.
  ABRT   =  1,
  /// Alarm clock.
  ///
  /// Action: Terminates the process.
  ALRM   =  2,
  /// Access to an undefined portion of a memory object.
  ///
  /// Action: Terminates the process.
  BUS    =  3,
  /// Child process terminated, stopped, or continued.
  ///
  /// Action: Ignored.
  CHLD   =  4,
  /// Continue executing, if stopped.
  ///
  /// Action: Continues executing, if stopped.
  CONT   =  5,
  /// Erroneous arithmetic operation.
  ///
  /// Action: Terminates the process.
  FPE    =  6,
  /// Hangup.
  ///
  /// Action: Terminates the process.
  HUP    =  7,
  /// Illegal instruction.
  ///
  /// Action: Terminates the process.
  ILL    =  8,
  /// Terminate interrupt signal.
  ///
  /// Action: Terminates the process.
  INT    =  9,
  /// Kill.
  ///
  /// Action: Terminates the process.
  KILL   = 10,
  /// Write on a pipe with no one to read it.
  ///
  /// Action: Ignored.
  PIPE   = 11,
  /// Terminal quit signal.
  ///
  /// Action: Terminates the process.
  QUIT   = 12,
  /// Invalid memory reference.
  ///
  /// Action: Terminates the process.
  SEGV   = 13,
  /// Stop executing.
  ///
  /// Action: Stops executing.
  STOP   = 14,
  /// Bad system call.
  ///
  /// Action: Terminates the process.
  SYS    = 15,
  /// Termination signal.
  ///
  /// Action: Terminates the process.
  TERM   = 16,
  /// Trace/breakpoint trap.
  ///
  /// Action: Terminates the process.
  TRAP   = 17,
  /// Terminal stop signal.
  ///
  /// Action: Stops executing.
  TSTP   = 18,
  /// Background process attempting read.
  ///
  /// Action: Stops executing.
  TTIN   = 19,
  /// Background process attempting write.
  ///
  /// Action: Stops executing.
  TTOU   = 20,
  /// High bandwidth data is available at a socket.
  ///
  /// Action: Ignored.
  URG    = 21,
  /// User-defined signal 1.
  ///
  /// Action: Terminates the process.
  USR1   = 22,
  /// User-defined signal 2.
  ///
  /// Action: Terminates the process.
  USR2   = 23,
  /// Virtual timer expired.
  ///
  /// Action: Terminates the process.
  VTALRM = 24,
  /// CPU time limit exceeded.
  ///
  /// Action: Terminates the process.
  XCPU   = 25,
  /// File size limit exceeded.
  ///
  /// Action: Terminates the process.
  XFSZ   = 26,
  #[doc(hidden)] _NonExhaustive = -1 as isize as u8,
}

bitflags! {
  /// Flags determining how the timestamp provided in
  /// [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout) should be interpreted.
  #[repr(C)]
  pub struct subclockflags: u16 {
    /// If set, treat the timestamp provided in
    /// [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout) as an absolute timestamp
    /// of clock [`subscription.union.clock.clock_id`](struct.subscription_clock.html#structfield.clock_id).
    ///
    /// If clear, treat the timestamp provided in
    /// [`subscription.union.clock.timeout`](struct.subscription_clock.html#structfield.timeout) relative to the current
    /// time value of clock [`subscription.union.clock.clock_id`](struct.subscription_clock.html#structfield.clock_id).
    const ABSTIME = 0x0001;
  }
}

bitflags! {
  /// Flags influencing the method of polling for read or writing on
  /// a file descriptor.
  #[repr(C)]
  pub struct subrwflags: u16 {
    /// Deprecated. Must be set by callers and ignored by
    /// implementations.
    const POLL = 0x0001;
  }
}

/// Unique system-local identifier of a thread. This identifier is
/// only valid during the lifetime of the thread.
///
/// Threads must be aware of their thread identifier, as it is
/// written it into locks when acquiring them for writing. It is
/// not advised to use these identifiers for any other purpose.
///
/// As the thread identifier is also stored in [`lock`](struct.lock.html) when
/// [`LOCK_WRLOCKED`](constant.LOCK_WRLOCKED.html) is set, the top two bits of the thread
/// must always be set to zero.
#[repr(C)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct tid(pub u32);

/// Timestamp in nanoseconds.
pub type timestamp = u64;

bitflags! {
  /// Specifies whether files are unlinked or directories are
  /// removed.
  #[repr(C)]
  pub struct ulflags: u8 {
    /// If set, removes a directory. Otherwise, unlinks any
    /// non-directory file.
    const REMOVEDIR = 0x01;
  }
}

/// User-provided value that can be attached to objects that is
/// retained when extracted from the kernel.
pub type userdata = u64;

/// Relative to which position the offset of the file descriptor
/// should be set.
#[repr(u8)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum whence {
  /// Seek relative to current position.
  CUR = 1,
  /// Seek relative to end-of-file.
  END = 2,
  /// Seek relative to start-of-file.
  SET = 3,
  #[doc(hidden)] _NonExhaustive = -1 as isize as u8,
}

/// Auxiliary vector entry.
///
/// The auxiliary vector is a list of key-value pairs that is
/// provided to the process on startup. Unlike structures, it is
/// extensible, as it is possible to add new records later on.
/// The auxiliary vector is always terminated by an entry having
/// type [`NULL`](enum.auxtype.html#variant.NULL).
///
/// The auxiliary vector is part of the x86-64 ABI, but is used by
/// this environment on all architectures.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct auxv {
  /// The type of the auxiliary vector entry.
  pub a_type: auxtype,
  pub union: auxv_union
}
/// A union inside `auxv`.
#[repr(C)]
#[derive(Copy, Clone)]
pub union auxv_union {
  /// Used when `a_type` is [`ARGDATALEN`](enum.auxtype.html#variant.ARGDATALEN), [`CANARYLEN`](enum.auxtype.html#variant.CANARYLEN), [`NCPUS`](enum.auxtype.html#variant.NCPUS), [`PAGESZ`](enum.auxtype.html#variant.PAGESZ), [`PHNUM`](enum.auxtype.html#variant.PHNUM), or [`TID`](enum.auxtype.html#variant.TID).
/// A numerical value.
  pub a_val: usize,
  /// Used when `a_type` is [`ARGDATA`](enum.auxtype.html#variant.ARGDATA), [`BASE`](enum.auxtype.html#variant.BASE), [`CANARY`](enum.auxtype.html#variant.CANARY), [`PHDR`](enum.auxtype.html#variant.PHDR), [`PID`](enum.auxtype.html#variant.PID), or [`SYSINFO_EHDR`](enum.auxtype.html#variant.SYSINFO_EHDR).
/// A pointer value.
  pub a_ptr: *mut (),
}
#[test]
#[cfg(target_pointer_width = "32")]
fn auxv_layout_test_32() {
  assert_eq!(::core::mem::size_of::<auxv>(), 8);
  assert_eq!(::core::mem::align_of::<auxv>(), 4);
  unsafe {
    let obj: auxv = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.a_type as *const _ as usize - base, 0);
    assert_eq!(&obj.union.a_val as *const _ as usize - base, 4);
    assert_eq!(&obj.union.a_ptr as *const _ as usize - base, 4);
  }
}
#[test]
#[cfg(target_pointer_width = "64")]
fn auxv_layout_test_64() {
  assert_eq!(::core::mem::size_of::<auxv>(), 16);
  assert_eq!(::core::mem::align_of::<auxv>(), 8);
  unsafe {
    let obj: auxv = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.a_type as *const _ as usize - base, 0);
    assert_eq!(&obj.union.a_val as *const _ as usize - base, 8);
    assert_eq!(&obj.union.a_ptr as *const _ as usize - base, 8);
  }
}

/// A region of memory for scatter/gather writes.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct ciovec {
  /// The address and length of the buffer to be written.
  pub buf: (*const (), usize),
}
#[test]
#[cfg(target_pointer_width = "32")]
fn ciovec_layout_test_32() {
  assert_eq!(::core::mem::size_of::<ciovec>(), 8);
  assert_eq!(::core::mem::align_of::<ciovec>(), 4);
  unsafe {
    let obj: ciovec = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
    assert_eq!(&obj.buf.1 as *const _ as usize - base, 4);
  }
}
#[test]
#[cfg(target_pointer_width = "64")]
fn ciovec_layout_test_64() {
  assert_eq!(::core::mem::size_of::<ciovec>(), 16);
  assert_eq!(::core::mem::align_of::<ciovec>(), 8);
  unsafe {
    let obj: ciovec = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
    assert_eq!(&obj.buf.1 as *const _ as usize - base, 8);
  }
}

/// A directory entry.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct dirent {
  /// The offset of the next directory entry stored in this
  /// directory.
  pub d_next: dircookie,
  /// The serial number of the file referred to by this
  /// directory entry.
  pub d_ino: inode,
  /// The length of the name of the directory entry.
  pub d_namlen: u32,
  /// The type of the file referred to by this directory
  /// entry.
  pub d_type: filetype,
}
#[test]
fn dirent_layout_test() {
  assert_eq!(::core::mem::size_of::<dirent>(), 24);
  assert_eq!(::core::mem::align_of::<dirent>(), 8);
  unsafe {
    let obj: dirent = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.d_next as *const _ as usize - base, 0);
    assert_eq!(&obj.d_ino as *const _ as usize - base, 8);
    assert_eq!(&obj.d_namlen as *const _ as usize - base, 16);
    assert_eq!(&obj.d_type as *const _ as usize - base, 20);
  }
}

/// An event that occurred.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct event {
  /// User-provided value that got attached to
  /// [`subscription.userdata`](struct.subscription.html#structfield.userdata).
  pub userdata: userdata,
  /// If non-zero, an error that occurred while processing
  /// the subscription request.
  pub error: errno,
  /// The type of the event that occurred.
  pub type_: eventtype,
  pub union: event_union
}
/// A union inside `event`.
#[repr(C)]
#[derive(Copy, Clone)]
pub union event_union {
  /// Used when `type_` is [`FD_READ`](enum.eventtype.html#variant.FD_READ) or [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
  pub fd_readwrite: event_fd_readwrite,
  /// Used when `type_` is [`PROC_TERMINATE`](enum.eventtype.html#variant.PROC_TERMINATE).
  pub proc_terminate: event_proc_terminate,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct event_fd_readwrite {
  /// The number of bytes available
  /// for reading or writing.
  pub nbytes: filesize,
  /// Obsolete.
  pub unused: [u8; 4],
  /// The state of the file
  /// descriptor.
  pub flags: eventrwflags,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct event_proc_terminate {
  /// Obsolete.
  pub unused: [u8; 4],
  /// If zero, the process has
  /// exited.
  /// Otherwise, the signal
  /// condition causing it to
  /// terminated.
  pub signal: signal,
  /// If exited, the exit code of
  /// the process.
  pub exitcode: exitcode,
}
#[test]
fn event_layout_test() {
  assert_eq!(::core::mem::size_of::<event>(), 32);
  assert_eq!(::core::mem::align_of::<event>(), 8);
  unsafe {
    let obj: event = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.userdata as *const _ as usize - base, 0);
    assert_eq!(&obj.error as *const _ as usize - base, 8);
    assert_eq!(&obj.type_ as *const _ as usize - base, 10);
    assert_eq!(&obj.union.fd_readwrite.nbytes as *const _ as usize - base, 16);
    assert_eq!(&obj.union.fd_readwrite.unused as *const _ as usize - base, 24);
    assert_eq!(&obj.union.fd_readwrite.flags as *const _ as usize - base, 28);
    assert_eq!(&obj.union.proc_terminate.unused as *const _ as usize - base, 16);
    assert_eq!(&obj.union.proc_terminate.signal as *const _ as usize - base, 20);
    assert_eq!(&obj.union.proc_terminate.exitcode as *const _ as usize - base, 24);
  }
}

/// File descriptor attributes.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct fdstat {
  /// File type.
  pub fs_filetype: filetype,
  /// File descriptor flags.
  pub fs_flags: fdflags,
  /// Rights that apply to this file descriptor.
  pub fs_rights_base: rights,
  /// Maximum set of rights that can be installed on new
  /// file descriptors that are created through this file
  /// descriptor, e.g., through [`file_open()`](fn.file_open.html).
  pub fs_rights_inheriting: rights,
}
#[test]
fn fdstat_layout_test() {
  assert_eq!(::core::mem::size_of::<fdstat>(), 24);
  assert_eq!(::core::mem::align_of::<fdstat>(), 8);
  unsafe {
    let obj: fdstat = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.fs_filetype as *const _ as usize - base, 0);
    assert_eq!(&obj.fs_flags as *const _ as usize - base, 2);
    assert_eq!(&obj.fs_rights_base as *const _ as usize - base, 8);
    assert_eq!(&obj.fs_rights_inheriting as *const _ as usize - base, 16);
  }
}

/// File attributes.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct filestat {
  /// Device ID of device containing the file.
  pub st_dev: device,
  /// File serial number.
  pub st_ino: inode,
  /// File type.
  pub st_filetype: filetype,
  /// Number of hard links to the file.
  pub st_nlink: linkcount,
  /// For regular files, the file size in bytes. For
  /// symbolic links, the length in bytes of the pathname
  /// contained in the symbolic link.
  pub st_size: filesize,
  /// Last data access timestamp.
  pub st_atim: timestamp,
  /// Last data modification timestamp.
  pub st_mtim: timestamp,
  /// Last file status change timestamp.
  pub st_ctim: timestamp,
}
#[test]
fn filestat_layout_test() {
  assert_eq!(::core::mem::size_of::<filestat>(), 56);
  assert_eq!(::core::mem::align_of::<filestat>(), 8);
  unsafe {
    let obj: filestat = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.st_dev as *const _ as usize - base, 0);
    assert_eq!(&obj.st_ino as *const _ as usize - base, 8);
    assert_eq!(&obj.st_filetype as *const _ as usize - base, 16);
    assert_eq!(&obj.st_nlink as *const _ as usize - base, 20);
    assert_eq!(&obj.st_size as *const _ as usize - base, 24);
    assert_eq!(&obj.st_atim as *const _ as usize - base, 32);
    assert_eq!(&obj.st_mtim as *const _ as usize - base, 40);
    assert_eq!(&obj.st_ctim as *const _ as usize - base, 48);
  }
}

/// A region of memory for scatter/gather reads.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct iovec {
  /// The address and length of the buffer to be filled.
  pub buf: (*mut (), usize),
}
#[test]
#[cfg(target_pointer_width = "32")]
fn iovec_layout_test_32() {
  assert_eq!(::core::mem::size_of::<iovec>(), 8);
  assert_eq!(::core::mem::align_of::<iovec>(), 4);
  unsafe {
    let obj: iovec = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
    assert_eq!(&obj.buf.1 as *const _ as usize - base, 4);
  }
}
#[test]
#[cfg(target_pointer_width = "64")]
fn iovec_layout_test_64() {
  assert_eq!(::core::mem::size_of::<iovec>(), 16);
  assert_eq!(::core::mem::align_of::<iovec>(), 8);
  unsafe {
    let obj: iovec = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.buf.0 as *const _ as usize - base, 0);
    assert_eq!(&obj.buf.1 as *const _ as usize - base, 8);
  }
}

/// Path lookup properties.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct lookup {
  /// The working directory at which the resolution of the
  /// path starts.
  pub fd: fd,
  /// Flags determining the method of how the path is
  /// resolved.
  pub flags: lookupflags,
}
#[test]
fn lookup_layout_test() {
  assert_eq!(::core::mem::size_of::<lookup>(), 8);
  assert_eq!(::core::mem::align_of::<lookup>(), 4);
  unsafe {
    let obj: lookup = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.fd as *const _ as usize - base, 0);
    assert_eq!(&obj.flags as *const _ as usize - base, 4);
  }
}

/// Entry point for a process (`_start`).
///
/// **auxv**:
/// The auxiliary vector. See [`auxv`](struct.auxv.html).
pub type processentry = unsafe extern "C" fn(
  auxv: *const auxv,
) -> ();

/// Arguments of [`sock_recv()`](fn.sock_recv.html).
#[repr(C)]
#[derive(Copy, Clone)]
pub struct recv_in {
  /// List of scatter/gather vectors where message data
  /// should be stored.
  pub ri_data: (*const iovec, usize),
  /// Buffer where numbers of incoming file descriptors
  /// should be stored.
  pub ri_fds: (*mut fd, usize),
  /// Message flags.
  pub ri_flags: riflags,
}
#[test]
#[cfg(target_pointer_width = "32")]
fn recv_in_layout_test_32() {
  assert_eq!(::core::mem::size_of::<recv_in>(), 20);
  assert_eq!(::core::mem::align_of::<recv_in>(), 4);
  unsafe {
    let obj: recv_in = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.ri_data.0 as *const _ as usize - base, 0);
    assert_eq!(&obj.ri_data.1 as *const _ as usize - base, 4);
    assert_eq!(&obj.ri_fds.0 as *const _ as usize - base, 8);
    assert_eq!(&obj.ri_fds.1 as *const _ as usize - base, 12);
    assert_eq!(&obj.ri_flags as *const _ as usize - base, 16);
  }
}
#[test]
#[cfg(target_pointer_width = "64")]
fn recv_in_layout_test_64() {
  assert_eq!(::core::mem::size_of::<recv_in>(), 40);
  assert_eq!(::core::mem::align_of::<recv_in>(), 8);
  unsafe {
    let obj: recv_in = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.ri_data.0 as *const _ as usize - base, 0);
    assert_eq!(&obj.ri_data.1 as *const _ as usize - base, 8);
    assert_eq!(&obj.ri_fds.0 as *const _ as usize - base, 16);
    assert_eq!(&obj.ri_fds.1 as *const _ as usize - base, 24);
    assert_eq!(&obj.ri_flags as *const _ as usize - base, 32);
  }
}

/// Results of [`sock_recv()`](fn.sock_recv.html).
#[repr(C)]
#[derive(Copy, Clone)]
pub struct recv_out {
  /// Number of bytes stored in [`recv_in.ri_data`](struct.recv_in.html#structfield.ri_data).
  pub ro_datalen: usize,
  /// Number of file descriptors stored in [`recv_in.ri_fds`](struct.recv_in.html#structfield.ri_fds).
  pub ro_fdslen: usize,
  /// Fields that were used by previous implementations.
  pub ro_unused: [u8; 40],
  /// Message flags.
  pub ro_flags: roflags,
}
#[test]
#[cfg(target_pointer_width = "32")]
fn recv_out_layout_test_32() {
  assert_eq!(::core::mem::size_of::<recv_out>(), 52);
  assert_eq!(::core::mem::align_of::<recv_out>(), 4);
  unsafe {
    let obj: recv_out = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.ro_datalen as *const _ as usize - base, 0);
    assert_eq!(&obj.ro_fdslen as *const _ as usize - base, 4);
    assert_eq!(&obj.ro_unused as *const _ as usize - base, 8);
    assert_eq!(&obj.ro_flags as *const _ as usize - base, 48);
  }
}
#[test]
#[cfg(target_pointer_width = "64")]
fn recv_out_layout_test_64() {
  assert_eq!(::core::mem::size_of::<recv_out>(), 64);
  assert_eq!(::core::mem::align_of::<recv_out>(), 8);
  unsafe {
    let obj: recv_out = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.ro_datalen as *const _ as usize - base, 0);
    assert_eq!(&obj.ro_fdslen as *const _ as usize - base, 8);
    assert_eq!(&obj.ro_unused as *const _ as usize - base, 16);
    assert_eq!(&obj.ro_flags as *const _ as usize - base, 56);
  }
}

/// Arguments of [`sock_send()`](fn.sock_send.html).
#[repr(C)]
#[derive(Copy, Clone)]
pub struct send_in {
  /// List of scatter/gather vectors where message data
  /// should be retrieved.
  pub si_data: (*const ciovec, usize),
  /// File descriptors that need to be attached to the
  /// message.
  pub si_fds: (*const fd, usize),
  /// Message flags.
  pub si_flags: siflags,
}
#[test]
#[cfg(target_pointer_width = "32")]
fn send_in_layout_test_32() {
  assert_eq!(::core::mem::size_of::<send_in>(), 20);
  assert_eq!(::core::mem::align_of::<send_in>(), 4);
  unsafe {
    let obj: send_in = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.si_data.0 as *const _ as usize - base, 0);
    assert_eq!(&obj.si_data.1 as *const _ as usize - base, 4);
    assert_eq!(&obj.si_fds.0 as *const _ as usize - base, 8);
    assert_eq!(&obj.si_fds.1 as *const _ as usize - base, 12);
    assert_eq!(&obj.si_flags as *const _ as usize - base, 16);
  }
}
#[test]
#[cfg(target_pointer_width = "64")]
fn send_in_layout_test_64() {
  assert_eq!(::core::mem::size_of::<send_in>(), 40);
  assert_eq!(::core::mem::align_of::<send_in>(), 8);
  unsafe {
    let obj: send_in = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.si_data.0 as *const _ as usize - base, 0);
    assert_eq!(&obj.si_data.1 as *const _ as usize - base, 8);
    assert_eq!(&obj.si_fds.0 as *const _ as usize - base, 16);
    assert_eq!(&obj.si_fds.1 as *const _ as usize - base, 24);
    assert_eq!(&obj.si_flags as *const _ as usize - base, 32);
  }
}

/// Results of [`sock_send()`](fn.sock_send.html).
#[repr(C)]
#[derive(Copy, Clone)]
pub struct send_out {
  /// Number of bytes transmitted.
  pub so_datalen: usize,
}
#[test]
#[cfg(target_pointer_width = "32")]
fn send_out_layout_test_32() {
  assert_eq!(::core::mem::size_of::<send_out>(), 4);
  assert_eq!(::core::mem::align_of::<send_out>(), 4);
  unsafe {
    let obj: send_out = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.so_datalen as *const _ as usize - base, 0);
  }
}
#[test]
#[cfg(target_pointer_width = "64")]
fn send_out_layout_test_64() {
  assert_eq!(::core::mem::size_of::<send_out>(), 8);
  assert_eq!(::core::mem::align_of::<send_out>(), 8);
  unsafe {
    let obj: send_out = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.so_datalen as *const _ as usize - base, 0);
  }
}

/// Subscription to an event.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct subscription {
  /// User-provided value that is attached to the
  /// subscription in the kernel and returned through
  /// [`event.userdata`](struct.event.html#structfield.userdata).
  pub userdata: userdata,
  /// Used by previous implementations. Ignored.
  pub unused: u16,
  /// The type of the event to which to subscribe.
  ///
  /// Currently, [`CONDVAR`](enum.eventtype.html#variant.CONDVAR),
  /// [`LOCK_RDLOCK`](enum.eventtype.html#variant.LOCK_RDLOCK), and [`LOCK_WRLOCK`](enum.eventtype.html#variant.LOCK_WRLOCK)
  /// must be provided as the first subscription and may
  /// only be followed by up to one other subscription,
  /// having type [`CLOCK`](enum.eventtype.html#variant.CLOCK).
  pub type_: eventtype,
  pub union: subscription_union
}
/// A union inside `subscription`.
#[repr(C)]
#[derive(Copy, Clone)]
pub union subscription_union {
  /// Used when `type_` is [`CLOCK`](enum.eventtype.html#variant.CLOCK).
  pub clock: subscription_clock,
  /// Used when `type_` is [`CONDVAR`](enum.eventtype.html#variant.CONDVAR).
  pub condvar: subscription_condvar,
  /// Used when `type_` is [`FD_READ`](enum.eventtype.html#variant.FD_READ) or [`FD_WRITE`](enum.eventtype.html#variant.FD_WRITE).
  pub fd_readwrite: subscription_fd_readwrite,
  /// Used when `type_` is [`LOCK_RDLOCK`](enum.eventtype.html#variant.LOCK_RDLOCK) or [`LOCK_WRLOCK`](enum.eventtype.html#variant.LOCK_WRLOCK).
  pub lock: subscription_lock,
  /// Used when `type_` is [`PROC_TERMINATE`](enum.eventtype.html#variant.PROC_TERMINATE).
  pub proc_terminate: subscription_proc_terminate,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct subscription_clock {
  /// The user-defined unique
  /// identifier of the clock.
  pub identifier: userdata,
  /// The clock against which the
  /// timestamp should be compared.
  pub clock_id: clockid,
  /// The absolute or relative
  /// timestamp.
  pub timeout: timestamp,
  /// The amount of time that the
  /// kernel may wait additionally
  /// to coalesce with other events.
  pub precision: timestamp,
  /// Flags specifying whether the
  /// timeout is absolute or
  /// relative.
  pub flags: subclockflags,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct subscription_condvar {
  /// The condition variable on
  /// which to wait to be woken up.
  pub condvar: *mut condvar,
  /// The lock that will be
  /// released while waiting.
  ///
  /// The lock will be reacquired
  /// for writing when the condition
  /// variable triggers.
  pub lock: *mut lock,
  /// Whether the condition variable
  /// is stored in private or shared
  /// memory.
  pub condvar_scope: scope,
  /// Whether the lock is stored in
  /// private or shared memory.
  pub lock_scope: scope,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct subscription_fd_readwrite {
  /// The file descriptor on which
  /// to wait for it to become ready
  /// for reading or writing.
  pub fd: fd,
  /// Under which conditions to
  /// trigger.
  pub flags: subrwflags,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct subscription_lock {
  /// The lock that will be acquired
  /// for reading or writing.
  pub lock: *mut lock,
  /// Whether the lock is stored in
  /// private or shared memory.
  pub lock_scope: scope,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct subscription_proc_terminate {
  /// The process descriptor on
  /// which to wait for process
  /// termination.
  pub fd: fd,
}
#[test]
#[cfg(target_pointer_width = "32")]
fn subscription_layout_test_32() {
  assert_eq!(::core::mem::size_of::<subscription>(), 56);
  assert_eq!(::core::mem::align_of::<subscription>(), 8);
  unsafe {
    let obj: subscription = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.userdata as *const _ as usize - base, 0);
    assert_eq!(&obj.unused as *const _ as usize - base, 8);
    assert_eq!(&obj.type_ as *const _ as usize - base, 10);
    assert_eq!(&obj.union.clock.identifier as *const _ as usize - base, 16);
    assert_eq!(&obj.union.clock.clock_id as *const _ as usize - base, 24);
    assert_eq!(&obj.union.clock.timeout as *const _ as usize - base, 32);
    assert_eq!(&obj.union.clock.precision as *const _ as usize - base, 40);
    assert_eq!(&obj.union.clock.flags as *const _ as usize - base, 48);
    assert_eq!(&obj.union.condvar.condvar as *const _ as usize - base, 16);
    assert_eq!(&obj.union.condvar.lock as *const _ as usize - base, 20);
    assert_eq!(&obj.union.condvar.condvar_scope as *const _ as usize - base, 24);
    assert_eq!(&obj.union.condvar.lock_scope as *const _ as usize - base, 25);
    assert_eq!(&obj.union.fd_readwrite.fd as *const _ as usize - base, 16);
    assert_eq!(&obj.union.fd_readwrite.flags as *const _ as usize - base, 20);
    assert_eq!(&obj.union.lock.lock as *const _ as usize - base, 16);
    assert_eq!(&obj.union.lock.lock_scope as *const _ as usize - base, 20);
    assert_eq!(&obj.union.proc_terminate.fd as *const _ as usize - base, 16);
  }
}
#[test]
#[cfg(target_pointer_width = "64")]
fn subscription_layout_test_64() {
  assert_eq!(::core::mem::size_of::<subscription>(), 56);
  assert_eq!(::core::mem::align_of::<subscription>(), 8);
  unsafe {
    let obj: subscription = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.userdata as *const _ as usize - base, 0);
    assert_eq!(&obj.unused as *const _ as usize - base, 8);
    assert_eq!(&obj.type_ as *const _ as usize - base, 10);
    assert_eq!(&obj.union.clock.identifier as *const _ as usize - base, 16);
    assert_eq!(&obj.union.clock.clock_id as *const _ as usize - base, 24);
    assert_eq!(&obj.union.clock.timeout as *const _ as usize - base, 32);
    assert_eq!(&obj.union.clock.precision as *const _ as usize - base, 40);
    assert_eq!(&obj.union.clock.flags as *const _ as usize - base, 48);
    assert_eq!(&obj.union.condvar.condvar as *const _ as usize - base, 16);
    assert_eq!(&obj.union.condvar.lock as *const _ as usize - base, 24);
    assert_eq!(&obj.union.condvar.condvar_scope as *const _ as usize - base, 32);
    assert_eq!(&obj.union.condvar.lock_scope as *const _ as usize - base, 33);
    assert_eq!(&obj.union.fd_readwrite.fd as *const _ as usize - base, 16);
    assert_eq!(&obj.union.fd_readwrite.flags as *const _ as usize - base, 20);
    assert_eq!(&obj.union.lock.lock as *const _ as usize - base, 16);
    assert_eq!(&obj.union.lock.lock_scope as *const _ as usize - base, 24);
    assert_eq!(&obj.union.proc_terminate.fd as *const _ as usize - base, 16);
  }
}

/// The Thread Control Block (TCB).
///
/// After a thread begins execution (at program startup or when
/// created through [`thread_create()`](fn.thread_create.html)), the CPU's registers
/// controlling Thread-Local Storage (TLS) will already be
/// initialized. They will point to an area only containing the
/// TCB.
///
/// If the thread needs space for storing thread-specific
/// variables, the thread may allocate a larger area and adjust
/// the CPU's registers to point to that area instead. However, it
/// does need to make sure that the TCB is copied over to the new
/// TLS area.
///
/// The purpose of the TCB is that it allows light-weight
/// emulators to store information related to individual threads.
/// For example, it may be used to store a copy of the CPU
/// registers prior emulation, so that TLS for the host system
/// can be restored if needed.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct tcb {
  /// Pointer that may be freely assigned by the system. Its
  /// value cannot be interpreted by the application.
  pub parent: *mut (),
}
#[test]
#[cfg(target_pointer_width = "32")]
fn tcb_layout_test_32() {
  assert_eq!(::core::mem::size_of::<tcb>(), 4);
  assert_eq!(::core::mem::align_of::<tcb>(), 4);
  unsafe {
    let obj: tcb = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.parent as *const _ as usize - base, 0);
  }
}
#[test]
#[cfg(target_pointer_width = "64")]
fn tcb_layout_test_64() {
  assert_eq!(::core::mem::size_of::<tcb>(), 8);
  assert_eq!(::core::mem::align_of::<tcb>(), 8);
  unsafe {
    let obj: tcb = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.parent as *const _ as usize - base, 0);
  }
}

/// Entry point for additionally created threads.
///
/// **tid**:
/// Thread ID of the current thread.
///
/// **aux**:
/// Copy of the value stored in
/// [`threadattr.argument`](struct.threadattr.html#structfield.argument).
pub type threadentry = unsafe extern "C" fn(
  tid: tid,
  aux: *mut (),
) -> ();

/// Attributes for thread creation.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct threadattr {
  /// Initial program counter value.
  pub entry_point: threadentry,
  /// Region allocated to serve as stack space.
  pub stack: (*mut (), usize),
  /// Argument to be forwarded to the entry point function.
  pub argument: *mut (),
}
#[test]
#[cfg(target_pointer_width = "32")]
fn threadattr_layout_test_32() {
  assert_eq!(::core::mem::size_of::<threadattr>(), 16);
  assert_eq!(::core::mem::align_of::<threadattr>(), 4);
  unsafe {
    let obj: threadattr = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.entry_point as *const _ as usize - base, 0);
    assert_eq!(&obj.stack.0 as *const _ as usize - base, 4);
    assert_eq!(&obj.stack.1 as *const _ as usize - base, 8);
    assert_eq!(&obj.argument as *const _ as usize - base, 12);
  }
}
#[test]
#[cfg(target_pointer_width = "64")]
fn threadattr_layout_test_64() {
  assert_eq!(::core::mem::size_of::<threadattr>(), 32);
  assert_eq!(::core::mem::align_of::<threadattr>(), 8);
  unsafe {
    let obj: threadattr = ::core::mem::uninitialized();
    let base = &obj as *const _ as usize;
    assert_eq!(&obj.entry_point as *const _ as usize - base, 0);
    assert_eq!(&obj.stack.0 as *const _ as usize - base, 8);
    assert_eq!(&obj.stack.1 as *const _ as usize - base, 16);
    assert_eq!(&obj.argument as *const _ as usize - base, 24);
  }
}

/// The table with pointers to all syscall implementations.
#[allow(improper_ctypes)]
extern "C" {
  fn cloudabi_sys_clock_res_get(_: clockid, _: *mut timestamp) -> errno;
  fn cloudabi_sys_clock_time_get(_: clockid, _: timestamp, _: *mut timestamp) -> errno;
  fn cloudabi_sys_condvar_signal(_: *mut condvar, _: scope, _: nthreads) -> errno;
  fn cloudabi_sys_fd_close(_: fd) -> errno;
  fn cloudabi_sys_fd_create1(_: filetype, _: *mut fd) -> errno;
  fn cloudabi_sys_fd_create2(_: filetype, _: *mut fd, _: *mut fd) -> errno;
  fn cloudabi_sys_fd_datasync(_: fd) -> errno;
  fn cloudabi_sys_fd_dup(_: fd, _: *mut fd) -> errno;
  fn cloudabi_sys_fd_pread(_: fd, _: *const iovec, _: usize, _: filesize, _: *mut usize) -> errno;
  fn cloudabi_sys_fd_pwrite(_: fd, _: *const ciovec, _: usize, _: filesize, _: *mut usize) -> errno;
  fn cloudabi_sys_fd_read(_: fd, _: *const iovec, _: usize, _: *mut usize) -> errno;
  fn cloudabi_sys_fd_replace(_: fd, _: fd) -> errno;
  fn cloudabi_sys_fd_seek(_: fd, _: filedelta, _: whence, _: *mut filesize) -> errno;
  fn cloudabi_sys_fd_stat_get(_: fd, _: *mut fdstat) -> errno;
  fn cloudabi_sys_fd_stat_put(_: fd, _: *const fdstat, _: fdsflags) -> errno;
  fn cloudabi_sys_fd_sync(_: fd) -> errno;
  fn cloudabi_sys_fd_write(_: fd, _: *const ciovec, _: usize, _: *mut usize) -> errno;
  fn cloudabi_sys_file_advise(_: fd, _: filesize, _: filesize, _: advice) -> errno;
  fn cloudabi_sys_file_allocate(_: fd, _: filesize, _: filesize) -> errno;
  fn cloudabi_sys_file_create(_: fd, _: *const u8, _: usize, _: filetype) -> errno;
  fn cloudabi_sys_file_link(_: lookup, _: *const u8, _: usize, _: fd, _: *const u8, _: usize) -> errno;
  fn cloudabi_sys_file_open(_: lookup, _: *const u8, _: usize, _: oflags, _: *const fdstat, _: *mut fd) -> errno;
  fn cloudabi_sys_file_readdir(_: fd, _: *mut (), _: usize, _: dircookie, _: *mut usize) -> errno;
  fn cloudabi_sys_file_readlink(_: fd, _: *const u8, _: usize, _: *mut u8, _: usize, _: *mut usize) -> errno;
  fn cloudabi_sys_file_rename(_: fd, _: *const u8, _: usize, _: fd, _: *const u8, _: usize) -> errno;
  fn cloudabi_sys_file_stat_fget(_: fd, _: *mut filestat) -> errno;
  fn cloudabi_sys_file_stat_fput(_: fd, _: *const filestat, _: fsflags) -> errno;
  fn cloudabi_sys_file_stat_get(_: lookup, _: *const u8, _: usize, _: *mut filestat) -> errno;
  fn cloudabi_sys_file_stat_put(_: lookup, _: *const u8, _: usize, _: *const filestat, _: fsflags) -> errno;
  fn cloudabi_sys_file_symlink(_: *const u8, _: usize, _: fd, _: *const u8, _: usize) -> errno;
  fn cloudabi_sys_file_unlink(_: fd, _: *const u8, _: usize, _: ulflags) -> errno;
  fn cloudabi_sys_lock_unlock(_: *mut lock, _: scope) -> errno;
  fn cloudabi_sys_mem_advise(_: *mut (), _: usize, _: advice) -> errno;
  fn cloudabi_sys_mem_map(_: *mut (), _: usize, _: mprot, _: mflags, _: fd, _: filesize, _: *mut *mut ()) -> errno;
  fn cloudabi_sys_mem_protect(_: *mut (), _: usize, _: mprot) -> errno;
  fn cloudabi_sys_mem_sync(_: *mut (), _: usize, _: msflags) -> errno;
  fn cloudabi_sys_mem_unmap(_: *mut (), _: usize) -> errno;
  fn cloudabi_sys_poll(_: *const subscription, _: *mut event, _: usize, _: *mut usize) -> errno;
  fn cloudabi_sys_proc_exec(_: fd, _: *const (), _: usize, _: *const fd, _: usize) -> errno;
  fn cloudabi_sys_proc_exit(_: exitcode) -> !;
  fn cloudabi_sys_proc_fork(_: *mut fd, _: *mut tid) -> errno;
  fn cloudabi_sys_proc_raise(_: signal) -> errno;
  fn cloudabi_sys_random_get(_: *mut (), _: usize) -> errno;
  fn cloudabi_sys_sock_recv(_: fd, _: *const recv_in, _: *mut recv_out) -> errno;
  fn cloudabi_sys_sock_send(_: fd, _: *const send_in, _: *mut send_out) -> errno;
  fn cloudabi_sys_sock_shutdown(_: fd, _: sdflags) -> errno;
  fn cloudabi_sys_thread_create(_: *mut threadattr, _: *mut tid) -> errno;
  fn cloudabi_sys_thread_exit(_: *mut lock, _: scope) -> !;
  fn cloudabi_sys_thread_yield() -> errno;
}

/// Obtains the resolution of a clock.
///
/// ## Parameters
///
/// **clock_id**:
/// The clock for which the resolution needs to be
/// returned.
///
/// **resolution**:
/// The resolution of the clock.
#[inline]
pub unsafe fn clock_res_get(clock_id_: clockid, resolution_: &mut timestamp) -> errno {
  cloudabi_sys_clock_res_get(clock_id_, resolution_)
}

/// Obtains the time value of a clock.
///
/// ## Parameters
///
/// **clock_id**:
/// The clock for which the time needs to be
/// returned.
///
/// **precision**:
/// The maximum lag (exclusive) that the returned
/// time value may have, compared to its actual
/// value.
///
/// **time**:
/// The time value of the clock.
#[inline]
pub unsafe fn clock_time_get(clock_id_: clockid, precision_: timestamp, time_: &mut timestamp) -> errno {
  cloudabi_sys_clock_time_get(clock_id_, precision_, time_)
}

/// Wakes up threads waiting on a userspace condition variable.
///
/// If an invocation of this system call causes all waiting
/// threads to be woken up, the value of the condition variable
/// is set to [`CONDVAR_HAS_NO_WAITERS`](constant.CONDVAR_HAS_NO_WAITERS.html). As long as the condition
/// variable is set to this value, it is not needed to invoke this
/// system call.
///
/// ## Parameters
///
/// **condvar**:
/// The userspace condition variable that has
/// waiting threads.
///
/// **scope**:
/// Whether the condition variable is stored in
/// private or shared memory.
///
/// **nwaiters**:
/// The number of threads that need to be woken
/// up. If it exceeds the number of waiting
/// threads, all threads are woken up.
#[inline]
pub unsafe fn condvar_signal(condvar_: *mut condvar, scope_: scope, nwaiters_: nthreads) -> errno {
  cloudabi_sys_condvar_signal(condvar_, scope_, nwaiters_)
}

/// Closes a file descriptor.
///
/// ## Parameters
///
/// **fd**:
/// The file descriptor that needs to be closed.
#[inline]
pub unsafe fn fd_close(fd_: fd) -> errno {
  cloudabi_sys_fd_close(fd_)
}

/// Creates a file descriptor.
///
/// ## Parameters
///
/// **type**:
/// Possible values:
///
///   - [`SHARED_MEMORY`](enum.filetype.html#variant.SHARED_MEMORY):
///     Creates an anonymous shared memory
///     object.
///
/// **fd**:
/// The file descriptor that has been created.
#[inline]
pub unsafe fn fd_create1(type_: filetype, fd_: &mut fd) -> errno {
  cloudabi_sys_fd_create1(type_, fd_)
}

/// Creates a pair of file descriptors.
///
/// ## Parameters
///
/// **type**:
/// Possible values:
///
///   - [`SOCKET_DGRAM`](enum.filetype.html#variant.SOCKET_DGRAM):
///     Creates a UNIX datagram socket pair.
///   - [`SOCKET_STREAM`](enum.filetype.html#variant.SOCKET_STREAM):
///     Creates a UNIX byte-stream socket
///     pair.
///
/// **fd1**:
/// The first file descriptor of the pair.
///
/// **fd2**:
/// The second file descriptor of the pair.
#[inline]
pub unsafe fn fd_create2(type_: filetype, fd1_: &mut fd, fd2_: &mut fd) -> errno {
  cloudabi_sys_fd_create2(type_, fd1_, fd2_)
}

/// Synchronizes the data of a file to disk.
///
/// ## Parameters
///
/// **fd**:
/// The file descriptor of the file whose data
/// needs to be synchronized to disk.
#[inline]
pub unsafe fn fd_datasync(fd_: fd) -> errno {
  cloudabi_sys_fd_datasync(fd_)
}

/// Duplicates a file descriptor.
///
/// ## Parameters
///
/// **from**:
/// The file descriptor that needs to be
/// duplicated.
///
/// **fd**:
/// The new file descriptor.
#[inline]
pub unsafe fn fd_dup(from_: fd, fd_: &mut fd) -> errno {
  cloudabi_sys_fd_dup(from_, fd_)
}

/// Reads from a file descriptor, without using and updating the
/// file descriptor's offset.
///
/// ## Parameters
///
/// **fd**:
/// The file descriptor from which data should be
/// read.
///
/// **iovs**:
/// List of scatter/gather vectors where data
/// should be stored.
///
/// **offset**:
/// The offset within the file at which reading
/// should start.
///
/// **nread**:
/// The number of bytes read.
#[inline]
pub unsafe fn fd_pread(fd_: fd, iovs_: &[iovec], offset_: filesize, nread_: &mut usize) -> errno {
  cloudabi_sys_fd_pread(fd_, iovs_.as_ptr(), iovs_.len(), offset_, nread_)
}

/// Writes to a file descriptor, without using and updating the
/// file descriptor's offset.
///
/// ## Parameters
///
/// **fd**:
/// The file descriptor to which data should be
/// written.
///
/// **iovs**:
/// List of scatter/gather vectors where data
/// should be retrieved.
///
/// **offset**:
/// The offset within the file at which writing
/// should start.
///
/// **nwritten**:
/// The number of bytes written.
#[inline]
pub unsafe fn fd_pwrite(fd_: fd, iovs_: &[ciovec], offset_: filesize, nwritten_: &mut usize) -> errno {
  cloudabi_sys_fd_pwrite(fd_, iovs_.as_ptr(), iovs_.len(), offset_, nwritten_)
}

/// Reads from a file descriptor.
///
/// ## Parameters
///
/// **fd**:
/// The file descriptor from which data should be
/// read.
///
/// **iovs**:
/// List of scatter/gather vectors where data
/// should be stored.
///
/// **nread**:
/// The number of bytes read.
#[inline]
pub unsafe fn fd_read(fd_: fd, iovs_: &[iovec], nread_: &mut usize) -> errno {
  cloudabi_sys_fd_read(fd_, iovs_.as_ptr(), iovs_.len(), nread_)
}

/// Atomically replaces a file descriptor by a copy of another
/// file descriptor.
///
/// Due to the strong focus on thread safety, this environment
/// does not provide a mechanism to duplicate a file descriptor to
/// an arbitrary number, like dup2(). This would be prone to race
/// conditions, as an actual file descriptor with the same number
/// could be allocated by a different thread at the same time.
///
/// This system call provides a way to atomically replace file
/// descriptors, which would disappear if dup2() were to be
/// removed entirely.
///
/// ## Parameters
///
/// **from**:
/// The file descriptor that needs to be copied.
///
/// **to**:
/// The file descriptor that needs to be
/// overwritten.
#[inline]
pub unsafe fn fd_replace(from_: fd, to_: fd) -> errno {
  cloudabi_sys_fd_replace(from_, to_)
}

/// Moves the offset of the file descriptor.
///
/// ## Parameters
///
/// **fd**:
/// The file descriptor whose offset has to be
/// moved.
///
/// **offset**:
/// The number of bytes to move.
///
/// **whence**:
/// Relative to which position the move should
/// take place.
///
/// **newoffset**:
/// The new offset of the file descriptor,
/// relative to the start of the file.
#[inline]
pub unsafe fn fd_seek(fd_: fd, offset_: filedelta, whence_: whence, newoffset_: &mut filesize) -> errno {
  cloudabi_sys_fd_seek(fd_, offset_, whence_, newoffset_)
}

/// Gets attributes of a file descriptor.
///
/// ## Parameters
///
/// **fd**:
/// The file descriptor whose attributes have to
/// be obtained.
///
/// **buf**:
/// The buffer where the file descriptor's
/// attributes are stored.
#[inline]
pub unsafe fn fd_stat_get(fd_: fd, buf_: *mut fdstat) -> errno {
  cloudabi_sys_fd_stat_get(fd_, buf_)
}

/// Adjusts attributes of a file descriptor.
///
/// ## Parameters
///
/// **fd**:
/// The file descriptor whose attributes have to
/// be adjusted.
///
/// **buf**:
/// The desired values of the file descriptor
/// attributes that are adjusted.
///
/// **flags**:
/// A bitmask indicating which attributes have to
/// be adjusted.
#[inline]
pub unsafe fn fd_stat_put(fd_: fd, buf_: *const fdstat, flags_: fdsflags) -> errno {
  cloudabi_sys_fd_stat_put(fd_, buf_, flags_)
}

/// Synchronizes the data and metadata of a file to disk.
///
/// ## Parameters
///
/// **fd**:
/// The file descriptor of the file whose data
/// and metadata needs to be synchronized to disk.
#[inline]
pub unsafe fn fd_sync(fd_: fd) -> errno {
  cloudabi_sys_fd_sync(fd_)
}

/// Writes to a file descriptor.
///
/// ## Parameters
///
/// **fd**:
/// The file descriptor to which data should be
/// written.
///
/// **iovs**:
/// List of scatter/gather vectors where data
/// should be retrieved.
///
/// **nwritten**:
/// The number of bytes written.
#[inline]
pub unsafe fn fd_write(fd_: fd, iovs_: &[ciovec], nwritten_: &mut usize) -> errno {
  cloudabi_sys_fd_write(fd_, iovs_.as_ptr(), iovs_.len(), nwritten_)
}

/// Provides file advisory information on a file descriptor.
///
/// ## Parameters
///
/// **fd**:
/// The file descriptor for which to provide file
/// advisory information.
///
/// **offset**:
/// The offset within the file to which the
/// advisory applies.
///
/// **len**:
/// The length of the region to which the advisory
/// applies.
///
/// **advice**:
/// The advice.
#[inline]
pub unsafe fn file_advise(fd_: fd, offset_: filesize, len_: filesize, advice_: advice) -> errno {
  cloudabi_sys_file_advise(fd_, offset_, len_, advice_)
}

/// Forces the allocation of space in a file.
///
/// ## Parameters
///
/// **fd**:
/// The file in which the space should be
/// allocated.
///
/// **offset**:
/// The offset at which the allocation should
/// start.
///
/// **len**:
/// The length of the area that is allocated.
#[inline]
pub unsafe fn file_allocate(fd_: fd, offset_: filesize, len_: filesize) -> errno {
  cloudabi_sys_file_allocate(fd_, offset_, len_)
}

/// Creates a file of a specified type.
///
/// ## Parameters
///
/// **fd**:
/// The working directory at which the resolution
/// of the file to be created starts.
///
/// **path**:
/// The path at which the file should be created.
///
/// **type**:
/// Possible values:
///
///   - [`DIRECTORY`](enum.filetype.html#variant.DIRECTORY):
///     Creates a directory.
#[inline]
pub unsafe fn file_create(fd_: fd, path_: &[u8], type_: filetype) -> errno {
  cloudabi_sys_file_create(fd_, path_.as_ptr(), path_.len(), type_)
}

/// Creates a hard link.
///
/// ## Parameters
///
/// **fd1**:
/// The working directory at which the resolution
/// of the source path starts.
///
/// **path1**:
/// The source path of the file that should be
/// hard linked.
///
/// **fd2**:
/// The working directory at which the resolution
/// of the destination path starts.
///
/// **path2**:
/// The destination path at which the hard link
/// should be created.
#[inline]
pub unsafe fn file_link(fd1_: lookup, path1_: &[u8], fd2_: fd, path2_: &[u8]) -> errno {
  cloudabi_sys_file_link(fd1_, path1_.as_ptr(), path1_.len(), fd2_, path2_.as_ptr(), path2_.len())
}

/// Opens a file.
///
/// ## Parameters
///
/// **dirfd**:
/// The working directory at which the resolution
/// of the file to be opened starts.
///
/// **path**:
/// The path of the file that should be opened.
///
/// **oflags**:
/// The method at which the file should be opened.
///
/// **fds**:
/// [`fdstat.fs_rights_base`](struct.fdstat.html#structfield.fs_rights_base) and
/// [`fdstat.fs_rights_inheriting`](struct.fdstat.html#structfield.fs_rights_inheriting) specify the
/// initial rights of the newly created file
/// descriptor. The operating system is allowed to
/// return a file descriptor with fewer rights
/// than specified, if and only if those rights do
/// not apply to the type of file being opened.
///
/// [`fdstat.fs_flags`](struct.fdstat.html#structfield.fs_flags) specifies the initial flags
/// of the file descriptor.
///
/// [`fdstat.fs_filetype`](struct.fdstat.html#structfield.fs_filetype) is ignored.
///
/// **fd**:
/// The file descriptor of the file that has been
/// opened.
#[inline]
pub unsafe fn file_open(dirfd_: lookup, path_: &[u8], oflags_: oflags, fds_: *const fdstat, fd_: &mut fd) -> errno {
  cloudabi_sys_file_open(dirfd_, path_.as_ptr(), path_.len(), oflags_, fds_, fd_)
}

/// Reads directory entries from a directory.
///
/// When successful, the contents of the output buffer consist of
/// a sequence of directory entries. Each directory entry consists
/// of a [`dirent`](struct.dirent.html) object, followed by [`dirent.d_namlen`](struct.dirent.html#structfield.d_namlen) bytes
/// holding the name of the directory entry.
///
/// This system call fills the output buffer as much as possible,
/// potentially truncating the last directory entry. This allows
/// the caller to grow its read buffer size in case it's too small
/// to fit a single large directory entry, or skip the oversized
/// directory entry.
///
/// ## Parameters
///
/// **fd**:
/// The directory from which to read the directory
/// entries.
///
/// **buf**:
/// The buffer where directory entries are stored.
///
/// **cookie**:
/// The location within the directory to start
/// reading.
///
/// **bufused**:
/// The number of bytes stored in the read buffer.
/// If less than the size of the read buffer, the
/// end of the directory has been reached.
#[inline]
pub unsafe fn file_readdir(fd_: fd, buf_: &mut [u8], cookie_: dircookie, bufused_: &mut usize) -> errno {
  cloudabi_sys_file_readdir(fd_, buf_.as_mut_ptr() as *mut (), buf_.len(), cookie_, bufused_)
}

/// Reads the contents of a symbolic link.
///
/// ## Parameters
///
/// **fd**:
/// The working directory at which the resolution
/// of the path of the symbolic starts.
///
/// **path**:
/// The path of the symbolic link whose contents
/// should be read.
///
/// **buf**:
/// The buffer where the contents of the symbolic
/// link should be stored.
///
/// **bufused**:
/// The number of bytes placed in the buffer.
#[inline]
pub unsafe fn file_readlink(fd_: fd, path_: &[u8], buf_: &mut [u8], bufused_: &mut usize) -> errno {
  cloudabi_sys_file_readlink(fd_, path_.as_ptr(), path_.len(), buf_.as_mut_ptr(), buf_.len(), bufused_)
}

/// Renames a file.
///
/// ## Parameters
///
/// **fd1**:
/// The working directory at which the resolution
/// of the source path starts.
///
/// **path1**:
/// The source path of the file that should be
/// renamed.
///
/// **fd2**:
/// The working directory at which the resolution
/// of the destination path starts.
///
/// **path2**:
/// The destination path to which the file should
/// be renamed.
#[inline]
pub unsafe fn file_rename(fd1_: fd, path1_: &[u8], fd2_: fd, path2_: &[u8]) -> errno {
  cloudabi_sys_file_rename(fd1_, path1_.as_ptr(), path1_.len(), fd2_, path2_.as_ptr(), path2_.len())
}

/// Gets attributes of a file by file descriptor.
///
/// ## Parameters
///
/// **fd**:
/// The file descriptor whose attributes have to
/// be obtained.
///
/// **buf**:
/// The buffer where the file's attributes are
/// stored.
#[inline]
pub unsafe fn file_stat_fget(fd_: fd, buf_: *mut filestat) -> errno {
  cloudabi_sys_file_stat_fget(fd_, buf_)
}

/// Adjusts attributes of a file by file descriptor.
///
/// ## Parameters
///
/// **fd**:
/// The file descriptor whose attributes have to
/// be adjusted.
///
/// **buf**:
/// The desired values of the file attributes that
/// are adjusted.
///
/// **flags**:
/// A bitmask indicating which attributes have to
/// be adjusted.
#[inline]
pub unsafe fn file_stat_fput(fd_: fd, buf_: *const filestat, flags_: fsflags) -> errno {
  cloudabi_sys_file_stat_fput(fd_, buf_, flags_)
}

/// Gets attributes of a file by path.
///
/// ## Parameters
///
/// **fd**:
/// The working directory at which the resolution
/// of the path whose attributes have to be
/// obtained starts.
///
/// **path**:
/// The path of the file whose attributes have to
/// be obtained.
///
/// **buf**:
/// The buffer where the file's attributes are
/// stored.
#[inline]
pub unsafe fn file_stat_get(fd_: lookup, path_: &[u8], buf_: *mut filestat) -> errno {
  cloudabi_sys_file_stat_get(fd_, path_.as_ptr(), path_.len(), buf_)
}

/// Adjusts attributes of a file by path.
///
/// ## Parameters
///
/// **fd**:
/// The working directory at which the resolution
/// of the path whose attributes have to be
/// adjusted starts.
///
/// **path**:
/// The path of the file whose attributes have to
/// be adjusted.
///
/// **buf**:
/// The desired values of the file attributes that
/// are adjusted.
///
/// **flags**:
/// A bitmask indicating which attributes have to
/// be adjusted.
#[inline]
pub unsafe fn file_stat_put(fd_: lookup, path_: &[u8], buf_: *const filestat, flags_: fsflags) -> errno {
  cloudabi_sys_file_stat_put(fd_, path_.as_ptr(), path_.len(), buf_, flags_)
}

/// Creates a symbolic link.
///
/// ## Parameters
///
/// **path1**:
/// The contents of the symbolic link.
///
/// **fd**:
/// The working directory at which the resolution
/// of the destination path starts.
///
/// **path2**:
/// The destination path at which the symbolic
/// link should be created.
#[inline]
pub unsafe fn file_symlink(path1_: &[u8], fd_: fd, path2_: &[u8]) -> errno {
  cloudabi_sys_file_symlink(path1_.as_ptr(), path1_.len(), fd_, path2_.as_ptr(), path2_.len())
}

/// Unlinks a file, or removes a directory.
///
/// ## Parameters
///
/// **fd**:
/// The working directory at which the resolution
/// of the path starts.
///
/// **path**:
/// The path that needs to be unlinked or removed.
///
/// **flags**:
/// Possible values:
///
///   - [`REMOVEDIR`](struct.ulflags.html#associatedconstant.REMOVEDIR):
///     If set, attempt to remove a directory.
///     Otherwise, unlink a file.
#[inline]
pub unsafe fn file_unlink(fd_: fd, path_: &[u8], flags_: ulflags) -> errno {
  cloudabi_sys_file_unlink(fd_, path_.as_ptr(), path_.len(), flags_)
}

/// Unlocks a write-locked userspace lock.
///
/// If a userspace lock is unlocked while having its
/// [`LOCK_KERNEL_MANAGED`](constant.LOCK_KERNEL_MANAGED.html) flag set, the lock cannot be unlocked in
/// userspace directly. This system call needs to be performed
/// instead, so that any waiting threads can be woken up.
///
/// To prevent spurious invocations of this system call, the lock
/// must be locked for writing. This prevents other threads from
/// acquiring additional read locks while the system call is in
/// progress. If the lock is acquired for reading, it must first
/// be upgraded to a write lock.
///
/// ## Parameters
///
/// **lock**:
/// The userspace lock that is locked for writing
/// by the calling thread.
///
/// **scope**:
/// Whether the lock is stored in private or
/// shared memory.
#[inline]
pub unsafe fn lock_unlock(lock_: *mut lock, scope_: scope) -> errno {
  cloudabi_sys_lock_unlock(lock_, scope_)
}

/// Provides memory advisory information on a region of memory.
///
/// ## Parameters
///
/// **mapping**:
/// The pages for which to provide memory advisory
/// information.
///
/// **advice**:
/// The advice.
#[inline]
pub unsafe fn mem_advise(mapping_: &mut [u8], advice_: advice) -> errno {
  cloudabi_sys_mem_advise(mapping_.as_mut_ptr() as *mut (), mapping_.len(), advice_)
}

/// Creates a memory mapping, making the contents of a file
/// accessible through memory.
///
/// ## Parameters
///
/// **addr**:
/// If [`FIXED`](struct.mflags.html#associatedconstant.FIXED) is set, specifies to which
/// address the file region is mapped. Otherwise,
/// the mapping is performed at an unused
/// location.
///
/// **len**:
/// The length of the memory mapping to be
/// created.
///
/// **prot**:
/// Initial memory protection options for the
/// memory mapping.
///
/// **flags**:
/// Memory mapping flags.
///
/// **fd**:
/// If [`ANON`](struct.mflags.html#associatedconstant.ANON) is set, this argument must be
/// [`MAP_ANON_FD`](constant.MAP_ANON_FD.html). Otherwise, this argument
/// specifies the file whose contents need to be
/// mapped.
///
/// **off**:
/// If [`ANON`](struct.mflags.html#associatedconstant.ANON) is set, this argument must be
/// zero. Otherwise, this argument specifies the
/// offset within the file at which the mapping
/// starts.
///
/// **mem**:
/// The starting address of the memory mapping.
#[inline]
pub unsafe fn mem_map(addr_: *mut (), len_: usize, prot_: mprot, flags_: mflags, fd_: fd, off_: filesize, mem_: &mut *mut ()) -> errno {
  cloudabi_sys_mem_map(addr_, len_, prot_, flags_, fd_, off_, mem_)
}

/// Change the protection of a memory mapping.
///
/// ## Parameters
///
/// **mapping**:
/// The pages that need their protection changed.
///
/// **prot**:
/// New protection options.
#[inline]
pub unsafe fn mem_protect(mapping_: &mut [u8], prot_: mprot) -> errno {
  cloudabi_sys_mem_protect(mapping_.as_mut_ptr() as *mut (), mapping_.len(), prot_)
}

/// Synchronize a region of memory with its physical storage.
///
/// ## Parameters
///
/// **mapping**:
/// The pages that need to be synchronized.
///
/// **flags**:
/// The method of synchronization.
#[inline]
pub unsafe fn mem_sync(mapping_: &mut [u8], flags_: msflags) -> errno {
  cloudabi_sys_mem_sync(mapping_.as_mut_ptr() as *mut (), mapping_.len(), flags_)
}

/// Unmaps a region of memory.
///
/// ## Parameters
///
/// **mapping**:
/// The pages that needs to be unmapped.
#[inline]
pub unsafe fn mem_unmap(mapping_: &mut [u8]) -> errno {
  cloudabi_sys_mem_unmap(mapping_.as_mut_ptr() as *mut (), mapping_.len())
}

/// Concurrently polls for the occurrence of a set of events.
///
/// ## Parameters
///
/// **in**:
/// The events to which to subscribe.
///
/// **out**:
/// The events that have occurred.
///
/// **nsubscriptions**:
/// Both the number of subscriptions and events.
///
/// **nevents**:
/// The number of events stored.
#[inline]
pub unsafe fn poll(in_: *const subscription, out_: *mut event, nsubscriptions_: usize, nevents_: &mut usize) -> errno {
  cloudabi_sys_poll(in_, out_, nsubscriptions_, nevents_)
}

/// Replaces the process by a new executable.
///
/// Process execution in CloudABI differs from POSIX in two ways:
/// handling of arguments and inheritance of file descriptors.
///
/// CloudABI does not use string command line arguments. Instead,
/// a buffer with binary data is copied into the address space of
/// the new executable. The kernel does not enforce any specific
/// structure to this data, although CloudABI's C library uses it
/// to store a tree structure that is semantically identical to
/// YAML.
///
/// Due to the strong focus on thread safety, file descriptors
/// aren't inherited through close-on-exec flags. An explicit
/// list of file descriptors that need to be retained needs to be
/// provided. After execution, file descriptors are placed in the
/// order in which they are stored in the array. This not only
/// makes the execution process deterministic. It also prevents
/// potential information disclosures about the layout of the
/// original process.
///
/// ## Parameters
///
/// **fd**:
/// A file descriptor of the new executable.
///
/// **data**:
/// Binary argument data that is passed on to the
/// new executable.
///
/// **fds**:
/// The layout of the file descriptor table after
/// execution.
#[inline]
pub unsafe fn proc_exec(fd_: fd, data_: &[u8], fds_: &[fd]) -> errno {
  cloudabi_sys_proc_exec(fd_, data_.as_ptr() as *const (), data_.len(), fds_.as_ptr(), fds_.len())
}

/// Terminates the process normally.
///
/// ## Parameters
///
/// **rval**:
/// The exit code returned by the process. The
/// exit code can be obtained by other processes
/// through [`event.union.proc_terminate.exitcode`](struct.event_proc_terminate.html#structfield.exitcode).
#[inline]
pub unsafe fn proc_exit(rval_: exitcode) -> ! {
  cloudabi_sys_proc_exit(rval_)
}

/// Forks the process of the calling thread.
///
/// After forking, a new process shall be created, having only a
/// copy of the calling thread. The parent process will obtain a
/// process descriptor. When closed, the child process is
/// automatically signaled with [`KILL`](enum.signal.html#variant.KILL).
///
/// ## Parameters
///
/// **fd**:
/// In the parent process: the file descriptor
/// number of the process descriptor.
///
/// In the child process: [`PROCESS_CHILD`](constant.PROCESS_CHILD.html).
///
/// **tid**:
/// In the parent process: undefined.
///
/// In the child process: the thread ID of the
/// initial thread of the child process.
#[inline]
pub unsafe fn proc_fork(fd_: &mut fd, tid_: &mut tid) -> errno {
  cloudabi_sys_proc_fork(fd_, tid_)
}

/// Sends a signal to the process of the calling thread.
///
/// ## Parameters
///
/// **sig**:
/// The signal condition that should be triggered.
/// If the signal causes the process to terminate,
/// its condition can be obtained by other
/// processes through
/// [`event.union.proc_terminate.signal`](struct.event_proc_terminate.html#structfield.signal).
#[inline]
pub unsafe fn proc_raise(sig_: signal) -> errno {
  cloudabi_sys_proc_raise(sig_)
}

/// Obtains random data from the kernel random number generator.
///
/// As this interface is not guaranteed to be fast, it is advised
/// that the random data obtained through this system call is used
/// as the seed for a userspace pseudo-random number generator.
///
/// ## Parameters
///
/// **buf**:
/// The buffer that needs to be filled with random
/// data.
#[inline]
pub unsafe fn random_get(buf_: &mut [u8]) -> errno {
  cloudabi_sys_random_get(buf_.as_mut_ptr() as *mut (), buf_.len())
}

/// Receives a message on a socket.
///
/// ## Parameters
///
/// **sock**:
/// The socket on which a message should be
/// received.
///
/// **in**:
/// Input parameters.
///
/// **out**:
/// Output parameters.
#[inline]
pub unsafe fn sock_recv(sock_: fd, in_: *const recv_in, out_: *mut recv_out) -> errno {
  cloudabi_sys_sock_recv(sock_, in_, out_)
}

/// Sends a message on a socket.
///
/// ## Parameters
///
/// **sock**:
/// The socket on which a message should be sent.
///
/// **in**:
/// Input parameters.
///
/// **out**:
/// Output parameters.
#[inline]
pub unsafe fn sock_send(sock_: fd, in_: *const send_in, out_: *mut send_out) -> errno {
  cloudabi_sys_sock_send(sock_, in_, out_)
}

/// Shuts down socket send and receive channels.
///
/// ## Parameters
///
/// **sock**:
/// The socket that needs its channels shut down.
///
/// **how**:
/// Which channels on the socket need to be shut
/// down.
#[inline]
pub unsafe fn sock_shutdown(sock_: fd, how_: sdflags) -> errno {
  cloudabi_sys_sock_shutdown(sock_, how_)
}

/// Creates a new thread within the current process.
///
/// ## Parameters
///
/// **attr**:
/// The desired attributes of the new thread.
///
/// **tid**:
/// The thread ID of the new thread.
#[inline]
pub unsafe fn thread_create(attr_: *mut threadattr, tid_: &mut tid) -> errno {
  cloudabi_sys_thread_create(attr_, tid_)
}

/// Terminates the calling thread.
///
/// This system call can also unlock a single userspace lock
/// after termination, which can be used to implement thread
/// joining.
///
/// ## Parameters
///
/// **lock**:
/// Userspace lock that is locked for writing by
/// the calling thread.
///
/// **scope**:
/// Whether the lock is stored in private or
/// shared memory.
#[inline]
pub unsafe fn thread_exit(lock_: *mut lock, scope_: scope) -> ! {
  cloudabi_sys_thread_exit(lock_, scope_)
}

/// Temporarily yields execution of the calling thread.
#[inline]
pub unsafe fn thread_yield() -> errno {
  cloudabi_sys_thread_yield()
}