diff options
-rw-r--r-- | sim/common/syscall.c | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/sim/common/syscall.c b/sim/common/syscall.c index 9d08730..e3378a1 100644 --- a/sim/common/syscall.c +++ b/sim/common/syscall.c @@ -99,7 +99,8 @@ cb_get_string (host_callback *cb, CB_SYSCALL *sc, char *buf, int buflen, If an error occurs, no buffer is left malloc'd. */ static int -get_path (host_callback *cb, CB_SYSCALL *sc, TADDR addr, char **bufp) +get_path (host_callback *cb, CB_SYSCALL *sc, TADDR addr, char **bufp, + int use_sysroot) { char *buf = xmalloc (MAX_PATH_LEN); int result; @@ -111,7 +112,7 @@ get_path (host_callback *cb, CB_SYSCALL *sc, TADDR addr, char **bufp) /* Prepend absolute paths with simulator_sysroot. Relative paths are supposed to be relative to a chdir within that path, but at this point unknown where. */ - if (simulator_sysroot[0] != '\0' && *buf == '/') + if (use_sysroot && simulator_sysroot[0] != '\0' && *buf == '/') { /* Considering expected rareness of syscalls with absolute file paths (compared to relative file paths and insn @@ -286,7 +287,22 @@ cb_syscall (host_callback *cb, CB_SYSCALL *sc) { char *path; - errcode = get_path (cb, sc, sc->arg1, &path); + /* Try sysroot only if opening read-only. */ + if (!(sc->arg2 & 3)) + { + errcode = get_path (cb, sc, sc->arg1, &path, 1); + if (errcode != 0) + { + result = -1; + goto FinishSyscall; + } + result = (*cb->open) (cb, path, sc->arg2 /*, sc->arg3*/); + free (path); + if (result >= 0) + break; + } + + errcode = get_path (cb, sc, sc->arg1, &path, 0); if (errcode != 0) { result = -1; @@ -296,6 +312,12 @@ cb_syscall (host_callback *cb, CB_SYSCALL *sc) free (path); if (result < 0) goto ErrorFinish; + + { + struct timespec t[2]; + memset(&t, 0, sizeof(t)); + futimens(cb->fdmap[result], t); + } } break; @@ -411,7 +433,7 @@ cb_syscall (host_callback *cb, CB_SYSCALL *sc) { char *path; - errcode = get_path (cb, sc, sc->arg1, &path); + errcode = get_path (cb, sc, sc->arg1, &path, 0); if (errcode != 0) { result = -1; @@ -429,7 +451,7 @@ cb_syscall (host_callback *cb, CB_SYSCALL *sc) char *path; long len = sc->arg2; - errcode = get_path (cb, sc, sc->arg1, &path); + errcode = get_path (cb, sc, sc->arg1, &path, 0); if (errcode != 0) { result = -1; @@ -458,14 +480,14 @@ cb_syscall (host_callback *cb, CB_SYSCALL *sc) { char *path1, *path2; - errcode = get_path (cb, sc, sc->arg1, &path1); + errcode = get_path (cb, sc, sc->arg1, &path1, 0); if (errcode != 0) { result = -1; errcode = EFAULT; goto FinishSyscall; } - errcode = get_path (cb, sc, sc->arg2, &path2); + errcode = get_path (cb, sc, sc->arg2, &path2, 0); if (errcode != 0) { result = -1; @@ -488,7 +510,7 @@ cb_syscall (host_callback *cb, CB_SYSCALL *sc) struct stat statbuf; TADDR addr = sc->arg2; - errcode = get_path (cb, sc, sc->arg1, &path); + errcode = get_path (cb, sc, sc->arg1, &path, 1); if (errcode != 0) { result = -1; @@ -559,7 +581,7 @@ cb_syscall (host_callback *cb, CB_SYSCALL *sc) struct stat statbuf; TADDR addr = sc->arg2; - errcode = get_path (cb, sc, sc->arg1, &path); + errcode = get_path (cb, sc, sc->arg1, &path, 1); if (errcode != 0) { result = -1; |