@@ -13,42 +13,51 @@ static int __wasilibc_cwd_mallocd = 0;
13
13
14
14
int chdir (const char * path )
15
15
{
16
+ static char * relative_buf = NULL ;
17
+ static size_t relative_buf_len = 0 ;
18
+
16
19
// Find a preopen'd directory as well as a relative path we're anchored
17
20
// from which we're changing directories to.
18
- char * relative ;
19
21
const char * abs ;
20
- int parent_fd = __wasilibc_find_relpath (path , & abs , & relative );
21
- if (parent_fd == -1 ) {
22
- errno = ENOENT ;
23
- return -1 ;
22
+ int parent_fd ;
23
+ while (1 ) {
24
+ parent_fd = __wasilibc_find_relpath (path , & abs , relative_buf , relative_buf_len );
25
+ if (parent_fd != -1 )
26
+ break ;
27
+ if (errno != ERANGE )
28
+ return -1 ;
29
+ size_t new_len = relative_buf_len == 0 ? 16 : 2 * relative_buf_len ;
30
+ relative_buf = realloc (relative_buf , new_len );
31
+ if (relative_buf == NULL ) {
32
+ errno = ENOMEM ;
33
+ return -1 ;
34
+ }
35
+ relative_buf_len = new_len ;
24
36
}
25
37
26
38
// Make sure that this directory we're accessing is indeed a directory.
27
39
struct stat dirinfo ;
28
- int ret = fstatat (parent_fd , relative , & dirinfo , 0 );
40
+ int ret = fstatat (parent_fd , relative_buf , & dirinfo , 0 );
29
41
if (ret == -1 ) {
30
- free (relative );
31
42
return -1 ;
32
43
}
33
44
if (!S_ISDIR (dirinfo .st_mode )) {
34
- free (relative );
35
45
errno = ENOTDIR ;
36
46
return -1 ;
37
47
}
38
48
39
49
// Copy over our new absolute path into `__wasilibc_cwd`. Only copy over
40
50
// the relative portion of the path if it's not equal to `.`
41
51
size_t len = strlen (abs );
42
- int copy_relative = strcmp (relative , "." ) != 0 ;
43
- char * new_cwd = malloc (len + (copy_relative ? strlen (relative ) : 0 ));
52
+ int copy_relative = strcmp (relative_buf , "." ) != 0 ;
53
+ char * new_cwd = malloc (len + (copy_relative ? strlen (relative_buf ) : 0 ));
44
54
if (new_cwd == NULL ) {
45
55
errno = ENOMEM ;
46
56
return -1 ;
47
57
}
48
58
strcpy (new_cwd , abs );
49
59
if (copy_relative )
50
- strcpy (new_cwd + strlen (abs ), relative );
51
- free (relative );
60
+ strcpy (new_cwd + strlen (abs ), relative_buf );
52
61
53
62
// And set our new malloc'd buffer into the global cwd, freeing the
54
63
// previous one if necessary.
0 commit comments