2 #include <sys/dirent.h>
11 int _syscall_set_errno(struct _reent *ptr, int err) {
16 extern int _stat_r(struct _reent *, const char *, struct stat *);
17 int _access_r(struct _reent *ptr, const char *pathname, int mode) {
19 if(_stat_r(ptr,pathname,&statbuf) < 0) return -1;
23 /* NestedVM doesn't, and probably never will, support this security related stuff */
24 uid_t getuid() { return 0; }
25 gid_t getgid() { return 0; }
26 uid_t geteuid() { return 0; }
27 gid_t getegid() { return 0; }
28 int getgroups(int gidsetlen, gid_t *gidset) {
29 if(gidsetlen) *gidset = 0;
32 mode_t umask(mode_t new) { return 0022; }
33 int _chmod_r(struct _reent *ptr, const char *f, mode_t mode) { return 0; }
34 int _fchmod_r(struct _reent *ptr, int fd, mode_t mode) { return 0; }
35 int _chown_r(struct _reent *ptr, const char *f, uid_t uid, gid_t gid) { return 0; }
36 int _fchown_r(struct _reent *ptr, int fd, uid_t uid, gid_t gid) { return 0; }
38 #define REENT_WRAPPER1R(f,rt,t1) \
39 extern rt _##f##_r(struct _reent *ptr, t1 a); \
40 rt f(t1 a) { return _##f##_r(_REENT,a); }
41 #define REENT_WRAPPER1(f,t1) REENT_WRAPPER1R(f,int,t1)
43 #define REENT_WRAPPER2R(f,rt,t1,t2) \
44 extern rt _##f##_r(struct _reent *ptr, t1 a, t2 b); \
45 rt f(t1 a, t2 b) { return _##f##_r(_REENT,a,b); }
46 #define REENT_WRAPPER2(f,t1,t2) REENT_WRAPPER2R(f,int,t1,t2)
48 #define REENT_WRAPPER3R(f,rt,t1,t2,t3) \
49 extern rt _##f##_r(struct _reent *ptr, t1 a, t2 b, t3 c); \
50 rt f(t1 a, t2 b, t3 c) { return _##f##_r(_REENT,a,b,c); }
51 #define REENT_WRAPPER3(f,t1,t2,t3) REENT_WRAPPER3R(f,int,t1,t2,t3)
53 REENT_WRAPPER2(mkdir,const char *,mode_t)
54 REENT_WRAPPER2(access,const char *,int)
55 REENT_WRAPPER1(rmdir,const char *)
56 REENT_WRAPPER1R(sysconf,long,int)
57 REENT_WRAPPER1(chdir,const char*)
58 REENT_WRAPPER2(utime,const char *,const struct utimbuf *)
59 REENT_WRAPPER1(pipe,int *)
60 REENT_WRAPPER2(dup2,int,int)
61 REENT_WRAPPER3(waitpid,pid_t,int *,int)
62 REENT_WRAPPER2R(getcwd,char *,char *,size_t)
63 REENT_WRAPPER2(symlink,const char *,const char *)
64 REENT_WRAPPER3(readlink,const char *, char *,int)
65 REENT_WRAPPER3(chown,const char *,uid_t,gid_t)
66 REENT_WRAPPER3(fchown,int,uid_t,gid_t)
67 REENT_WRAPPER2(chmod,const char *,mode_t)
68 REENT_WRAPPER2(fchmod,int,mode_t)
69 REENT_WRAPPER2(lstat,const char *,struct stat *)
71 extern int __execve_r(struct _reent *ptr, const char *path, char *const argv[], char *const envp[]);
72 int _execve(const char *path, char *const argv[], char *const envp[]) {
73 return __execve_r(_REENT,path,argv,envp);
76 static int read_fully(int fd, void *buf, size_t size) {
79 n = read(fd,buf,size);
87 DIR *opendir(const char *path) {
92 fd = open(path,O_RDONLY);
93 if(fd < 0) return NULL;
95 if(fstat(fd,&sb) < 0 || !S_ISDIR(sb.st_mode)) {
101 dir = malloc(sizeof(*dir));
112 int readdir_r(DIR *dir,struct dirent *entry, struct dirent **result) {
117 if(dir->dd_fd < 0) return -1;
119 if(read_fully(dir->dd_fd,&h,sizeof(h)) < 0) goto fail;
120 if(h.name_len < 0 || h.name_len >= sizeof(entry->d_name)-1) goto fail;
122 entry->d_ino = h.inode;
123 if(read_fully(dir->dd_fd,entry->d_name,h.name_len) < 0) goto fail;
125 entry->d_name[h.name_len] = '\0';
126 //dir->dd_pos += h.name_len + 8;
128 if(result) *result = entry;
131 if(result) *result = NULL;
135 // FIXME: Rewrite all this dirent stuff in terms of a getdirentries syscall
136 static struct dirent static_dir_ent;
138 struct dirent *readdir(DIR *dir) { return readdir_r(dir,&static_dir_ent,NULL) == 0 ? &static_dir_ent : NULL; }
140 int closedir(DIR *dir) {