X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Fnestedvm%2Fsupport_aux.c;h=513434ef320f691f4dffecd5d579b39ce3fe67a0;hb=b6be9bcc91cf8e995a0e616a480813cdbef09dc2;hp=59164cba59b55d6b3e59cab345e6d2727374ba2d;hpb=c59b7cfc7a6b67574d38c5c8eb7732bad37236b0;p=nestedvm.git diff --git a/src/org/ibex/nestedvm/support_aux.c b/src/org/ibex/nestedvm/support_aux.c index 59164cb..513434e 100644 --- a/src/org/ibex/nestedvm/support_aux.c +++ b/src/org/ibex/nestedvm/support_aux.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -7,6 +8,7 @@ #include #include #include +#include int _syscall_set_errno(struct _reent *ptr, int err) { ptr->_errno = -err; @@ -35,6 +37,11 @@ int _fchmod_r(struct _reent *ptr, int fd, mode_t mode) { return 0; } int _chown_r(struct _reent *ptr, const char *f, uid_t uid, gid_t gid) { return 0; } int _fchown_r(struct _reent *ptr, int fd, uid_t uid, gid_t gid) { return 0; } +#define REENT_WRAPPER0R(f,rt) \ + extern rt _##f##_r(struct _reent *ptr); \ + rt f() { return _##f##_r(_REENT); } +#define REENT_WRAPPER0(f) REENT_WRAPPER0R(f,int) + #define REENT_WRAPPER1R(f,rt,t1) \ extern rt _##f##_r(struct _reent *ptr, t1 a); \ rt f(t1 a) { return _##f##_r(_REENT,a); } @@ -50,6 +57,11 @@ int _fchown_r(struct _reent *ptr, int fd, uid_t uid, gid_t gid) { return 0; } rt f(t1 a, t2 b, t3 c) { return _##f##_r(_REENT,a,b,c); } #define REENT_WRAPPER3(f,t1,t2,t3) REENT_WRAPPER3R(f,int,t1,t2,t3) +#define REENT_WRAPPER4R(f,rt,t1,t2,t3,t4) \ +extern rt _##f##_r(struct _reent *ptr, t1 a, t2 b, t3 c, t4 d); \ +rt f(t1 a, t2 b, t3 c, t4 d) { return _##f##_r(_REENT,a,b,c,d); } +#define REENT_WRAPPER4(f,t1,t2,t3,t4) REENT_WRAPPER4R(f,int,t1,t2,t3,t4) + REENT_WRAPPER2(mkdir,const char *,mode_t) REENT_WRAPPER2(access,const char *,int) REENT_WRAPPER1(rmdir,const char *) @@ -60,27 +72,101 @@ REENT_WRAPPER1(pipe,int *) REENT_WRAPPER2(dup2,int,int) REENT_WRAPPER3(waitpid,pid_t,int *,int) REENT_WRAPPER2R(getcwd,char *,char *,size_t) +REENT_WRAPPER2R(_getcwd,char *,char *,size_t) REENT_WRAPPER2(symlink,const char *,const char *) REENT_WRAPPER3(readlink,const char *, char *,int) REENT_WRAPPER3(chown,const char *,uid_t,gid_t) REENT_WRAPPER3(fchown,int,uid_t,gid_t) +REENT_WRAPPER3(lchown,const char *,uid_t,gid_t) REENT_WRAPPER2(chmod,const char *,mode_t) REENT_WRAPPER2(fchmod,int,mode_t) REENT_WRAPPER2(lstat,const char *,struct stat *) +REENT_WRAPPER4(getdents,int, char *, size_t,long *) +REENT_WRAPPER1(dup,int) +REENT_WRAPPER2R(pathconf,long,const char *,int) +REENT_WRAPPER0(vfork) +REENT_WRAPPER1(chroot,const char *) +REENT_WRAPPER3(mknod,const char *,mode_t,dev_t) +REENT_WRAPPER2(ftruncate,int,off_t) +REENT_WRAPPER1(usleep,unsigned int) +REENT_WRAPPER2(mkfifo,const char *, mode_t) +REENT_WRAPPER2(_open_socket,const char *,int) +REENT_WRAPPER1(_listen_socket,int) +REENT_WRAPPER1(_accept,int) extern int __execve_r(struct _reent *ptr, const char *path, char *const argv[], char *const envp[]); int _execve(const char *path, char *const argv[], char *const envp[]) { return __execve_r(_REENT,path,argv,envp); } -static int read_fully(int fd, void *buf, size_t size) { - int n; - while(size) { - n = read(fd,buf,size); - if(n <= 0) return -1; - size -= n; - buf += n; +char *_getcwd_r(struct _reent *ptr, char *buf, size_t size) { + if(buf != NULL) { + buf = __getcwd_r(ptr,buf,size); + return (long)buf == -1 ? NULL : buf; + } + + size = 256; + for(;;) { + buf = malloc(size); + char *ret = __getcwd_r(ptr,buf,size); + if((long)ret != -1) return ret; + free(buf); + size *= 2; + if(ptr->_errno != ERANGE) return NULL; + } +} + +pid_t _wait_r(struct _reent *ptr, int *status) { + return _waitpid_r(ptr,-1,status,0); +} + +long _pathconf_r(struct _reent *ptr,const char *path, int name) { + switch(name) { + default: + fprintf(stderr,"WARNING: pathconf: Unknown \"name\": %d\n",name); + ptr->_errno = EINVAL; + return -1; + } +} + +void sync() { + /* do nothing*/ +} + +int fsync(int fd) { + /* do nothing */ + return 0; +} + +char *ttyname(int fd) { + return isatty(fd) ? "/dev/console" : NULL; +} + +int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { + _sig_func_ptr old; + _sig_func_ptr new; + if(act) { + if(act->sa_flags || act->sa_mask != ~((sigset_t)0)) { errno = EINVAL; return -1; } + old = signal(sig,act->sa_handler); + } else if(oact) { + old = signal(sig,SIG_DFL); + signal(sig,old); } + if(oact) { + oact->sa_handler = old; + oact->sa_mask = 0; + oact->sa_mask = ~((sigset_t)0); + } + return 0; +} + +int sigfillset(sigset_t *set) { + *set = ~((sigset_t)0); + return 0; +} + +int sigemptyset(sigset_t *set) { + *set = (sigset_t) 0; return 0; } @@ -105,40 +191,150 @@ DIR *opendir(const char *path) { return NULL; } dir->dd_fd = fd; - //dir->dd_pos = 0; + dir->dd_buf = malloc(sizeof(struct dirent)); + dir->dd_size = sizeof(struct dirent); + if(dir->dd_buf == NULL) { + close(fd); + free(dir); + return NULL; + } + dir->dd_loc = 0; + dir->dd_len = 0; return dir; } -int readdir_r(DIR *dir,struct dirent *entry, struct dirent **result) { - struct { - int inode; - int name_len; - } h; - if(dir->dd_fd < 0) return -1; -again: - if(read_fully(dir->dd_fd,&h,sizeof(h)) < 0) goto fail; - if(h.name_len < 0 || h.name_len >= sizeof(entry->d_name)-1) goto fail; +struct dirent *readdir(DIR *dir) { + struct dirent *dp; + errno = 0; + if(dir->dd_loc == 0 || dir->dd_loc == dir->dd_len) { + dir->dd_len = getdents(dir->dd_fd,dir->dd_buf,dir->dd_size,NULL); + dir->dd_loc = 0; + if(dir->dd_len <= 0) { dir->dd_len = 0; return NULL; } + } + dp = (struct dirent*) (dir->dd_buf + dir->dd_loc); + if(dp->d_reclen == 0 || dp->d_reclen > dir->dd_len - dir->dd_loc) return NULL; + dir->dd_loc += dp->d_reclen; + return dp; +} + +int closedir(DIR *dir) { + int fd = dir->dd_fd; + free(dir->dd_buf); + free(dir); + return close(fd); +} + +/* + * Other People's Code + */ + +/* FreeBSD's dirname/basename */ + +/* FIXME: Put these in a header */ + +/* + * Copyright (c) 1997 Todd C. Miller + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +char * +dirname(path) +const char *path; +{ + static char bname[MAXPATHLEN]; + register const char *endp; - entry->d_ino = h.inode; - if(read_fully(dir->dd_fd,entry->d_name,h.name_len) < 0) goto fail; + /* Empty or NULL string gets treated as "." */ + if (path == NULL || *path == '\0') { + (void)strcpy(bname, "."); + return(bname); + } - entry->d_name[h.name_len] = '\0'; - //dir->dd_pos += h.name_len + 8; + /* Strip trailing slashes */ + endp = path + strlen(path) - 1; + while (endp > path && *endp == '/') + endp--; - if(result) *result = entry; - return 0; -fail: - if(result) *result = NULL; - return -1; + /* Find the start of the dir */ + while (endp > path && *endp != '/') + endp--; + + /* Either the dir is "/" or there are no slashes */ + if (endp == path) { + (void)strcpy(bname, *endp == '/' ? "/" : "."); + return(bname); + } else { + do { + endp--; + } while (endp > path && *endp == '/'); + } + + if (endp - path + 2 > sizeof(bname)) { + errno = ENAMETOOLONG; + return(NULL); + } + (void)strncpy(bname, path, endp - path + 1); + bname[endp - path + 1] = '\0'; + return(bname); } -// FIXME: Rewrite all this dirent stuff in terms of a getdirentries syscall -static struct dirent static_dir_ent; - -struct dirent *readdir(DIR *dir) { return readdir_r(dir,&static_dir_ent,NULL) == 0 ? &static_dir_ent : NULL; } - -int closedir(DIR *dir) { - close(dir->dd_fd); - free(dir); - return 0; +char * +basename(path) +const char *path; +{ + static char bname[MAXPATHLEN]; + register const char *endp, *startp; + + /* Empty or NULL string gets treated as "." */ + if (path == NULL || *path == '\0') { + (void)strcpy(bname, "."); + return(bname); + } + + /* Strip trailing slashes */ + endp = path + strlen(path) - 1; + while (endp > path && *endp == '/') + endp--; + + /* All slashes becomes "/" */ + if (endp == path && *endp == '/') { + (void)strcpy(bname, "/"); + return(bname); + } + + /* Find the start of the base */ + startp = endp; + while (startp > path && *(startp - 1) != '/') + startp--; + + if (endp - startp + 2 > sizeof(bname)) { + errno = ENAMETOOLONG; + return(NULL); + } + (void)strncpy(bname, startp, endp - startp + 1); + bname[endp - startp + 1] = '\0'; + return(bname); } +