xref: /freebsd/crypto/openssh/m4/openssh.m4 (revision db33c6f3ae9d1231087710068ee4ea5398aacca7)
1dnl OpenSSH-specific autoconf macros
2dnl
3
4dnl The test program that is used to try to trigger various compiler
5dnl behaviours.
6AC_DEFUN([OSSH_COMPILER_FLAG_TEST_PROGRAM],
7	[AC_LANG_SOURCE([[
8#include <stdlib.h>
9#include <stdarg.h>
10#include <stdio.h>
11#include <string.h>
12#include <unistd.h>
13/* Trivial function to help test for -fzero-call-used-regs */
14int f(int n) {return rand() % n;}
15char *f2(char *s, ...) {
16	char ret[64];
17	va_list args;
18	va_start(args, s);
19	vsnprintf(ret, sizeof(ret), s, args);
20	va_end(args);
21	return strdup(ret);
22}
23const char *f3(int s) {
24	return s ? "good" : "gooder";
25}
26int main(int argc, char **argv) {
27	char b[256], *cp;
28	const char *s;
29	/* Some math to catch -ftrapv problems in the toolchain */
30	int i = 123 * argc, j = 456 + argc, k = 789 - argc;
31	float l = i * 2.1;
32	double m = l / 0.5;
33	long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
34	(void)argv;
35	f(1);
36	s = f3(f(2));
37	snprintf(b, sizeof b, "%d %d %d %f %f %lld %lld %s\n", i,j,k,l,m,n,o,s);
38	if (write(1, b, 0) == -1) exit(0);
39	cp = f2("%d %d %d %f %f %lld %lld %s\n", i,j,k,l,m,n,o,s);
40	if (write(1, cp, 0) == -1) exit(0);
41	free(cp);
42	/*
43	 * Test fallthrough behaviour.  clang 10's -Wimplicit-fallthrough does
44	 * not understand comments and we don't use the "fallthrough" attribute
45	 * that it's looking for.
46	 */
47	switch(i){
48	case 0: j += i;
49		/* FALLTHROUGH */
50	default: j += k;
51	}
52	exit(0);
53}
54	]])]
55)
56
57dnl OSSH_CHECK_CFLAG_COMPILE(check_flag[, define_flag])
58dnl Check that $CC accepts a flag 'check_flag'. If it is supported append
59dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append
60dnl 'check_flag'.
61AC_DEFUN([OSSH_CHECK_CFLAG_COMPILE], [{
62	AC_MSG_CHECKING([if $CC supports compile flag $1])
63	saved_CFLAGS="$CFLAGS"
64	CFLAGS="$CFLAGS $WERROR $1"
65	_define_flag="$2"
66	test "x$_define_flag" = "x" && _define_flag="$1"
67	AC_COMPILE_IFELSE([OSSH_COMPILER_FLAG_TEST_PROGRAM],
68		[
69if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null
70then
71		AC_MSG_RESULT([no])
72		CFLAGS="$saved_CFLAGS"
73else
74		dnl If we are compiling natively, try running the program.
75		AC_RUN_IFELSE([OSSH_COMPILER_FLAG_TEST_PROGRAM],
76			[ AC_MSG_RESULT([yes])
77			  CFLAGS="$saved_CFLAGS $_define_flag" ],
78			[ AC_MSG_RESULT([no, fails at run time])
79			  CFLAGS="$saved_CFLAGS" ],
80			[ AC_MSG_RESULT([yes])
81			  CFLAGS="$saved_CFLAGS $_define_flag" ],
82		)
83fi],
84		[ AC_MSG_RESULT([no])
85		  CFLAGS="$saved_CFLAGS" ]
86	)
87}])
88
89dnl OSSH_CHECK_CFLAG_LINK(check_flag[, define_flag])
90dnl Check that $CC accepts a flag 'check_flag'. If it is supported append
91dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append
92dnl 'check_flag'.
93AC_DEFUN([OSSH_CHECK_CFLAG_LINK], [{
94	AC_MSG_CHECKING([if $CC supports compile flag $1 and linking succeeds])
95	saved_CFLAGS="$CFLAGS"
96	CFLAGS="$CFLAGS $WERROR $1"
97	_define_flag="$2"
98	test "x$_define_flag" = "x" && _define_flag="$1"
99	AC_LINK_IFELSE([OSSH_COMPILER_FLAG_TEST_PROGRAM],
100		[
101if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null
102then
103		AC_MSG_RESULT([no])
104		CFLAGS="$saved_CFLAGS"
105else
106		dnl If we are compiling natively, try running the program.
107		AC_RUN_IFELSE([OSSH_COMPILER_FLAG_TEST_PROGRAM],
108			[ AC_MSG_RESULT([yes])
109			  CFLAGS="$saved_CFLAGS $_define_flag" ],
110			[ AC_MSG_RESULT([no, fails at run time])
111			  CFLAGS="$saved_CFLAGS" ],
112			[ AC_MSG_RESULT([yes])
113			  CFLAGS="$saved_CFLAGS $_define_flag" ],
114		)
115fi],
116		[ AC_MSG_RESULT([no])
117		  CFLAGS="$saved_CFLAGS" ]
118	)
119}])
120
121dnl OSSH_CHECK_LDFLAG_LINK(check_flag[, define_flag])
122dnl Check that $LD accepts a flag 'check_flag'. If it is supported append
123dnl 'define_flag' to $LDFLAGS. If 'define_flag' is not specified, then append
124dnl 'check_flag'.
125AC_DEFUN([OSSH_CHECK_LDFLAG_LINK], [{
126	AC_MSG_CHECKING([if $LD supports link flag $1])
127	saved_LDFLAGS="$LDFLAGS"
128	LDFLAGS="$LDFLAGS $WERROR $1"
129	_define_flag="$2"
130	test "x$_define_flag" = "x" && _define_flag="$1"
131	AC_LINK_IFELSE([OSSH_COMPILER_FLAG_TEST_PROGRAM],
132		[
133if $ac_cv_path_EGREP -i "unrecognized option|warning.*ignored" conftest.err >/dev/null
134then
135		  AC_MSG_RESULT([no])
136		  LDFLAGS="$saved_LDFLAGS"
137else
138		  dnl If we are compiling natively, try running the program.
139		  AC_RUN_IFELSE([OSSH_COMPILER_FLAG_TEST_PROGRAM],
140			[ AC_MSG_RESULT([yes])
141			  LDFLAGS="$saved_LDFLAGS $_define_flag" ],
142			[ AC_MSG_RESULT([no, fails at run time])
143			  LDFLAGS="$saved_LDFLAGS" ],
144			[ AC_MSG_RESULT([yes])
145			  LDFLAGS="$saved_LDFLAGS $_define_flag" ]
146		  )
147fi		],
148		[ AC_MSG_RESULT([no])
149		  LDFLAGS="$saved_LDFLAGS" ]
150	)
151}])
152
153dnl OSSH_CHECK_HEADER_FOR_FIELD(field, header, symbol)
154dnl Does AC_EGREP_HEADER on 'header' for the string 'field'
155dnl If found, set 'symbol' to be defined. Cache the result.
156dnl TODO: This is not foolproof, better to compile and read from there
157AC_DEFUN([OSSH_CHECK_HEADER_FOR_FIELD], [
158# look for field '$1' in header '$2'
159	dnl This strips characters illegal to m4 from the header filename
160	ossh_safe=`echo "$2" | sed 'y%./+-%__p_%'`
161	dnl
162	ossh_varname="ossh_cv_$ossh_safe""_has_"$1
163	AC_MSG_CHECKING(for $1 field in $2)
164	AC_CACHE_VAL($ossh_varname, [
165		AC_EGREP_HEADER($1, $2, [ dnl
166			eval "$ossh_varname=yes" dnl
167		], [ dnl
168			eval "$ossh_varname=no" dnl
169		]) dnl
170	])
171	ossh_result=`eval 'echo $'"$ossh_varname"`
172	if test -n "`echo $ossh_varname`"; then
173		AC_MSG_RESULT($ossh_result)
174		if test "x$ossh_result" = "xyes"; then
175			AC_DEFINE($3, 1, [Define if you have $1 in $2])
176		fi
177	else
178		AC_MSG_RESULT(no)
179	fi
180])
181
182dnl Check for socklen_t: historically on BSD it is an int, and in
183dnl POSIX 1g it is a type of its own, but some platforms use different
184dnl types for the argument to getsockopt, getpeername, etc.  So we
185dnl have to test to find something that will work.
186AC_DEFUN([TYPE_SOCKLEN_T],
187[
188   AC_CHECK_TYPE([socklen_t], ,[
189      AC_MSG_CHECKING([for socklen_t equivalent])
190      AC_CACHE_VAL([curl_cv_socklen_t_equiv],
191      [
192	 # Systems have either "struct sockaddr *" or
193	 # "void *" as the second argument to getpeername
194	 curl_cv_socklen_t_equiv=
195	 for arg2 in "struct sockaddr" void; do
196	    for t in int size_t unsigned long "unsigned long"; do
197	       AC_COMPILE_IFELSE([
198		  AC_LANG_PROGRAM([[
199		    #include <sys/types.h>
200		    #include <sys/socket.h>
201		    int getpeername (int, $arg2 *, $t *);
202		  ]], [[
203		    $t len;
204		    getpeername(0,0,&len);
205		  ]])
206	       ],[
207		  curl_cv_socklen_t_equiv="$t"
208		  break
209	       ])
210	    done
211	 done
212
213	 if test "x$curl_cv_socklen_t_equiv" = x; then
214	    AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
215	 fi
216      ])
217      AC_MSG_RESULT($curl_cv_socklen_t_equiv)
218      AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv,
219			[type to use in place of socklen_t if not defined])],
220      [#include <sys/types.h>
221#include <sys/socket.h>])
222])
223
224