@@ -981,51 +981,68 @@ static int rwrap_res_fake_hosts(const char *hostfile,
981
981
982
982
#include <dlfcn.h>
983
983
984
- struct rwrap_libc_fns {
985
- int (* libc_res_init )(void );
986
- int (* libc___res_init )(void );
987
- int (* libc_res_ninit )(struct __res_state * state );
988
- int (* libc___res_ninit )(struct __res_state * state );
989
- void (* libc_res_nclose )(struct __res_state * state );
990
- void (* libc___res_nclose )(struct __res_state * state );
991
- void (* libc_res_close )(void );
992
- void (* libc___res_close )(void );
993
- int (* libc_res_nquery )(struct __res_state * state ,
994
- const char * dname ,
995
- int class ,
996
- int type ,
997
- unsigned char * answer ,
998
- int anslen );
999
- int (* libc___res_nquery )(struct __res_state * state ,
984
+ typedef int (* __libc_res_ninit )(struct __res_state * state );
985
+ typedef int (* __libc___res_ninit )(struct __res_state * state );
986
+ typedef void (* __libc_res_nclose )(struct __res_state * state );
987
+ typedef void (* __libc___res_nclose )(struct __res_state * state );
988
+ typedef int (* __libc_res_nquery )(struct __res_state * state ,
1000
989
const char * dname ,
1001
990
int class ,
1002
991
int type ,
1003
992
unsigned char * answer ,
1004
993
int anslen );
1005
- int (* libc_res_nsearch )(struct __res_state * state ,
1006
- const char * dname ,
1007
- int class ,
1008
- int type ,
1009
- unsigned char * answer ,
1010
- int anslen );
1011
- int (* libc___res_nsearch )(struct __res_state * state ,
994
+ typedef int (* __libc___res_nquery )(struct __res_state * state ,
995
+ const char * dname ,
996
+ int class ,
997
+ int type ,
998
+ unsigned char * answer ,
999
+ int anslen );
1000
+ typedef int (* __libc_res_nsearch )(struct __res_state * state ,
1012
1001
const char * dname ,
1013
1002
int class ,
1014
1003
int type ,
1015
1004
unsigned char * answer ,
1016
1005
int anslen );
1006
+ typedef int (* __libc___res_nsearch )(struct __res_state * state ,
1007
+ const char * dname ,
1008
+ int class ,
1009
+ int type ,
1010
+ unsigned char * answer ,
1011
+ int anslen );
1012
+
1013
+ #define RWRAP_SYMBOL_ENTRY (i ) \
1014
+ union { \
1015
+ __libc_##i f; \
1016
+ void *obj; \
1017
+ } _libc_##i
1018
+
1019
+ struct rwrap_libc_symbols {
1020
+ RWRAP_SYMBOL_ENTRY (res_ninit );
1021
+ RWRAP_SYMBOL_ENTRY (__res_ninit );
1022
+ RWRAP_SYMBOL_ENTRY (res_nclose );
1023
+ RWRAP_SYMBOL_ENTRY (__res_nclose );
1024
+ RWRAP_SYMBOL_ENTRY (res_nquery );
1025
+ RWRAP_SYMBOL_ENTRY (__res_nquery );
1026
+ RWRAP_SYMBOL_ENTRY (res_nsearch );
1027
+ RWRAP_SYMBOL_ENTRY (__res_nsearch );
1017
1028
};
1029
+ #undef RWRAP_SYMBOL_ENTRY
1018
1030
1019
1031
struct rwrap {
1020
- void * libc_handle ;
1021
- void * libresolv_handle ;
1032
+ struct {
1033
+ void * handle ;
1034
+ struct rwrap_libc_symbols symbols ;
1035
+ } libc ;
1036
+
1037
+ struct {
1038
+ void * handle ;
1039
+ struct rwrap_libc_symbols symbols ;
1040
+ } libresolv ;
1022
1041
1023
1042
bool initialised ;
1024
1043
bool enabled ;
1025
1044
1026
1045
char * socket_dir ;
1027
-
1028
- struct rwrap_libc_fns fns ;
1029
1046
};
1030
1047
1031
1048
static struct rwrap rwrap ;
@@ -1063,7 +1080,7 @@ static void *rwrap_load_lib_handle(enum rwrap_lib lib)
1063
1080
switch (lib ) {
1064
1081
case RWRAP_LIBRESOLV :
1065
1082
#ifdef HAVE_LIBRESOLV
1066
- handle = rwrap .libresolv_handle ;
1083
+ handle = rwrap .libresolv . handle ;
1067
1084
if (handle == NULL ) {
1068
1085
for (i = 10 ; i >= 0 ; i -- ) {
1069
1086
char soname [256 ] = {0 };
@@ -1075,18 +1092,18 @@ static void *rwrap_load_lib_handle(enum rwrap_lib lib)
1075
1092
}
1076
1093
}
1077
1094
1078
- rwrap .libresolv_handle = handle ;
1095
+ rwrap .libresolv . handle = handle ;
1079
1096
}
1080
1097
break ;
1081
1098
#endif
1082
1099
/* FALL TROUGH */
1083
1100
case RWRAP_LIBC :
1084
- handle = rwrap .libc_handle ;
1101
+ handle = rwrap .libc . handle ;
1085
1102
#ifdef LIBC_SO
1086
1103
if (handle == NULL ) {
1087
1104
handle = dlopen (LIBC_SO , flags );
1088
1105
1089
- rwrap .libc_handle = handle ;
1106
+ rwrap .libc . handle = handle ;
1090
1107
}
1091
1108
#endif
1092
1109
if (handle == NULL ) {
@@ -1100,14 +1117,14 @@ static void *rwrap_load_lib_handle(enum rwrap_lib lib)
1100
1117
}
1101
1118
}
1102
1119
1103
- rwrap .libc_handle = handle ;
1120
+ rwrap .libc . handle = handle ;
1104
1121
}
1105
1122
break ;
1106
1123
}
1107
1124
1108
1125
if (handle == NULL ) {
1109
1126
#ifdef RTLD_NEXT
1110
- handle = rwrap .libc_handle = rwrap .libresolv_handle = RTLD_NEXT ;
1127
+ handle = rwrap .libc . handle = rwrap .libresolv . handle = RTLD_NEXT ;
1111
1128
#else
1112
1129
RWRAP_LOG (RWRAP_LOG_ERROR ,
1113
1130
"Failed to dlopen library: %s\n" ,
@@ -1119,7 +1136,7 @@ static void *rwrap_load_lib_handle(enum rwrap_lib lib)
1119
1136
return handle ;
1120
1137
}
1121
1138
1122
- static void * _rwrap_load_lib_function (enum rwrap_lib lib , const char * fn_name )
1139
+ static void * _rwrap_bind_symbol (enum rwrap_lib lib , const char * fn_name )
1123
1140
{
1124
1141
void * handle ;
1125
1142
void * func ;
@@ -1140,10 +1157,16 @@ static void *_rwrap_load_lib_function(enum rwrap_lib lib, const char *fn_name)
1140
1157
return func ;
1141
1158
}
1142
1159
1143
- #define rwrap_load_lib_function (lib , fn_name ) \
1144
- if (rwrap.fns.libc_##fn_name == NULL) { \
1145
- *(void **) (&rwrap.fns.libc_##fn_name) = \
1146
- _rwrap_load_lib_function(lib, #fn_name); \
1160
+ #define rwrap_bind_symbol_libc (sym_name ) \
1161
+ if (rwrap.libc.symbols._libc_##sym_name.obj == NULL) { \
1162
+ rwrap.libc.symbols._libc_##sym_name.obj = \
1163
+ _rwrap_bind_symbol(RWRAP_LIBC, #sym_name); \
1164
+ }
1165
+
1166
+ #define rwrap_bind_symbol_libresolv (sym_name ) \
1167
+ if (rwrap.libresolv.symbols._libc_##sym_name.obj == NULL) { \
1168
+ rwrap.libresolv.symbols._libc_##sym_name.obj = \
1169
+ _rwrap_bind_symbol(RWRAP_LIBRESOLV, #sym_name); \
1147
1170
}
1148
1171
1149
1172
/*
@@ -1154,36 +1177,25 @@ static void *_rwrap_load_lib_function(enum rwrap_lib lib, const char *fn_name)
1154
1177
* has probably something todo with with the linker.
1155
1178
* So we need load each function at the point it is called the first time.
1156
1179
*/
1157
- #if 0
1158
- static int libc_res_init (void )
1159
- {
1160
- #if !defined(res_init ) && defined(HAVE_RES_INIT )
1161
- rwrap_load_lib_function (RWRAP_LIBRESOLV , res_init );
1162
-
1163
- return rwrap .fns .libc_res_init ();
1164
- #elif defined(HAVE___RES_INIT )
1165
- rwrap_load_lib_function (RWRAP_LIBRESOLV , __res_init );
1166
-
1167
- return rwrap .fns .libc___res_init ();
1168
- #endif
1169
- }
1170
- #endif
1171
1180
1172
1181
static int libc_res_ninit (struct __res_state * state )
1173
1182
{
1174
1183
#if !defined(res_ninit ) && defined(HAVE_RES_NINIT )
1175
1184
1176
1185
#if defined(HAVE_RES_NINIT_IN_LIBRESOLV )
1177
- rwrap_load_lib_function (RWRAP_LIBRESOLV , res_ninit );
1186
+ rwrap_bind_symbol_libresolv (res_ninit );
1187
+
1188
+ return rwrap .libresolv .symbols ._libc_res_ninit .f (state );
1178
1189
#else /* HAVE_RES_NINIT_IN_LIBRESOLV */
1179
- rwrap_load_lib_function (RWRAP_LIBC , res_ninit );
1190
+ rwrap_bind_symbol_libc (res_ninit );
1191
+
1192
+ return rwrap .libc .symbols ._libc_res_ninit .f (state );
1180
1193
#endif /* HAVE_RES_NINIT_IN_LIBRESOLV */
1181
1194
1182
- return rwrap .fns .libc_res_ninit (state );
1183
1195
#elif defined(HAVE___RES_NINIT )
1184
- rwrap_load_lib_function ( RWRAP_LIBC , __res_ninit );
1196
+ rwrap_bind_symbol_libc ( __res_ninit );
1185
1197
1186
- return rwrap .fns . libc___res_ninit (state );
1198
+ return rwrap .libc . symbols . _libc___res_ninit . f (state );
1187
1199
#else
1188
1200
#error "No res_ninit function"
1189
1201
#endif
@@ -1194,16 +1206,21 @@ static void libc_res_nclose(struct __res_state *state)
1194
1206
#if !defined(res_close ) && defined(HAVE_RES_NCLOSE )
1195
1207
1196
1208
#if defined(HAVE_RES_NCLOSE_IN_LIBRESOLV )
1197
- rwrap_load_lib_function (RWRAP_LIBRESOLV , res_nclose );
1209
+ rwrap_bind_symbol_libresolv (res_nclose );
1210
+
1211
+ rwrap .libresolv .symbols ._libc_res_nclose .f (state );
1212
+ return ;
1198
1213
#else /* HAVE_RES_NCLOSE_IN_LIBRESOLV */
1199
- rwrap_load_lib_function (RWRAP_LIBC , res_nclose );
1214
+ rwrap_bind_symbol_libc (res_nclose );
1215
+
1216
+ rwrap .libc .symbols ._libc_res_nclose .f (state );
1217
+ return ;
1200
1218
#endif /* HAVE_RES_NCLOSE_IN_LIBRESOLV */
1201
1219
1202
- rwrap .fns .libc_res_nclose (state );
1203
1220
#elif defined(HAVE___RES_NCLOSE )
1204
- rwrap_load_lib_function ( RWRAP_LIBC , __res_nclose );
1221
+ rwrap_bind_symbol_libc ( __res_nclose );
1205
1222
1206
- rwrap .fns . libc___res_nclose (state );
1223
+ rwrap .libc . symbols . _libc___res_nclose . f (state );
1207
1224
#else
1208
1225
#error "No res_nclose function"
1209
1226
#endif
@@ -1217,23 +1234,23 @@ static int libc_res_nquery(struct __res_state *state,
1217
1234
int anslen )
1218
1235
{
1219
1236
#if !defined(res_nquery ) && defined(HAVE_RES_NQUERY )
1220
- rwrap_load_lib_function ( RWRAP_LIBRESOLV , res_nquery );
1221
-
1222
- return rwrap .fns . libc_res_nquery (state ,
1223
- dname ,
1224
- class ,
1225
- type ,
1226
- answer ,
1227
- anslen );
1237
+ rwrap_bind_symbol_libresolv ( res_nquery );
1238
+
1239
+ return rwrap .libresolv . symbols . _libc_res_nquery . f (state ,
1240
+ dname ,
1241
+ class ,
1242
+ type ,
1243
+ answer ,
1244
+ anslen );
1228
1245
#elif defined(HAVE___RES_NQUERY )
1229
- rwrap_load_lib_function ( RWRAP_LIBRESOLV , __res_nquery );
1230
-
1231
- return rwrap .fns . libc___res_nquery (state ,
1232
- dname ,
1233
- class ,
1234
- type ,
1235
- answer ,
1236
- anslen );
1246
+ rwrap_bind_symbol_libresolv ( __res_nquery );
1247
+
1248
+ return rwrap .libresolv . symbols . _libc___res_nquery . f (state ,
1249
+ dname ,
1250
+ class ,
1251
+ type ,
1252
+ answer ,
1253
+ anslen );
1237
1254
#else
1238
1255
#error "No res_nquery function"
1239
1256
#endif
@@ -1247,23 +1264,23 @@ static int libc_res_nsearch(struct __res_state *state,
1247
1264
int anslen )
1248
1265
{
1249
1266
#if !defined(res_nsearch ) && defined(HAVE_RES_NSEARCH )
1250
- rwrap_load_lib_function ( RWRAP_LIBRESOLV , res_nsearch );
1251
-
1252
- return rwrap .fns . libc_res_nsearch (state ,
1253
- dname ,
1254
- class ,
1255
- type ,
1256
- answer ,
1257
- anslen );
1267
+ rwrap_bind_symbol_libresolv ( res_nsearch );
1268
+
1269
+ return rwrap .libresolv . symbols . _libc_res_nsearch . f (state ,
1270
+ dname ,
1271
+ class ,
1272
+ type ,
1273
+ answer ,
1274
+ anslen );
1258
1275
#elif defined(HAVE___RES_NSEARCH )
1259
- rwrap_load_lib_function ( RWRAP_LIBRESOLV , __res_nsearch );
1260
-
1261
- return rwrap .fns . libc___res_nsearch (state ,
1262
- dname ,
1263
- class ,
1264
- type ,
1265
- answer ,
1266
- anslen );
1276
+ rwrap_bind_symbol_libresolv ( __res_nsearch );
1277
+
1278
+ return rwrap .libresolv . symbols . _libc___res_nsearch . f (state ,
1279
+ dname ,
1280
+ class ,
1281
+ type ,
1282
+ answer ,
1283
+ anslen );
1267
1284
#else
1268
1285
#error "No res_nsearch function"
1269
1286
#endif
0 commit comments