s3: VFS: shadow_copy2: Fix usage of saved_errno to only set errno on error.
commiteeef5e408ba03815cf175539f5c83c34cb05aa24
authorJeremy Allison <jra@samba.org>
Mon, 23 Jan 2017 18:20:13 +0000 (23 10:20 -0800)
committerKarolin Seeger <kseeger@samba.org>
Wed, 15 Feb 2017 10:42:23 +0000 (15 11:42 +0100)
tree4eeee8c2b3d553f2f5cc2587ec4303aac11f9870
parent79c2349c2d57068a34356918a8db285515a23812
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>
(backported from commit cda6764f1a8db96182bfd1855440bc6a1ba1abee)
source3/modules/vfs_shadow_copy2.c