Skip to content

Commit 6e24289

Browse files
committed
CDRIVER-2015 getpeername and getsockopt params vary
Call getpeername and getsockopt with the right parameters on each platform where we use the Autotools build system. Set reasonable defaults in CMake builds.
1 parent 8eaff0d commit 6e24289

File tree

5 files changed

+306
-3
lines changed

5 files changed

+306
-3
lines changed

CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,15 @@ else()
181181
set(MONGOC_HAVE_SOCKLEN 0)
182182
endif()
183183

184+
# Reasonable defaults. CheckCompiler.m4 checks thoroughly for HP-UX's sake.
185+
set (ACCEPT_ARG2 "struct sockaddr")
186+
set (ACCEPT_ARG3 "socklen_t")
187+
set (GETPEERNAME_ARG2 "struct sockaddr")
188+
set (GETPEERNAME_ARG3 "socklen_t")
189+
set (GETSOCKNAME_ARG2 "struct sockaddr")
190+
set (GETSOCKNAME_ARG3 "socklen_t")
191+
set (GETSOCKOPT_ARG5 "socklen_t")
192+
184193
set (SOURCE_DIR "${PROJECT_SOURCE_DIR}/")
185194

186195
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/build/cmake)

build/autotools/CheckCompiler.m4

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,52 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
4242
#error Not a supported Sun compiler
4343
#endif
4444
])], [c_compiler="sun"], [])
45+
46+
AX_PROTOTYPE(accept, [
47+
#include <sys/types.h>
48+
#include <sys/socket.h>
49+
], [
50+
int a = 0;
51+
ARG2 *b = 0;
52+
ARG3 *c = 0;
53+
accept (a, b, c);],
54+
ARG2, [struct sockaddr, void],
55+
ARG3, [socklen_t, size_t, int])
56+
57+
AX_PROTOTYPE(getpeername, [
58+
#include <sys/types.h>
59+
#include <sys/socket.h>
60+
], [
61+
int a = 0;
62+
ARG2 *b = 0;
63+
ARG3 *c = 0;
64+
getpeername (a, b, c);],
65+
ARG2, [struct sockaddr, void],
66+
ARG3, [socklen_t, size_t, int])
67+
68+
AX_PROTOTYPE(getsockname, [
69+
#include <sys/types.h>
70+
#include <sys/socket.h>
71+
], [
72+
int a = 0;
73+
ARG2 *b = 0;
74+
ARG3 *c = 0;
75+
getsockname (a, b, c);],
76+
ARG2, [struct sockaddr, void],
77+
ARG3, [socklen_t, size_t, int])
78+
79+
AX_PROTOTYPE(getsockopt, [
80+
#include <sys/types.h>
81+
#include <sys/socket.h>
82+
], [
83+
int a = 0;
84+
int b = 0;
85+
int c = 0;
86+
void *d = 0;
87+
ARG5 *e = 0;
88+
getsockopt (a, b, c, d, e);],
89+
ARG5, [socklen_t, int])
90+
4591
AC_LANG_POP([C])
4692

4793
if test "$c_compiler" = "unknown"; then

