Merge pull request #2046 from RincewindsHat/fix/format_string
[monitoring-plugins.git] / gl / m4 / ftello.m4
blob0eb8fa0da476d72725cc268f89ac2a8e1320dc46
1 # ftello.m4
2 # serial 16
3 dnl Copyright (C) 2007-2024 Free Software Foundation, Inc.
4 dnl This file is free software; the Free Software Foundation
5 dnl gives unlimited permission to copy and/or distribute it,
6 dnl with or without modifications, as long as this notice is preserved.
8 AC_DEFUN([gl_FUNC_FTELLO],
10   AC_REQUIRE([gl_STDIO_H_DEFAULTS])
11   AC_REQUIRE([AC_PROG_CC])
12   AC_REQUIRE([gl_STDIN_LARGE_OFFSET])
13   AC_REQUIRE([gl_SYS_TYPES_H])
15   dnl Persuade glibc <stdio.h> to declare ftello().
16   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
18   AC_CHECK_DECLS_ONCE([ftello])
19   if test $ac_cv_have_decl_ftello = no; then
20     HAVE_DECL_FTELLO=0
21   fi
23   AC_CACHE_CHECK([for ftello], [gl_cv_func_ftello],
24     [
25       AC_LINK_IFELSE(
26         [AC_LANG_PROGRAM(
27            [[#include <stdio.h>]],
28            [[ftello (stdin);]])],
29         [gl_cv_func_ftello=yes],
30         [gl_cv_func_ftello=no])
31     ])
32   if test $gl_cv_func_ftello = no; then
33     HAVE_FTELLO=0
34   else
35     if test $WINDOWS_64_BIT_OFF_T = 1; then
36       REPLACE_FTELLO=1
37     fi
38     if test $gl_cv_var_stdin_large_offset = no; then
39       REPLACE_FTELLO=1
40     fi
41     AC_REQUIRE([AC_CANONICAL_HOST])
42     if test $REPLACE_FTELLO = 0; then
43       dnl On native Windows, in some circumstances, ftell(), ftello(),
44       dnl fgetpos(), lseek(), _lseeki64() all succeed on devices of type
45       dnl FILE_TYPE_PIPE. However, to match POSIX behaviour, we want
46       dnl ftell(), ftello(), fgetpos(), lseek() to fail when the argument fd
47       dnl designates a pipe. See also
48       dnl https://github.com/python/cpython/issues/78961#issuecomment-1093800325
49       case "$host_os" in
50         mingw* | windows*) REPLACE_FTELLO=1 ;;
51       esac
52     fi
53     if test $REPLACE_FTELLO = 0; then
54       dnl Detect bug on Solaris.
55       dnl ftell and ftello produce incorrect results after putc that followed a
56       dnl getc call that reached EOF on Solaris. This is because the _IOREAD
57       dnl flag does not get cleared in this case, even though _IOWRT gets set,
58       dnl and ftell and ftello look whether the _IOREAD flag is set.
59       AC_CACHE_CHECK([whether ftello works],
60         [gl_cv_func_ftello_works],
61         [
62           dnl Initial guess, used when cross-compiling or when /dev/tty cannot
63           dnl be opened.
64 changequote(,)dnl
65           case "$host_os" in
66                                # Guess no on Solaris.
67             solaris*)          gl_cv_func_ftello_works="guessing no" ;;
68                                # Guess yes on native Windows.
69             mingw* | windows*) gl_cv_func_ftello_works="guessing yes" ;;
70                                # Guess yes otherwise.
71             *)                 gl_cv_func_ftello_works="guessing yes" ;;
72           esac
73 changequote([,])dnl
74           AC_RUN_IFELSE(
75             [AC_LANG_SOURCE([[
76 #include <stdio.h>
77 #include <stdlib.h>
78 #include <string.h>
79 #define TESTFILE "conftest.tmp"
80 int
81 main (void)
83   FILE *fp;
85   /* Create a file with some contents.  */
86   fp = fopen (TESTFILE, "w");
87   if (fp == NULL)
88     return 70;
89   if (fwrite ("foogarsh", 1, 8, fp) < 8)
90     { fclose (fp); return 71; }
91   if (fclose (fp))
92     return 72;
94   /* The file's contents is now "foogarsh".  */
96   /* Try writing after reading to EOF.  */
97   fp = fopen (TESTFILE, "r+");
98   if (fp == NULL)
99     return 73;
100   if (fseek (fp, -1, SEEK_END))
101     { fclose (fp); return 74; }
102   if (!(getc (fp) == 'h'))
103     { fclose (fp); return 1; }
104   if (!(getc (fp) == EOF))
105     { fclose (fp); return 2; }
106   if (!(ftell (fp) == 8))
107     { fclose (fp); return 3; }
108   if (!(ftell (fp) == 8))
109     { fclose (fp); return 4; }
110   if (!(putc ('!', fp) == '!'))
111     { fclose (fp); return 5; }
112   if (!(ftell (fp) == 9))
113     { fclose (fp); return 6; }
114   if (!(fclose (fp) == 0))
115     return 7;
116   fp = fopen (TESTFILE, "r");
117   if (fp == NULL)
118     return 75;
119   {
120     char buf[10];
121     if (!(fread (buf, 1, 10, fp) == 9))
122       { fclose (fp); return 10; }
123     if (!(memcmp (buf, "foogarsh!", 9) == 0))
124       { fclose (fp); return 11; }
125   }
126   if (!(fclose (fp) == 0))
127     return 12;
129   /* The file's contents is now "foogarsh!".  */
131   return 0;
132 }]])],
133             [gl_cv_func_ftello_works=yes],
134             [gl_cv_func_ftello_works=no], [:])
135         ])
136       case "$gl_cv_func_ftello_works" in
137         *yes) ;;
138         *)
139           REPLACE_FTELLO=1
140           AC_DEFINE([FTELLO_BROKEN_AFTER_SWITCHING_FROM_READ_TO_WRITE], [1],
141             [Define to 1 if the system's ftello function has the Solaris bug.])
142           ;;
143       esac
144     fi
145     if test $REPLACE_FTELLO = 0; then
146       dnl Detect bug on macOS >= 10.15.
147       gl_FUNC_UNGETC_WORKS
148       if test $gl_ftello_broken_after_ungetc = yes; then
149         REPLACE_FTELLO=1
150         AC_DEFINE([FTELLO_BROKEN_AFTER_UNGETC], [1],
151           [Define to 1 if the system's ftello function has the macOS bug.])
152       fi
153     fi
154   fi
157 # Prerequisites of lib/ftello.c.
158 AC_DEFUN([gl_PREREQ_FTELLO],
160   dnl Native Windows has the function _ftelli64. mingw hides it, but mingw64
161   dnl makes it usable again.
162   AC_CHECK_FUNCS([_ftelli64])