mirror of
https://github.com/open-goal/jak-project
synced 2026-08-06 09:54:10 -04:00
5d5e35fb9b
## Problem Windows builds break with a current local toolchain (Scoop LLVM 22.1.8, CMake 4.4.0, VS 2026), in two independent ways: 1. The build stops at curl's deliberate guard: `#error "no non-blocking method was found/used/set"` in `third-party/curl/lib/nonblock.c`. 2. From the second configure onward, `cmake --build` re-runs CMake in an endless loop (observed 42 consecutive reconfigure cycles in a single build). Likely the same mechanism behind the "endlessly building" VS 2026 note in `docs/setup/dev/vs.md`. ## Root cause 1. `third-party/curl/CMake/CurlTests.c` passes `int *` to `ioctlsocket()`, whose third parameter is `u_long *`. Clang 22 promotes `-Wincompatible-pointer-types` to a hard error in C, so the `HAVE_IOCTLSOCKET_FIONBIO` try_compile silently fails and `curl_config.h` never defines it. Upstream CI does not see this because the windows-2022 runner image ships an older LLVM. GCC 14 promotes the same warning to a hard error, which is very likely the `CurlTests.c.obj` failure reported from MSYS2 in open-goal/jak-project#3551. Upstream curl hit the identical problem with GCC 14 and fixed the probe in curl 8.8.0 (curl/curl#13578). 2. The root CMakeLists copies the build tree's `compile_commands.json` into `<src>/build/` for clangd using `configure_file()`, which registers its input as a configure dependency. CMake rewrites `compile_commands.json` late in every generation, after `CTestTestfile.cmake` and `cmake_install.cmake` (outputs of the same Ninja regen rule), so once the dependency is registered the rule is deterministically dirty and every `ninja` invocation re-runs CMake. A pristine first configure is safe (the file does not exist yet, so the `if(EXISTS ...)` guard skips the copy), which is why the loop looks machine- or IDE-specific. ## Fix 1. Per review, re-vendor `third-party/curl` at the `curl-8_21_0` tag (previously `curl-8_3_0`), which carries the upstream probe fix plus two years of upstream development; `vendor.yaml` updated to match. Adjustments the version jump forced: - curl 8.15 removed the native macOS Secure Transport backend (`CURL_USE_SECTRANSP`), so macOS now builds curl against OpenSSL like Linux. The two macOS workflows install Homebrew `openssl@3` and export `OPENSSL_ROOT_DIR` (keg-only), and the macOS setup docs gained the same two lines. - `CURL_BROTLI` / `CURL_ZSTD` switched to AUTO-detection in curl 8.10; pinned OFF to keep the previous no-compression behavior and avoid silently linking whatever the CI images happen to have. - curl's new top-level `BUILD_EXAMPLES` cache option (default ON) leaked into discord-rpc's identically named option and broke configure at a nonexistent `examples/send-presence` directory; pinned OFF ahead of the third-party subdirectories. The diff is dominated by the mechanical tag-tree swap under `third-party/curl` (linguist-vendored, collapsed in review). The hand-written changes are `CMakeLists.txt`, the two macOS workflows, `docs/setup/system/macos.md`, and `vendor.yaml`. 2. Swap `configure_file()` for `file(COPY ...)`: the same clangd copy with no configure dependency registered. (`file(COPY_FILE ... ONLY_IF_DIFFERENT)` would be cleaner still but requires CMake 3.21, above the declared `cmake_minimum_required(VERSION 3.10)`.) ## Test plan - [x] Fresh `cmake --preset Release-windows-clang` (LLVM 22, no cache seeding) completes and logs `Enabled SSL backends: Schannel`; the FIONBIO probe passes without the previous `#error` - [x] Full Windows Release build from scratch in the branch worktree (all 1422 targets) - [x] goalc-test suite: 1509 passed, 0 failed - [x] Second consecutive configure with `compile_commands.json` present: the regen rule in `build.ninja` has no `compile_commands.json` input; `<src>/build/compile_commands.json` is still refreshed for clangd - [x] Repeated `ninja` invocations after a full build no longer re-run CMake - [x] macOS Intel and ARM CI green (first exercise of the OpenSSL backend switch) --- I work off a self-hosted forge, so this GitHub account is quiet; the configure logs and ninja dirty-node traces from the investigation are available if anyone wants the raw data. (AI-assisted)
297 lines
13 KiB
C
Vendored
Generated
297 lines
13 KiB
C
Vendored
Generated
#ifndef HEADER_CURL_PROTOCOL_H
|
|
#define HEADER_CURL_PROTOCOL_H
|
|
/***************************************************************************
|
|
* _ _ ____ _
|
|
* Project ___| | | | _ \| |
|
|
* / __| | | | |_) | |
|
|
* | (__| |_| | _ <| |___
|
|
* \___|\___/|_| \_\_____|
|
|
*
|
|
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
|
*
|
|
* This software is licensed as described in the file COPYING, which
|
|
* you should have received as part of this distribution. The terms
|
|
* are also available at https://curl.se/docs/copyright.html.
|
|
*
|
|
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
|
* copies of the Software, and permit persons to whom the Software is
|
|
* furnished to do so, under the terms of the COPYING file.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
* SPDX-License-Identifier: curl
|
|
*
|
|
***************************************************************************/
|
|
/* This file is for lib internal stuff */
|
|
#include "curl_setup.h"
|
|
|
|
struct Curl_easy;
|
|
struct connectdata;
|
|
struct easy_pollset;
|
|
|
|
/* Known protocol default port numbers */
|
|
#define PORT_FTP 21
|
|
#define PORT_FTPS 990
|
|
#define PORT_TELNET 23
|
|
#define PORT_HTTP 80
|
|
#define PORT_HTTPS 443
|
|
#define PORT_DICT 2628
|
|
#define PORT_LDAP 389
|
|
#define PORT_LDAPS 636
|
|
#define PORT_TFTP 69
|
|
#define PORT_SSH 22
|
|
#define PORT_IMAP 143
|
|
#define PORT_IMAPS 993
|
|
#define PORT_POP3 110
|
|
#define PORT_POP3S 995
|
|
#define PORT_SMB 445
|
|
#define PORT_SMBS 445
|
|
#define PORT_SMTP 25
|
|
#define PORT_SMTPS 465 /* sometimes called SSMTP */
|
|
#define PORT_RTSP 554
|
|
#define PORT_GOPHER 70
|
|
#define PORT_SOCKS 1080
|
|
#define PORT_MQTT 1883
|
|
#define PORT_MQTTS 8883
|
|
|
|
/* CURLPROTO_GOPHERS (29) is the highest publicly used protocol bit number,
|
|
* the rest are internal information. If we use higher bits we only do this on
|
|
* platforms that have a >= 64-bit type and then we use such a type for the
|
|
* protocol fields in the scheme definition.
|
|
*/
|
|
#define CURLPROTO_WS (1L << 30)
|
|
#define CURLPROTO_WSS ((curl_prot_t)1 << 31)
|
|
#define CURLPROTO_MQTTS (1LL << 32)
|
|
#define CURLPROTO_SOCKS (1LL << 33)
|
|
|
|
#define CURLPROTO_64ALL ((uint64_t)0xffffffffffffffff)
|
|
|
|
/* the default protocols accepting a redirect to */
|
|
#define CURLPROTO_REDIR (CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP | \
|
|
CURLPROTO_FTPS)
|
|
|
|
typedef curl_off_t curl_prot_t;
|
|
|
|
/* This mask is for all the old protocols that are provided and defined in the
|
|
public header and shall exclude protocols added since which are not exposed
|
|
in the API */
|
|
#define CURLPROTO_MASK 0x3fffffff
|
|
|
|
/* Convenience defines for checking protocols or their SSL based version. Each
|
|
protocol scheme should only ever have a single CURLPROTO_ in its protocol
|
|
field. */
|
|
#define PROTO_FAMILY_HTTP (CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_WS | \
|
|
CURLPROTO_WSS)
|
|
#define PROTO_FAMILY_FTP (CURLPROTO_FTP | CURLPROTO_FTPS)
|
|
#define PROTO_FAMILY_POP3 (CURLPROTO_POP3 | CURLPROTO_POP3S)
|
|
#define PROTO_FAMILY_SMB (CURLPROTO_SMB | CURLPROTO_SMBS)
|
|
#define PROTO_FAMILY_SMTP (CURLPROTO_SMTP | CURLPROTO_SMTPS)
|
|
#define PROTO_FAMILY_SSH (CURLPROTO_SCP | CURLPROTO_SFTP)
|
|
|
|
#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) || \
|
|
!defined(CURL_DISABLE_POP3)
|
|
/* these protocols support CURLOPT_DIRLISTONLY */
|
|
#define CURL_LIST_ONLY_PROTOCOL 1
|
|
#endif
|
|
|
|
/* When redirecting transfers. */
|
|
typedef enum {
|
|
FOLLOW_NONE, /* not used within the function, a placeholder to allow
|
|
initing to this */
|
|
FOLLOW_FAKE, /* only records stuff, not actually following */
|
|
FOLLOW_RETRY, /* set if this is a request retry as opposed to a real
|
|
redirect following */
|
|
FOLLOW_REDIR /* a full true redirect */
|
|
} followtype;
|
|
|
|
typedef enum {
|
|
DOMORE_GOBACK = -1,
|
|
DOMORE_INCOMPLETE = 0,
|
|
DOMORE_DONE = 1
|
|
} domore;
|
|
|
|
/*
|
|
* Specific protocol handler, an implementation of one or more URI schemes.
|
|
*/
|
|
struct Curl_protocol {
|
|
/* Complement to setup_connection_internals(). This is done before the
|
|
transfer "owns" the connection. */
|
|
CURLcode (*setup_connection)(struct Curl_easy *data,
|
|
struct connectdata *conn);
|
|
|
|
/* These two functions MUST be set to be protocol dependent */
|
|
CURLcode (*do_it)(struct Curl_easy *data, bool *done);
|
|
CURLcode (*done)(struct Curl_easy *, CURLcode, bool);
|
|
|
|
/* If the curl_do() function is better made in two halves, this
|
|
* curl_do_more() function will be called afterwards, if set. For example
|
|
* for doing the FTP stuff after the PASV/PORT command. The second
|
|
* argument is an output parameter that MUST be set to one of the
|
|
* DOMORE_* values: DOMORE_INCOMPLETE if more do_more work remains,
|
|
* DOMORE_DONE when the second phase is complete, or DOMORE_GOBACK
|
|
* to return to the regular DO/DOING handling.
|
|
*/
|
|
CURLcode (*do_more)(struct Curl_easy *, domore *);
|
|
|
|
/* This function *MAY* be set to a protocol-dependent function that is run
|
|
* after the connect() and everything is done, as a step in the connection.
|
|
* The 'done' pointer points to a bool that should be set to TRUE if the
|
|
* function completes before return. If it does not complete, the caller
|
|
* should call the ->connecting() function until it is.
|
|
*/
|
|
CURLcode (*connect_it)(struct Curl_easy *data, bool *done);
|
|
|
|
/* See above. */
|
|
CURLcode (*connecting)(struct Curl_easy *data, bool *done);
|
|
CURLcode (*doing)(struct Curl_easy *data, bool *done);
|
|
|
|
/* Called from the multi interface during the PROTOCONNECT phase, and it
|
|
should then return a proper fd set */
|
|
CURLcode (*proto_pollset)(struct Curl_easy *data,
|
|
struct easy_pollset *ps);
|
|
|
|
/* Called from the multi interface during the DOING phase, and it should
|
|
then return a proper fd set */
|
|
CURLcode (*doing_pollset)(struct Curl_easy *data,
|
|
struct easy_pollset *ps);
|
|
|
|
/* Called from the multi interface during the DO_MORE phase, and it should
|
|
then return a proper fd set */
|
|
CURLcode (*domore_pollset)(struct Curl_easy *data,
|
|
struct easy_pollset *ps);
|
|
|
|
/* Called from the multi interface during the DO_DONE, PERFORM and
|
|
WAITPERFORM phases, and it should then return a proper fd set. Not setting
|
|
this will make libcurl use the generic default one. */
|
|
CURLcode (*perform_pollset)(struct Curl_easy *data,
|
|
struct easy_pollset *ps);
|
|
|
|
/* This function *MAY* be set to a protocol-dependent function that is run
|
|
* by the curl_disconnect(), as a step in the disconnection. If the handler
|
|
* is called because the connection has been considered dead,
|
|
* dead_connection is set to TRUE. The connection is (again) associated with
|
|
* the transfer here.
|
|
*/
|
|
CURLcode (*disconnect)(struct Curl_easy *, struct connectdata *,
|
|
bool dead_connection);
|
|
|
|
/* If used, this function gets called from transfer.c to
|
|
allow the protocol to do extra handling in writing response to
|
|
the client. */
|
|
CURLcode (*write_resp)(struct Curl_easy *data, const char *buf, size_t blen,
|
|
bool is_eos);
|
|
|
|
/* If used, this function gets called from transfer.c to
|
|
allow the protocol to do extra handling in writing a single response
|
|
header line to the client. */
|
|
CURLcode (*write_resp_hd)(struct Curl_easy *data,
|
|
const char *hd, size_t hdlen, bool is_eos);
|
|
|
|
/* If used, this function checks for a connection managed by this
|
|
protocol and currently not in use, if it should be considered dead. */
|
|
bool (*connection_is_dead)(struct Curl_easy *data,
|
|
struct connectdata *conn);
|
|
|
|
/* attach() attaches this transfer to this connection */
|
|
void (*attach)(struct Curl_easy *data, struct connectdata *conn);
|
|
|
|
/* return CURLE_OK if a redirect to `newurl` should be followed,
|
|
CURLE_TOO_MANY_REDIRECTS otherwise. May alter `data` to change
|
|
the way the follow request is performed. */
|
|
CURLcode (*follow)(struct Curl_easy *data, const char *newurl,
|
|
followtype type);
|
|
};
|
|
|
|
#define PROTOPT_NONE 0 /* nothing extra */
|
|
#define PROTOPT_SSL (1 << 0) /* uses SSL */
|
|
#define PROTOPT_DUAL (1 << 1) /* this protocol uses two connections */
|
|
#define PROTOPT_CLOSEACTION (1 << 2) /* need action before socket close */
|
|
/* some protocols will have to call the underlying functions without regard to
|
|
what exact state the socket signals. IE even if the socket says "readable",
|
|
the send function might need to be called while uploading, or vice versa.
|
|
*/
|
|
#define PROTOPT_DIRLOCK (1 << 3)
|
|
#define PROTOPT_NONETWORK (1 << 4) /* protocol does not use the network! */
|
|
#define PROTOPT_NEEDSPWD (1 << 5) /* needs a password, and if none is set it
|
|
gets a default */
|
|
#define PROTOPT_NOURLQUERY (1 << 6) /* protocol cannot handle
|
|
URL query strings (?foo=bar) ! */
|
|
#define PROTOPT_CREDSPERREQUEST (1 << 7) /* requires login credentials per
|
|
request instead of per
|
|
connection */
|
|
#define PROTOPT_ALPN (1 << 8) /* set ALPN for this */
|
|
/* (1 << 9) was PROTOPT_STREAM, now free */
|
|
#define PROTOPT_URLOPTIONS (1 << 10) /* allow options part in the userinfo
|
|
field of the URL */
|
|
#define PROTOPT_PROXY_AS_HTTP (1 << 11) /* allow this non-HTTP scheme over a
|
|
HTTP proxy as HTTP proxies may know
|
|
this protocol and act as
|
|
a gateway */
|
|
#define PROTOPT_WILDCARD (1 << 12) /* protocol supports wildcard matching */
|
|
#define PROTOPT_USERPWDCTRL (1 << 13) /* Allow "control bytes" (< 32 ASCII) in
|
|
username and password */
|
|
#define PROTOPT_NOTCPPROXY (1 << 14) /* this protocol cannot proxy over TCP */
|
|
#define PROTOPT_SSL_REUSE (1 << 15) /* this protocol may reuse an existing
|
|
SSL connection in the same family
|
|
without having PROTOPT_SSL. */
|
|
#define PROTOPT_CONN_REUSE (1 << 16) /* this protocol can reuse connections */
|
|
#define PROTOPT_NO_TRANSFER (1 << 17) /* this protocol is not for transfers */
|
|
#define PROTOPT_HTTP_PROXY_TUNNEL (1 << 18) /* Using this protocol with a
|
|
* HTTP proxy requires tunneling */
|
|
|
|
/* Everything about a URI scheme. */
|
|
struct Curl_scheme {
|
|
const char *name; /* URL scheme name in lowercase */
|
|
const struct Curl_protocol *run; /* implementation, optional */
|
|
curl_prot_t protocol; /* See CURLPROTO_* - this needs to be the single
|
|
specific protocol bit */
|
|
curl_prot_t family; /* single bit for protocol family; the non-TLS name
|
|
of the protocol this is */
|
|
uint32_t flags; /* Extra particular characteristics, see PROTOPT_* */
|
|
uint16_t defport; /* Default port. */
|
|
};
|
|
|
|
/* Get scheme definition for a URI scheme name
|
|
* @param scheme URI scheme name, case-insensitive
|
|
* @return NULL if scheme is not known
|
|
*/
|
|
const struct Curl_scheme *Curl_get_scheme(const char *scheme);
|
|
const struct Curl_scheme *Curl_getn_scheme(const char *scheme, size_t len);
|
|
|
|
/* For direct access to a URI scheme */
|
|
extern const struct Curl_scheme Curl_scheme_dict;
|
|
extern const struct Curl_scheme Curl_scheme_file;
|
|
extern const struct Curl_scheme Curl_scheme_ftp;
|
|
extern const struct Curl_scheme Curl_scheme_ftps;
|
|
extern const struct Curl_scheme Curl_scheme_gopher;
|
|
extern const struct Curl_scheme Curl_scheme_gophers;
|
|
extern const struct Curl_scheme Curl_scheme_http;
|
|
extern const struct Curl_scheme Curl_scheme_https;
|
|
extern const struct Curl_scheme Curl_scheme_imap;
|
|
extern const struct Curl_scheme Curl_scheme_imaps;
|
|
extern const struct Curl_scheme Curl_scheme_ldap;
|
|
extern const struct Curl_scheme Curl_scheme_ldaps;
|
|
extern const struct Curl_scheme Curl_scheme_mqtt;
|
|
extern const struct Curl_scheme Curl_scheme_mqtts;
|
|
extern const struct Curl_scheme Curl_scheme_pop3;
|
|
extern const struct Curl_scheme Curl_scheme_pop3s;
|
|
extern const struct Curl_scheme Curl_scheme_rtsp;
|
|
extern const struct Curl_scheme Curl_scheme_scp;
|
|
extern const struct Curl_scheme Curl_scheme_sftp;
|
|
extern const struct Curl_scheme Curl_scheme_smb;
|
|
extern const struct Curl_scheme Curl_scheme_smbs;
|
|
extern const struct Curl_scheme Curl_scheme_smtp;
|
|
extern const struct Curl_scheme Curl_scheme_smtps;
|
|
extern const struct Curl_scheme Curl_scheme_socks;
|
|
extern const struct Curl_scheme Curl_scheme_socks4;
|
|
extern const struct Curl_scheme Curl_scheme_socks4a;
|
|
extern const struct Curl_scheme Curl_scheme_socks5;
|
|
extern const struct Curl_scheme Curl_scheme_socks5h;
|
|
extern const struct Curl_scheme Curl_scheme_telnet;
|
|
extern const struct Curl_scheme Curl_scheme_tftp;
|
|
extern const struct Curl_scheme Curl_scheme_ws;
|
|
extern const struct Curl_scheme Curl_scheme_wss;
|
|
|
|
#endif /* HEADER_CURL_PROTOCOL_H */
|