3 #include <sys/dirent.h>
12 #include <sys/sysctl.h>
13 #include <sys/utsname.h>
16 #include <nestedvm/socket.h>
18 int _syscall_set_errno(struct _reent *ptr, int err) {
23 #define REENT_WRAPPER0R(f,rt) \
24 extern rt _##f##_r(struct _reent *ptr); \
25 rt f() { return _##f##_r(_REENT); }
26 #define REENT_WRAPPER0(f) REENT_WRAPPER0R(f,int)
28 #define REENT_WRAPPER1R(f,rt,t1) \
29 extern rt _##f##_r(struct _reent *ptr, t1 a); \
30 rt f(t1 a) { return _##f##_r(_REENT,a); }
31 #define REENT_WRAPPER1(f,t1) REENT_WRAPPER1R(f,int,t1)
33 #define REENT_WRAPPER2R(f,rt,t1,t2) \
34 extern rt _##f##_r(struct _reent *ptr, t1 a, t2 b); \
35 rt f(t1 a, t2 b) { return _##f##_r(_REENT,a,b); }
36 #define REENT_WRAPPER2(f,t1,t2) REENT_WRAPPER2R(f,int,t1,t2)
38 #define REENT_WRAPPER3R(f,rt,t1,t2,t3) \
39 extern rt _##f##_r(struct _reent *ptr, t1 a, t2 b, t3 c); \
40 rt f(t1 a, t2 b, t3 c) { return _##f##_r(_REENT,a,b,c); }
41 #define REENT_WRAPPER3(f,t1,t2,t3) REENT_WRAPPER3R(f,int,t1,t2,t3)
43 #define REENT_WRAPPER4R(f,rt,t1,t2,t3,t4) \
44 extern rt _##f##_r(struct _reent *ptr, t1 a, t2 b, t3 c, t4 d); \
45 rt f(t1 a, t2 b, t3 c, t4 d) { return _##f##_r(_REENT,a,b,c,d); }
46 #define REENT_WRAPPER4(f,t1,t2,t3,t4) REENT_WRAPPER4R(f,int,t1,t2,t3,t4)
48 #define REENT_WRAPPER5R(f,rt,t1,t2,t3,t4,t5) \
49 extern rt _##f##_r(struct _reent *ptr, t1 a, t2 b, t3 c, t4 d, t5 e); \
50 rt f(t1 a, t2 b, t3 c, t4 d, t5 e) { return _##f##_r(_REENT,a,b,c,d,e); }
51 #define REENT_WRAPPER5(f,t1,t2,t3,t4,t5) REENT_WRAPPER5R(f,int,t1,t2,t3,t4,t5)
53 #define REENT_WRAPPER6R(f,rt,t1,t2,t3,t4,t5,t6) \
54 extern rt _##f##_r(struct _reent *ptr, t1 a, t2 b, t3 c, t4 d, t5 e, t6 f); \
55 rt f(t1 a, t2 b, t3 c, t4 d, t5 e, t6 f) { return _##f##_r(_REENT,a,b,c,d,e,f); }
56 #define REENT_WRAPPER6(f,t1,t2,t3,t4,t5,t6) REENT_WRAPPER6R(f,int,t1,t2,t3,t4,t5,t6)
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_WRAPPER3(lchown,const char *,uid_t,gid_t)
74 REENT_WRAPPER2(chmod,const char *,mode_t)
75 REENT_WRAPPER2(fchmod,int,mode_t)
76 REENT_WRAPPER2(lstat,const char *,struct stat *)
77 REENT_WRAPPER4(getdents,int, char *, size_t,long *)
78 REENT_WRAPPER1(dup,int)
79 REENT_WRAPPER2R(pathconf,long,const char *,int)
81 REENT_WRAPPER1(chroot,const char *)
82 REENT_WRAPPER3(mknod,const char *,mode_t,dev_t)
83 REENT_WRAPPER2(ftruncate,int,off_t)
84 REENT_WRAPPER1(usleep,unsigned int)
85 REENT_WRAPPER2(mkfifo,const char *, mode_t)
86 REENT_WRAPPER3(klogctl,int,char*,int)
87 REENT_WRAPPER2R(realpath,char *,const char *,char *)
88 REENT_WRAPPER6(_sysctl,int *,int, void *, size_t*, void *, size_t)
89 REENT_WRAPPER6(sysctl,int *, int, void *, size_t*, void *, size_t)
90 REENT_WRAPPER2(getpriority,int,int)
91 REENT_WRAPPER3(setpriority,int,int,int)
92 REENT_WRAPPER3(connect,int,const struct sockaddr *,socklen_t)
93 REENT_WRAPPER3(socket,int,int,int)
94 REENT_WRAPPER3(_resolve_hostname,const char *,char*,size_t*)
95 REENT_WRAPPER3(_resolve_ip,int,char*,size_t)
96 REENT_WRAPPER3(accept,int,struct sockaddr *,socklen_t*)
97 REENT_WRAPPER5(getsockopt,int,int,int,void*,socklen_t*)
98 REENT_WRAPPER5(setsockopt,int,int,int,const void*,socklen_t)
99 REENT_WRAPPER3(bind,int,const struct sockaddr *,socklen_t)
100 REENT_WRAPPER2(listen,int,int)
101 REENT_WRAPPER2(shutdown,int,int)
102 REENT_WRAPPER6(sendto,int,const void*,size_t,int,const struct sockaddr*,socklen_t)
103 REENT_WRAPPER6(recvfrom,int,void*,size_t,int,struct sockaddr*,socklen_t*)
104 REENT_WRAPPER5(select,int,fd_set*,fd_set*,fd_set*,struct timeval*)
105 REENT_WRAPPER4(send,int,const void*,size_t,int)
106 REENT_WRAPPER4(recv,int,void*,size_t,int)
107 REENT_WRAPPER2(getgroups,int,gid_t*)
108 REENT_WRAPPER3(getsockname,int,struct sockaddr*,int*)
109 REENT_WRAPPER3(getpeername,int,struct sockaddr*,int*)
110 REENT_WRAPPER1(setuid,uid_t)
111 REENT_WRAPPER1(seteuid,uid_t)
112 REENT_WRAPPER1(setgid,gid_t)
113 REENT_WRAPPER1(setegid,gid_t)
114 REENT_WRAPPER2(setgroups,int,const gid_t *)
115 REENT_WRAPPER0R(setsid,pid_t)
117 extern int __execve_r(struct _reent *ptr, const char *path, char *const argv[], char *const envp[]);
118 int _execve(const char *path, char *const argv[], char *const envp[]) {
119 return __execve_r(_REENT,path,argv,envp);
122 char *_getcwd_r(struct _reent *ptr, char *buf, size_t size) {
124 buf = __getcwd_r(ptr,buf,size);
125 return (long)buf == -1 ? NULL : buf;
131 char *ret = __getcwd_r(ptr,buf,size);
132 if((long)ret != -1) return ret;
135 if(ptr->_errno != ERANGE) return NULL;
139 pid_t _wait_r(struct _reent *ptr, int *status) {
140 return _waitpid_r(ptr,-1,status,0);
143 long _pathconf_r(struct _reent *ptr,const char *path, int name) {
146 fprintf(stderr,"WARNING: pathconf: Unknown \"name\": %d\n",name);
147 ptr->_errno = EINVAL;
152 int _sysctl_r(struct _reent *ptr, int *name, int namelen, void *oldp, size_t *oldlen, void *newp, size_t newlen) {
153 if(name[0] != CTL_USER) return _sysctl(name,namelen,oldp,oldlen,newp,newlen);
154 if(newp != NULL) { ptr->_errno = EPERM; return -1; }
155 if(namelen != 2) { ptr->_errno = EINVAL; return -1; }
159 fprintf(stderr,"WARNING: sysctl: Unknown name: %d\n",name[1]);
160 ptr->_errno = EINVAL;
174 char *ttyname(int fd) {
175 return isatty(fd) ? "/dev/console" : NULL;
178 int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
182 if(act->sa_flags || act->sa_mask != ~((sigset_t)0)) { errno = EINVAL; return -1; }
183 old = signal(sig,act->sa_handler);
185 old = signal(sig,SIG_DFL);
189 oact->sa_handler = old;
191 oact->sa_mask = ~((sigset_t)0);
196 int sigfillset(sigset_t *set) {
197 *set = ~((sigset_t)0);
201 int sigemptyset(sigset_t *set) {
206 DIR *opendir(const char *path) {
211 fd = open(path,O_RDONLY);
212 if(fd < 0) return NULL;
214 if(fstat(fd,&sb) < 0 || !S_ISDIR(sb.st_mode)) {
220 dir = malloc(sizeof(*dir));
227 dir->dd_buf = malloc(sizeof(struct dirent));
228 dir->dd_size = sizeof(struct dirent);
229 if(dir->dd_buf == NULL) {
239 struct dirent *readdir(DIR *dir) {
242 if(dir->dd_loc == 0 || dir->dd_loc == dir->dd_len) {
243 dir->dd_len = getdents(dir->dd_fd,dir->dd_buf,dir->dd_size,NULL);
245 if(dir->dd_len <= 0) { dir->dd_len = 0; return NULL; }
247 dp = (struct dirent*) (dir->dd_buf + dir->dd_loc);
248 if(dp->d_reclen == 0 || dp->d_reclen > dir->dd_len - dir->dd_loc) return NULL;
249 dir->dd_loc += dp->d_reclen;
253 int closedir(DIR *dir) {
261 * Networking/Socket stuff
264 /* This should really be part of the newlib _reent structure */
267 char *inet_ntoa(struct in_addr in) {
269 const unsigned char *p = (void*) ∈
270 snprintf(buf,sizeof(buf),"%u.%u.%u.%u",p[0],p[1],p[2],p[3]);
274 struct servent *getservbyname(const char *name,const char *proto) {
278 static const char *h_errlist[] = { "No Error","Unknown host", "Host name lookup failure","Unknown server error","No address associated with name" };
280 const char *hstrerror(int err) {
281 if(err < 0 || err > 4) return "Unknown Error";
282 return h_errlist[err];
285 void herror(const char *string) {
286 fprintf(stderr,"%s: %s\n",string,hstrerror(h_errno));
289 extern int _resolve_hostname(const char *, char *buf, size_t *size);
291 struct hostent *gethostbyname(const char *hostname) {
292 #define MAX_ADDRS 256
293 static struct hostent hostent;
294 static char saved_hostname[128];
295 static char *addr_list[MAX_ADDRS+1];
296 static char addr_list_buf[MAX_ADDRS*sizeof(struct in_addr)];
297 static char *aliases[1];
299 unsigned char buf[MAX_ADDRS*sizeof(struct in_addr)];
300 size_t size = sizeof(buf);
303 err = _resolve_hostname(hostname,buf,&size);
304 if(err != 0) { h_errno = err; return NULL; }
306 memcpy(addr_list_buf,buf,size);
307 for(i=0;i<size;i += sizeof(struct in_addr)) addr_list[n++] = &addr_list_buf[i];
309 strncpy(saved_hostname,hostname,sizeof(saved_hostname));
312 hostent.h_name = saved_hostname;
313 hostent.h_aliases = aliases;
314 hostent.h_addrtype = AF_INET;
315 hostent.h_length = sizeof(struct in_addr);
316 hostent.h_addr_list = addr_list;
322 * Other People's Code
325 /* FreeBSD's dirname/basename */
327 /* FIXME: Put these in a header */
330 * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
331 * All rights reserved.
333 * Redistribution and use in source and binary forms, with or without
334 * modification, are permitted provided that the following conditions
336 * 1. Redistributions of source code must retain the above copyright
337 * notice, this list of conditions and the following disclaimer.
338 * 2. Redistributions in binary form must reproduce the above copyright
339 * notice, this list of conditions and the following disclaimer in the
340 * documentation and/or other materials provided with the distribution.
341 * 3. The name of the author may not be used to endorse or promote products
342 * derived from this software without specific prior written permission.
344 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
345 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
346 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
347 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
348 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
349 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
350 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
351 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
352 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
353 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
360 static char bname[MAXPATHLEN];
361 register const char *endp;
363 /* Empty or NULL string gets treated as "." */
364 if (path == NULL || *path == '\0') {
365 (void)strcpy(bname, ".");
369 /* Strip trailing slashes */
370 endp = path + strlen(path) - 1;
371 while (endp > path && *endp == '/')
374 /* Find the start of the dir */
375 while (endp > path && *endp != '/')
378 /* Either the dir is "/" or there are no slashes */
380 (void)strcpy(bname, *endp == '/' ? "/" : ".");
385 } while (endp > path && *endp == '/');
388 if (endp - path + 2 > sizeof(bname)) {
389 errno = ENAMETOOLONG;
392 (void)strncpy(bname, path, endp - path + 1);
393 bname[endp - path + 1] = '\0';
401 static char bname[MAXPATHLEN];
402 register const char *endp, *startp;
404 /* Empty or NULL string gets treated as "." */
405 if (path == NULL || *path == '\0') {
406 (void)strcpy(bname, ".");
410 /* Strip trailing slashes */
411 endp = path + strlen(path) - 1;
412 while (endp > path && *endp == '/')
415 /* All slashes becomes "/" */
416 if (endp == path && *endp == '/') {
417 (void)strcpy(bname, "/");
421 /* Find the start of the base */
423 while (startp > path && *(startp - 1) != '/')
426 if (endp - startp + 2 > sizeof(bname)) {
427 errno = ENAMETOOLONG;
430 (void)strncpy(bname, startp, endp - startp + 1);
431 bname[endp - startp + 1] = '\0';
435 /* FreeBSD's uname */
438 struct utsname *name;
448 mib[1] = KERN_OSTYPE;
449 len = sizeof(name->sysname);
451 if (sysctl(mib, 2, &name->sysname, &len, NULL, 0) == -1) {
457 name->sysname[sizeof(name->sysname) - 1] = '\0';
460 mib[1] = KERN_HOSTNAME;
461 len = sizeof(name->nodename);
463 if (sysctl(mib, 2, &name->nodename, &len, NULL, 0) == -1) {
469 name->nodename[sizeof(name->nodename) - 1] = '\0';
472 mib[1] = KERN_OSRELEASE;
473 len = sizeof(name->release);
475 if (sysctl(mib, 2, &name->release, &len, NULL, 0) == -1) {
481 name->release[sizeof(name->release) - 1] = '\0';
483 /* The version may have newlines in it, turn them into spaces. */
485 mib[1] = KERN_VERSION;
486 len = sizeof(name->version);
488 if (sysctl(mib, 2, &name->version, &len, NULL, 0) == -1) {
494 name->version[sizeof(name->version) - 1] = '\0';
495 for (p = name->version; len--; ++p) {
496 if (*p == '\n' || *p == '\t') {
506 len = sizeof(name->machine);
508 if (sysctl(mib, 2, &name->machine, &len, NULL, 0) == -1) {
514 name->machine[sizeof(name->machine) - 1] = '\0';
518 /* FreeBSD's daemon() - modified for nestedvm */
520 daemon(nochdir, noclose)
521 int nochdir, noclose;
540 if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
541 (void)dup2(fd, STDIN_FILENO);
542 (void)dup2(fd, STDOUT_FILENO);
543 (void)dup2(fd, STDERR_FILENO);