build/autotools/m4/ax_prototype.m4

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# ===========================================================================
2+
# https://www.gnu.org/software/autoconf-archive/ax_prototype.html
3+
# ===========================================================================
4+
#
5+
# SYNOPSIS
6+
#
7+
# AX_PROTOTYPE(function, includes, code, TAG1, values1 [, TAG2, values2 [...]])
8+
#
9+
# DESCRIPTION
10+
#
11+
# Try all the combinations of <TAG1>, <TAG2>... to successfully compile
12+
# <code>. <TAG1>, <TAG2>, ... are substituted in <code> and <include> with
13+
# values found in <values1>, <values2>, ... respectively. <values1>,
14+
# <values2>, ... contain a list of possible values for each corresponding
15+
# tag and all combinations are tested. When AC_TRY_COMPILE(include, code)
16+
# is successfull for a given substitution, the macro stops and defines the
17+
# following macros: FUNCTION_TAG1, FUNCTION_TAG2, ... using AC_DEFINE()
18+
# with values set to the current values of <TAG1>, <TAG2>, ... If no
19+
# combination is successfull the configure script is aborted with a
20+
# message.
21+
#
22+
# Intended purpose is to find which combination of argument types is
23+
# acceptable for a given function <function>. It is recommended to list
24+
# the most specific types first. For instance ARG1, [size_t, int] instead
25+
# of ARG1, [int, size_t].
26+
#
27+
# Generic usage pattern:
28+
#
29+
# 1) add a call in configure.in
30+
#
31+
# AX_PROTOTYPE(...)
32+
#
33+
# 2) call autoheader to see which symbols are not covered
34+
#
35+
# 3) add the lines in acconfig.h
36+
#
37+
# /* Type of Nth argument of function */
38+
# #undef FUNCTION_ARGN
39+
#
40+
# 4) Within the code use FUNCTION_ARGN instead of an hardwired type
41+
#
42+
# Complete example:
43+
#
44+
# 1) configure.in
45+
#
46+
# AX_PROTOTYPE(getpeername,
47+
# [
48+
# #include <sys/types.h>
49+
# #include <sys/socket.h>
50+
# ],
51+
# [
52+
# int a = 0;
53+
# ARG2 * b = 0;
54+
# ARG3 * c = 0;
55+
# getpeername(a, b, c);
56+
# ],
57+
# ARG2, [struct sockaddr, void],
58+
# ARG3, [socklen_t, size_t, int, unsigned int, long unsigned int])
59+
#
60+
# 2) call autoheader
61+
#
62+
# autoheader: Symbol `GETPEERNAME_ARG2' is not covered by ./acconfig.h
63+
# autoheader: Symbol `GETPEERNAME_ARG3' is not covered by ./acconfig.h
64+
#
65+
# 3) acconfig.h
66+
#
67+
# /* Type of second argument of getpeername */
68+
# #undef GETPEERNAME_ARG2
69+
#
70+
# /* Type of third argument of getpeername */
71+
# #undef GETPEERNAME_ARG3
72+
#
73+
# 4) in the code
74+
#
75+
# ...
76+
# GETPEERNAME_ARG2 name;
77+
# GETPEERNAME_ARG3 namelen;
78+
# ...
79+
# ret = getpeername(socket, &name, &namelen);
80+
# ...
81+
#
82+
# Implementation notes: generating all possible permutations of the
83+
# arguments is not easily done with the usual mixture of shell and m4,
84+
# that is why this macro is almost 100% m4 code. It generates long but
85+
# simple to read code.
86+
#
87+
# LICENSE
88+
#
89+
# Copyright (c) 2009 Loic Dachary <[email protected]>
90+
#
91+
# This program is free software; you can redistribute it and/or modify it
92+
# under the terms of the GNU General Public License as published by the
93+
# Free Software Foundation; either version 2 of the License, or (at your
94+
# option) any later version.
95+
#
96+
# This program is distributed in the hope that it will be useful, but
97+
# WITHOUT ANY WARRANTY; without even the implied warranty of
98+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
99+
# Public License for more details.
100+
#
101+
# You should have received a copy of the GNU General Public License along
102+
# with this program. If not, see <https://www.gnu.org/licenses/>.
103+
#
104+
# As a special exception, the respective Autoconf Macro's copyright owner
105+
# gives unlimited permission to copy, distribute and modify the configure
106+
# scripts that are the output of Autoconf when processing the Macro. You
107+
# need not follow the terms of the GNU General Public License when using
108+
# or distributing such scripts, even though portions of the text of the
109+
# Macro appear in them. The GNU General Public License (GPL) does govern
110+
# all other use of the material that constitutes the Autoconf Macro.
111+
#
112+
# This special exception to the GPL applies to versions of the Autoconf
113+
# Macro released by the Autoconf Archive. When you make and distribute a
114+
# modified version of the Autoconf Macro, you may extend this special
115+
# exception to the GPL to apply to your modified version as well.
116+
117+
#serial 6
118+
119+
AU_ALIAS([AC_PROTOTYPE], [AX_PROTOTYPE])
120+
AC_DEFUN([AX_PROTOTYPE],[
121+
dnl
122+
dnl Upper case function name
123+
dnl
124+
pushdef([function],translit([$1], [a-z], [A-Z]))
125+
dnl
126+
dnl Collect tags that will be substituted
127+
dnl
128+
pushdef([tags],[AX_PROTOTYPE_TAGS(builtin([shift],builtin([shift],builtin([shift],$@))))])
129+
dnl
130+
dnl Wrap in a 1 time loop, when a combination is found break to stop the combinatory exploration
131+
dnl
132+
for i in 1
133+
do
134+
AX_PROTOTYPE_LOOP(AX_PROTOTYPE_REVERSE($1, AX_PROTOTYPE_SUBST($2,tags),AX_PROTOTYPE_SUBST($3,tags),builtin([shift],builtin([shift],builtin([shift],$@)))))
135+
AC_MSG_ERROR($1 unable to find a working combination)
136+
done
137+
popdef([tags])
138+
popdef([function])
139+
])
140+
141+
dnl
142+
dnl AX_PROTOTYPE_REVERSE(list)
143+
dnl
144+
dnl Reverse the order of the <list>
145+
dnl
146+
AC_DEFUN([AX_PROTOTYPE_REVERSE],[ifelse($#,0,,$#,1,[[$1]],[AX_PROTOTYPE_REVERSE(builtin([shift],$@)),[$1]])])
147+
148+
dnl
149+
dnl AX_PROTOTYPE_SUBST(string, tag)
150+
dnl
151+
dnl Substitute all occurence of <tag> in <string> with <tag>_VAL.
152+
dnl Assumes that tag_VAL is a macro containing the value associated to tag.
153+
dnl
154+
AC_DEFUN([AX_PROTOTYPE_SUBST],[ifelse($2,,[$1],[AX_PROTOTYPE_SUBST(patsubst([$1],[$2],[$2[]_VAL]),builtin([shift],builtin([shift],$@)))])])
155+
156+
dnl
157+
dnl AX_PROTOTYPE_TAGS([tag, values, [tag, values ...]])
158+
dnl
159+
dnl Generate a list of <tag> by skipping <values>.
160+
dnl
161+
AC_DEFUN([AX_PROTOTYPE_TAGS],[ifelse($1,,[],[$1, AX_PROTOTYPE_TAGS(builtin([shift],builtin([shift],$@)))])])
162+
163+
dnl
164+
dnl AX_PROTOTYPE_DEFINES(tags)
165+
dnl
166+
dnl Generate a AC_DEFINE(function_tag, tag_VAL) for each tag in <tags> list
167+
dnl Assumes that function is a macro containing the name of the function in upper case
168+
dnl and that tag_VAL is a macro containing the value associated to tag.
169+
dnl
170+
AC_DEFUN([AX_PROTOTYPE_DEFINES],[ifelse($1,,[],
171+
[AC_DEFINE(function[]_$1, $1_VAL)
172+
AC_SUBST(function[]_$1, "$1_VAL")
173+
AX_PROTOTYPE_DEFINES(builtin([shift],$@))])])
174+
175+
dnl
176+
dnl AX_PROTOTYPE_STATUS(tags)
177+
dnl
178+
dnl Generates a message suitable for argument to AC_MSG_* macros. For each tag
179+
dnl in the <tags> list the message tag => tag_VAL is generated.
180+
dnl Assumes that tag_VAL is a macro containing the value associated to tag.
181+
dnl
182+
AC_DEFUN([AX_PROTOTYPE_STATUS],[ifelse($1,,[],[$1 => $1_VAL AX_PROTOTYPE_STATUS(builtin([shift],$@))])])
183+
184+
dnl
185+
dnl AX_PROTOTYPE_EACH(tag, values)
186+
dnl
187+
dnl Call AX_PROTOTYPE_LOOP for each values and define the macro tag_VAL to
188+
dnl the current value.
189+
dnl
190+
AC_DEFUN([AX_PROTOTYPE_EACH],[
191+
ifelse($2,, [
192+
], [
193+
pushdef([$1_VAL], $2)
194+
AX_PROTOTYPE_LOOP(rest)
195+
popdef([$1_VAL])
196+
AX_PROTOTYPE_EACH($1, builtin([shift], builtin([shift], $@)))
197+
])
198+
])
199+
200+
dnl
201+
dnl AX_PROTOTYPE_LOOP([tag, values, [tag, values ...]], code, include, function)
202+
dnl
203+
dnl If there is a tag/values pair, call AX_PROTOTYPE_EACH with it.
204+
dnl If there is no tag/values pair left, tries to compile the code and include
205+
dnl using AC_TRY_COMPILE. If it compiles, AC_DEFINE all the tags to their
206+
dnl current value and exit with success.
207+
dnl
208+
AC_DEFUN([AX_PROTOTYPE_LOOP],[
209+
ifelse(builtin([eval], $# > 3), 1,
210+
[
211+
pushdef([rest],[builtin([shift],builtin([shift],$@))])
212+
AX_PROTOTYPE_EACH($2,$1)
213+
popdef([rest])
214+
], [
215+
AC_MSG_CHECKING($3 AX_PROTOTYPE_STATUS(tags))
216+
dnl
217+
dnl Activate fatal warnings if possible, gives better guess
218+
dnl
219+
ac_save_CPPFLAGS="$CPPFLAGS"
220+
if test "$GCC" = "yes" ; then CPPFLAGS="$CPPFLAGS -Werror" ; fi
221+
AC_TRY_COMPILE($2, $1, [
222+
CPPFLAGS="$ac_save_CPPFLAGS"
223+
AC_MSG_RESULT(ok)
224+
AX_PROTOTYPE_DEFINES(tags)
225+
break;
226+
], [
227+
CPPFLAGS="$ac_save_CPPFLAGS"
228+
AC_MSG_RESULT(not ok)
229+
])
230+
]
231+
)
232+
])

src/mongoc/mongoc-config.h.in

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,20 @@
213213
#if MONGOC_HAVE_SOCKLEN != 1
214214
# undef MONGOC_HAVE_SOCKLEN
215215
#endif
216+
217+
218+
/*
219+
* Set from configure, see
220+
* https://curl.haxx.se/mail/lib-2009-04/0287.html
221+
*/
222+
#define MONGOC_ACCEPT_ARG2 @ACCEPT_ARG2@
223+
#define MONGOC_ACCEPT_ARG3 @ACCEPT_ARG3@
224+
#define MONGOC_GETPEERNAME_ARG2 @GETPEERNAME_ARG2@
225+
#define MONGOC_GETPEERNAME_ARG3 @GETPEERNAME_ARG3@
226+
#define MONGOC_GETSOCKNAME_ARG2 @GETSOCKNAME_ARG2@
227+
#define MONGOC_GETSOCKNAME_ARG3 @GETSOCKNAME_ARG3@
228+
#define MONGOC_GETSOCKOPT_ARG5 @GETSOCKOPT_ARG5@
229+
216230
/*
217231
* NOTICE:
218232
* If you're about to update this file and add a config flag, make sure to

src/mongoc/mongoc-socket.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,8 @@ mongoc_socket_connect (mongoc_socket_t *sock, /* IN */
585585
bool failed = false;
586586
int ret;
587587
int optval;
588-
mongoc_socklen_t optlen = sizeof optval;
588+
/* getsockopt parameter types vary, we check in CheckCompiler.m4 */
589+
MONGOC_GETSOCKOPT_ARG5 optlen = (MONGOC_GETSOCKOPT_ARG5) sizeof optval;
589590

590591
ENTRY;
591592

@@ -1196,8 +1197,9 @@ mongoc_socket_getsockname (mongoc_socket_t *sock, /* IN */
11961197
char *
11971198
mongoc_socket_getnameinfo (mongoc_socket_t *sock) /* IN */
11981199
{
1199-
struct sockaddr addr;
1200-
mongoc_socklen_t len = sizeof addr;
1200+
/* getpeername parameter types vary, we check in CheckCompiler.m4 */
1201+
MONGOC_GETPEERNAME_ARG2 addr;
1202+
MONGOC_GETPEERNAME_ARG3 len = (MONGOC_GETPEERNAME_ARG3) sizeof addr;
12011203
char *ret;
12021204
char host[BSON_HOST_NAME_MAX + 1];
12031205

0 commit comments

Comments
 (0)