@@ -1222,43 +1222,52 @@ __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 ;
1227
+ size_t buf_len ;
1228
1228
1229
+ error = os_fstatat (handle , path , & stat , __WASI_LOOKUP_SYMLINK_FOLLOW );
1230
+ if (error != __WASI_ESUCCESS ) {
1231
+ * p_len = 0 ;
1232
+ * out_buf = NULL ;
1233
+ return error ;
1234
+ }
1235
+
1236
+ /*
1237
+ * Some magic symlinks report `st_size` as zero. In that case, take
1238
+ * 32 as the initial buffer size. Otherwise, use `st_size + 1`.
1239
+ */
1240
+ buf_len = stat .st_size ? stat .st_size + 1 : 32 ;
1229
1241
for (;;) {
1230
- char * newbuf = wasm_runtime_malloc ((uint32 )len );
1242
+ size_t bytes_read = 0 ;
1243
+ char * buf ;
1231
1244
1232
- if (newbuf == NULL ) {
1233
- if (buf )
1234
- wasm_runtime_free (buf );
1245
+ buf = wasm_runtime_malloc ((uint32 )buf_len );
1246
+ if (buf == NULL ) {
1235
1247
* out_buf = NULL ;
1236
1248
return __WASI_ENOMEM ;
1237
1249
}
1238
1250
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 );
1251
+ error = os_readlinkat (handle , path , buf , buf_len , & bytes_read );
1248
1252
if (error != __WASI_ESUCCESS ) {
1249
1253
wasm_runtime_free (buf );
1254
+ * p_len = 0 ;
1250
1255
* out_buf = NULL ;
1251
1256
return error ;
1252
1257
}
1253
- if ((size_t )bytes_read + 1 < len ) {
1258
+
1259
+ /* not truncated */
1260
+ if (bytes_read < buf_len ) {
1254
1261
buf [bytes_read ] = '\0' ;
1255
- * p_len = len ;
1262
+ * p_len = bytes_read + 1 ;
1256
1263
* out_buf = buf ;
1257
-
1258
1264
return __WASI_ESUCCESS ;
1259
1265
}
1260
- len_org = len ;
1261
- len *= 2 ;
1266
+
1267
+ /* truncated, try again with a bigger buf */
1268
+ wasm_runtime_free (buf );
1269
+ buf = NULL ;
1270
+ buf_len *= 2 ;
1262
1271
}
1263
1272
}
1264
1273
0 commit comments