root/maint/gnulib/tests/test-flock.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. test_shared
  2. test_exclusive
  3. main

   1 /* Test of flock() function.
   2    Copyright (C) 2008-2021 Free Software Foundation, Inc.
   3 
   4    This program is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU General Public License as published by
   6    the Free Software Foundation; either version 3 of the License, or
   7    (at your option) any later version.
   8 
   9    This program is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU General Public License for more details.
  13 
  14    You should have received a copy of the GNU General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 #include <config.h>
  18 
  19 #include <sys/file.h>
  20 
  21 #include "signature.h"
  22 SIGNATURE_CHECK (flock, int, (int, int));
  23 
  24 #include <fcntl.h>
  25 #include <unistd.h>
  26 #include <errno.h>
  27 
  28 #include "macros.h"
  29 
  30 static void
  31 test_shared (const char *file, int fd)
     /* [previous][next][first][last][top][bottom][index][help] */
  32 {
  33   /* Should be able to acquire several shared locks on a file, through
  34    * different file table entries.
  35    */
  36   int fd2, r;
  37 
  38   ASSERT (flock (fd, LOCK_SH) == 0);
  39 
  40   fd2 = open (file, O_RDWR, 0644);
  41   ASSERT (fd2 >= 0);
  42 
  43   r = flock (fd2, LOCK_SH | LOCK_NB);
  44   ASSERT (r == 0);              /* Was able to acquire a second shared lock. */
  45 
  46   ASSERT (flock (fd, LOCK_UN) == 0);
  47   ASSERT (close (fd2) == 0);
  48 }
  49 
  50 static void
  51 test_exclusive (const char *file, int fd)
     /* [previous][next][first][last][top][bottom][index][help] */
  52 {
  53   /* Should not be able to acquire more than one exclusive lock on a file. */
  54   int fd2, r;
  55 
  56   ASSERT (flock (fd, LOCK_EX) == 0);
  57 
  58   fd2 = open (file, O_RDWR, 0644);
  59   ASSERT (fd2 >= 0);
  60 
  61   r = flock (fd2, LOCK_EX | LOCK_NB);
  62   ASSERT (r == -1);             /* Was unable to acquire a second exclusive lock. */
  63 
  64 #if 0
  65   /* The Linux manual page of flock(2) says:
  66        "A process may only hold one type of lock (shared or exclusive) on a
  67        file. Subsequent flock() calls on an already locked file will convert
  68        an existing lock to the new lock mode."
  69      So, the call below should convert the exclusive lock for fd to a shared
  70      and thus succeeds.  The fact that it doesn't but instead fails is
  71      apparently a bug.  */
  72   /* The Solaris manual page of flock(2) says:
  73        "More than one process may hold a shared lock for a file at any given
  74         time, but multiple exclusive, or both shared and exclusive, locks may
  75         not exist simultaneously on a file. ...
  76         Requesting a lock on an object that is already locked normally causes
  77         the caller to block until the lock may be acquired. If LOCK_NB is
  78         included in operation, then this will not happen; instead, the call
  79         will fail and the error EWOULDBLOCK will be returned."
  80      So, the call below should fail and set errno to EWOULDBLOCK.  The fact
  81      that it succeeds is apparently a bug.  */
  82   r = flock (fd2, LOCK_SH | LOCK_NB);
  83   ASSERT (r == -1);
  84 #endif
  85 
  86   ASSERT (flock (fd, LOCK_UN) == 0);
  87   ASSERT (close (fd2) == 0);
  88 }
  89 
  90 int
  91 main (int argc, char *argv[])
     /* [previous][next][first][last][top][bottom][index][help] */
  92 {
  93   int fd;
  94   const char *file = "test-flock.txt";
  95 
  96   /* Open a non-empty file for testing. */
  97   fd = open (file, O_RDWR | O_CREAT | O_TRUNC, 0644);
  98   ASSERT (fd >= 0);
  99   ASSERT (write (fd, "hello", 5) == 5);
 100 
 101 #if defined __linux__ || defined __ANDROID__
 102   /* Invalid operation codes are rejected by the Linux implementation and by
 103      the gnulib replacement,  but not by the Mac OS X implementation.  */
 104   ASSERT (flock (fd, LOCK_SH | LOCK_EX) == -1);
 105   ASSERT (errno == EINVAL);
 106   ASSERT (flock (fd, LOCK_SH | LOCK_UN) == -1);
 107   ASSERT (errno == EINVAL);
 108   ASSERT (flock (fd, LOCK_EX | LOCK_UN) == -1);
 109   ASSERT (errno == EINVAL);
 110   ASSERT (flock (fd, 0) == -1);
 111   ASSERT (errno == EINVAL);
 112 #endif
 113 
 114   test_shared (file, fd);
 115   test_exclusive (file, fd);
 116 
 117   /* Close and remove the test file. */
 118   ASSERT (close (fd) == 0);
 119   ASSERT (unlink (file) == 0);
 120 
 121   return 0;
 122 }

/* [previous][next][first][last][top][bottom][index][help] */