d9a0e2e079125c746a1c1a674e1b62efb714ae98
[gpgme.git] / m4 / gnupg-ttyname.m4
1 # gnupg-ttyname.m4
2 # Copyright (C) 2010-2012 Free Software Foundation, Inc.
3 # This file is free software; the Free Software Foundation
4 # gives unlimited permission to copy and/or distribute it,
5 # with or without modifications, as long as this notice is preserved.
6 #
7 # This file is based on gnulib/m4/ttyname_r.m4 serial 8.
8 #
9
10
11 # gnupg_REPLACE_TTYNAME_R
12 #
13 # This macro is an extended version of AC_REPLACE_FUNCS(ttyname_r).
14 # It takes peculiarities in the implementation of ttyname_r in account.
15 #
16 # The macro HAVE_TTYNAME_R will be defined to 1 if the function
17 # exists; it will be defined to 0 if it does not exists or no
18 # declaration is available.
19 #
20 # The macro HAVE_POSIXDECL_TTYNAME_R is defined if ttyname_r conforms
21 # to the Posix declaration.
22 #
23 # The macro HAVE_BROKEN_TTYNAME_R is defined it ttyname_r does not work
24 # correctly with the supplied buffer size.  If this is defined the function
25 # will also be replaced.
26 #
27 # The macro REPLACE_TTYNAME_R is defined if ttyname_r is a replacement
28 # function.  This macro is useful for the definition of the prototype.
29 #
30 AC_DEFUN([gnupg_REPLACE_TTYNAME_R],
31 [
32   AC_CHECK_HEADERS([unistd.h])
33
34   AC_CHECK_DECLS_ONCE([ttyname_r])
35   if test $ac_cv_have_decl_ttyname_r = no; then
36     HAVE_DECL_TTYNAME_R=0
37   fi
38
39   AC_CHECK_FUNCS([ttyname_r])
40   if test $ac_cv_func_ttyname_r = no; then
41     HAVE_TTYNAME_R=0
42     AC_LIBOBJ([ttyname_r])
43     AC_DEFINE([REPLACE_TTYNAME_R],[1],
44               [Define to 1 if ttyname_r is a replacement function.])
45   else
46     HAVE_TTYNAME_R=1
47     dnl On MacOS X 10.4 (and Solaris 10 without __EXTENSIONS__)
48     dnl the return type is 'char *', not 'int'.
49     AC_CACHE_CHECK([whether ttyname_r is compatible with its POSIX signature],
50       [gnupg_cv_func_ttyname_r_posix],
51       [AC_COMPILE_IFELSE(
52          [AC_LANG_PROGRAM(
53             [[#include <stddef.h>
54               #include <unistd.h>]],
55             [[*ttyname_r (0, NULL, 0);]])
56          ],
57          [gnupg_cv_func_ttyname_r_posix=no],
58          [gnupg_cv_func_ttyname_r_posix=yes])
59       ])
60     if test $gnupg_cv_func_ttyname_r_posix = no; then
61       AC_LIBOBJ([ttyname_r])
62       AC_DEFINE([REPLACE_TTYNAME_R],[1])
63     else
64       AC_DEFINE([HAVE_POSIXDECL_TTYNAME_R], [1],
65         [Define if the ttyname_r function has a POSIX compliant declaration.])
66       dnl On Solaris 10, both ttyname_r functions (the one with the non-POSIX
67       dnl declaration and the one with the POSIX declaration) refuse to do
68       dnl anything when the output buffer is less than 128 bytes large.
69       dnl On OSF/1 5.1, ttyname_r ignores the buffer size and assumes the
70       dnl buffer is large enough.
71       AC_REQUIRE([AC_CANONICAL_HOST])
72       AC_CACHE_CHECK([whether ttyname_r works with small buffers],
73         [gnupg_cv_func_ttyname_r_works],
74         [
75           dnl Initial guess, used when cross-compiling or when /dev/tty cannot
76           dnl be opened.
77 changequote(,)dnl
78           case "$host_os" in
79                       # Guess no on Solaris.
80             solaris*) gnupg_cv_func_ttyname_r_works="guessing no" ;;
81                       # Guess no on OSF/1.
82             osf*)     gnupg_cv_func_ttyname_r_works="guessing no" ;;
83                       # Guess yes otherwise.
84             *)        gnupg_cv_func_ttyname_r_works="guessing yes" ;;
85           esac
86 changequote([,])dnl
87           AC_RUN_IFELSE(
88             [AC_LANG_SOURCE([[
89 #include <fcntl.h>
90 #include <unistd.h>
91 int
92 main (void)
93 {
94   int result = 0;
95   int fd;
96   char buf[31]; /* use any size < 128 here */
97
98   fd = open ("/dev/tty", O_RDONLY);
99   if (fd < 0)
100     result |= 16;
101   else if (ttyname_r (fd, buf, sizeof (buf)) != 0)
102     result |= 17;
103   else if (ttyname_r (fd, buf, 1) == 0)
104     result |= 18;
105   return result;
106 }]])],
107             [gnupg_cv_func_ttyname_r_works=yes],
108             [case $? in
109                17 | 18) gnupg_cv_func_ttyname_r_works=no ;;
110              esac],
111             [:])
112         ])
113       case "$gnupg_cv_func_ttyname_r_works" in
114         *yes) ;;
115         *) AC_LIBOBJ([ttyname_r])
116            AC_DEFINE([REPLACE_TTYNAME_R],[1])
117            AC_DEFINE([HAVE_BROKEN_TTYNAME_R], [1],
118                      [Define if ttyname_r is does not work with small buffers])
119            ;;
120       esac
121     fi
122   fi
123 ])