From 7ae8e64d1ee79c23da96c326111fdc40015ed5a6 Mon Sep 17 00:00:00 2001 From: Mark Vitale Date: Mon, 9 Feb 2015 18:16:16 -0500 Subject: [PATCH 1/1] pioctl.c: restore required result variable Commit b9fb9c62a6779aa997259ddf2a83a90b08e04d5f refactored lpioctl() so that LINUX would have its own implementation. This also simplified the other lpioctl() implementations by removing superfluous variable 'rval'. Unfortunately, 'rval' was actually required for both DARWIN and SUN511. On both of these platforms, the address of 'errcode' is passed to the respective ioctl_*() routine so its value may be passed back to lpioctl(). Therefore, 'errcode' must not also be used for the return value from these functions; doing so results in the return value from the function overwriting the intended value of 'errcode' upon return to lpioctl(). In the case of Solaris 11, ioctl_sun_afs_syscall() always returns zero (as long as the ioctl device 'dev/afs' opened successfully). So 'errcode' was always being set to zero, even if the pioctl had actually failed. For example, without this fix, 'fs listcells' loops forever on Solaris 11, listing an infinite number of "cells", because it will never "see" the EDOM that informs it of the last defined cell. Partially revert b9fb9c62a6779aa997259ddf2a83a90b08e04d5f by restoring the 'rval' variable and logic for DARWIN and SUN511. Change-Id: I4407af29d54813689cf8ccf2517bb2df4dd8eb25 Reviewed-on: http://gerrit.openafs.org/11734 Tested-by: BuildBot Reviewed-by: Michael Meffie Reviewed-by: Chas Williams - CONTRACTOR Reviewed-by: Jeffrey Altman --- src/sys/pioctl.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/sys/pioctl.c b/src/sys/pioctl.c index 8bb6424..031def2 100644 --- a/src/sys/pioctl.c +++ b/src/sys/pioctl.c @@ -68,15 +68,23 @@ lpioctl(char *path, int cmd, void *cmarg, int follow) * exists (yet). */ void (*old)(int) = signal(SIGSYS, SIG_IGN); -#if defined(AFS_DARWIN80_ENV) - errcode = ioctl_afs_syscall(AFSCALL_PIOCTL, (long)path, cmd, (long)cmarg, +# if defined(AFS_DARWIN80_ENV) || defined(AFS_SUN511_ENV) + { + int rval; /* rval and errcode are distinct for pioctl platforms */ +# if defined(AFS_DARWIN80_ENV) + rval = ioctl_afs_syscall(AFSCALL_PIOCTL, (long)path, cmd, (long)cmarg, follow, 0, 0, &errcode); -#elif defined(AFS_SUN511_ENV) - errcode = ioctl_sun_afs_syscall(AFSCALL_PIOCTL, (uintptr_t)path, cmd, +# elif defined(AFS_SUN511_ENV) + rval = ioctl_sun_afs_syscall(AFSCALL_PIOCTL, (uintptr_t)path, cmd, (uintptr_t)cmarg, follow, 0, 0, &errcode); -#else +# endif /* !AFS_DARWIN80_ENV */ + /* non-zero rval takes precedence over errcode */ + if (rval) + errcode = rval; + } +# else /* ! AFS_DARWIN80_ENV || AFS_SUN511_ENV */ errcode = syscall(AFS_SYSCALL, AFSCALL_PIOCTL, path, cmd, cmarg, follow); -#endif +# endif signal(SIGSYS, old); -- 1.9.4