Set errno when only errstr was called
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 13 Sep 2013 01:51:18 +0000 (18:51 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 16 Jan 2014 01:55:42 +0000 (17:55 -0800)
Some error paths set errstr, but not errno.  Glibc will ignore errstr if there
isn't an errno too, so we need something.

Ultimately, we should be setting both errno and errstr (given a glibc-world
with errno).  Til then, we'll set a generic errno.

This won't harm the current glibc, which 0's sysc.errstr before calling, but
that isn't actually part of the ABI.  So with this hack, it is possible to set
errno when there wasn't actually an error.  Luckily, userspace shouldn't look
at errno unless it was told too (via a bad retval), in which case, we probably
wanted errno set anyway.  Still, be careful.

kern/src/syscall.c

index b82cffd..e506d76 100644 (file)
@@ -1781,6 +1781,10 @@ void run_local_syscall(struct syscall *sysc)
                               sysc->arg2, sysc->arg3, sysc->arg4, sysc->arg5);
        /* Need to re-load pcpui, in case we migrated */
        pcpui = &per_cpu_info[core_id()];
+       /* Some 9ns paths set errstr, but not errno.  glibc will ignore errstr.
+        * this is somewhat hacky, since errno might get set unnecessarily */
+       if ((current_errstr()[0] != 0) && (!sysc->err))
+               sysc->err = EUNSPECIFIED;
        finish_sysc(sysc, pcpui->cur_proc);
        /* Can unpin (UMEM) at this point */
        pcpui->cur_sysc = 0;    /* no longer working on sysc */