Blame m4/fcntl-o.m4

Packit Service a2489d
# fcntl-o.m4 serial 5
Packit Service a2489d
dnl Copyright (C) 2006, 2009-2018 Free Software Foundation, Inc.
Packit Service a2489d
dnl This file is free software; the Free Software Foundation
Packit Service a2489d
dnl gives unlimited permission to copy and/or distribute it,
Packit Service a2489d
dnl with or without modifications, as long as this notice is preserved.
Packit Service a2489d
Packit Service a2489d
dnl Written by Paul Eggert.
Packit Service a2489d
Packit Service a2489d
# Test whether the flags O_NOATIME and O_NOFOLLOW actually work.
Packit Service a2489d
# Define HAVE_WORKING_O_NOATIME to 1 if O_NOATIME works, or to 0 otherwise.
Packit Service a2489d
# Define HAVE_WORKING_O_NOFOLLOW to 1 if O_NOFOLLOW works, or to 0 otherwise.
Packit Service a2489d
AC_DEFUN([gl_FCNTL_O_FLAGS],
Packit Service a2489d
[
Packit Service a2489d
  dnl Persuade glibc <fcntl.h> to define O_NOATIME and O_NOFOLLOW.
Packit Service a2489d
  dnl AC_USE_SYSTEM_EXTENSIONS was introduced in autoconf 2.60 and obsoletes
Packit Service a2489d
  dnl AC_GNU_SOURCE.
Packit Service a2489d
  m4_ifdef([AC_USE_SYSTEM_EXTENSIONS],
Packit Service a2489d
    [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])],
Packit Service a2489d
    [AC_REQUIRE([AC_GNU_SOURCE])])
Packit Service a2489d
Packit Service a2489d
  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
Packit Service a2489d
  AC_CHECK_HEADERS_ONCE([unistd.h])
Packit Service a2489d
  AC_CHECK_FUNCS_ONCE([symlink])
