Blame m4/fcntl-o.m4

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