@@ -226,6 +226,18 @@ static int lcurl_multi_timeout(lua_State *L){
226226 return 1 ;
227227}
228228
229+ static int lcurl_multi_socket_action (lua_State * L ){
230+ lcurl_multi_t * p = lcurl_getmulti (L );
231+ curl_socket_t s = lutil_checkint64 (L , 2 );
232+ int n , mask = lutil_checkint64 (L , 3 );
233+ CURLMcode code = curl_multi_socket_action (p -> curl , s , mask , & n );
234+ if (code != CURLM_OK ){
235+ lcurl_fail_ex (L , p -> err_mode , LCURL_ERROR_MULTI , code );
236+ }
237+ lua_pushinteger (L , n );
238+ return 1 ;
239+ }
240+
229241//{ OPTIONS
230242static int lcurl_opt_set_long_ (lua_State * L , int opt ){
231243 lcurl_multi_t * p = lcurl_getmulti (L );
@@ -313,7 +325,7 @@ static int lcurl_multi_set_callback(lua_State *L,
313325 return 1 ;
314326}
315327
316- //{Timer
328+ //{ Timer
317329
318330int lcurl_multi_timer_callback (CURLM * multi , long ms , void * arg ){
319331 lcurl_multi_t * p = arg ;
@@ -347,7 +359,6 @@ int lcurl_multi_timer_callback(CURLM *multi, long ms, void *arg){
347359 return ret ;
348360}
349361
350-
351362static int lcurl_multi_set_TIMERFUNCTION (lua_State * L ){
352363 lcurl_multi_t * p = lcurl_getmulti (L );
353364 return lcurl_multi_set_callback (L , p , & p -> tm ,
@@ -358,6 +369,43 @@ static int lcurl_multi_set_TIMERFUNCTION(lua_State *L){
358369
359370//}
360371
372+ //{ Socket
373+
374+ static int lcurl_multi_socket_callback (CURL * easy , curl_socket_t s , int what , void * arg , void * socketp ){
375+ lcurl_multi_t * p = arg ;
376+ lua_State * L = p -> L ;
377+ lcurl_easy_t * e ;
378+ int n , top = lua_gettop (L );
379+
380+ n = lcurl_util_push_cb (L , & p -> sc );
381+
382+ lua_rawgeti (L , LCURL_LUA_REGISTRY , p -> h_ref );
383+ lua_rawgetp (L , -1 , easy );
384+ e = lcurl_geteasy_at (L , -1 );
385+ lua_remove (L , -2 );
386+ lutil_pushint64 (L , s );
387+ lua_pushinteger (L , what );
388+
389+ if (lua_pcall (L , n + 2 , 0 , 0 )){
390+ assert (lua_gettop (L ) >= top );
391+ lua_settop (L , top );
392+ return -1 ; //! @todo break perform
393+ }
394+
395+ lua_settop (L , top );
396+ return 0 ;
397+ }
398+
399+ static int lcurl_multi_set_SOCKETFUNCTION (lua_State * L ){
400+ lcurl_multi_t * p = lcurl_getmulti (L );
401+ return lcurl_multi_set_callback (L , p , & p -> sc ,
402+ CURLMOPT_SOCKETFUNCTION , CURLMOPT_SOCKETDATA ,
403+ "socket" , lcurl_multi_socket_callback
404+ );
405+ }
406+
407+ //}
408+
361409//}
362410
363411static int lcurl_multi_setopt (lua_State * L ){
@@ -396,10 +444,12 @@ static const struct luaL_Reg lcurl_multi_methods[] = {
396444 {"setopt" , lcurl_multi_setopt },
397445 {"wait" , lcurl_multi_wait },
398446 {"timeout" , lcurl_multi_timeout },
447+ {"socket_action" , lcurl_multi_socket_action },
399448
400449#define OPT_ENTRY (L , N , T , S ) { "setopt_" #L , lcurl_multi_set_##N },
401450 #include "lcoptmulti.h"
402- OPT_ENTRY (timerfunction , TIMERFUNCTION , TTT , 0 )
451+ OPT_ENTRY (timerfunction , TIMERFUNCTION , TTT , 0 )
452+ OPT_ENTRY (socketfunction , SOCKETFUNCTION , TTT , 0 )
403453#undef OPT_ENTRY
404454
405455 {"close" , lcurl_multi_cleanup },
@@ -411,7 +461,8 @@ static const struct luaL_Reg lcurl_multi_methods[] = {
411461static const lcurl_const_t lcurl_multi_opt [] = {
412462#define OPT_ENTRY (L , N , T , S ) { "OPT_MULTI_" #N , CURLMOPT_ ##N },
413463 #include "lcoptmulti.h"
414- OPT_ENTRY (timerfunction , TIMERFUNCTION , TTT , 0 )
464+ OPT_ENTRY (timerfunction , TIMERFUNCTION , TTT , 0 )
465+ OPT_ENTRY (socketfunction , SOCKETFUNCTION , TTT , 0 )
415466#undef OPT_ENTRY
416467
417468 {NULL , 0 }
0 commit comments