s3: VFS: shadow_copy2: Fix usage of saved_errno to only set errno on error.
authorJeremy Allison <jra@samba.org>
Mon, 23 Jan 2017 18:20:13 +0000 (10:20 -0800)
committerJeremy Allison <jra@samba.org>
Mon, 30 Jan 2017 17:39:19 +0000 (18:39 +0100)
commitcda6764f1a8db96182bfd1855440bc6a1ba1abee
tree9892d034db931f749ec791d5a5c5016f7a85cbde
parent4d339a88851f601fae195ac8ff0691cbd3504f41
s3: VFS: shadow_copy2: Fix usage of saved_errno to only set errno on error.

Rationale:

VFS calls must act like their POSIX equivalents, and the POSIX versions
*only* set errno on a failure. There is actually code in the upper smbd
layers that depends on errno being correct on a fail return from a VFS call.

For a compound VFS module like this, a common pattern is :

SMB_VFS_CALL_X()
{
      int ret;

      syscall1();
      ret = syscall2();
      syscall3();

      return ret;
}

Where if *any* of the contained syscallX()'s fail, they'll set errno.
However, the actual errno we should return is *only* the one returned
if syscall2() fails (the others are lstat's checking for existence etc.).

So what we should do to correctly return only the errno from syscall2() is:

SMB_VFS_CALL_X()
{
      int ret;
      int saved_errno = 0;

      syscall1()

      ret = syscall2();
      if (ret == -1) {
            saved_errno = errno;
      }
      syscall3()

      if (saved_errno != 0) {
           errno = saved_errno;
      }
      return ret;
}

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Uri Simchoni <uri@samba.org>
source3/modules/vfs_shadow_copy2.c