From: Marc Dionne Date: Thu, 1 Jul 2010 15:38:20 +0000 (-0400) Subject: Linux: normalize error return for emulated syscalls X-Git-Tag: openafs-devel-1_5_78~145 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=bfd269535f032dce04c0769ac2ca97ca3753fcf9;p=packages%2Fo%2Fopenafs.git Linux: normalize error return for emulated syscalls pagsh and other code expect setpag() and pioctl() to behave like a regular syscall or pioctl, that is to return -1 on error, with errno set to the specific error code. On Linux, the underlying emulation does a straight return of any error code it gets from the ioctl, and errors are not properly caught by the callers. As an example, pagsh won't detect an error from setpag such as exceeding a keyring quota limit. With this patch, the user will see this: $ pagsh setpag: Disk quota exceeded sh-4.1$ The code in proc_afs_syscall is modified to set errno to the error code and to set errorcode to -1 in case of error. proc_afs_sycall is reindented while we're changing code there. FIXES 126230 Change-Id: I945f2d28eb0ae26c7f42502c90eb2e6e95c29a58 Reviewed-on: http://gerrit.openafs.org/2770 Tested-by: BuildBot Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear (cherry picked from commit 0bc837f68a72ba1f75d940cc5dd057774d9f36bb) Reviewed-on: http://gerrit.openafs.org/2797 --- diff --git a/src/sys/glue.c b/src/sys/glue.c index c17e2a88b..8a2985b98 100644 --- a/src/sys/glue.c +++ b/src/sys/glue.c @@ -20,6 +20,7 @@ #include #include #include +#include #ifdef AFS_SUN5_ENV #include #endif @@ -28,24 +29,29 @@ #ifdef AFS_LINUX20_ENV int proc_afs_syscall(long syscall, long param1, long param2, long param3, long param4, int *rval) { - struct afsprocdata syscall_data; - int fd = open(PROC_SYSCALL_FNAME, O_RDWR); - if(fd < 0) - fd = open(PROC_SYSCALL_ARLA_FNAME, O_RDWR); - if(fd < 0) - return -1; + struct afsprocdata syscall_data; + int fd = open(PROC_SYSCALL_FNAME, O_RDWR); + if(fd < 0) + fd = open(PROC_SYSCALL_ARLA_FNAME, O_RDWR); + if(fd < 0) + return -1; - syscall_data.syscall = syscall; - syscall_data.param1 = param1; - syscall_data.param2 = param2; - syscall_data.param3 = param3; - syscall_data.param4 = param4; + syscall_data.syscall = syscall; + syscall_data.param1 = param1; + syscall_data.param2 = param2; + syscall_data.param3 = param3; + syscall_data.param4 = param4; - *rval = ioctl(fd, VIOC_SYSCALL, &syscall_data); + *rval = ioctl(fd, VIOC_SYSCALL, &syscall_data); - close(fd); + close(fd); - return 0; + /* Callers expect us to emulate a syscall - return -1 on error, set errno */ + if (*rval) { + errno = *rval; + *rval = -1; + } + return 0; } #endif