make plain old gcc -o foo foo.c work
[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
78 extern int __execve_r(struct _reent *ptr, const char *path, char *const argv[], char *const envp[]);
79 int _execve(const char *path, char *const argv[], char *const envp[]) {
80     return __execve_r(_REENT,path,argv,envp);
81 }
82
83 char *_getcwd_r(struct _reent *ptr, char *buf, size_t size) {
84     if(buf != NULL) {
85         buf = __getcwd_r(ptr,buf,size);
86         return (long)buf == -1 ? NULL : buf;
87     }
88     
89     size = 256;
90     for(;;) {
91         buf = malloc(size);
92         char *ret = __getcwd_r(ptr,buf,size);
93         if((long)ret != -1) return ret;
94         free(buf);
95         size *= 2;
96         if(ptr->_errno != ERANGE) return NULL;
97     }
98 }
99
100 DIR *opendir(const char *path) {
101     struct stat sb;
102     int fd;
103     DIR *dir;
104     
105     fd = open(path,O_RDONLY);
106     if(fd < 0) return NULL;
107     
108     if(fstat(fd,&sb) < 0 || !S_ISDIR(sb.st_mode)) {
109         close(fd);
110         errno = ENOTDIR;
111         return NULL;
112     }
113     
114     dir = malloc(sizeof(*dir));
115     if(dir == NULL) {
116         close(fd);
117         errno = ENOMEM;
118         return NULL;
119     }
120     dir->dd_fd = fd;
121     dir->dd_buf = malloc(sizeof(struct dirent));
122     dir->dd_size = sizeof(struct dirent);
123     if(dir->dd_buf == NULL) {
124         close(fd);
125         free(dir);
126         return NULL;
127     }
128     dir->dd_loc = 0;
129     dir->dd_len = 0;
130     return dir;
131 }
132
133 struct dirent *readdir(DIR *dir) {
134     struct dirent *dp;
135     errno = 0;
136     if(dir->dd_loc == 0 || dir->dd_loc == dir->dd_len) {
137         dir->dd_len = getdents(dir->dd_fd,dir->dd_buf,dir->dd_size,NULL);
138         dir->dd_loc = 0;
139         if(dir->dd_len <= 0) { dir->dd_len = 0; return NULL; }
140     }
141     dp = (struct dirent*) (dir->dd_buf + dir->dd_loc);
142     if(dp->d_reclen == 0 || dp->d_reclen > dir->dd_len - dir->dd_loc) return NULL;
143     dir->dd_loc += dp->d_reclen;
144     return dp;
145 }
146
147 int closedir(DIR *dir) {
148     int fd = dir->dd_fd;
149     free(dir->dd_buf);
150     free(dir);
151     return close(fd);
152 }