Blame gnulib-tests/test-open.h

Packit 709fb3
/* Test of opening a file descriptor.
Packit 709fb3
   Copyright (C) 2007-2017 Free Software Foundation, Inc.
Packit 709fb3
Packit 709fb3
   This program is free software: you can redistribute it and/or modify
Packit 709fb3
   it under the terms of the GNU General Public License as published by
Packit 709fb3
   the Free Software Foundation; either version 3 of the License, or
Packit 709fb3
   (at your option) any later version.
Packit 709fb3
Packit 709fb3
   This program is distributed in the hope that it will be useful,
Packit 709fb3
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 709fb3
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 709fb3
   GNU General Public License for more details.
Packit 709fb3
Packit 709fb3
   You should have received a copy of the GNU General Public License
Packit 709fb3
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit 709fb3
Packit 709fb3
/* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
Packit 709fb3
Packit 709fb3
/* Make test_open always inline if we're using Fortify, which defines
Packit 709fb3
   __always_inline to do that.  Do nothing otherwise.  This works
Packit 709fb3
   around a glibc bug whereby 'open' cannot be used as a function
Packit 709fb3
   pointer when _FORTIFY_SOURCE is positive.  */
Packit 709fb3
Packit 709fb3
#if __GLIBC__ && defined __always_inline
Packit 709fb3
# define ALWAYS_INLINE __always_inline
Packit 709fb3
#else
Packit 709fb3
# define ALWAYS_INLINE
Packit 709fb3
#endif
Packit 709fb3
Packit 709fb3
/* This file is designed to test both open(n,buf[,mode]) and
Packit 709fb3
   openat(AT_FDCWD,n,buf[,mode]).  FUNC is the function to test.
Packit 709fb3
   Assumes that BASE and ASSERT are already defined, and that
Packit 709fb3
   appropriate headers are already included.  If PRINT, warn before
Packit 709fb3
   skipping symlink tests with status 77.  */
Packit 709fb3
Packit 709fb3
static ALWAYS_INLINE int
Packit 709fb3
test_open (int (*func) (char const *, int, ...), bool print)
Packit 709fb3
{
Packit 709fb3
  int fd;
Packit 709fb3
  /* Remove anything from prior partial run.  */
Packit 709fb3
  unlink (BASE "file");
Packit 709fb3
Packit 709fb3
  /* Cannot create directory.  */
Packit 709fb3
  errno = 0;
Packit 709fb3
  ASSERT (func ("nonexist.ent/", O_CREAT | O_RDONLY, 0600) == -1);
Packit 709fb3
  ASSERT (errno == ENOTDIR || errno == EISDIR || errno == ENOENT
Packit 709fb3
          || errno == EINVAL);
Packit 709fb3
Packit 709fb3
  /* Create a regular file.  */
Packit 709fb3
  fd = func (BASE "file", O_CREAT | O_RDONLY, 0600);
Packit 709fb3
  ASSERT (0 <= fd);
Packit 709fb3
  ASSERT (close (fd) == 0);
Packit 709fb3
Packit 709fb3
  /* Trailing slash handling.  */
Packit 709fb3
  errno = 0;
Packit 709fb3
  ASSERT (func (BASE "file/", O_RDONLY) == -1);
Packit 709fb3
  ASSERT (errno == ENOTDIR || errno == EISDIR || errno == EINVAL);
Packit 709fb3
Packit 709fb3
  /* Directories cannot be opened for writing.  */
Packit 709fb3
  errno = 0;
Packit 709fb3
  ASSERT (func (".", O_WRONLY) == -1);
Packit 709fb3
  ASSERT (errno == EISDIR || errno == EACCES);
Packit 709fb3
Packit 709fb3
  /* /dev/null must exist, and be writable.  */
Packit 709fb3
  fd = func ("/dev/null", O_RDONLY);
Packit 709fb3
  ASSERT (0 <= fd);
Packit 709fb3
  {
Packit 709fb3
    char c;
Packit 709fb3
    ASSERT (read (fd, &c, 1) == 0);
Packit 709fb3
  }
Packit 709fb3
  ASSERT (close (fd) == 0);
Packit 709fb3
  fd = func ("/dev/null", O_WRONLY);
Packit 709fb3
  ASSERT (0 <= fd);
Packit 709fb3
  ASSERT (write (fd, "c", 1) == 1);
Packit 709fb3
  ASSERT (close (fd) == 0);
Packit 709fb3
Packit 709fb3
  /* Although O_NONBLOCK on regular files can be ignored, it must not
Packit 709fb3
     cause a failure.  */
Packit 709fb3
  fd = func (BASE "file", O_NONBLOCK | O_RDONLY);
Packit 709fb3
  ASSERT (0 <= fd);
Packit 709fb3
  ASSERT (close (fd) == 0);
Packit 709fb3
Packit 709fb3
  /* Symlink handling, where supported.  */
Packit 709fb3
  if (symlink (BASE "file", BASE "link") != 0)
Packit 709fb3
    {
Packit 709fb3
      ASSERT (unlink (BASE "file") == 0);
Packit 709fb3
      if (print)
Packit 709fb3
        fputs ("skipping test: symlinks not supported on this file system\n",
Packit 709fb3
               stderr);
Packit 709fb3
      return 77;
Packit 709fb3
    }
Packit 709fb3
  errno = 0;
Packit 709fb3
  ASSERT (func (BASE "link/", O_RDONLY) == -1);
Packit 709fb3
  ASSERT (errno == ENOTDIR);
Packit 709fb3
  fd = func (BASE "link", O_RDONLY);
Packit 709fb3
  ASSERT (0 <= fd);
Packit 709fb3
  ASSERT (close (fd) == 0);
Packit 709fb3
Packit 709fb3
  /* Cleanup.  */
Packit 709fb3
  ASSERT (unlink (BASE "file") == 0);
Packit 709fb3
  ASSERT (unlink (BASE "link") == 0);
Packit 709fb3
Packit 709fb3
  return 0;
Packit 709fb3
}