aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sim/common/syscall.c40
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;