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