Visitar URL original
setopt: return CURLE_NOT_BUILT_IN for known but disabled options by JayRGadekar · Pull Request #23309 · curl/curl · GitHub
Skip to content

setopt: return CURLE_NOT_BUILT_IN for known but disabled options - #23309

Open
JayRGadekar wants to merge 1 commit into
curl:masterfrom
JayRGadekar:setopt-not-built-in
Open

JayRGadekar wants to merge 1 commit into
curl:masterfrom
JayRGadekar:setopt-not-built-in

Conversation

@JayRGadekar

Copy link
Copy Markdown

When libcurl is built without a feature (smtp or proxy support, for
example), curl_easy_setopt() on that feature's options returns
CURLE_UNKNOWN_OPTION, the same as for an option number that does not
exist. The curl_easy_setopt man page says CURLE_NOT_BUILT_IN is returned
for options disabled at build time, and #15472 asks for this (it was
listed in KNOWN_BUGS).

This turns CURLE_UNKNOWN_OPTION into CURLE_NOT_BUILT_IN in
Curl_vsetopt() when curl_easy_option_by_id() knows the option. An option
libcurl does not know at all still returns CURLE_UNKNOWN_OPTION. I removed
the KNOWN_BUGS entry.

Test 1923 sets every known option and fails if any returns
CURLE_UNKNOWN_OPTION. It fails without the change and passes with it.

Tested on Linux (WSL Ubuntu), on a build with many features disabled and
on a full-featured one. On the stripped build, 135 of 312 options returned
CURLE_UNKNOWN_OPTION before and none do now. In the full test suite
everything passes except:

  • test 537 (file descriptor limit here), which fails the same without my
    change
  • test 375 on the stripped build, which also fails on master without my
    change since d8363b7

When libcurl is built with a feature disabled, curl_easy_setopt() on the
options belonging to that feature returned CURLE_UNKNOWN_OPTION, the same
as for an option number libcurl has never heard of. The documentation says
such options return CURLE_NOT_BUILT_IN, and applications cannot tell a
stripped build from an invalid option.

Turn CURLE_UNKNOWN_OPTION into CURLE_NOT_BUILT_IN in Curl_vsetopt() when
curl_easy_option_by_id() knows the option. An option unknown to libcurl
still returns CURLE_UNKNOWN_OPTION.

Add test 1923, which sets every known option and fails if any returns
CURLE_UNKNOWN_OPTION, whatever the build configuration. Remove the
corresponding entry from KNOWN_BUGS.

Ref: curl#15472

This change was made with the help of an AI assistant (Claude).
@github-actions github-actions Bot added the tests label Oct 8, 2026
Comment thread lib/setopt.c
CURLcode result = setopt_dispatch(data, option, param);
/* An option that libcurl knows about, but which is left out of this build
because its feature is disabled, is "not built in" and not "unknown". */
if((result == CURLE_UNKNOWN_OPTION) && curl_easy_option_by_id(option))

@vszakats vszakats Oct 8, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this adding an overhead to all setopt calls after this patch?

Even with a small overhead, it adds up, and may not to be worth
the runtime price in many use-cases.

Also, isn't the not-built-in status decided at build-time? If so, is it
perhaps possible to make the decision to return this status at
build-time too, rather than using the runtime lookup this patch
implements?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking at it. I measured it on a -O2 build: a successful
curl_easy_setopt() takes about 8.5 ns before and about 8.8 ns after, so
the difference is within noise. The lookup only runs when the call would
return CURLE_UNKNOWN_OPTION anyway, so a successful call pays one
comparison and one extra function call. The failing call goes from about
7 ns to about 42 ns.

You are right that this is known at build time. I used the lookup to keep
the diff small, but it also does nothing when libcurl is built with
CURL_DISABLE_GETOPTIONS, where curl_easy_option_by_id() returns NULL.

I can rework it so the decision is made at build time: a switch on the
disabled options, grouped by their CURL_DISABLE_* guard. It is about 180
labels, so a bigger diff. Would you prefer that?

@vszakats vszakats Oct 8, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The trick, I think, is to avoid runtime overhead while also minimizing built-time
branching (and the diff with it) to offer this enhancement. It's also possible there
is no effective way to implement this. My guess is these are the reasons why it's
still on the TODO list.

A build-time solution, if feasible, would also remove the limitation of requiring
CURL_DISABLE_GETOPTION=0.

Curious, are you employing an LLM to make the PR and measurements above?

@JayRGadekar JayRGadekar Oct 8, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The trick, I think, is to avoid runtime overhead while also minimizing built-time branching (and the diff with it) to offer this enhancement. It's also possible there is no effective way to implement this. My guess is these are the reasons why it's still on the TODO list.

Makes sense that there was no forks/prs for this yet

Curious, are you employing an LLM to make the PR and measurements above?

Yes, I am using claude for this and understanding the code myself as I am new to open source contributions and this is my second PR so it really helps me with understanding the bugs and solutions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants