@@ -1222,43 +1222,56 @@ __wasi_errno_t
1222
1222
readlinkat_dup (os_file_handle handle , const char * path , size_t * p_len ,
1223
1223
char * * out_buf )
1224
1224
{
1225
- char * buf = NULL ;
1226
- size_t len = 32 ;
1227
- size_t len_org = len ;
1225
+ __wasi_errno_t error ;
1226
+ struct __wasi_filestat_t stat = { 0 };
1227
+ size_t buf_len ;
1228
+
1229
+ /*
1230
+ * use fstatat to get a better estimation
1231
+ * If path is a symbolic link, do not dereference it:
1232
+ * instead return information about the link itself,
1233
+ * like lstat().
1234
+ */
1235
+ error = os_fstatat (handle , path , & stat , 0 );
1236
+ if (error != __WASI_ESUCCESS ) {
1237
+ stat .st_size = 0 ;
1238
+ }
1228
1239
1240
+ /*
1241
+ * Some magic symlinks report `st_size` as zero. In that case, take
1242
+ * 32 as the initial buffer size. Otherwise, use `st_size + 1`.
1243
+ */
1244
+ buf_len = stat .st_size ? stat .st_size + 1 : 32 ;
1229
1245
for (;;) {
1230
- char * newbuf = wasm_runtime_malloc ((uint32 )len );
1246
+ size_t bytes_read = 0 ;
1247
+ char * buf ;
1231
1248
1232
- if (newbuf == NULL ) {
1233
- if (buf )
1234
- wasm_runtime_free (buf );
1249
+ buf = wasm_runtime_malloc ((uint32 )buf_len );
1250
+ if (buf == NULL ) {
1235
1251
* out_buf = NULL ;
1236
1252
return __WASI_ENOMEM ;
1237
1253
}
1238
1254
1239
- if (buf != NULL ) {
1240
- bh_memcpy_s (newbuf , (uint32 )len , buf , (uint32 )len_org );
1241
- wasm_runtime_free (buf );
1242
- }
1243
-
1244
- buf = newbuf ;
1245
- size_t bytes_read = 0 ;
1246
- __wasi_errno_t error =
1247
- os_readlinkat (handle , path , buf , len , & bytes_read );
1255
+ error = os_readlinkat (handle , path , buf , buf_len , & bytes_read );
1248
1256
if (error != __WASI_ESUCCESS ) {
1249
1257
wasm_runtime_free (buf );
1258
+ * p_len = 0 ;
1250
1259
* out_buf = NULL ;
1251
1260
return error ;
1252
1261
}
1253
- if ((size_t )bytes_read + 1 < len ) {
1262
+
1263
+ /* not truncated */
1264
+ if (bytes_read < buf_len ) {
1254
1265
buf [bytes_read ] = '\0' ;
1255
- * p_len = len ;
1266
+ * p_len = bytes_read + 1 ;
1256
1267
* out_buf = buf ;
1257
-
1258
1268
return __WASI_ESUCCESS ;
1259
1269
}
1260
- len_org = len ;
1261
- len *= 2 ;
1270
+
1271
+ /* truncated, try again with a bigger buf */
1272
+ wasm_runtime_free (buf );
1273
+ buf = NULL ;
1274
+ buf_len *= 2 ;
1262
1275
}
1263
1276
}
1264
1277
0 commit comments