Packit Service a2489d
  AC_CACHE_CHECK([for working fcntl.h], [gl_cv_header_working_fcntl_h],
Packit Service a2489d
    [AC_RUN_IFELSE(
Packit Service a2489d
       [AC_LANG_PROGRAM(
Packit Service a2489d
          [[#include <sys/types.h>
Packit Service a2489d
           #include <sys/stat.h>
Packit Service a2489d
           #if HAVE_UNISTD_H
Packit Service a2489d
           # include <unistd.h>
Packit Service a2489d
           #else /* on Windows with MSVC */
Packit Service a2489d
           # include <io.h>
Packit Service a2489d
           # include <stdlib.h>
Packit Service a2489d
           # defined sleep(n) _sleep ((n) * 1000)
Packit Service a2489d
           #endif
Packit Service a2489d
           #include <fcntl.h>
Packit Service a2489d
           #ifndef O_NOATIME
Packit Service a2489d
            #define O_NOATIME 0
Packit Service a2489d
           #endif
Packit Service a2489d
           #ifndef O_NOFOLLOW
Packit Service a2489d
            #define O_NOFOLLOW 0
Packit Service a2489d
           #endif
Packit Service a2489d
           static int const constants[] =
Packit Service a2489d
            {
Packit Service a2489d
              O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND,
Packit Service a2489d
              O_NONBLOCK, O_SYNC, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY
Packit Service a2489d
            };
Packit Service a2489d
          ]],
Packit Service a2489d
          [[
Packit Service a2489d
            int result = !constants;
Packit Service a2489d
            #if HAVE_SYMLINK
Packit Service a2489d
            {
Packit Service a2489d
              static char const sym[] = "conftest.sym";
Packit Service a2489d
              if (symlink ("/dev/null", sym) != 0)
Packit Service a2489d
                result |= 2;
Packit Service a2489d
              else
Packit Service a2489d
                {
Packit Service a2489d
                  int fd = open (sym, O_WRONLY | O_NOFOLLOW | O_CREAT, 0);
Packit Service a2489d
                  if (fd >= 0)
Packit Service a2489d
                    {
Packit Service a2489d
                      close (fd);
Packit Service a2489d
                      result |= 4;
Packit Service a2489d
                    }
Packit Service a2489d
                }
Packit Service a2489d
              if (unlink (sym) != 0 || symlink (".", sym) != 0)
Packit Service a2489d
                result |= 2;
Packit Service a2489d
              else
Packit Service a2489d
                {
Packit Service a2489d
                  int fd = open (sym, O_RDONLY | O_NOFOLLOW);
Packit Service a2489d
                  if (fd >= 0)
Packit Service a2489d
                    {
Packit Service a2489d
                      close (fd);
Packit Service a2489d
                      result |= 4;
Packit Service a2489d
                    }
Packit Service a2489d
                }
Packit Service a2489d
              unlink (sym);
Packit Service a2489d
            }
Packit Service a2489d
            #endif
Packit Service a2489d
            {
Packit Service a2489d
              static char const file[] = "confdefs.h";
Packit Service a2489d
              int fd = open (file, O_RDONLY | O_NOATIME);
Packit Service a2489d
              if (fd < 0)
Packit Service a2489d
                result |= 8;
Packit Service a2489d
              else
Packit Service a2489d
                {
Packit Service a2489d
                  struct stat st0;
Packit Service a2489d
                  if (fstat (fd, &st0) != 0)
Packit Service a2489d
                    result |= 16;
Packit Service a2489d
                  else
Packit Service a2489d
                    {
Packit Service a2489d
                      char c;
Packit Service a2489d
                      sleep (1);
Packit Service a2489d
                      if (read (fd, &c, 1) != 1)
Packit Service a2489d
                        result |= 24;
Packit Service a2489d
                      else
Packit Service a2489d
                        {
Packit Service a2489d
                          if (close (fd) != 0)
Packit Service a2489d
                            result |= 32;
Packit Service a2489d
                          else
Packit Service a2489d
                            {
Packit Service a2489d
                              struct stat st1;
Packit Service a2489d
                              if (stat (file, &st1) != 0)
Packit Service a2489d
                                result |= 40;
Packit Service a2489d
                              else
Packit Service a2489d
                                if (st0.st_atime != st1.st_atime)
Packit Service a2489d
                                  result |= 64;
Packit Service a2489d
                            }
Packit Service a2489d
                        }
Packit Service a2489d
                    }
Packit Service a2489d
                }
Packit Service a2489d
            }
Packit Service a2489d
            return result;]])],
Packit Service a2489d
       [gl_cv_header_working_fcntl_h=yes],
Packit Service a2489d
       [case $? in #(
Packit Service a2489d
        4) gl_cv_header_working_fcntl_h='no (bad O_NOFOLLOW)';; #(
Packit Service a2489d
        64) gl_cv_header_working_fcntl_h='no (bad O_NOATIME)';; #(
Packit Service a2489d
        68) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #(
Packit Service a2489d
         *) gl_cv_header_working_fcntl_h='no';;
Packit Service a2489d
        esac],
Packit Service a2489d
       [case "$host_os" in
Packit Service a2489d
                  # Guess 'no' on native Windows.
Packit Service a2489d
          mingw*) gl_cv_header_working_fcntl_h='no' ;;
Packit Service a2489d
          *)      gl_cv_header_working_fcntl_h=cross-compiling ;;
Packit Service a2489d
        esac
Packit Service a2489d
       ])
Packit Service a2489d
    ])
Packit Service a2489d
Packit Service a2489d
  case $gl_cv_header_working_fcntl_h in #(
Packit Service a2489d
  *O_NOATIME* | no | cross-compiling) ac_val=0;; #(
Packit Service a2489d
  *) ac_val=1;;
Packit Service a2489d
  esac
Packit Service a2489d
  AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOATIME], [$ac_val],
Packit Service a2489d
    [Define to 1 if O_NOATIME works.])
Packit Service a2489d
Packit Service a2489d
  case $gl_cv_header_working_fcntl_h in #(
Packit Service a2489d
  *O_NOFOLLOW* | no | cross-compiling) ac_val=0;; #(
Packit Service a2489d
  *) ac_val=1;;
Packit Service a2489d
  esac
Packit Service a2489d
  AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOFOLLOW], [$ac_val],
Packit Service a2489d
    [Define to 1 if O_NOFOLLOW works.])
Packit Service a2489d
])