commit 6d562d2
zzo38
·
2022-11-20 22:26:30 +0000 UTC
parent ddce5b8
Implement directory listing.
2 files changed,
+32,
-6
M
main.c
M
main.c
+21,
-5
1@@ -8,6 +8,7 @@ exit
2 #include "SDL.h"
3 #include <dirent.h>
4 #include <err.h>
5+#include <fcntl.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9@@ -414,10 +415,11 @@ static void console_out(Device*dev,Uint8 id) {
10 }
11 }
12
13-static Uint16 files_stat(char*name,Uint16 len,Uint8*out) {
14+static Uint16 files_stat(int fd,char*name,Uint16 len,Uint8*out) {
15 struct stat st;
16- if(strlen(name)+7>len || stat(name,&st)) return 0;
17- if(st.st_size<0x10000) return snprintf(out,len,"%04x %s\n",(unsigned int)st.st_size,name);
18+ if(strlen(name)+7>len || fstatat(fd,name,&st,0)) return 0;
19+ if(S_ISDIR(st.st_mode)) return snprintf(out,len,"---- %s\n",name);
20+ else if(st.st_size<0x10000) return snprintf(out,len,"%04x %s\n",(unsigned int)st.st_size,name);
21 else return snprintf(out,len,"???? %s\n",name);
22 return 0;
23 }
24@@ -438,6 +440,10 @@ static void files_seek(UxnFile*uf,Uint8 mode,Uint32 len) {
25 case 3: fseek(uf->file,-len,SEEK_END); break;
26 }
27 break;
28+ case 3:
29+ if(((mode>>2)&3)==2) rewinddir(uf->dir);
30+ uf->de=0;
31+ break;
32 }
33 }
34
35@@ -497,7 +503,7 @@ static void files_out(Device*dev,Uint8 id) {
36 addr=GET16(dev->d+4);
37 dev->d[2]=dev->d[3]=0;
38 if(!uf->name[0]) break;
39- y=files_stat(uf->name,len,mem+addr);
40+ y=files_stat(AT_FDCWD,uf->name,len,mem+addr);
41 if(y<=len) PUT16(dev->d+2,y);
42 break;
43 case 6:
44@@ -536,7 +542,17 @@ static void files_out(Device*dev,Uint8 id) {
45 clearerr(uf->file);
46 }
47 } else if(uf->mode==3) {
48- //TODO
49+ do {
50+ if(uf->de) {
51+ if(x=files_stat(dirfd(uf->dir),uf->de->d_name,len,mem+addr)) {
52+ addr+=x;
53+ len-=x;
54+ } else {
55+ break;
56+ }
57+ }
58+ } while(uf->de=readdir(uf->dir));
59+ PUT16(dev->d+2,addr-GET16(dev->d+12));
60 } else {
61 if(files_set(dev,1)) goto read;
62 }
+11,
-1
1@@ -224,7 +224,17 @@ file (in this case, the address and max number of bytes is ignored). In
2 this case, you should write to both 0xAB and 0xAC if you want to do a
3 long read since if you write to only 0xAC then the address is undefined.
4
5-(TODO)
6+Stat will result in a directory entry for the current file being written
7+to the specified address (or nothing if it does not fit). The format of
8+a directory entry is four characters being its size in lowercase
9+hexadecimal with leading zeros, or ???? if it is bigger than 64K, or ----
10+if it is a subdirectory; after that is a space, and then the file name,
11+and then a line feed.
12+
13+If the current file is a directory, then reading from it will read the
14+directory entries in the same format as above. Only full entries can be
15+read; you cannot read partial entries. Only as many full entries as will
16+fit in the allowed space will be retrieved.
17
18 See also emulator.doc for nonstandard meanings of delete/append ports.
19