commit c0da892
Devine Lu Linvega
·
2026-06-13 17:15:42 +0000 UTC
parent b58e472
Turns out the file device change does not catch the issue Im trying to fix
1 files changed,
+93,
-104
+93,
-104
1@@ -641,21 +641,47 @@ mouse_deo_vector(void)
2 #include <string.h>
3
4 typedef struct {
5- union {
6- FILE *f;
7- DIR *dir;
8- } h;
9+ FILE *f;
10+ DIR *dir;
11 char *filepath;
12 enum { IDLE,
13 FILE_READ,
14 FILE_WRITE,
15 DIR_READ,
16- DIR_WRITE } state;
17+ DIR_WRITE
18+ } state;
19 } UxnFile;
20
21 static UxnFile ufs[2];
22-static char dir_cache[0x200];
23-static unsigned int dir_cache_len;
24+
25+static void
26+make_pathfile(char *pathbuf, const char *filepath, const char *basename)
27+{
28+ char c = '/';
29+ while(*filepath)
30+ c = *filepath++, *pathbuf = c, pathbuf++;
31+ if(c != '/')
32+ *pathbuf = '/', pathbuf++;
33+ while(*basename)
34+ *pathbuf = *basename++, pathbuf++;
35+ *pathbuf = 0;
36+}
37+
38+static inline unsigned int
39+put_fill(Uint8 *dest, unsigned int len, char c)
40+{
41+ memset(dest, c, len);
42+ return len;
43+}
44+
45+static inline unsigned int
46+put_size(Uint8 *dest, unsigned int len, unsigned int size)
47+{
48+ unsigned int i;
49+ for(i = 0, dest += len; i < len; i++, size >>= 4)
50+ *(--dest) = "0123456789abcdef"[(Uint8)(size & 0xf)];
51+ return len;
52+}
53
54 static inline unsigned int
55 put_text(Uint8 *dest, const char *text)
56@@ -670,29 +696,20 @@ put_text(Uint8 *dest, const char *text)
57 static unsigned int
58 put_stat(Uint8 *dest, unsigned int len, unsigned int size, unsigned int err, unsigned int dir, unsigned int capsize)
59 {
60- unsigned int i;
61- if(err || dir || (capsize && size >= 0x10000)) {
62- memset(dest, err ? '!' : dir ? '-' :
63- '?',
64- len);
65- return len;
66- }
67- for(i = 0, dest += len; i < len; i++, size >>= 4)
68- *(--dest) = "0123456789abcdef"[(Uint8)(size & 0xf)];
69- return len;
70+ if(err) return put_fill(dest, len, '!');
71+ if(dir) return put_fill(dest, len, '-');
72+ if(capsize && size >= 0x10000) return put_fill(dest, len, '?');
73+ return put_size(dest, len, size);
74 }
75
76 static unsigned int
77-put_statfile(Uint8 *dest, char *pathbuf, unsigned int prefix_len, unsigned int cap, const char *basename)
78+put_statfile(Uint8 *dest, const char *filepath, const char *basename)
79 {
80 unsigned int err, dir;
81 struct stat st;
82 Uint8 *anchor = dest;
83- char *p = pathbuf + prefix_len, *end = pathbuf + cap - 1;
84- const char *b = basename;
85- while(*b && p < end)
86- *p++ = *b++;
87- *p = 0;
88+ char pathbuf[0x200];
89+ make_pathfile(pathbuf, filepath, basename);
90 err = stat(pathbuf, &st);
91 dir = !err && S_ISDIR(st.st_mode);
92 dest += put_stat(dest, 4, st.st_size, err, dir, 1);
93@@ -707,19 +724,11 @@ put_fdir(Uint8 *dest, unsigned int len, const char *filepath, DIR *dir)
94 {
95 Uint8 *p = dest, *end = dest + len - 1;
96 struct dirent *de;
97- char pathbuf[0x200];
98- unsigned int prefix_len = 0;
99- char c = '/';
100- const char *fp = filepath;
101- while(*fp && prefix_len < sizeof pathbuf - 1)
102- c = *fp++, pathbuf[prefix_len++] = c;
103- if(c != '/' && prefix_len < sizeof pathbuf - 1)
104- pathbuf[prefix_len++] = '/';
105 while((de = readdir(dir)) && p < end) {
106 const char *name = de->d_name;
107 if(name[0] == '.' && (!name[1] || (name[1] == '.' && !name[2])))
108 continue;
109- p += put_statfile(p, pathbuf, prefix_len, sizeof pathbuf, name);
110+ p += put_statfile(p, filepath, name);
111 }
112 *p = 0;
113 return p - dest;
114@@ -744,65 +753,27 @@ static unsigned int
115 file_write_dir(const char *p)
116 {
117 char buf[0x200];
118- char *s = buf, *end = buf + sizeof buf - 1;
119+ char *s = buf;
120 unsigned int ok = 1;
121- while(*p && ok && s < end) {
122+ while(*p && ok) {
123 *s++ = *p;
124 if(*p++ == '/') {
125- unsigned int seg_len = s - buf;
126- if(seg_len <= dir_cache_len && !memcmp(buf, dir_cache, seg_len)) {
127- // reuse
128- } else {
129- s[-1] = '\0', ok = is_dir_real(buf) || mkdir(buf, 0755) == 0, s[-1] = '/';
130- if(ok)
131- memcpy(dir_cache, buf, seg_len), dir_cache_len = seg_len;
132- }
133+ s[-1] = '\0';
134+ ok = is_dir_real(buf) || mkdir(buf, 0755) == 0;
135+ s[-1] = '/';
136 }
137 }
138- return ok && !*p;
139+ return ok;
140 }
141
142 static void
143 file_reset(unsigned int id)
144 {
145- switch(ufs[id].state) {
146- case FILE_READ:
147- case FILE_WRITE: fclose(ufs[id].h.f); break;
148- case DIR_READ: closedir(ufs[id].h.dir); break;
149- default: break;
150- }
151+ if(ufs[id].f != NULL) fclose(ufs[id].f), ufs[id].f = NULL;
152+ if(ufs[id].dir != NULL) closedir(ufs[id].dir), ufs[id].dir = NULL;
153 ufs[id].state = IDLE;
154 }
155
156-static unsigned int
157-file_open(unsigned int id, unsigned int want_write, Uint8 flags)
158-{
159- UxnFile *u = &ufs[id];
160- struct stat st;
161- if(want_write) {
162- if(u->state == FILE_WRITE || u->state == DIR_WRITE)
163- return 1;
164- file_reset(id);
165- file_write_dir(u->filepath);
166- if(is_dir_path(u->filepath)) {
167- u->state = is_dir_real(u->filepath) ? DIR_WRITE : IDLE;
168- } else if((u->h.f = fopen(u->filepath, (flags & 0x01) ? "ab" : "wb"))) {
169- u->state = FILE_WRITE;
170- }
171- } else {
172- if(u->state == FILE_READ || u->state == DIR_READ)
173- return 1;
174- file_reset(id);
175- if(stat(u->filepath, &st) == 0 && S_ISDIR(st.st_mode)) {
176- if((u->h.dir = opendir(u->filepath)))
177- u->state = DIR_READ;
178- } else if((u->h.f = fopen(u->filepath, "rb"))) {
179- u->state = FILE_READ;
180- }
181- }
182- return u->state != IDLE;
183-}
184-
185 static unsigned int
186 file_init(unsigned int id, Uint16 addr)
187 {
188@@ -812,54 +783,72 @@ file_init(unsigned int id, Uint16 addr)
189 }
190
191 static unsigned int
192-file_write(unsigned int id, Uint16 addr, unsigned int len, Uint8 flags)
193+file_read(unsigned int id, Uint16 addr, unsigned int len)
194 {
195+ void *dest = &ram[addr];
196+ struct stat st;
197+ unsigned int n;
198 if(ufs[id].filepath == 0)
199 return 0;
200 if(addr + len > 0x10000)
201 len = 0x10000 - addr;
202- if(!file_open(id, 1, flags))
203- return 0;
204- if(ufs[id].state == FILE_WRITE)
205- return fwrite(&ram[addr], 1, len, ufs[id].h.f);
206- return is_dir_real(ufs[id].filepath);
207+ if(ufs[id].state != FILE_READ && ufs[id].state != DIR_READ) {
208+ file_reset(id);
209+ if(stat(ufs[id].filepath, &st) == 0 && S_ISDIR(st.st_mode)) {
210+ if((ufs[id].dir = opendir(ufs[id].filepath)) != NULL)
211+ ufs[id].state = DIR_READ;
212+ } else if((ufs[id].f = fopen(ufs[id].filepath, "rb")) != NULL) {
213+ ufs[id].state = FILE_READ;
214+ }
215+ }
216+ if(ufs[id].state == FILE_READ) {
217+ n = fread(dest, 1, len, ufs[id].f);
218+ if(n == 0) file_reset(id);
219+ return n;
220+ }
221+ if(ufs[id].state == DIR_READ) {
222+ n = put_fdir(dest, len, ufs[id].filepath, ufs[id].dir);
223+ if(n == 0) file_reset(id);
224+ return n;
225+ }
226+ return 0;
227 }
228
229 static unsigned int
230-file_stat(unsigned int id, Uint16 addr, unsigned int len)
231+file_write(unsigned int id, Uint16 addr, unsigned int len, Uint8 flags)
232 {
233- unsigned int err, dir;
234- struct stat st;
235+ unsigned int ret = 0;
236 if(ufs[id].filepath == 0)
237 return 0;
238 if(addr + len > 0x10000)
239 len = 0x10000 - addr;
240+ if(ufs[id].state != FILE_WRITE && ufs[id].state != DIR_WRITE) {
241+ file_reset(id);
242+ file_write_dir(ufs[id].filepath);
243+ if(is_dir_path(ufs[id].filepath))
244+ ufs[id].state = DIR_WRITE;
245+ else if((ufs[id].f = fopen(ufs[id].filepath, (flags & 0x01) ? "ab" : "wb")) != NULL)
246+ ufs[id].state = FILE_WRITE;
247+ }
248 if(ufs[id].state == FILE_WRITE)
249- fflush(ufs[id].h.f);
250- err = stat(ufs[id].filepath, &st);
251- dir = !err && S_ISDIR(st.st_mode);
252- return put_stat(&ram[addr], len, st.st_size, err, dir, 0);
253+ ret = fwrite(&ram[addr], 1, len, ufs[id].f);
254+ if(ufs[id].state == DIR_WRITE)
255+ ret = is_dir_real(ufs[id].filepath);
256+ return ret;
257 }
258
259 static unsigned int
260-file_read(unsigned int id, Uint16 addr, unsigned int len)
261+file_stat(unsigned int id, Uint16 addr, unsigned int len)
262 {
263- void *dest = &ram[addr];
264- unsigned int n;
265+ unsigned int err, dir;
266+ struct stat st;
267 if(ufs[id].filepath == 0)
268 return 0;
269 if(addr + len > 0x10000)
270 len = 0x10000 - addr;
271- if(ufs[id].state == FILE_WRITE)
272- fflush(ufs[id].h.f);
273- if(!file_open(id, 0, 0))
274- return 0;
275- if(ufs[id].state == FILE_READ)
276- n = fread(dest, 1, len, ufs[id].h.f);
277- else
278- n = put_fdir(dest, len, ufs[id].filepath, ufs[id].h.dir);
279- if(n == 0) file_reset(id);
280- return n;
281+ err = stat(ufs[id].filepath, &st);
282+ dir = !err && S_ISDIR(st.st_mode);
283+ return put_stat(&ram[addr], len, st.st_size, err, dir, 0);
284 }
285
286 static unsigned int