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