|
32 | 32 |
|
33 | 33 | functions["fopen"] = function() |
34 | 34 | local path_ptr, mode_ptr = get_args() |
35 | | - -- local path = read_string(path_ptr) |
| 35 | + local path = read_string(path_ptr) |
36 | 36 | -- local mode = read_string(mode_ptr) |
37 | | - -- Just return 0 (NULL) for all file open requests for now |
38 | | - push_args(0) |
| 37 | + |
| 38 | + local file_buffer = files[path] |
| 39 | + if not file_buffer then |
| 40 | + push_args(0) -- Return NULL if file not found |
| 41 | + return |
| 42 | + end |
| 43 | + |
| 44 | + local fd = next_fd |
| 45 | + next_fd += 1 |
| 46 | + open_files[fd] = { |
| 47 | + buffer = file_buffer, |
| 48 | + pos = 0, |
| 49 | + name = path |
| 50 | + } |
| 51 | + push_args(fd) |
39 | 52 | end |
40 | 53 |
|
41 | 54 | functions["fclose"] = function() |
42 | | - push_args(0) |
| 55 | + local stream = get_args() |
| 56 | + if open_files[stream] then |
| 57 | + open_files[stream] = nil |
| 58 | + push_args(0) |
| 59 | + else |
| 60 | + push_args(-1) -- EOF/Error |
| 61 | + end |
43 | 62 | end |
44 | 63 |
|
45 | 64 | functions["fread"] = function() |
46 | | - push_args(0) |
| 65 | + local ptr, size, nmemb, stream = get_args() |
| 66 | + local handle = open_files[stream] |
| 67 | + if not handle or size == 0 or nmemb == 0 then |
| 68 | + push_args(0) |
| 69 | + return |
| 70 | + end |
| 71 | + |
| 72 | + local total_bytes = size * nmemb |
| 73 | + local available = buffer.len(handle.buffer) - handle.pos |
| 74 | + local to_read = math.min(total_bytes, available) |
| 75 | + |
| 76 | + if to_read > 0 then |
| 77 | + buffer.copy(memory, ptr, handle.buffer, handle.pos, to_read) |
| 78 | + handle.pos += to_read |
| 79 | + end |
| 80 | + |
| 81 | + push_args(math.floor(to_read / size)) |
47 | 82 | end |
48 | 83 |
|
49 | 84 | functions["fseek"] = function() |
50 | | - push_args(-1) |
| 85 | + local stream, offset, whence = get_args() |
| 86 | + local handle = open_files[stream] |
| 87 | + if not handle then |
| 88 | + push_args(-1) |
| 89 | + return |
| 90 | + end |
| 91 | + |
| 92 | + local new_pos = handle.pos |
| 93 | + if whence == 0 then -- SEEK_SET |
| 94 | + new_pos = offset |
| 95 | + elseif whence == 1 then -- SEEK_CUR |
| 96 | + new_pos = handle.pos + offset |
| 97 | + elseif whence == 2 then -- SEEK_END |
| 98 | + new_pos = buffer.len(handle.buffer) + offset |
| 99 | + end |
| 100 | + |
| 101 | + if new_pos < 0 then |
| 102 | + push_args(-1) |
| 103 | + return |
| 104 | + end |
| 105 | + |
| 106 | + handle.pos = new_pos |
| 107 | + push_args(0) |
51 | 108 | end |
52 | 109 |
|
53 | 110 | functions["ftell"] = function() |
54 | | - push_args(-1) |
| 111 | + local stream = get_args() |
| 112 | + local handle = open_files[stream] |
| 113 | + if not handle then |
| 114 | + push_args(-1) |
| 115 | + return |
| 116 | + end |
| 117 | + push_args(handle.pos) |
55 | 118 | end |
56 | 119 |
|
57 | 120 | functions["feof"] = function() |
58 | | - push_args(1) |
| 121 | + local stream = get_args() |
| 122 | + local handle = open_files[stream] |
| 123 | + if not handle then |
| 124 | + push_args(1) |
| 125 | + return |
| 126 | + end |
| 127 | + push_args(handle.pos >= buffer.len(handle.buffer) and 1 or 0) |
| 128 | +end |
| 129 | + |
| 130 | +functions["fgetc"] = function() |
| 131 | + local stream = get_args() |
| 132 | + local handle = open_files[stream] |
| 133 | + if not handle or handle.pos >= buffer.len(handle.buffer) then |
| 134 | + push_args(-1) -- EOF |
| 135 | + return |
| 136 | + end |
| 137 | + local c = buffer.readu8(handle.buffer, handle.pos) |
| 138 | + handle.pos += 1 |
| 139 | + push_args(c) |
| 140 | +end |
| 141 | + |
| 142 | +functions["fgets"] = function() |
| 143 | + local s_ptr, size, stream = get_args() |
| 144 | + local handle = open_files[stream] |
| 145 | + if not handle or size <= 0 or handle.pos >= buffer.len(handle.buffer) then |
| 146 | + push_args(0) -- NULL |
| 147 | + return |
| 148 | + end |
| 149 | + |
| 150 | + local count = 0 |
| 151 | + while count < size - 1 and handle.pos < buffer.len(handle.buffer) do |
| 152 | + local c = buffer.readu8(handle.buffer, handle.pos) |
| 153 | + buffer.writeu8(memory, s_ptr + count, c) |
| 154 | + handle.pos += 1 |
| 155 | + count += 1 |
| 156 | + if c == 10 then -- \n |
| 157 | + break |
| 158 | + end |
| 159 | + end |
| 160 | + buffer.writeu8(memory, s_ptr + count, 0) |
| 161 | + push_args(s_ptr) |
| 162 | +end |
| 163 | + |
| 164 | +functions["fputc"] = function() |
| 165 | + local c, stream = get_args() |
| 166 | + local handle = open_files[stream] |
| 167 | + if not handle then |
| 168 | + push_args(-1) |
| 169 | + return |
| 170 | + end |
| 171 | + -- If we exceed buffer, we can't write more for now as buffers are fixed size |
| 172 | + if handle.pos < buffer.len(handle.buffer) then |
| 173 | + buffer.writeu8(handle.buffer, handle.pos, c) |
| 174 | + handle.pos += 1 |
| 175 | + push_args(c) |
| 176 | + else |
| 177 | + push_args(-1) |
| 178 | + end |
| 179 | +end |
| 180 | + |
| 181 | +functions["fwrite"] = function() |
| 182 | + local ptr, size, nmemb, stream = get_args() |
| 183 | + local handle = open_files[stream] |
| 184 | + if not handle or size == 0 or nmemb == 0 then |
| 185 | + push_args(0) |
| 186 | + return |
| 187 | + end |
| 188 | + |
| 189 | + local total_bytes = size * nmemb |
| 190 | + local available = buffer.len(handle.buffer) - handle.pos |
| 191 | + local to_write = math.min(total_bytes, available) |
| 192 | + |
| 193 | + if to_write > 0 then |
| 194 | + buffer.copy(handle.buffer, handle.pos, memory, ptr, to_write) |
| 195 | + handle.pos += to_write |
| 196 | + end |
| 197 | + |
| 198 | + push_args(math.floor(to_write / size)) |
59 | 199 | end |
60 | 200 |
|
61 | 201 | functions["printf"] = function() |
|
0 commit comments