diff mbox

[v2,02/28] linux-user: Consistently return host errnos from do_openat()

Message ID 1463075272-9933-3-git-send-email-peter.maydell@linaro.org (mailing list archive)
State New, archived
Headers show

Commit Message

Peter Maydell May 12, 2016, 5:47 p.m. UTC
The function do_openat() is not consistent about whether it is
returning a host errno or a guest errno in case of failure.
Standardise on returning -1 with errno set (ie caller has
to call get_errno()).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reported-by: Timothy Edward Baldwin <T.E.Baldwin99@members.leeds.ac.uk>
---
Timothy's patchset for fixing signal races had a patch which also
addressed this bug.  However I preferred to take the opposite tack
and have the callers do get_errno() rather than the callee, because
it means changes in fewer places and it's generally more natural
for the 'fill' functions that do_openat() calls.
---
 linux-user/syscall.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

Comments

Laurent Vivier May 24, 2016, 12:05 a.m. UTC | #1
Le 12/05/2016 à 19:47, Peter Maydell a écrit :
> The function do_openat() is not consistent about whether it is
> returning a host errno or a guest errno in case of failure.
> Standardise on returning -1 with errno set (ie caller has
> to call get_errno()).
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Reported-by: Timothy Edward Baldwin <T.E.Baldwin99@members.leeds.ac.uk>

Reviewed-by: Laurent Vivier <laurent@vivier.eu>

> ---
> Timothy's patchset for fixing signal races had a patch which also
> addressed this bug.  However I preferred to take the opposite tack
> and have the callers do get_errno() rather than the callee, because
> it means changes in fewer places and it's generally more natural
> for the 'fill' functions that do_openat() calls.
> ---
>  linux-user/syscall.c | 14 ++++++++++----
>  1 file changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 5246f36..f4c2e19 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -5559,7 +5559,9 @@ static int open_self_cmdline(void *cpu_env, int fd)
>  
>          nb_read = read(fd_orig, buf, sizeof(buf));
>          if (nb_read < 0) {
> +            int e = errno;
>              fd_orig = close(fd_orig);
> +            errno = e;
>              return -1;
>          } else if (nb_read == 0) {
>              break;
> @@ -5579,7 +5581,9 @@ static int open_self_cmdline(void *cpu_env, int fd)
>  
>          if (word_skipped) {
>              if (write(fd, cp_buf, nb_read) != nb_read) {
> +                int e = errno;
>                  close(fd_orig);
> +                errno = e;
>                  return -1;
>              }
>          }
> @@ -5599,7 +5603,7 @@ static int open_self_maps(void *cpu_env, int fd)
>  
>      fp = fopen("/proc/self/maps", "r");
>      if (fp == NULL) {
> -        return -EACCES;
> +        return -1;
>      }
>  
>      while ((read = getline(&line, &len, fp)) != -1) {
> @@ -5743,7 +5747,7 @@ static int open_net_route(void *cpu_env, int fd)
>  
>      fp = fopen("/proc/net/route", "r");
>      if (fp == NULL) {
> -        return -EACCES;
> +        return -1;
>      }
>  
>      /* read header */
> @@ -5793,7 +5797,7 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags,
>  
>      if (is_proc_myself(pathname, "exe")) {
>          int execfd = qemu_getauxval(AT_EXECFD);
> -        return execfd ? execfd : get_errno(sys_openat(dirfd, exec_path, flags, mode));
> +        return execfd ? execfd : sys_openat(dirfd, exec_path, flags, mode);
>      }
>  
>      for (fake_open = fakes; fake_open->filename; fake_open++) {
> @@ -5819,7 +5823,9 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags,
>          unlink(filename);
>  
>          if ((r = fake_open->fill(cpu_env, fd))) {
> +            int e = errno;
>              close(fd);
> +            errno = e;
>              return r;
>          }
>          lseek(fd, 0, SEEK_SET);
> @@ -5827,7 +5833,7 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags,
>          return fd;
>      }
>  
> -    return get_errno(sys_openat(dirfd, path(pathname), flags, mode));
> +    return sys_openat(dirfd, path(pathname), flags, mode);
>  }
>  
>  #define TIMER_MAGIC 0x0caf0000
>
diff mbox

Patch

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5246f36..f4c2e19 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5559,7 +5559,9 @@  static int open_self_cmdline(void *cpu_env, int fd)
 
         nb_read = read(fd_orig, buf, sizeof(buf));
         if (nb_read < 0) {
+            int e = errno;
             fd_orig = close(fd_orig);
+            errno = e;
             return -1;
         } else if (nb_read == 0) {
             break;
@@ -5579,7 +5581,9 @@  static int open_self_cmdline(void *cpu_env, int fd)
 
         if (word_skipped) {
             if (write(fd, cp_buf, nb_read) != nb_read) {
+                int e = errno;
                 close(fd_orig);
+                errno = e;
                 return -1;
             }
         }
@@ -5599,7 +5603,7 @@  static int open_self_maps(void *cpu_env, int fd)
 
     fp = fopen("/proc/self/maps", "r");
     if (fp == NULL) {
-        return -EACCES;
+        return -1;
     }
 
     while ((read = getline(&line, &len, fp)) != -1) {
@@ -5743,7 +5747,7 @@  static int open_net_route(void *cpu_env, int fd)
 
     fp = fopen("/proc/net/route", "r");
     if (fp == NULL) {
-        return -EACCES;
+        return -1;
     }
 
     /* read header */
@@ -5793,7 +5797,7 @@  static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags,
 
     if (is_proc_myself(pathname, "exe")) {
         int execfd = qemu_getauxval(AT_EXECFD);
-        return execfd ? execfd : get_errno(sys_openat(dirfd, exec_path, flags, mode));
+        return execfd ? execfd : sys_openat(dirfd, exec_path, flags, mode);
     }
 
     for (fake_open = fakes; fake_open->filename; fake_open++) {
@@ -5819,7 +5823,9 @@  static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags,
         unlink(filename);
 
         if ((r = fake_open->fill(cpu_env, fd))) {
+            int e = errno;
             close(fd);
+            errno = e;
             return r;
         }
         lseek(fd, 0, SEEK_SET);
@@ -5827,7 +5833,7 @@  static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags,
         return fd;
     }
 
-    return get_errno(sys_openat(dirfd, path(pathname), flags, mode));
+    return sys_openat(dirfd, path(pathname), flags, mode);
 }
 
 #define TIMER_MAGIC 0x0caf0000