1#*************************************************************************** 2# _ _ ____ _ 3# Project ___| | | | _ \| | 4# / __| | | | |_) | | 5# | (__| |_| | _ <| |___ 6# \___|\___/|_| \_\_____| 7# 8# Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. 9# 10# This software is licensed as described in the file COPYING, which 11# you should have received as part of this distribution. The terms 12# are also available at https://curl.se/docs/copyright.html. 13# 14# You may opt to use, copy, modify, merge, publish, distribute and/or sell 15# copies of the Software, and permit persons to whom the Software is 16# furnished to do so, under the terms of the COPYING file. 17# 18# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19# KIND, either express or implied. 20# 21########################################################################### 22include(CheckCSourceCompiles) 23# The begin of the sources (macros and includes) 24set(_source_epilogue "#undef inline") 25 26macro(add_header_include check header) 27 if(${check}) 28 set(_source_epilogue "${_source_epilogue}\n#include <${header}>") 29 endif() 30endmacro() 31 32set(signature_call_conv) 33if(HAVE_WINDOWS_H) 34 add_header_include(HAVE_WINSOCK2_H "winsock2.h") 35 add_header_include(HAVE_WINDOWS_H "windows.h") 36 add_header_include(HAVE_WINSOCK_H "winsock.h") 37 set(_source_epilogue 38 "${_source_epilogue}\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif") 39 set(signature_call_conv "PASCAL") 40 if(HAVE_LIBWS2_32) 41 set(CMAKE_REQUIRED_LIBRARIES ws2_32) 42 endif() 43else() 44 add_header_include(HAVE_SYS_TYPES_H "sys/types.h") 45 add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h") 46endif() 47 48set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) 49 50function(curl_cv_func_recv_run_test recv_retv recv_arg1 recv_arg2 recv_arg3 recv_arg4) 51 unset(curl_cv_func_recv_test CACHE) 52 check_c_source_compiles(" 53 ${_source_epilogue} 54 #ifdef WINSOCK_API_LINKAGE 55 WINSOCK_API_LINKAGE 56 #endif 57 extern ${recv_retv} ${signature_call_conv} 58 recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4}); 59 int main(void) { 60 ${recv_arg1} s=0; 61 ${recv_arg2} buf=0; 62 ${recv_arg3} len=0; 63 ${recv_arg4} flags=0; 64 ${recv_retv} res = recv(s, buf, len, flags); 65 (void) res; 66 return 0; 67 }" 68 curl_cv_func_recv_test) 69 message(STATUS 70 "Tested: ${recv_retv} recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4})") 71 if(curl_cv_func_recv_test) 72 set(curl_cv_func_recv_args 73 "${recv_arg1},${recv_arg2},${recv_arg3},${recv_arg4},${recv_retv}" PARENT_SCOPE) 74 set(RECV_TYPE_ARG1 "${recv_arg1}" PARENT_SCOPE) 75 set(RECV_TYPE_ARG2 "${recv_arg2}" PARENT_SCOPE) 76 set(RECV_TYPE_ARG3 "${recv_arg3}" PARENT_SCOPE) 77 set(RECV_TYPE_ARG4 "${recv_arg4}" PARENT_SCOPE) 78 set(RECV_TYPE_RETV "${recv_retv}" PARENT_SCOPE) 79 set(HAVE_RECV 1 PARENT_SCOPE) 80 set(curl_cv_func_recv_done 1 PARENT_SCOPE) 81 endif() 82endfunction() 83 84check_c_source_compiles("${_source_epilogue} 85int main(void) { 86 recv(0, 0, 0, 0); 87 return 0; 88}" curl_cv_recv) 89if(curl_cv_recv) 90 if(NOT DEFINED curl_cv_func_recv_args OR curl_cv_func_recv_args STREQUAL "unknown") 91 if(APPLE) 92 curl_cv_func_recv_run_test("ssize_t" "int" "void *" "size_t" "int") 93 endif() 94 foreach(recv_retv "int" "ssize_t" ) 95 foreach(recv_arg1 "SOCKET" "int" ) 96 foreach(recv_arg2 "char *" "void *" ) 97 foreach(recv_arg3 "int" "size_t" "socklen_t" "unsigned int") 98 foreach(recv_arg4 "int" "unsigned int") 99 if(NOT curl_cv_func_recv_done) 100 curl_cv_func_recv_run_test(${recv_retv} ${recv_arg1} ${recv_arg2} ${recv_arg3} ${recv_arg4}) 101 endif() 102 endforeach() 103 endforeach() 104 endforeach() 105 endforeach() 106 endforeach() 107 else() 108 string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG1 "${curl_cv_func_recv_args}") 109 string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG2 "${curl_cv_func_recv_args}") 110 string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG3 "${curl_cv_func_recv_args}") 111 string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" RECV_TYPE_ARG4 "${curl_cv_func_recv_args}") 112 string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" RECV_TYPE_RETV "${curl_cv_func_recv_args}") 113 endif() 114 115 if(curl_cv_func_recv_args STREQUAL "unknown") 116 message(FATAL_ERROR "Cannot find proper types to use for recv args") 117 endif() 118else() 119 message(FATAL_ERROR "Unable to link function recv") 120endif() 121set(curl_cv_func_recv_args "${curl_cv_func_recv_args}" CACHE INTERNAL "Arguments for recv") 122set(HAVE_RECV 1) 123 124function(curl_cv_func_send_run_test send_retv send_arg1 send_arg2 send_arg3 send_arg4) 125 unset(curl_cv_func_send_test CACHE) 126 check_c_source_compiles(" 127 ${_source_epilogue} 128 #ifdef WINSOCK_API_LINKAGE 129 WINSOCK_API_LINKAGE 130 #endif 131 extern ${send_retv} ${signature_call_conv} 132 send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4}); 133 int main(void) { 134 ${send_arg1} s=0; 135 ${send_arg2} buf=0; 136 ${send_arg3} len=0; 137 ${send_arg4} flags=0; 138 ${send_retv} res = send(s, buf, len, flags); 139 (void) res; 140 return 0; 141 }" 142 curl_cv_func_send_test) 143 message(STATUS 144 "Tested: ${send_retv} send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4})") 145 if(curl_cv_func_send_test) 146 string(REGEX REPLACE "(const) .*" "\\1" send_qual_arg2 "${send_arg2}") 147 string(REGEX REPLACE "const (.*)" "\\1" send_arg2 "${send_arg2}") 148 set(curl_cv_func_send_args 149 "${send_arg1},${send_arg2},${send_arg3},${send_arg4},${send_retv},${send_qual_arg2}" PARENT_SCOPE) 150 set(SEND_TYPE_ARG1 "${send_arg1}" PARENT_SCOPE) 151 set(SEND_TYPE_ARG2 "${send_arg2}" PARENT_SCOPE) 152 set(SEND_TYPE_ARG3 "${send_arg3}" PARENT_SCOPE) 153 set(SEND_TYPE_ARG4 "${send_arg4}" PARENT_SCOPE) 154 set(SEND_TYPE_RETV "${send_retv}" PARENT_SCOPE) 155 set(HAVE_SEND 1 PARENT_SCOPE) 156 set(curl_cv_func_send_done 1 PARENT_SCOPE) 157 endif() 158endfunction() 159 160check_c_source_compiles("${_source_epilogue} 161int main(void) { 162 send(0, 0, 0, 0); 163 return 0; 164}" curl_cv_send) 165if(curl_cv_send) 166 if(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown") 167 if(APPLE) 168 curl_cv_func_send_run_test("ssize_t" "int" "const void *" "size_t" "int") 169 endif() 170 foreach(send_retv "int" "ssize_t" ) 171 foreach(send_arg1 "SOCKET" "int" "ssize_t" ) 172 foreach(send_arg2 "const char *" "const void *" "void *" "char *") 173 foreach(send_arg3 "int" "size_t" "socklen_t" "unsigned int") 174 foreach(send_arg4 "int" "unsigned int") 175 if(NOT curl_cv_func_send_done) 176 curl_cv_func_send_run_test("${send_retv}" "${send_arg1}" "${send_arg2}" "${send_arg3}" "${send_arg4}") 177 endif() 178 endforeach() 179 endforeach() 180 endforeach() 181 endforeach() 182 endforeach() 183 else() 184 string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG1 "${curl_cv_func_send_args}") 185 string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG2 "${curl_cv_func_send_args}") 186 string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG3 "${curl_cv_func_send_args}") 187 string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG4 "${curl_cv_func_send_args}") 188 string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" SEND_TYPE_RETV "${curl_cv_func_send_args}") 189 string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" SEND_QUAL_ARG2 "${curl_cv_func_send_args}") 190 endif() 191 192 if("${curl_cv_func_send_args}" STREQUAL "unknown") 193 message(FATAL_ERROR "Cannot find proper types to use for send args") 194 endif() 195 set(SEND_QUAL_ARG2 "const") 196else() 197 message(FATAL_ERROR "Unable to link function send") 198endif() 199set(curl_cv_func_send_args "${curl_cv_func_send_args}" CACHE INTERNAL "Arguments for send") 200set(HAVE_SEND 1) 201 202check_c_source_compiles("${_source_epilogue} 203 int main(void) { 204 int flag = MSG_NOSIGNAL; 205 (void)flag; 206 return 0; 207 }" HAVE_MSG_NOSIGNAL) 208 209if(NOT HAVE_WINDOWS_H) 210 add_header_include(HAVE_SYS_TIME_H "sys/time.h") 211 add_header_include(TIME_WITH_SYS_TIME "time.h") 212 add_header_include(HAVE_TIME_H "time.h") 213endif() 214check_c_source_compiles("${_source_epilogue} 215int main(void) { 216 struct timeval ts; 217 ts.tv_sec = 0; 218 ts.tv_usec = 0; 219 (void)ts; 220 return 0; 221}" HAVE_STRUCT_TIMEVAL) 222 223set(HAVE_SIG_ATOMIC_T 1) 224set(CMAKE_REQUIRED_FLAGS) 225if(HAVE_SIGNAL_H) 226 set(CMAKE_REQUIRED_FLAGS "-DHAVE_SIGNAL_H") 227 set(CMAKE_EXTRA_INCLUDE_FILES "signal.h") 228endif() 229check_type_size("sig_atomic_t" SIZEOF_SIG_ATOMIC_T) 230if(HAVE_SIZEOF_SIG_ATOMIC_T) 231 check_c_source_compiles(" 232 #ifdef HAVE_SIGNAL_H 233 # include <signal.h> 234 #endif 235 int main(void) { 236 static volatile sig_atomic_t dummy = 0; 237 (void)dummy; 238 return 0; 239 }" HAVE_SIG_ATOMIC_T_NOT_VOLATILE) 240 if(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE) 241 set(HAVE_SIG_ATOMIC_T_VOLATILE 1) 242 endif() 243endif() 244 245if(HAVE_WINDOWS_H) 246 set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h) 247else() 248 set(CMAKE_EXTRA_INCLUDE_FILES) 249 if(HAVE_SYS_SOCKET_H) 250 set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h) 251 endif() 252endif() 253 254check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE) 255if(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE) 256 set(HAVE_STRUCT_SOCKADDR_STORAGE 1) 257endif() 258 259unset(CMAKE_TRY_COMPILE_TARGET_TYPE) 260 261if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) 262 # if not cross-compilation... 263 include(CheckCSourceRuns) 264 set(CMAKE_REQUIRED_FLAGS "") 265 if(HAVE_SYS_POLL_H) 266 set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H") 267 elseif(HAVE_POLL_H) 268 set(CMAKE_REQUIRED_FLAGS "-DHAVE_POLL_H") 269 endif() 270 check_c_source_runs(" 271 #include <stdlib.h> 272 #include <sys/time.h> 273 274 #ifdef HAVE_SYS_POLL_H 275 # include <sys/poll.h> 276 #elif HAVE_POLL_H 277 # include <poll.h> 278 #endif 279 280 int main(void) 281 { 282 if(0 != poll(0, 0, 10)) { 283 return 1; /* fail */ 284 } 285 else { 286 /* detect the 10.12 poll() breakage */ 287 struct timeval before, after; 288 int rc; 289 size_t us; 290 291 gettimeofday(&before, NULL); 292 rc = poll(NULL, 0, 500); 293 gettimeofday(&after, NULL); 294 295 us = (after.tv_sec - before.tv_sec) * 1000000 + 296 (after.tv_usec - before.tv_usec); 297 298 if(us < 400000) { 299 return 1; 300 } 301 } 302 return 0; 303 }" HAVE_POLL_FINE) 304endif() 305 306