9800e4a3ad37182612afd8b7da3b73b298ffdae0
[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 *ptr, const char *path, struct stat *sb);
17 int _lstat_r(struct _reent *ptr, const char *path, struct stat *sb) {
18     return _stat_r(ptr,path,sb);
19 }
20
21 uid_t getuid() { return 0; }
22 gid_t getgid() { return 0; }
23 uid_t geteuid() { return 0; }
24 gid_t getegid() { return 0; }
25 int getgroups(int gidsetlen, gid_t *gidset) {
26     if(gidsetlen) *gidset = 0;
27     return 1;
28 }
29 mode_t umask(mode_t new) { return 0022; }
30
31 static int syscall_nosys(struct _reent *ptr) {
32     ptr->_errno = ENOSYS;
33     return -1;
34 }
35
36 int _access_r(struct _reent *ptr, const char *pathname, int mode) {
37     struct stat statbuf;
38     if(_stat_r(ptr,pathname,&statbuf) < 0) return -1;
39     return 0;
40 }
41
42 /* FIXME: These should be in newlib */
43 int access(const char *pathname, int mode) { return _access_r(_REENT,pathname,mode); }
44 extern int _rmdir_r(struct _reent *ptr, const char *pathname);
45 int rmdir(const char *pathname) { return _rmdir_r(_REENT,pathname); }
46 extern long _sysconf_r(struct _reent *ptr, int n);
47 long sysconf(int n) { return _sysconf_r(_REENT,n); }
48
49 #define SYSCALL_NOSYS_R(name) int _##name##_r(struct _reent *ptr) { return syscall_nosys(ptr); }
50
51 SYSCALL_NOSYS_R(link)
52 SYSCALL_NOSYS_R(symlink)
53 SYSCALL_NOSYS_R(readlink)
54 SYSCALL_NOSYS_R(chown)
55 SYSCALL_NOSYS_R(fchown)
56 SYSCALL_NOSYS_R(chmod)
57 SYSCALL_NOSYS_R(fchmod)
58
59 static int read_fully(int fd, void *buf, size_t size) {
60     int n;
61     while(size) {
62         n = read(fd,buf,size);
63         if(n <= 0) return -1;
64         size -= n;
65         buf += n;
66     }
67     return 0;
68 }
69
70 DIR *opendir(const char *path) {
71     struct stat sb;
72     int fd;
73     DIR *dir;
74     
75     fd = open(path,O_RDONLY);
76     if(fd < 0) return NULL;
77     
78     if(fstat(fd,&sb) < 0 || !S_ISDIR(sb.st_mode)) {
79         close(fd);
80         errno = ENOTDIR;
81         return NULL;
82     }
83     
84     dir = malloc(sizeof(*dir));
85     if(dir == NULL) {
86         close(fd);
87         errno = ENOMEM;
88         return NULL;
89     }
90     dir->dd_fd = fd;
91     dir->dd_pos = 0;
92     return dir;
93 }
94
95 static int readdir_r(DIR *dir,struct dirent *entry, struct dirent **result) {
96     struct {
97         int inode;
98         int name_len;
99     } h;
100     if(dir->dd_fd < 0) return -1;
101 again:
102     if(read_fully(dir->dd_fd,&h,sizeof(h)) < 0) goto fail;
103     if(h.name_len < 0 || h.name_len >= sizeof(entry->d_name)-1) goto fail;
104     
105     entry->d_ino = h.inode;
106     if(read_fully(dir->dd_fd,entry->d_name,h.name_len) < 0) goto fail;
107     
108     entry->d_name[h.name_len] = '\0';
109     dir->dd_pos += h.name_len + 8;
110     
111     if(result) *result = entry;
112     return 0;
113 fail:
114     if(result) *result = NULL; 
115     return -1;    
116 }
117
118 struct dirent *readdir(DIR *dir) { return readdir_r(dir,&dir->ent,NULL) == 0 ? &dir->ent : NULL; }
119
120 int closedir(DIR *dir) {
121     close(dir->dd_fd);
122     free(dir);
123     return 0;
124 }