libzypp 17.38.15
curl_dl.cc File Reference

Load libcurl with dlopen() on first use instead of a DT_NEEDED entry. More...

#include <curl/curl.h>
#include <dlfcn.h>
#include <pthread.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
Include dependency graph for curl_dl.cc:

Go to the source code of this file.

Macros

#define ZYPP_CURL_SONAME   "libcurl.so.4"
#define CURL_DL_HIDDEN   __attribute__((visibility("hidden")))
#define CURL_DL_FN(ret, name, proto, args)
#define CURL_DL_FN_VOID(name, proto, args)

Functions

 CURL_DL_FN (CURLcode, curl_global_init,(long flags),(flags)) CURL_DL_FN(CURL *
 CURL_DL_FN_VOID (curl_easy_cleanup,(CURL *handle),(handle)) CURL_DL_FN_VOID(curl_easy_reset
CURL handle CURL_DL_FN (const char *, curl_easy_strerror,(CURLcode code),(code)) CURL_DL_FN_VOID(curl_free
CURL handle void p CURL_DL_FN (char *, curl_unescape,(const char *str, int length),(str, length)) CURL_DL_FN(curl_version_info_data *
CURL handle void p CURLversion age CURL_DL_FN (struct curl_slist *, curl_slist_append,(struct curl_slist *list, const char *str),(list, str)) CURL_DL_FN_VOID(curl_slist_free_all
CURL handle void p CURLversion age struct curl_slist list CURL_DL_FN (CURLM *, curl_multi_init,(void),()) CURL_DL_FN(CURLMcode
CURL handle void p CURLversion age struct curl_slist list CURLM multi CURL_DL_FN (CURLMcode, curl_multi_add_handle,(CURLM *multi, CURL *handle),(multi, handle)) CURL_DL_FN(CURLMcode
CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle CURL_DL_FN (CURLMsg *, curl_multi_info_read,(CURLM *multi, int *msgs_in_queue),(multi, msgs_in_queue)) CURL_DL_FN(CURLMcode
CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle CURLM curl_socket_t int int running_handles CURL_DL_FN (const char *, curl_multi_strerror,(CURLMcode code),(code)) CURL_DL_HIDDEN CURLcode curl_easy_getinfo(CURL *handle
 if (!fn) *(void **) &fn
 va_start (ap, info)
 va_end (ap)
return fn (handle, info, arg)
CURL_DL_HIDDEN CURLcode curl_easy_setopt (CURL *handle, CURLoption option,...)
CURL_DL_HIDDEN CURLMcode curl_multi_setopt (CURLM *multi, CURLMoption option,...)

Variables

 curl_easy_init
 void
CURL * handle
CURL handle void * p
CURL handle void p curl_version_info
CURL handle void p CURLversion age
CURL handle void p CURLversion age struct curl_slist * list
CURL handle void p CURLversion age struct curl_slist list curl_multi_cleanup
CURL handle void p CURLversion age struct curl_slist list CURLM * multi
CURL handle void p CURLversion age struct curl_slist list CURLM multi curl_multi_remove_handle
CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle curl_multi_socket_action
CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle CURLM curl_socket_t s
CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle CURLM curl_socket_t int ev_bitmask
CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle CURLM curl_socket_t int int * running_handles
CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle CURLM curl_socket_t int int running_handles CURLINFO info
CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle CURLM curl_socket_t int int running_handles CURLINFO va_list ap
void * arg = va_arg( ap, void * )

Detailed Description

Load libcurl with dlopen() on first use instead of a DT_NEEDED entry.

The distro libcurl pulls ~30 shared objects (TLS, ssh, ldap, idn, kerberos, ...) into every process that links it, costing ~2ms of startup per exec - paid even by runs that never touch the network (zypper –help, cached info/search).

This file defines every libcurl symbol libzypp references. Each wrapper resolves the real function from libcurl.so.4 on first call, so the library and its dependency closure are only mapped when a download actually happens. All other code keeps calling plain curl_* functions and stays oblivious.

Keep the list in sync with the real usage: nm -D –undefined-only libzypp.so | grep ' curl_' A missing wrapper resurfaces as a DT_NEEDED on libcurl again (the linker pulls it from CURL_LIBRARIES if someone re-adds it) or as a link error, never as silent misbehavior. A libcurl that cannot be loaded at all, or that lacks one of these symbols, aborts with a message on first use - the same outcome the dynamic loader produced while libcurl was a DT_NEEDED entry, just deferred.

Correctness here depends on libzypp being built with hidden visibility (ENABLE_VISIBILITY_HIDDEN): these definitions must not be exported, or they would interpose libcurl's own intra-library calls.

curl_easy_setopt, curl_multi_setopt and curl_easy_getinfo are variadic in the libcurl ABI. getinfo always takes one pointer; the setopt argument class is defined by the CURLOPTTYPE_* range of the option id, exactly the rule libcurl documents for bindings.

Definition in file curl_dl.cc.

Macro Definition Documentation

◆ ZYPP_CURL_SONAME

#define ZYPP_CURL_SONAME   "libcurl.so.4"

Definition at line 54 of file curl_dl.cc.

◆ CURL_DL_HIDDEN

#define CURL_DL_HIDDEN   __attribute__((visibility("hidden")))

Definition at line 113 of file curl_dl.cc.

◆ CURL_DL_FN

#define CURL_DL_FN ( ret,
name,
proto,
args )
Value:
CURL_DL_HIDDEN ret name proto \
{ \
static ret (*fn) proto; \
if ( !fn ) \
*(void **)&fn = curl_dl_sym( #name ); \
return fn args; \
}
return fn(handle, info, arg)
#define CURL_DL_HIDDEN
Definition curl_dl.cc:113

Definition at line 116 of file curl_dl.cc.

◆ CURL_DL_FN_VOID

#define CURL_DL_FN_VOID ( name,
proto,
args )
Value:
CURL_DL_HIDDEN void name proto \
{ \
static void (*fn) proto; \
if ( !fn ) \
*(void **)&fn = curl_dl_sym( #name ); \
fn args; \
}
void
Definition curl_dl.cc:137

Definition at line 126 of file curl_dl.cc.

Function Documentation

◆ CURL_DL_FN() [1/8]

CURL_DL_FN ( CURLcode ,
curl_global_init ,
(long flags) ,
(flags)  )

◆ CURL_DL_FN_VOID()

CURL_DL_FN_VOID ( curl_easy_cleanup ,
(CURL *handle) ,
(handle)  )

◆ CURL_DL_FN() [2/8]

CURL handle CURL_DL_FN ( const char * ,
curl_easy_strerror ,
(CURLcode code) ,
(code)  )

◆ CURL_DL_FN() [3/8]

CURL handle void p CURL_DL_FN ( char * ,
curl_unescape ,
(const char *str, int length) ,
(str, length)  )

◆ CURL_DL_FN() [4/8]

CURL handle void p CURLversion age CURL_DL_FN ( struct curl_slist * ,
curl_slist_append ,
(struct curl_slist *list, const char *str) ,
(list, str)  )

◆ CURL_DL_FN() [5/8]

CURL handle void p CURLversion age struct curl_slist list CURL_DL_FN ( CURLM * ,
curl_multi_init ,
(void) ,
()  )

◆ CURL_DL_FN() [6/8]

CURL handle void p CURLversion age struct curl_slist list CURLM multi CURL_DL_FN ( CURLMcode ,
curl_multi_add_handle ,
(CURLM *multi, CURL *handle) ,
(multi, handle)  )

◆ CURL_DL_FN() [7/8]

CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle CURL_DL_FN ( CURLMsg * ,
curl_multi_info_read ,
(CURLM *multi, int *msgs_in_queue) ,
(multi, msgs_in_queue)  )

◆ CURL_DL_FN() [8/8]

CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle CURLM curl_socket_t int int running_handles CURL_DL_FN ( const char * ,
curl_multi_strerror ,
(CURLMcode code) ,
(code)  )

◆ if()

if ( ! fn) &

◆ va_start()

va_start ( ap ,
info  )

◆ va_end()

va_end ( ap )

◆ fn()

return fn ( handle ,
info ,
arg  )

◆ curl_easy_setopt()

CURL_DL_HIDDEN CURLcode curl_easy_setopt ( CURL * handle,
CURLoption option,
... )

Definition at line 173 of file curl_dl.cc.

◆ curl_multi_setopt()

CURL_DL_HIDDEN CURLMcode curl_multi_setopt ( CURLM * multi,
CURLMoption option,
... )

Definition at line 193 of file curl_dl.cc.

Variable Documentation

◆ curl_easy_init

curl_easy_init

Definition at line 137 of file curl_dl.cc.

◆ void

void

Definition at line 137 of file curl_dl.cc.

◆ handle

CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL * handle

Definition at line 139 of file curl_dl.cc.

◆ p

CURL handle void* p

Definition at line 142 of file curl_dl.cc.

◆ curl_version_info

CURL handle void p curl_version_info

Definition at line 144 of file curl_dl.cc.

◆ age

CURL handle void p CURLversion age

Definition at line 144 of file curl_dl.cc.

◆ list

CURL handle void p CURLversion age struct curl_slist* list

Definition at line 147 of file curl_dl.cc.

◆ curl_multi_cleanup

CURL handle void p CURLversion age struct curl_slist list curl_multi_cleanup

Definition at line 150 of file curl_dl.cc.

◆ multi

CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle CURLM curl_socket_t int int multi

Definition at line 150 of file curl_dl.cc.

◆ curl_multi_remove_handle

CURL handle void p CURLversion age struct curl_slist list CURLM multi curl_multi_remove_handle

Definition at line 152 of file curl_dl.cc.

◆ curl_multi_socket_action

CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle curl_multi_socket_action

Definition at line 154 of file curl_dl.cc.

◆ s

CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle CURLM curl_socket_t int int s

Definition at line 154 of file curl_dl.cc.

◆ ev_bitmask

CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle CURLM curl_socket_t int int ev_bitmask

Definition at line 154 of file curl_dl.cc.

◆ running_handles

CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle CURLM curl_socket_t int int* running_handles

Definition at line 154 of file curl_dl.cc.

◆ info

CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle CURLM curl_socket_t int int running_handles CURLINFO info

Definition at line 160 of file curl_dl.cc.

◆ ap

CURL handle void p CURLversion age struct curl_slist list CURLM multi CURLM CURL handle CURLM curl_socket_t int int running_handles CURLINFO va_list ap
Initial value:
{
static CURLcode (*fn)( CURL *, CURLINFO, ... )

Definition at line 163 of file curl_dl.cc.

◆ arg

arg = va_arg( ap, void * )

Definition at line 164 of file curl_dl.cc.