|
4 | 4 | #include <emscripten.h> |
5 | 5 | #include <sys/stat.h> |
6 | 6 |
|
| 7 | +#include "debug/tracers.h" |
7 | 8 | #include "system/file.h" |
8 | 9 |
|
9 | | -int sys_canonicalize(char *result, const char *filename) { |
10 | | - if (!sys_filename_is_absolute(filename)) return ENOENT; |
11 | | - return (realpath(filename, result)==result) ? 0 : ENOENT; |
12 | | -} |
| 10 | +typedef struct { |
| 11 | + int diskId; |
| 12 | + FileOfs pos; |
| 13 | +} JSFile; |
13 | 14 |
|
14 | 15 | int sys_file_mode(int mode) { |
15 | 16 | int m = 0; |
@@ -42,21 +43,6 @@ int sys_file_mode(int mode) { |
42 | 43 | return m; |
43 | 44 | } |
44 | 45 |
|
45 | | -int sys_findclose(pfind_t &pfind) { |
46 | | - printf("sys_findclose()\n"); |
47 | | - return 0; |
48 | | -} |
49 | | - |
50 | | -int sys_findfirst(pfind_t &pfind, const char *dirname) { |
51 | | - printf("sys_findfirst(%s)\n", dirname); |
52 | | - return 0; |
53 | | -} |
54 | | - |
55 | | -int sys_findnext(pfind_t &pfind) { |
56 | | - printf("sys_findnext()\n"); |
57 | | - return 0; |
58 | | -} |
59 | | - |
60 | 46 | static void stat_to_pstat_t(const struct stat &st, pstat_t &s) { |
61 | 47 | s.caps = pstat_ctime|pstat_mtime|pstat_atime|pstat_uid|pstat_gid|pstat_mode_all|pstat_size|pstat_inode; |
62 | 48 | s.ctime = st.st_ctime; |
@@ -98,62 +84,88 @@ int sys_truncate_fd(int fd, FileOfs ofs) { |
98 | 84 | return 0; |
99 | 85 | } |
100 | 86 |
|
101 | | -int sys_deletefile(const char *filename) { |
102 | | - printf("sys_deletefile(%s)\n", filename); |
103 | | - return 0; |
104 | | -} |
105 | | - |
106 | 87 | bool sys_is_path_delim(char c) { |
107 | 88 | return c == '/'; |
108 | 89 | } |
109 | 90 |
|
110 | | -int sys_filename_cmp(const char *a, const char *b) { |
111 | | - while (*a && *b) { |
112 | | - if (sys_is_path_delim(*a) && sys_is_path_delim(*b)) { |
113 | | - } else if (*a != *b) { |
114 | | - break; |
115 | | - } |
116 | | - a++; |
117 | | - b++; |
118 | | - } |
119 | | - return *a - *b; |
120 | | -} |
121 | | - |
122 | 91 | bool sys_filename_is_absolute(const char *filename) { |
123 | 92 | return sys_is_path_delim(filename[0]); |
124 | 93 | } |
125 | 94 |
|
126 | 95 | SYS_FILE *sys_fopen(const char *filename, int openmode) { |
127 | | - printf("sys_fopen(%s, %d)\n", filename, openmode); |
128 | | - return nullptr; |
| 96 | + int diskId = EM_ASM_INT({ |
| 97 | + return workerApi.disks.open(UTF8ToString($0)); |
| 98 | + }, filename); |
| 99 | + if (diskId == -1) { |
| 100 | + SYS_FILE_WARN("Failing non-disk sys_fopen(%s, %d)\n", filename, openmode); |
| 101 | + return nullptr; |
| 102 | + } |
| 103 | + |
| 104 | + SYS_FILE_TRACE("sys_fopen %s -> disk ID %d\n", filename, diskId); |
| 105 | + |
| 106 | + return new JSFile{diskId, 0}; |
129 | 107 | } |
130 | 108 |
|
131 | 109 | void sys_fclose(SYS_FILE *file) { |
132 | | - printf("sys_fclose()\n"); |
| 110 | + JSFile *jsFile = static_cast<JSFile*>(file); |
| 111 | + EM_ASM_({ workerApi.disks.close($0); }, jsFile->diskId); |
| 112 | + delete jsFile; |
133 | 113 | } |
134 | 114 |
|
135 | 115 | int sys_fread(SYS_FILE *file, byte *buf, int size) { |
136 | | - printf("sys_fread(%d)\n", size); |
137 | | - return 0; |
| 116 | + JSFile *jsFile = static_cast<JSFile*>(file); |
| 117 | + uint64 readSize = EM_ASM_DOUBLE({ |
| 118 | + return workerApi.disks.read($0, $1, $2, $3); |
| 119 | + }, jsFile->diskId, buf, double(jsFile->pos), double(size)); |
| 120 | + SYS_FILE_TRACE("[disk %d] sys_fread %d bytes at %d\n", jsFile->diskId, size, jsFile->pos); |
| 121 | + jsFile->pos += readSize; |
| 122 | + return readSize; |
138 | 123 | } |
139 | 124 |
|
140 | 125 | int sys_fwrite(SYS_FILE *file, byte *buf, int size) { |
141 | | - printf("sys_fwrite(%d)\n", size); |
142 | | - return 0; |
| 126 | + JSFile *jsFile = static_cast<JSFile*>(file); |
| 127 | + uint64 writeSize = EM_ASM_DOUBLE({ |
| 128 | + return workerApi.disks.write($0, $1, $2, $3); |
| 129 | + }, jsFile->diskId, buf, double(jsFile->pos), double(size)); |
| 130 | + SYS_FILE_TRACE("[disk %d] sys_fwrite %d bytes at %llu\n", jsFile->diskId, size, jsFile->pos); |
| 131 | + jsFile->pos += writeSize; |
| 132 | + return writeSize; |
143 | 133 | } |
144 | 134 |
|
145 | 135 | int sys_fseek(SYS_FILE *file, FileOfs newofs, int seekmode) { |
146 | | - printf("sys_fseek(%lld, %d)\n", newofs, seekmode); |
| 136 | + JSFile *jsFile = static_cast<JSFile*>(file); |
| 137 | + switch (seekmode) { |
| 138 | + case SYS_SEEK_SET: { |
| 139 | + SYS_FILE_TRACE("[disk %d] sys_fseek SEEK_SET to %llu\n", jsFile->diskId, newofs); |
| 140 | + jsFile->pos = newofs; |
| 141 | + break; |
| 142 | + } |
| 143 | + case SYS_SEEK_REL: { |
| 144 | + jsFile->pos += newofs; |
| 145 | + SYS_FILE_TRACE("[disk %d] sys_fseek SEEK_CUR by %llu -> %llu\n", jsFile->diskId, newofs, jsFile->pos); |
| 146 | + break; |
| 147 | + } |
| 148 | + case SYS_SEEK_END: { |
| 149 | + FileOfs size = EM_ASM_DOUBLE({ return workerApi.disks.size($0); }, jsFile->diskId); |
| 150 | + jsFile->pos = size - newofs; |
| 151 | + SYS_FILE_TRACE("[disk %d] sys_fseek SEEK_END by %llu -> %llu\n", jsFile->diskId, newofs, jsFile->pos); |
| 152 | + break; |
| 153 | + } |
| 154 | + default: |
| 155 | + SYS_FILE_TRACE("disk %d] unknown sys_fseek mode %d\n", jsFile->diskId, seekmode); |
| 156 | + break; |
| 157 | + } |
147 | 158 | return 0; |
148 | 159 | } |
149 | 160 |
|
150 | 161 | FileOfs sys_ftell(SYS_FILE *file) { |
151 | | - printf("sys_ftell()\n"); |
152 | | - return 0; |
| 162 | + JSFile *jsFile = static_cast<JSFile*>(file); |
| 163 | + SYS_FILE_TRACE("[disk %d] sys_ftell -> %lld\n", jsFile->diskId, jsFile->pos); |
| 164 | + return jsFile->pos; |
153 | 165 | } |
154 | 166 |
|
155 | 167 | void sys_flush(SYS_FILE *file) { |
156 | | - printf("sys_flush()\n"); |
| 168 | + // No-op in JS |
157 | 169 | } |
158 | 170 |
|
159 | 171 | void sys_suspend() { |
|
0 commit comments