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