diff --git a/arch/amd64/include/u.h b/arch/amd64/include/u.h index eb2bb53..58e3317 100644 --- a/arch/amd64/include/u.h +++ b/arch/amd64/include/u.h @@ -25,7 +25,7 @@ typedef long ssize_t; typedef int32_t pid_t; typedef uint32_t Rune; typedef union FPdbleword FPdbleword; -typedef uintptr jmp_buf[10]; // for registers. +typedef uintptr_t jmp_buf[10]; // for registers. typedef long off_t; typedef long ptrdiff_t; diff --git a/hacking b/hacking index 9aabccd..39de8b3 160000 --- a/hacking +++ b/hacking @@ -1 +1 @@ -Subproject commit 9aabccdc3c8e1d0e69cfdda10e034843e51ad41e +Subproject commit 39de8b385117b2cf192356eeca7e9fda14e92c5a diff --git a/qa/lib/newlib/031-setjmp.c b/qa/lib/newlib/031-setjmp.c new file mode 100644 index 0000000..474b6c7 --- /dev/null +++ b/qa/lib/newlib/031-setjmp.c @@ -0,0 +1,35 @@ +#include +#include +#include + +/* declare variable of type jmp_buf */ +jmp_buf resume_here; + +void hello(void); + +int main(void) +{ + int ret_val; + printf("sizeof(jmp_buf) = %lu\n", sizeof(jmp_buf)); + + /* Initialize 'resume_here' by calling setjmp() */ + if (ret_val = setjmp(resume_here)) { + printf("After \'longjump()\', back in \'main()\'\n"); + printf("\'jump buffer variable \'resume_here\'\' becomes " + "INVALID!\n"); + return 0; + } else { + printf("\'setjmp()\' returns first time\n"); + hello(); + return 1; + } +} + +void hello(void) +{ + printf("Hey, I'm in \'hello()\'\n"); + longjmp(resume_here, 1); + + /* other code */ + printf("can't be reached here because I did longjmp!\n"); +} diff --git a/qa/lib/newlib/build.json b/qa/lib/newlib/build.json index ea341f4..67356f2 100644 --- a/qa/lib/newlib/build.json +++ b/qa/lib/newlib/build.json @@ -35,6 +35,7 @@ "010-fork.c", "020-waitpid.c", "030-pause.c", + "031-setjmp.c", "040-gettimeofday.c", "100-files.c", "101-files.c", diff --git a/sys/include/posix.h b/sys/include/posix.h index e9c61dc..2784185 100644 --- a/sys/include/posix.h +++ b/sys/include/posix.h @@ -82,11 +82,21 @@ struct __attribute__((__packed__)) dirent typedef unsigned long clock_t; +typedef enum PosixRUsages +{ + PosixRUsageSelf = 0, + PosixRUsageChildren = 1, + + PosixRUsageUnknown = -1 +} PosixRUsages; + #define __POSIX_EXIT_PREFIX "posix error " #define __POSIX_EXIT_SIGNAL_PREFIX "terminated by posix signal " #define __POSIX_SIGNAL_PREFIX "posix: " extern int POSIX_access(int *errnop, const char *path, int amode); +extern int POSIX_dup(int *errnop, int fildes); +extern int POSIX_dup2(int *errnop, int fildes, int fildes2); extern void POSIX_exit(int code) __attribute__((noreturn)); extern int POSIX_chmod(int *errnop, const char *path, int mode); extern int POSIX_fchmodat(int *errnop, int fd, const char *path, long mode, int flag); @@ -99,7 +109,7 @@ extern int POSIX_mkdir(int *errnop, const char *path, int mode); extern int POSIX_close(int *errnop, int file); extern int POSIX_execve(int *errnop, const char *name, char * const*argv, char * const*env); extern int POSIX_fork(int *errnop); -extern int POSIX_fstat(int *errnop, int file, void *stat); +extern int POSIX_getrusage(int *errnop, PosixRUsages who, void *r_usage); extern char* POSIX_getcwd(int *errnop, char *buf, int size); extern char* POSIX_getlogin(int *errnop); extern int POSIX_getlogin_r(int *errnop, char *name, int namesize); @@ -115,6 +125,8 @@ extern long POSIX_pread(int *errnop, int fd, char *buf, size_t len, long offset) extern long POSIX_pwrite(int *errnop, int fd, const char *buf, size_t len, long offset); extern long POSIX_read(int *errnop, int fd, char *buf, size_t len); extern int POSIX_stat(int *errnop, const char *file, void *stat); +extern int POSIX_fstat(int *errnop, int file, void *stat); +extern int POSIX_lstat(int *errnop, const char *file, void *stat); extern clock_t POSIX_times(int *errnop, void *tms); extern int POSIX_unlink(int *errnop, const char *name); extern int POSIX_wait(int *errnop, int *status); diff --git a/sys/src/lib/c/9sys/times.c b/sys/src/lib/c/9sys/times.c index a04308e..527f93c 100644 --- a/sys/src/lib/c/9sys/times.c +++ b/sys/src/lib/c/9sys/times.c @@ -35,7 +35,7 @@ jehanne_times(int32_t *t) char b[200], *p; static int f = -1; int i, retries; - uint32_t r; + uint32_t r = -1; jehanne_memset(b, 0, sizeof(b)); for(retries = 0; retries < 100; retries++){ diff --git a/sys/src/lib/posix/build.json b/sys/src/lib/posix/build.json index fe2da9d..ff4998e 100644 --- a/sys/src/lib/posix/build.json +++ b/sys/src/lib/posix/build.json @@ -14,6 +14,7 @@ "errors.c", "files.c", "initlib.c", + "links.c", "memory.c", "others.c", "processes.c", diff --git a/sys/src/lib/posix/files.c b/sys/src/lib/posix/files.c index 97ff98f..e01f9db 100644 --- a/sys/src/lib/posix/files.c +++ b/sys/src/lib/posix/files.c @@ -153,6 +153,38 @@ AccessDone: return -1; } +int +POSIX_dup2(int *errnop, int fildes, int fildes2) +{ + int newfd; + if(fildes < 0 || fildes2 < 0){ + *errnop = __libposix_get_errno(PosixEBADF); + return -1; + } + newfd = dup(fildes, fildes2); + if(newfd < 0){ + *errnop = __libposix_get_errno(PosixEINTR); + return -1; + } + return newfd; +} + +int +POSIX_dup(int *errnop, int fildes) +{ + int newfd; + if(fildes < 0){ + *errnop = __libposix_get_errno(PosixEBADF); + return -1; + } + newfd = dup(fildes, -1); + if(newfd < 0){ + *errnop = __libposix_get_errno(PosixEBADF); + return -1; + } + return newfd; +} + int POSIX_pipe(int *errnop, int fildes[2]) { @@ -325,31 +357,6 @@ POSIX_close(int *errno, int file) return -1; } -int -POSIX_link(int *errnop, const char *old, const char *new) -{ - int err; - /* let choose the most appropriate error */ - if(old == nil || new == nil || old[0] == 0 || new[0] == 0) - err = __libposix_get_errno(PosixENOENT); - else if(access(new, AEXIST) == 0) - err = __libposix_get_errno(PosixEEXIST); - else if(access(old, AEXIST) == 0) - err = __libposix_get_errno(PosixENOENT); - else { - /* Jehanne does not support links. - * A custom overlay filesystem might support them in - * the future but so far it does not exists yet. - * - * We return EXDEV so that a posix compliant caller - * can fallback to a simple copy. - */ - err = __libposix_get_errno(PosixEXDEV); - } - *errnop = err; - return -1; -} - int POSIX_unlink(int *errnop, const char *name) { @@ -543,13 +550,6 @@ POSIX_fchownat(int *errnop, int fd, const char *path, int owner, int group, int return 0; } -int -POSIX_lchown(int *errnop, const char *path, int owner, int group) -{ - /* TODO: implement when actually needed */ - return 0; -} - int POSIX_chdir(int *errnop, const char *path) { diff --git a/sys/src/lib/posix/links.c b/sys/src/lib/posix/links.c new file mode 100644 index 0000000..ad37819 --- /dev/null +++ b/sys/src/lib/posix/links.c @@ -0,0 +1,74 @@ +/* + * This file is part of Jehanne. + * + * Copyright (C) 2017 Giacomo Tesio + * + * This is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, version 3 of the License. + * + * Jehanne is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Jehanne. If not, see . + */ +#include +#include +#include <9P2000.h> +#include +#include "internal.h" + +int +POSIX_lchown(int *errnop, const char *path, int owner, int group) +{ + /* TODO: implement when actually needed */ + return 0; +} + +int +POSIX_link(int *errnop, const char *old, const char *new) +{ + int err; + /* let choose the most appropriate error */ + if(old == nil || new == nil || old[0] == 0 || new[0] == 0) + err = __libposix_get_errno(PosixENOENT); + else if(access(new, AEXIST) == 0) + err = __libposix_get_errno(PosixEEXIST); + else if(access(old, AEXIST) == 0) + err = __libposix_get_errno(PosixENOENT); + else { + /* Jehanne does not support links. + * A custom overlay filesystem might support them in + * the future but so far it does not exists yet. + * + * We return EXDEV so that a posix compliant caller + * can fallback to a simple copy. + */ + err = __libposix_get_errno(PosixEXDEV); + } + *errnop = err; + return -1; +} + +int +POSIX_lstat(int *errnop, const char *file, void *pstat) +{ + return POSIX_stat(errnop, file, pstat); +} + +int +POSIX_readlink(int *errnop, const char *path, char *buf, int bufsize) +{ + *errnop = __libposix_get_errno(PosixEINVAL); + return -1; +} + +int +POSIX_readlinkat(int *errnop, int fd, const char *path, char *buf, int bufsize) +{ + *errnop = __libposix_get_errno(PosixEINVAL); + return -1; +} diff --git a/sys/src/lib/posix/processes.c b/sys/src/lib/posix/processes.c index 31d0efa..e9be8f2 100644 --- a/sys/src/lib/posix/processes.c +++ b/sys/src/lib/posix/processes.c @@ -28,6 +28,17 @@ ChildList **__libposix_child_list; static PosixExitStatusTranslator __libposix_exit_status_translator; static int __libposix_wnohang; +struct timeval { + unsigned int tv_sec; + unsigned int tv_usec; +}; + +struct rusage { + struct timeval ru_utime; /* user time used */ + struct timeval ru_stime; /* system time used */ + struct timeval ru_etime; /* real elapsed time */ +}; + #define __POSIX_SIGNAL_PREFIX_LEN (sizeof(__POSIX_SIGNAL_PREFIX)-1) static int @@ -138,6 +149,32 @@ POSIX_exit(int code) exits(buf); } +int +POSIX_getrusage(int *errnop, PosixRUsages who, void *r_usagep) +{ + int32_t t[4]; + struct rusage *r_usage = r_usagep; + + times(&t[0]); + switch(who){ + case PosixRUsageSelf: + r_usage->ru_utime.tv_sec = t[0]/1000; + r_usage->ru_utime.tv_sec = (t[0]%1000)*1000; + r_usage->ru_stime.tv_sec = t[1]/1000; + r_usage->ru_stime.tv_sec = (t[1]%1000)*1000; + return 0; + case PosixRUsageChildren: + r_usage->ru_utime.tv_sec = t[2]/1000; + r_usage->ru_utime.tv_sec = (t[2]%1000)*1000; + r_usage->ru_stime.tv_sec = t[3]/1000; + r_usage->ru_stime.tv_sec = (t[3]%1000)*1000; + return 0; + default: + *errnop = __libposix_get_errno(PosixEINVAL); + return -1; + } +} + int POSIX_execve(int *errnop, const char *name, char * const*argv, char * const*env) {