bc32e8ecc39edecb3c2f160b189151ed4320214e
[nestedvm.git] / src / org / ibex / nestedvm / support_aux.c
1 #include <sys/stat.h>
2 #include <sys/dirent.h>
3 #include <sys/types.h>
4 #include <utime.h>
5 #include <errno.h>
6 #include <unistd.h>
7 #include <fcntl.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10
11 int _syscall_set_errno(struct _reent *ptr, int err) {
12     ptr->_errno = -err;
13     return -1;
14 }
15
16 extern int _stat_r(struct _reent *, const char *, struct stat *);
17 int _access_r(struct _reent *ptr, const char *pathname, int mode) {
18     struct stat statbuf;
19     if(_stat_r(ptr,pathname,&statbuf) < 0) return -1;
20     return 0;
21 }
22
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;
30     return 1;
31 }
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; }
37
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)
42
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)
47
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)
52
53 #define REENT_WRAPPER4R(f,rt,t1,t2,t3,t4) \
54 extern rt _##f##_r(struct _reent *ptr, t1 a, t2 b, t3 c, t4 d); \
55 rt f(t1 a, t2 b, t3 c, t4 d) { return _##f##_r(_REENT,a,b,c,d); }
56 #define REENT_WRAPPER4(f,t1,t2,t3,t4) REENT_WRAPPER4R(f,int,t1,t2,t3,t4)
57
58 REENT_WRAPPER2(mkdir,const char *,mode_t)
59 REENT_WRAPPER2(access,const char *,int)
60 REENT_WRAPPER1(rmdir,const char *)
61 REENT_WRAPPER1R(sysconf,long,int)
62 REENT_WRAPPER1(chdir,const char*)
63 REENT_WRAPPER2(utime,const char *,const struct utimbuf *)
64 REENT_WRAPPER1(pipe,int *)
65 REENT_WRAPPER2(dup2,int,int)
66 REENT_WRAPPER3(waitpid,pid_t,int *,int)
67 REENT_WRAPPER2R(getcwd,char *,char *,size_t)
68 REENT_WRAPPER2R(_getcwd,char *,char *,size_t)
69 REENT_WRAPPER2(symlink,const char *,const char *)
70 REENT_WRAPPER3(readlink,const char *, char *,int)
71 REENT_WRAPPER3(chown,const char *,uid_t,gid_t)
72 REENT_WRAPPER3(fchown,int,uid_t,gid_t)
73 REENT_WRAPPER2(chmod,const char *,mode_t)
74 REENT_WRAPPER2(fchmod,int,mode_t)
75 REENT_WRAPPER2(lstat,const char *,struct stat *)
76 REENT_WRAPPER4(getdents,int, char *, size_t,long *)
77 REENT_WRAPPER1(dup,int)
78 REENT_WRAPPER2R(pathconf,long,const char *,int)
79
80 extern int __execve_r(struct _reent *ptr, const char *path, char *const argv[], char *const envp[]);
81 int _execve(const char *path, char *const argv[], char *const envp[]) {
82     return __execve_r(_REENT,path,argv,envp);
83 }
84
85 char *_getcwd_r(struct _reent *ptr, char *buf, size_t size) {
86     if(buf != NULL) {
87         buf = __getcwd_r(ptr,buf,size);
88         return (long)buf == -1 ? NULL : buf;
89     }
90     
91     size = 256;
92     for(;;) {
93         buf = malloc(size);
94         char *ret = __getcwd_r(ptr,buf,size);
95         if((long)ret != -1) return ret;
96         free(buf);
97         size *= 2;
98         if(ptr->_errno != ERANGE) return NULL;
99     }
100 }
101
102 pid_t _wait_r(struct _reent *ptr, int *status) {
103     return _waitpid_r(ptr,-1,status,0);
104 }
105
106 long _pathconf_r(struct _reent *ptr,const char *path, int name) {
107     switch(name) {
108         default:
109             fprintf(stderr,"WARNING: pathconf: Unknown \"name\": %d\n",name);
110             ptr->_errno = EINVAL;
111             return -1;
112     }
113 }
114
115 DIR *opendir(const char *path) {
116     struct stat sb;
117     int fd;
118     DIR *dir;
119     
120     fd = open(path,O_RDONLY);
121     if(fd < 0) return NULL;
122     
123     if(fstat(fd,&sb) < 0 || !S_ISDIR(sb.st_mode)) {
124         close(fd);
125         errno = ENOTDIR;
126         return NULL;
127     }
128     
129     dir = malloc(sizeof(*dir));
130     if(dir == NULL) {
131         close(fd);
132         errno = ENOMEM;
133         return NULL;
134     }
135     dir->dd_fd = fd;
136     dir->dd_buf = malloc(sizeof(struct dirent));
137     dir->dd_size = sizeof(struct dirent);
138     if(dir->dd_buf == NULL) {
139         close(fd);
140         free(dir);
141         return NULL;
142     }
143     dir->dd_loc = 0;
144     dir->dd_len = 0;
145     return dir;
146 }
147
148 struct dirent *readdir(DIR *dir) {
149     struct dirent *dp;
150     errno = 0;
151     if(dir->dd_loc == 0 || dir->dd_loc == dir->dd_len) {
152         dir->dd_len = getdents(dir->dd_fd,dir->dd_buf,dir->dd_size,NULL);
153         dir->dd_loc = 0;
154         if(dir->dd_len <= 0) { dir->dd_len = 0; return NULL; }
155     }
156     dp = (struct dirent*) (dir->dd_buf + dir->dd_loc);
157     if(dp->d_reclen == 0 || dp->d_reclen > dir->dd_len - dir->dd_loc) return NULL;
158     dir->dd_loc += dp->d_reclen;
159     return dp;
160 }
161
162 int closedir(DIR *dir) {
163     int fd = dir->dd_fd;
164     free(dir->dd_buf);
165     free(dir);
166     return close(fd);
167 }