libzypp 17.38.15
curl_dl.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
35
36#include <curl/curl.h>
37
38#include <dlfcn.h>
39#include <pthread.h>
40#include <stdarg.h>
41#include <stdio.h>
42
43/* curl.h installs call-site typecheck macros for these */
44#undef curl_easy_setopt
45#undef curl_easy_getinfo
46#undef curl_multi_setopt
47#undef curl_share_setopt
48
49namespace {
50
51void * curl_dl_handle = nullptr;
52pthread_once_t curl_dl_once = PTHREAD_ONCE_INIT;
53
54extern "C" void curl_dl_open()
55{
56 curl_dl_handle = dlopen( "libcurl.so.4", RTLD_LAZY | RTLD_LOCAL );
57 if ( !curl_dl_handle )
58 fprintf( stderr, "libzypp: dlopen(libcurl.so.4): %s\n", dlerror() );
59}
60
61void * curl_dl_sym( const char * name )
62{
63 pthread_once( &curl_dl_once, curl_dl_open );
64 return curl_dl_handle ? dlsym( curl_dl_handle, name ) : nullptr;
65}
66
67} // namespace
68
69/* Wrapper for a non-variadic function returning a value. */
70#define CURL_DL_FN( ret, name, proto, args, errret ) \
71ret name proto \
72{ \
73 static ret (*fn) proto; \
74 if ( !fn ) \
75 *(void **)&fn = curl_dl_sym( #name ); \
76 if ( !fn ) \
77 return errret; \
78 return fn args; \
79}
80
81/* Wrapper for a non-variadic function returning void. */
82#define CURL_DL_FN_VOID( name, proto, args ) \
83void name proto \
84{ \
85 static void (*fn) proto; \
86 if ( !fn ) \
87 *(void **)&fn = curl_dl_sym( #name ); \
88 if ( fn ) \
89 fn args; \
90}
91
92CURL_DL_FN( CURLcode, curl_global_init, (long flags), (flags), CURLE_FAILED_INIT )
93
94CURL_DL_FN( CURL *, curl_easy_init, (void), (), nullptr )
95CURL_DL_FN_VOID( curl_easy_cleanup, (CURL *handle), (handle) )
96CURL_DL_FN_VOID( curl_easy_reset, (CURL *handle), (handle) )
97CURL_DL_FN( const char *, curl_easy_strerror, (CURLcode code), (code), "libcurl is not available" )
98
99CURL_DL_FN_VOID( curl_free, (void *p), (p) )
100CURL_DL_FN( char *, curl_unescape, (const char *str, int length), (str, length), nullptr )
101CURL_DL_FN( curl_version_info_data *, curl_version_info, (CURLversion age), (age), nullptr )
102
103CURL_DL_FN( struct curl_slist *, curl_slist_append, (struct curl_slist *list, const char *str), (list, str), nullptr )
104CURL_DL_FN_VOID( curl_slist_free_all, (struct curl_slist *list), (list) )
105
106CURL_DL_FN( CURLM *, curl_multi_init, (void), (), nullptr )
107CURL_DL_FN( CURLMcode, curl_multi_cleanup, (CURLM *multi), (multi), CURLM_INTERNAL_ERROR )
108CURL_DL_FN( CURLMcode, curl_multi_add_handle, (CURLM *multi, CURL *handle), (multi, handle), CURLM_INTERNAL_ERROR )
109CURL_DL_FN( CURLMcode, curl_multi_remove_handle, (CURLM *multi, CURL *handle), (multi, handle), CURLM_INTERNAL_ERROR )
110CURL_DL_FN( CURLMsg *, curl_multi_info_read, (CURLM *multi, int *msgs_in_queue), (multi, msgs_in_queue), nullptr )
111CURL_DL_FN( CURLMcode, curl_multi_socket_action, (CURLM *multi, curl_socket_t s, int ev_bitmask, int *running_handles), (multi, s, ev_bitmask, running_handles), CURLM_INTERNAL_ERROR )
112CURL_DL_FN( const char *, curl_multi_strerror, (CURLMcode code), (code), "libcurl is not available" )
113
114/* The variadic trio. Forward through a variadic-typed pointer so the
115 * call uses the variadic ABI (%al on x86-64). */
116
117CURLcode curl_easy_getinfo( CURL *handle, CURLINFO info, ... )
118{
119 static CURLcode (*fn)( CURL *, CURLINFO, ... );
120 va_list ap;
121 void *arg;
122 if ( !fn )
123 *(void **)&fn = curl_dl_sym( "curl_easy_getinfo" );
124 if ( !fn )
125 return CURLE_FAILED_INIT;
127 arg = va_arg( ap, void * ); /* always a pointer out-arg */
129 return fn( handle, info, arg );
130}
131
132CURLcode curl_easy_setopt( CURL *handle, CURLoption option, ... )
133{
134 static CURLcode (*fn)( CURL *, CURLoption, ... );
135 va_list ap;
136 CURLcode ret;
137 if ( !fn )
138 *(void **)&fn = curl_dl_sym( "curl_easy_setopt" );
139 if ( !fn )
140 return CURLE_FAILED_INIT;
141 va_start( ap, option );
142 if ( option < CURLOPTTYPE_OBJECTPOINT ) /* long */
143 ret = fn( handle, option, va_arg( ap, long ) );
144 else if ( option < CURLOPTTYPE_OFF_T ) /* object/function pointer */
145 ret = fn( handle, option, va_arg( ap, void * ) );
146 else if ( option < CURLOPTTYPE_BLOB ) /* curl_off_t */
147 ret = fn( handle, option, va_arg( ap, curl_off_t ) );
148 else /* blob pointer */
149 ret = fn( handle, option, va_arg( ap, void * ) );
150 va_end( ap );
151 return ret;
152}
153
154CURLMcode curl_multi_setopt( CURLM *multi, CURLMoption option, ... )
155{
156 static CURLMcode (*fn)( CURLM *, CURLMoption, ... );
157 va_list ap;
158 CURLMcode ret;
159 if ( !fn )
160 *(void **)&fn = curl_dl_sym( "curl_multi_setopt" );
161 if ( !fn )
162 return CURLM_INTERNAL_ERROR;
163 va_start( ap, option );
164 if ( option < CURLOPTTYPE_OBJECTPOINT )
165 ret = fn( multi, option, va_arg( ap, long ) );
166 else if ( option < CURLOPTTYPE_OFF_T )
167 ret = fn( multi, option, va_arg( ap, void * ) );
168 else if ( option < CURLOPTTYPE_BLOB )
169 ret = fn( multi, option, va_arg( ap, curl_off_t ) );
170 else
171 ret = fn( multi, option, va_arg( ap, void * ) );
172 va_end( ap );
173 return ret;
174}
va_start(ap, info)
nullptr CURL handle void p curl_version_info
Definition curl_dl.cc:101
nullptr CURL handle void p CURLversion nullptr struct curl_slist list CURLM CURLM_INTERNAL_ERROR CURLM CURL CURLM_INTERNAL_ERROR CURLM curl_socket_t s
Definition curl_dl.cc:111
nullptr CURL handle void p CURLversion nullptr struct curl_slist list CURLM CURLM_INTERNAL_ERROR CURLM CURL CURLM_INTERNAL_ERROR CURLM curl_socket_t int ev_bitmask
Definition curl_dl.cc:111
nullptr CURL handle void p CURLversion nullptr struct curl_slist list CURLM CURLM_INTERNAL_ERROR curl_multi_remove_handle
Definition curl_dl.cc:109
nullptr CURL handle void p CURLversion nullptr struct curl_slist list curl_multi_cleanup
Definition curl_dl.cc:107
nullptr CURL handle void p CURLversion nullptr struct curl_slist list CURLM CURLM_INTERNAL_ERROR CURLM CURL CURLM_INTERNAL_ERROR curl_multi_socket_action
Definition curl_dl.cc:111
#define CURL_DL_FN(ret, name, proto, args, errret)
Definition curl_dl.cc:70
CURLcode curl_easy_setopt(CURL *handle, CURLoption option,...)
Definition curl_dl.cc:132
nullptr CURL handle void p CURLversion nullptr struct curl_slist list CURLM CURLM_INTERNAL_ERROR CURLM CURL CURLM_INTERNAL_ERROR CURLM curl_socket_t int int CURLM_INTERNAL_ERROR CURLINFO info
Definition curl_dl.cc:117
nullptr CURL handle void p CURLversion nullptr struct curl_slist * list
Definition curl_dl.cc:104
nullptr CURL handle void p CURLversion nullptr struct curl_slist list CURLM * multi
Definition curl_dl.cc:107
nullptr CURL handle void * p
Definition curl_dl.cc:99
curl_easy_init
Definition curl_dl.cc:94
va_end(ap)
nullptr CURL handle void p CURLversion nullptr struct curl_slist list CURLM CURLM_INTERNAL_ERROR CURLM CURL CURLM_INTERNAL_ERROR CURLM curl_socket_t int int CURLM_INTERNAL_ERROR CURLINFO va_list ap
Definition curl_dl.cc:120
void * arg
Definition curl_dl.cc:121
nullptr CURL handle void p CURLversion age
Definition curl_dl.cc:101
CURLMcode curl_multi_setopt(CURLM *multi, CURLMoption option,...)
Definition curl_dl.cc:154
#define CURL_DL_FN_VOID(name, proto, args)
Definition curl_dl.cc:82
nullptr CURL * handle
Definition curl_dl.cc:96
return fn(handle, info, arg)
nullptr CURL handle void p CURLversion nullptr struct curl_slist list CURLM CURLM_INTERNAL_ERROR CURLM CURL CURLM_INTERNAL_ERROR CURLM curl_socket_t int int * running_handles
Definition curl_dl.cc:111
String related utilities and Regular expression matching.