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
//! Operating system calls that work on OSX and Linux
/// Allocates physical memory for a file, device, or anonymous-file (ie, a file that is only stored in-memory; just a memory allocation for the running process).
///
/// Typically, the data in the device (eg, disk) is loaded when the page of memory is accessed. I use the word "typically" because
/// the implementation of the device determines how the data is populated in the physical-page, for instance you could implement the mmap functions
/// for a device that calls out over the network to populate the physical-page when the first-access to the memory occurs (per page).
///
/// For anonomyous files: the page of memory being accessed is allocated a physical-page in RAM whenever it is accessed.
///
/// *NOTE*: This is the best function for allocating program memory, and is the most effecient function for loading files
/// when the file-contents are accessed randomly; otherwise, if read sequentially once or written sequentially once, use direct-io (see open(2))
///
/// *NOTE*: Accessing outside of the logically-allocated-range will not result in a physical-page being allocated, to clarify.
///
/// # Example
/// mapping memory (not based on device or file). give it an address you want the mapping to be at, or just leave it blank (99% of the time)
/// then set the memory protection flags and allocation flags, use ANON for in-memory only, use -1 for the file-descriptor, and 0 as the offset.
///
/// the minimum flags for `map_flags` is one of either SHARED or PRIVATE.
/// ```
/// use os_core::{unix::{sys_mmap, sys_munmap}, constants::{map, mprot}};
///
/// let mut mapping = sys_mmap(0 as *mut (), 4096, mprot::READ | mprot::WRITE, map::ANON | map::SHARED, -1, 0);
/// assert!(mapping != map::FAILED);
///
/// let mut data = mapping as *mut u8;
/// unsafe {*(data.offset(4095)) = 0xFF;}
/// assert_eq!(unsafe {*(data.offset(4095))}, 0xFF);
/// sys_munmap(mapping, 4096);
/// // sanity: this would also work -> sys_munmap(data, 4096); <- since it's the same address (data and mapping)
/// ```
/// Unmap program memory and memory-mapped devices/files
/// Create a new process by copying the memory-mappings in the current process into a new address space and get a separate
/// scheduling-context in the OS.
/// Wait for any of the caller's child-process's scheduling-statuses to change (not including going from idle to runnable,
/// more signal related statuses; see manpage wait(2))
///
/// Returns a 2-tuple with the PID first, then the status of the child process.
/// Create a pipe
///
/// The first i32 is the read-end of the pipe, the second i32 is the write-end