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 set(_source_epilogue 37 "${_source_epilogue}\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif") 38 set(signature_call_conv "PASCAL") 39 if(HAVE_LIBWS2_32) 40 set(CMAKE_REQUIRED_LIBRARIES ws2_32) 41 endif() 42else() 43 add_header_include(HAVE_SYS_TYPES_H "sys/types.h") 44 add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h") 45endif() 46 47set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) 48 49function(curl_cv_func_recv_run_test recv_retv recv_arg1 recv_arg2 recv_arg3 recv_arg4) 50 unset(curl_cv_func_recv_test CACHE) 51 check_c_source_compiles(" 52 ${_source_epilogue} 53 #ifdef WINSOCK_API_LINKAGE 54 WINSOCK_API_LINKAGE 55 #endif 56 extern ${recv_retv} ${signature_call_conv} 57 recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4}); 58 int main(void) { 59 ${recv_arg1} s=0; 60 ${recv_arg2} buf=0; 61 ${recv_arg3} len=0; 62 ${recv_arg4} flags=0; 63 ${recv_retv} res = recv(s, buf, len, flags); 64 (void) res; 65 return 0; 66 }" 67 curl_cv_func_recv_test) 68 message(STATUS 69 "Tested: ${recv_retv} recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4})") 70 if(curl_cv_func_recv_test) 71 set(curl_cv_func_recv_args 72 "${recv_arg1},${recv_arg2},${recv_arg3},${recv_arg4},${recv_retv}" PARENT_SCOPE) 73 set(RECV_TYPE_ARG1 "${recv_arg1}" PARENT_SCOPE) 74 set(RECV_TYPE_ARG2 "${recv_arg2}" PARENT_SCOPE) 75 set(RECV_TYPE_ARG3 "${recv_arg3}" PARENT_SCOPE) 76 set(RECV_TYPE_ARG4 "${recv_arg4}" PARENT_SCOPE) 77 set(RECV_TYPE_RETV "${recv_retv}" PARENT_SCOPE) 78 set(HAVE_RECV 1 PARENT_SCOPE) 79 set(curl_cv_func_recv_done 1 PARENT_SCOPE) 80 endif() 81endfunction() 82 83check_c_source_compiles("${_source_epilogue} 84int main(void) { 85 recv(0, 0, 0, 0); 86 return 0; 87}" curl_cv_recv) 88if(curl_cv_recv) 89 if(NOT DEFINED curl_cv_func_recv_args OR curl_cv_func_recv_args STREQUAL "unknown") 90 if(APPLE) 91 curl_cv_func_recv_run_test("ssize_t" "int" "void *" "size_t" "int") 92 endif() 93 foreach(recv_retv "int" "ssize_t" ) 94 foreach(recv_arg1 "SOCKET" "int" ) 95 foreach(recv_arg2 "char *" "void *" ) 96 foreach(recv_arg3 "int" "size_t" "socklen_t" "unsigned int") 97 foreach(recv_arg4 "int" "unsigned int") 98 if(NOT curl_cv_func_recv_done) 99 curl_cv_func_recv_run_test(${recv_retv} ${recv_arg1} ${recv_arg2} ${recv_arg3} ${recv_arg4}) 100 endif() 101 endforeach() 102 endforeach() 103 endforeach() 104 endforeach() 105 endforeach() 106 else() 107 string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG1 "${curl_cv_func_recv_args}") 108 string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG2 "${curl_cv_func_recv_args}") 109 string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG3 "${curl_cv_func_recv_args}") 110 string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" RECV_TYPE_ARG4 "${curl_cv_func_recv_args}") 111 string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" RECV_TYPE_RETV "${curl_cv_func_recv_args}") 112 endif() 113 114 if(curl_cv_func_recv_args STREQUAL "unknown") 115 message(FATAL_ERROR "Cannot find proper types to use for recv args") 116 endif() 117else() 118 message(FATAL_ERROR "Unable to link function recv") 119endif() 120set(curl_cv_func_recv_args "${curl_cv_func_recv_args}" CACHE INTERNAL "Arguments for recv") 121set(HAVE_RECV 1) 122 123function(curl_cv_func_send_run_test send_retv send_arg1 send_arg2 send_arg3 send_arg4) 124 unset(curl_cv_func_send_test CACHE) 125 check_c_source_compiles(" 126 ${_source_epilogue} 127 #ifdef WINSOCK_API_LINKAGE 128 WINSOCK_API_LINKAGE 129 #endif 130 extern ${send_retv} ${signature_call_conv} 131 send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4}); 132 int main(void) { 133 ${send_arg1} s=0; 134 ${send_arg2} buf=0; 135 ${send_arg3} len=0; 136 ${send_arg4} flags=0; 137 ${send_retv} res = send(s, buf, len, flags); 138 (void) res; 139 return 0; 140 }" 141 curl_cv_func_send_test) 142 message(STATUS 143 "Tested: ${send_retv} send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4})") 144 if(curl_cv_func_send_test) 145 string(REGEX REPLACE "(const) .*" "\\1" send_qual_arg2 "${send_arg2}") 146 string(REGEX REPLACE "const (.*)" "\\1" send_arg2 "${send_arg2}") 147 set(curl_cv_func_send_args 148 "${send_arg1},${send_arg2},${send_arg3},${send_arg4},${send_retv},${send_qual_arg2}" PARENT_SCOPE) 149 set(SEND_TYPE_ARG1 "${send_arg1}" PARENT_SCOPE) 150 set(SEND_TYPE_ARG2 "${send_arg2}" PARENT_SCOPE) 151 set(SEND_TYPE_ARG3 "${send_arg3}" PARENT_SCOPE) 152 set(SEND_TYPE_ARG4 "${send_arg4}" PARENT_SCOPE) 153 set(SEND_TYPE_RETV "${send_retv}" PARENT_SCOPE) 154 set(HAVE_SEND 1 PARENT_SCOPE) 155 set(curl_cv_func_send_done 1 PARENT_SCOPE) 156 endif() 157endfunction() 158 159check_c_source_compiles("${_source_epilogue} 160int main(void) { 161 send(0, 0, 0, 0); 162 return 0; 163}" curl_cv_send) 164if(curl_cv_send) 165 if(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown") 166 if(APPLE) 167 curl_cv_func_send_run_test("ssize_t" "int" "const void *" "size_t" "int") 168 endif() 169 foreach(send_retv "int" "ssize_t" ) 170 foreach(send_arg1 "SOCKET" "int" "ssize_t" ) 171 foreach(send_arg2 "const char *" "const void *" "void *" "char *") 172 foreach(send_arg3 "int" "size_t" "socklen_t" "unsigned int") 173 foreach(send_arg4 "int" "unsigned int") 174 if(NOT curl_cv_func_send_done) 175 curl_cv_func_send_run_test("${send_retv}" "${send_arg1}" "${send_arg2}" "${send_arg3}" "${send_arg4}") 176 endif() 177 endforeach() 178 endforeach() 179 endforeach() 180 endforeach() 181 endforeach() 182 else() 183 string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG1 "${curl_cv_func_send_args}") 184 string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG2 "${curl_cv_func_send_args}") 185 string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG3 "${curl_cv_func_send_args}") 186 string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG4 "${curl_cv_func_send_args}") 187 string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" SEND_TYPE_RETV "${curl_cv_func_send_args}") 188 string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" SEND_QUAL_ARG2 "${curl_cv_func_send_args}") 189 endif() 190 191 if("${curl_cv_func_send_args}" STREQUAL "unknown") 192 message(FATAL_ERROR "Cannot find proper types to use for send args") 193 endif() 194 set(SEND_QUAL_ARG2 "const") 195else() 196 message(FATAL_ERROR "Unable to link function send") 197endif() 198set(curl_cv_func_send_args "${curl_cv_func_send_args}" CACHE INTERNAL "Arguments for send") 199set(HAVE_SEND 1) 200 201check_c_source_compiles("${_source_epilogue} 202 int main(void) { 203 int flag = MSG_NOSIGNAL; 204 (void)flag; 205 return 0; 206 }" HAVE_MSG_NOSIGNAL) 207 208if(NOT HAVE_WINDOWS_H) 209 add_header_include(HAVE_SYS_TIME_H "sys/time.h") 210 add_header_include(TIME_WITH_SYS_TIME "time.h") 211 add_header_include(HAVE_TIME_H "time.h") 212endif() 213check_c_source_compiles("${_source_epilogue} 214int main(void) { 215 struct timeval ts; 216 ts.tv_sec = 0; 217 ts.tv_usec = 0; 218 (void)ts; 219 return 0; 220}" HAVE_STRUCT_TIMEVAL) 221 222if(HAVE_WINDOWS_H) 223 set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h) 224else() 225 set(CMAKE_EXTRA_INCLUDE_FILES) 226 if(HAVE_SYS_SOCKET_H) 227 set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h) 228 endif() 229endif() 230 231check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE) 232if(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE) 233 set(HAVE_STRUCT_SOCKADDR_STORAGE 1) 234endif() 235 236unset(CMAKE_TRY_COMPILE_TARGET_TYPE) 237 238if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) 239 if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 240 # only try this on non-macOS 241 242 # if not cross-compilation... 243 include(CheckCSourceRuns) 244 set(CMAKE_REQUIRED_FLAGS "") 245 if(HAVE_SYS_POLL_H) 246 set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H") 247 elseif(HAVE_POLL_H) 248 set(CMAKE_REQUIRED_FLAGS "-DHAVE_POLL_H") 249 endif() 250 check_c_source_runs(" 251 #include <stdlib.h> 252 #include <sys/time.h> 253 254 #ifdef HAVE_SYS_POLL_H 255 # include <sys/poll.h> 256 #elif HAVE_POLL_H 257 # include <poll.h> 258 #endif 259 260 int main(void) 261 { 262 if(0 != poll(0, 0, 10)) { 263 return 1; /* fail */ 264 } 265 else { 266 /* detect the 10.12 poll() breakage */ 267 struct timeval before, after; 268 int rc; 269 size_t us; 270 271 gettimeofday(&before, NULL); 272 rc = poll(NULL, 0, 500); 273 gettimeofday(&after, NULL); 274 275 us = (after.tv_sec - before.tv_sec) * 1000000 + 276 (after.tv_usec - before.tv_usec); 277 278 if(us < 400000) { 279 return 1; 280 } 281 } 282 return 0; 283 }" HAVE_POLL_FINE) 284 endif() 285endif() 286 287