Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2922193
fs.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
33 KB
Referenced Files
None
Subscribers
None
fs.c
View Options
#include
<compat.h>
// IWYU pragma: keep
#include
<uv.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include
<sys/stat.h>
#include
<fcntl.h>
#include
<uthash.h>
#include
<utarray.h>
#include
<errno.h>
#include
"modules/fs.h"
#include
"modules/symbol.h"
#include
"ant.h"
#include
"runtime.h"
typedef
enum
{
FS_OP_READ
,
FS_OP_WRITE
,
FS_OP_UNLINK
,
FS_OP_MKDIR
,
FS_OP_RMDIR
,
FS_OP_STAT
,
FS_OP_READ_BYTES
,
FS_OP_EXISTS
,
FS_OP_READDIR
}
fs_op_type_t
;
typedef
struct
fs_request_s
{
struct
js
*
js
;
jsval_t
promise
;
uv_fs_t
uv_req
;
fs_op_type_t
op_type
;
char
*
path
;
char
*
data
;
size_t
data_len
;
uv_file
fd
;
int
completed
;
int
failed
;
char
*
error_msg
;
}
fs_request_t
;
static
uv_loop_t
*
fs_loop
=
NULL
;
static
UT_array
*
pending_requests
=
NULL
;
static
void
free_fs_request
(
fs_request_t
*
req
)
{
if
(
!
req
)
return
;
if
(
req
->
path
)
free
(
req
->
path
);
if
(
req
->
data
)
free
(
req
->
data
);
if
(
req
->
error_msg
)
free
(
req
->
error_msg
);
uv_fs_req_cleanup
(
&
req
->
uv_req
);
free
(
req
);
}
static
void
remove_pending_request
(
fs_request_t
*
req
)
{
if
(
!
req
||
!
pending_requests
)
return
;
fs_request_t
**
p
=
NULL
;
unsigned
int
i
=
0
;
while
((
p
=
(
fs_request_t
**
)
utarray_next
(
pending_requests
,
p
)))
{
if
(
*
p
==
req
)
{
utarray_erase
(
pending_requests
,
i
,
1
);
break
;
}
i
++
;
}
}
static
void
complete_request
(
fs_request_t
*
req
)
{
if
(
req
->
failed
)
{
const
char
*
err_msg
=
req
->
error_msg
?
req
->
error_msg
:
"Unknown error"
;
jsval_t
err
=
js_mkstr
(
req
->
js
,
err_msg
,
strlen
(
err_msg
));
js_reject_promise
(
req
->
js
,
req
->
promise
,
err
);
}
else
{
jsval_t
result
;
if
((
req
->
op_type
==
FS_OP_READ
||
req
->
op_type
==
FS_OP_READ_BYTES
)
&&
req
->
data
)
{
result
=
js_mkstr
(
req
->
js
,
req
->
data
,
req
->
data_len
);
}
else
if
(
req
->
op_type
==
FS_OP_STAT
)
{
result
=
js_mkundef
();
}
else
{
result
=
js_mkundef
();
}
js_resolve_promise
(
req
->
js
,
req
->
promise
,
result
);
}
remove_pending_request
(
req
);
free_fs_request
(
req
);
}
static
void
on_read_complete
(
uv_fs_t
*
uv_req
)
{
fs_request_t
*
req
=
(
fs_request_t
*
)
uv_req
->
data
;
if
(
uv_req
->
result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
uv_req
->
result
));
req
->
completed
=
1
;
complete_request
(
req
);
return
;
}
req
->
data_len
=
uv_req
->
result
;
uv_fs_t
close_req
;
uv_fs_close
(
fs_loop
,
&
close_req
,
req
->
fd
,
NULL
);
uv_fs_req_cleanup
(
&
close_req
);
req
->
completed
=
1
;
complete_request
(
req
);
}
static
void
on_open_for_read
(
uv_fs_t
*
uv_req
)
{
fs_request_t
*
req
=
(
fs_request_t
*
)
uv_req
->
data
;
if
(
uv_req
->
result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
uv_req
->
result
));
req
->
completed
=
1
;
complete_request
(
req
);
return
;
}
req
->
fd
=
uv_req
->
result
;
uv_fs_req_cleanup
(
uv_req
);
uv_fs_t
stat_req
;
int
stat_result
=
uv_fs_fstat
(
fs_loop
,
&
stat_req
,
req
->
fd
,
NULL
);
if
(
stat_result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
stat_result
));
req
->
completed
=
1
;
uv_fs_t
close_req
;
uv_fs_close
(
fs_loop
,
&
close_req
,
req
->
fd
,
NULL
);
uv_fs_req_cleanup
(
&
close_req
);
complete_request
(
req
);
return
;
}
size_t
file_size
=
stat_req
.
statbuf
.
st_size
;
uv_fs_req_cleanup
(
&
stat_req
);
size_t
alloc_size
=
(
req
->
op_type
==
FS_OP_READ
)
?
file_size
+
1
:
file_size
;
req
->
data
=
malloc
(
alloc_size
);
if
(
!
req
->
data
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
"Out of memory"
);
req
->
completed
=
1
;
uv_fs_t
close_req
;
uv_fs_close
(
fs_loop
,
&
close_req
,
req
->
fd
,
NULL
);
uv_fs_req_cleanup
(
&
close_req
);
complete_request
(
req
);
return
;
}
uv_buf_t
buf
=
uv_buf_init
(
req
->
data
,
file_size
);
int
read_result
=
uv_fs_read
(
fs_loop
,
uv_req
,
req
->
fd
,
&
buf
,
1
,
0
,
on_read_complete
);
if
(
read_result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
read_result
));
req
->
completed
=
1
;
uv_fs_t
close_req
;
uv_fs_close
(
fs_loop
,
&
close_req
,
req
->
fd
,
NULL
);
uv_fs_req_cleanup
(
&
close_req
);
complete_request
(
req
);
return
;
}
}
static
void
on_write_complete
(
uv_fs_t
*
uv_req
)
{
fs_request_t
*
req
=
(
fs_request_t
*
)
uv_req
->
data
;
if
(
uv_req
->
result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
uv_req
->
result
));
}
uv_fs_t
close_req
;
uv_fs_close
(
fs_loop
,
&
close_req
,
req
->
fd
,
NULL
);
uv_fs_req_cleanup
(
&
close_req
);
req
->
completed
=
1
;
complete_request
(
req
);
}
static
void
on_open_for_write
(
uv_fs_t
*
uv_req
)
{
fs_request_t
*
req
=
(
fs_request_t
*
)
uv_req
->
data
;
if
(
uv_req
->
result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
uv_req
->
result
));
req
->
completed
=
1
;
complete_request
(
req
);
return
;
}
req
->
fd
=
uv_req
->
result
;
uv_fs_req_cleanup
(
uv_req
);
uv_buf_t
buf
=
uv_buf_init
(
req
->
data
,
req
->
data_len
);
int
write_result
=
uv_fs_write
(
fs_loop
,
uv_req
,
req
->
fd
,
&
buf
,
1
,
0
,
on_write_complete
);
if
(
write_result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
write_result
));
req
->
completed
=
1
;
uv_fs_t
close_req
;
uv_fs_close
(
fs_loop
,
&
close_req
,
req
->
fd
,
NULL
);
uv_fs_req_cleanup
(
&
close_req
);
complete_request
(
req
);
return
;
}
}
static
void
on_unlink_complete
(
uv_fs_t
*
uv_req
)
{
fs_request_t
*
req
=
(
fs_request_t
*
)
uv_req
->
data
;
if
(
uv_req
->
result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
uv_req
->
result
));
}
uv_fs_req_cleanup
(
uv_req
);
req
->
completed
=
1
;
complete_request
(
req
);
}
static
void
on_mkdir_complete
(
uv_fs_t
*
uv_req
)
{
fs_request_t
*
req
=
(
fs_request_t
*
)
uv_req
->
data
;
if
(
uv_req
->
result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
uv_req
->
result
));
}
uv_fs_req_cleanup
(
uv_req
);
req
->
completed
=
1
;
complete_request
(
req
);
}
static
void
on_rmdir_complete
(
uv_fs_t
*
uv_req
)
{
fs_request_t
*
req
=
(
fs_request_t
*
)
uv_req
->
data
;
if
(
uv_req
->
result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
uv_req
->
result
));
}
uv_fs_req_cleanup
(
uv_req
);
req
->
completed
=
1
;
complete_request
(
req
);
}
static
void
on_stat_complete
(
uv_fs_t
*
uv_req
)
{
fs_request_t
*
req
=
(
fs_request_t
*
)
uv_req
->
data
;
if
(
uv_req
->
result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
uv_req
->
result
));
req
->
completed
=
1
;
complete_request
(
req
);
return
;
}
jsval_t
stat_obj
=
js_mkobj
(
req
->
js
);
js_set
(
req
->
js
,
stat_obj
,
"size"
,
js_mknum
((
double
)
uv_req
->
statbuf
.
st_size
));
js_set
(
req
->
js
,
stat_obj
,
"mode"
,
js_mknum
((
double
)
uv_req
->
statbuf
.
st_mode
));
js_set
(
req
->
js
,
stat_obj
,
"isFile"
,
S_ISREG
(
uv_req
->
statbuf
.
st_mode
)
?
js_mktrue
()
:
js_mkfalse
());
js_set
(
req
->
js
,
stat_obj
,
"isDirectory"
,
S_ISDIR
(
uv_req
->
statbuf
.
st_mode
)
?
js_mktrue
()
:
js_mkfalse
());
req
->
completed
=
1
;
js_resolve_promise
(
req
->
js
,
req
->
promise
,
stat_obj
);
remove_pending_request
(
req
);
free_fs_request
(
req
);
}
static
void
on_exists_complete
(
uv_fs_t
*
uv_req
)
{
fs_request_t
*
req
=
(
fs_request_t
*
)
uv_req
->
data
;
jsval_t
result
=
(
uv_req
->
result
>=
0
)
?
js_mktrue
()
:
js_mkfalse
();
req
->
completed
=
1
;
js_resolve_promise
(
req
->
js
,
req
->
promise
,
result
);
remove_pending_request
(
req
);
free_fs_request
(
req
);
}
static
void
on_readdir_complete
(
uv_fs_t
*
uv_req
)
{
fs_request_t
*
req
=
(
fs_request_t
*
)
uv_req
->
data
;
if
(
uv_req
->
result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
uv_req
->
result
));
req
->
completed
=
1
;
complete_request
(
req
);
return
;
}
jsval_t
arr
=
js_mkarr
(
req
->
js
);
uv_dirent_t
dirent
;
while
(
uv_fs_scandir_next
(
uv_req
,
&
dirent
)
!=
UV_EOF
)
{
jsval_t
name
=
js_mkstr
(
req
->
js
,
dirent
.
name
,
strlen
(
dirent
.
name
));
js_arr_push
(
req
->
js
,
arr
,
name
);
}
req
->
completed
=
1
;
js_resolve_promise
(
req
->
js
,
req
->
promise
,
arr
);
remove_pending_request
(
req
);
free_fs_request
(
req
);
}
static
void
ensure_fs_loop
(
void
)
{
if
(
!
fs_loop
)
{
if
(
rt
->
flags
&
ANT_RUNTIME_EXT_EVENT_LOOP
)
{
fs_loop
=
uv_default_loop
();
}
else
{
fs_loop
=
malloc
(
sizeof
(
uv_loop_t
));
uv_loop_init
(
fs_loop
);
}
}
if
(
!
pending_requests
)
{
utarray_new
(
pending_requests
,
&
ut_ptr_icd
);
}
}
static
jsval_t
builtin_fs_readFileSync
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_mkerr
(
js
,
"readFileSync() requires a path argument"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"readFileSync() path must be a string"
);
size_t
path_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
if
(
!
path
)
return
js_mkerr
(
js
,
"Failed to get path string"
);
char
*
path_cstr
=
strndup
(
path
,
path_len
);
if
(
!
path_cstr
)
return
js_mkerr
(
js
,
"Out of memory"
);
FILE
*
file
=
fopen
(
path_cstr
,
"rb"
);
if
(
!
file
)
{
char
err_msg
[
256
];
snprintf
(
err_msg
,
sizeof
(
err_msg
),
"Failed to open file: %s"
,
strerror
(
errno
));
free
(
path_cstr
);
return
js_mkerr
(
js
,
err_msg
);
}
fseek
(
file
,
0
,
SEEK_END
);
long
file_size
=
ftell
(
file
);
fseek
(
file
,
0
,
SEEK_SET
);
if
(
file_size
<
0
)
{
fclose
(
file
);
free
(
path_cstr
);
return
js_mkerr
(
js
,
"Failed to get file size"
);
}
char
*
data
=
malloc
(
file_size
+
1
);
if
(
!
data
)
{
fclose
(
file
);
free
(
path_cstr
);
return
js_mkerr
(
js
,
"Out of memory"
);
}
size_t
bytes_read
=
fread
(
data
,
1
,
file_size
,
file
);
fclose
(
file
);
free
(
path_cstr
);
if
(
bytes_read
!=
(
size_t
)
file_size
)
{
free
(
data
);
return
js_mkerr
(
js
,
"Failed to read entire file"
);
}
data
[
file_size
]
=
'\0'
;
jsval_t
result
=
js_mkstr
(
js
,
data
,
file_size
);
free
(
data
);
return
result
;
}
static
jsval_t
builtin_fs_readBytesSync
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_mkerr
(
js
,
"readBytesSync() requires a path argument"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"readBytesSync() path must be a string"
);
size_t
path_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
if
(
!
path
)
return
js_mkerr
(
js
,
"Failed to get path string"
);
char
*
path_cstr
=
strndup
(
path
,
path_len
);
if
(
!
path_cstr
)
return
js_mkerr
(
js
,
"Out of memory"
);
FILE
*
file
=
fopen
(
path_cstr
,
"rb"
);
if
(
!
file
)
{
char
err_msg
[
256
];
snprintf
(
err_msg
,
sizeof
(
err_msg
),
"Failed to open file: %s"
,
strerror
(
errno
));
free
(
path_cstr
);
return
js_mkerr
(
js
,
err_msg
);
}
fseek
(
file
,
0
,
SEEK_END
);
long
file_size
=
ftell
(
file
);
fseek
(
file
,
0
,
SEEK_SET
);
if
(
file_size
<
0
)
{
fclose
(
file
);
free
(
path_cstr
);
return
js_mkerr
(
js
,
"Failed to get file size"
);
}
char
*
data
=
malloc
(
file_size
);
if
(
!
data
)
{
fclose
(
file
);
free
(
path_cstr
);
return
js_mkerr
(
js
,
"Out of memory"
);
}
size_t
bytes_read
=
fread
(
data
,
1
,
file_size
,
file
);
fclose
(
file
);
free
(
path_cstr
);
if
(
bytes_read
!=
(
size_t
)
file_size
)
{
free
(
data
);
return
js_mkerr
(
js
,
"Failed to read entire file"
);
}
jsval_t
result
=
js_mkstr
(
js
,
data
,
file_size
);
free
(
data
);
return
result
;
}
static
jsval_t
builtin_fs_readFile
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_mkerr
(
js
,
"readFile() requires a path argument"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"readFile() path must be a string"
);
size_t
path_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
if
(
!
path
)
return
js_mkerr
(
js
,
"Failed to get path string"
);
ensure_fs_loop
();
fs_request_t
*
req
=
calloc
(
1
,
sizeof
(
fs_request_t
));
if
(
!
req
)
return
js_mkerr
(
js
,
"Out of memory"
);
req
->
js
=
js
;
req
->
op_type
=
FS_OP_READ
;
req
->
promise
=
js_mkpromise
(
js
);
req
->
path
=
strndup
(
path
,
path_len
);
req
->
uv_req
.
data
=
req
;
utarray_push_back
(
pending_requests
,
&
req
);
int
result
=
uv_fs_open
(
fs_loop
,
&
req
->
uv_req
,
req
->
path
,
O_RDONLY
,
0
,
on_open_for_read
);
if
(
result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
result
));
req
->
completed
=
1
;
complete_request
(
req
);
}
return
req
->
promise
;
}
static
jsval_t
builtin_fs_readBytes
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_mkerr
(
js
,
"readBytes() requires a path argument"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"readBytes() path must be a string"
);
size_t
path_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
if
(
!
path
)
return
js_mkerr
(
js
,
"Failed to get path string"
);
ensure_fs_loop
();
fs_request_t
*
req
=
calloc
(
1
,
sizeof
(
fs_request_t
));
if
(
!
req
)
return
js_mkerr
(
js
,
"Out of memory"
);
req
->
js
=
js
;
req
->
op_type
=
FS_OP_READ_BYTES
;
req
->
promise
=
js_mkpromise
(
js
);
req
->
path
=
strndup
(
path
,
path_len
);
req
->
uv_req
.
data
=
req
;
utarray_push_back
(
pending_requests
,
&
req
);
int
result
=
uv_fs_open
(
fs_loop
,
&
req
->
uv_req
,
req
->
path
,
O_RDONLY
,
0
,
on_open_for_read
);
if
(
result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
result
));
req
->
completed
=
1
;
complete_request
(
req
);
}
return
req
->
promise
;
}
static
jsval_t
builtin_fs_writeFileSync
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
2
)
return
js_mkerr
(
js
,
"writeFileSync() requires path and data arguments"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"writeFileSync() path must be a string"
);
if
(
js_type
(
args
[
1
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"writeFileSync() data must be a string"
);
size_t
path_len
,
data_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
char
*
data
=
js_getstr
(
js
,
args
[
1
],
&
data_len
);
if
(
!
path
||
!
data
)
return
js_mkerr
(
js
,
"Failed to get arguments"
);
char
*
path_cstr
=
strndup
(
path
,
path_len
);
if
(
!
path_cstr
)
return
js_mkerr
(
js
,
"Out of memory"
);
FILE
*
file
=
fopen
(
path_cstr
,
"wb"
);
if
(
!
file
)
{
char
err_msg
[
256
];
snprintf
(
err_msg
,
sizeof
(
err_msg
),
"Failed to open file: %s"
,
strerror
(
errno
));
free
(
path_cstr
);
return
js_mkerr
(
js
,
err_msg
);
}
size_t
bytes_written
=
fwrite
(
data
,
1
,
data_len
,
file
);
fclose
(
file
);
free
(
path_cstr
);
if
(
bytes_written
!=
data_len
)
{
return
js_mkerr
(
js
,
"Failed to write entire file"
);
}
return
js_mkundef
();
}
static
jsval_t
builtin_fs_copyFileSync
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
2
)
return
js_mkerr
(
js
,
"copyFileSync() requires src and dest arguments"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"copyFileSync() src must be a string"
);
if
(
js_type
(
args
[
1
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"copyFileSync() dest must be a string"
);
size_t
src_len
,
dest_len
;
char
*
src
=
js_getstr
(
js
,
args
[
0
],
&
src_len
);
char
*
dest
=
js_getstr
(
js
,
args
[
1
],
&
dest_len
);
if
(
!
src
||
!
dest
)
return
js_mkerr
(
js
,
"Failed to get arguments"
);
char
*
src_cstr
=
strndup
(
src
,
src_len
);
char
*
dest_cstr
=
strndup
(
dest
,
dest_len
);
if
(
!
src_cstr
||
!
dest_cstr
)
{
free
(
src_cstr
);
free
(
dest_cstr
);
return
js_mkerr
(
js
,
"Out of memory"
);
}
FILE
*
in
=
fopen
(
src_cstr
,
"rb"
);
if
(
!
in
)
{
char
err_msg
[
256
];
snprintf
(
err_msg
,
sizeof
(
err_msg
),
"Failed to open source file: %s"
,
strerror
(
errno
));
free
(
src_cstr
);
free
(
dest_cstr
);
return
js_mkerr
(
js
,
err_msg
);
}
FILE
*
out
=
fopen
(
dest_cstr
,
"wb"
);
if
(
!
out
)
{
char
err_msg
[
256
];
snprintf
(
err_msg
,
sizeof
(
err_msg
),
"Failed to open dest file: %s"
,
strerror
(
errno
));
fclose
(
in
);
free
(
src_cstr
);
free
(
dest_cstr
);
return
js_mkerr
(
js
,
err_msg
);
}
char
buf
[
8192
];
size_t
n
;
while
((
n
=
fread
(
buf
,
1
,
sizeof
(
buf
),
in
))
>
0
)
{
if
(
fwrite
(
buf
,
1
,
n
,
out
)
!=
n
)
{
fclose
(
in
);
fclose
(
out
);
free
(
src_cstr
);
free
(
dest_cstr
);
return
js_mkerr
(
js
,
"Failed to write to dest file"
);
}
}
fclose
(
in
);
fclose
(
out
);
free
(
src_cstr
);
free
(
dest_cstr
);
return
js_mkundef
();
}
static
jsval_t
builtin_fs_renameSync
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
2
)
return
js_mkerr
(
js
,
"renameSync() requires oldPath and newPath arguments"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"renameSync() oldPath must be a string"
);
if
(
js_type
(
args
[
1
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"renameSync() newPath must be a string"
);
size_t
old_len
,
new_len
;
char
*
old_path
=
js_getstr
(
js
,
args
[
0
],
&
old_len
);
char
*
new_path
=
js_getstr
(
js
,
args
[
1
],
&
new_len
);
if
(
!
old_path
||
!
new_path
)
return
js_mkerr
(
js
,
"Failed to get arguments"
);
char
*
old_cstr
=
strndup
(
old_path
,
old_len
);
char
*
new_cstr
=
strndup
(
new_path
,
new_len
);
if
(
!
old_cstr
||
!
new_cstr
)
{
free
(
old_cstr
);
free
(
new_cstr
);
return
js_mkerr
(
js
,
"Out of memory"
);
}
int
result
=
rename
(
old_cstr
,
new_cstr
);
free
(
old_cstr
);
free
(
new_cstr
);
if
(
result
!=
0
)
{
char
err_msg
[
256
];
snprintf
(
err_msg
,
sizeof
(
err_msg
),
"Failed to rename: %s"
,
strerror
(
errno
));
return
js_mkerr
(
js
,
err_msg
);
}
return
js_mkundef
();
}
static
jsval_t
builtin_fs_appendFileSync
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
2
)
return
js_mkerr
(
js
,
"appendFileSync() requires path and data arguments"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"appendFileSync() path must be a string"
);
if
(
js_type
(
args
[
1
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"appendFileSync() data must be a string"
);
size_t
path_len
,
data_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
char
*
data
=
js_getstr
(
js
,
args
[
1
],
&
data_len
);
if
(
!
path
||
!
data
)
return
js_mkerr
(
js
,
"Failed to get arguments"
);
char
*
path_cstr
=
strndup
(
path
,
path_len
);
if
(
!
path_cstr
)
return
js_mkerr
(
js
,
"Out of memory"
);
FILE
*
file
=
fopen
(
path_cstr
,
"ab"
);
if
(
!
file
)
{
char
err_msg
[
256
];
snprintf
(
err_msg
,
sizeof
(
err_msg
),
"Failed to open file: %s"
,
strerror
(
errno
));
free
(
path_cstr
);
return
js_mkerr
(
js
,
err_msg
);
}
size_t
bytes_written
=
fwrite
(
data
,
1
,
data_len
,
file
);
fclose
(
file
);
free
(
path_cstr
);
if
(
bytes_written
!=
data_len
)
{
return
js_mkerr
(
js
,
"Failed to write entire file"
);
}
return
js_mkundef
();
}
static
jsval_t
builtin_fs_writeFile
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
2
)
return
js_mkerr
(
js
,
"writeFile() requires path and data arguments"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"writeFile() path must be a string"
);
if
(
js_type
(
args
[
1
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"writeFile() data must be a string"
);
size_t
path_len
,
data_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
char
*
data
=
js_getstr
(
js
,
args
[
1
],
&
data_len
);
if
(
!
path
||
!
data
)
return
js_mkerr
(
js
,
"Failed to get arguments"
);
ensure_fs_loop
();
fs_request_t
*
req
=
calloc
(
1
,
sizeof
(
fs_request_t
));
if
(
!
req
)
return
js_mkerr
(
js
,
"Out of memory"
);
req
->
js
=
js
;
req
->
op_type
=
FS_OP_WRITE
;
req
->
promise
=
js_mkpromise
(
js
);
req
->
path
=
strndup
(
path
,
path_len
);
req
->
data
=
malloc
(
data_len
);
if
(
!
req
->
data
)
{
free
(
req
->
path
);
free
(
req
);
return
js_mkerr
(
js
,
"Out of memory"
);
}
memcpy
(
req
->
data
,
data
,
data_len
);
req
->
data_len
=
data_len
;
req
->
uv_req
.
data
=
req
;
utarray_push_back
(
pending_requests
,
&
req
);
int
result
=
uv_fs_open
(
fs_loop
,
&
req
->
uv_req
,
req
->
path
,
O_WRONLY
|
O_CREAT
|
O_TRUNC
,
0644
,
on_open_for_write
);
if
(
result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
result
));
req
->
completed
=
1
;
complete_request
(
req
);
}
return
req
->
promise
;
}
static
jsval_t
builtin_fs_unlinkSync
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_mkerr
(
js
,
"unlinkSync() requires a path argument"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"unlinkSync() path must be a string"
);
size_t
path_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
if
(
!
path
)
return
js_mkerr
(
js
,
"Failed to get path string"
);
char
*
path_cstr
=
strndup
(
path
,
path_len
);
if
(
!
path_cstr
)
return
js_mkerr
(
js
,
"Out of memory"
);
int
result
=
unlink
(
path_cstr
);
free
(
path_cstr
);
if
(
result
!=
0
)
{
char
err_msg
[
256
];
snprintf
(
err_msg
,
sizeof
(
err_msg
),
"Failed to unlink file: %s"
,
strerror
(
errno
));
return
js_mkerr
(
js
,
err_msg
);
}
return
js_mkundef
();
}
static
jsval_t
builtin_fs_unlink
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_mkerr
(
js
,
"unlink() requires a path argument"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"unlink() path must be a string"
);
size_t
path_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
if
(
!
path
)
return
js_mkerr
(
js
,
"Failed to get path string"
);
ensure_fs_loop
();
fs_request_t
*
req
=
calloc
(
1
,
sizeof
(
fs_request_t
));
if
(
!
req
)
return
js_mkerr
(
js
,
"Out of memory"
);
req
->
js
=
js
;
req
->
op_type
=
FS_OP_UNLINK
;
req
->
promise
=
js_mkpromise
(
js
);
req
->
path
=
strndup
(
path
,
path_len
);
req
->
uv_req
.
data
=
req
;
utarray_push_back
(
pending_requests
,
&
req
);
int
result
=
uv_fs_unlink
(
fs_loop
,
&
req
->
uv_req
,
req
->
path
,
on_unlink_complete
);
if
(
result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
result
));
req
->
completed
=
1
;
complete_request
(
req
);
}
return
req
->
promise
;
}
static
jsval_t
builtin_fs_mkdirSync
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_mkerr
(
js
,
"mkdirSync() requires a path argument"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"mkdirSync() path must be a string"
);
size_t
path_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
if
(
!
path
)
return
js_mkerr
(
js
,
"Failed to get path string"
);
int
mode
=
0755
;
int
recursive
=
0
;
if
(
nargs
<
2
)
goto
do_mkdir
;
switch
(
js_type
(
args
[
1
]))
{
case
JS_NUM
:
mode
=
(
int
)
js_getnum
(
args
[
1
]);
break
;
case
JS_OBJ
:
{
jsval_t
opt
=
args
[
1
];
recursive
=
js_type
(
js_get
(
js
,
opt
,
"recursive"
))
==
JS_TRUE
;
jsval_t
mode_val
=
js_get
(
js
,
opt
,
"mode"
);
if
(
js_type
(
mode_val
)
==
JS_NUM
)
mode
=
(
int
)
js_getnum
(
mode_val
);
break
;
}
}
do_mkdir
:
char
*
path_cstr
=
strndup
(
path
,
path_len
);
if
(
!
path_cstr
)
return
js_mkerr
(
js
,
"Out of memory"
);
#ifdef _WIN32
int
result
=
_mkdir
(
path_cstr
);
#else
int
result
=
mkdir
(
path_cstr
,
mode
);
#endif
free
(
path_cstr
);
if
(
result
!=
0
)
{
if
(
recursive
&&
errno
==
EEXIST
)
{
return
js_mkundef
();
}
char
err_msg
[
256
];
snprintf
(
err_msg
,
sizeof
(
err_msg
),
"Failed to create directory: %s"
,
strerror
(
errno
));
return
js_mkerr
(
js
,
err_msg
);
}
return
js_mkundef
();
}
static
jsval_t
builtin_fs_mkdir
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_mkerr
(
js
,
"mkdir() requires a path argument"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"mkdir() path must be a string"
);
size_t
path_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
if
(
!
path
)
return
js_mkerr
(
js
,
"Failed to get path string"
);
int
mode
=
0755
;
if
(
nargs
>=
2
&&
js_type
(
args
[
1
])
==
JS_NUM
)
{
mode
=
(
int
)
js_getnum
(
args
[
1
]);
}
ensure_fs_loop
();
fs_request_t
*
req
=
calloc
(
1
,
sizeof
(
fs_request_t
));
if
(
!
req
)
return
js_mkerr
(
js
,
"Out of memory"
);
req
->
js
=
js
;
req
->
op_type
=
FS_OP_MKDIR
;
req
->
promise
=
js_mkpromise
(
js
);
req
->
path
=
strndup
(
path
,
path_len
);
req
->
uv_req
.
data
=
req
;
utarray_push_back
(
pending_requests
,
&
req
);
int
result
=
uv_fs_mkdir
(
fs_loop
,
&
req
->
uv_req
,
req
->
path
,
mode
,
on_mkdir_complete
);
if
(
result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
result
));
req
->
completed
=
1
;
complete_request
(
req
);
}
return
req
->
promise
;
}
static
jsval_t
builtin_fs_rmdirSync
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_mkerr
(
js
,
"rmdirSync() requires a path argument"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"rmdirSync() path must be a string"
);
size_t
path_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
if
(
!
path
)
return
js_mkerr
(
js
,
"Failed to get path string"
);
char
*
path_cstr
=
strndup
(
path
,
path_len
);
if
(
!
path_cstr
)
return
js_mkerr
(
js
,
"Out of memory"
);
#ifdef _WIN32
int
result
=
_rmdir
(
path_cstr
);
#else
int
result
=
rmdir
(
path_cstr
);
#endif
free
(
path_cstr
);
if
(
result
!=
0
)
{
char
err_msg
[
256
];
snprintf
(
err_msg
,
sizeof
(
err_msg
),
"Failed to remove directory: %s"
,
strerror
(
errno
));
return
js_mkerr
(
js
,
err_msg
);
}
return
js_mkundef
();
}
static
jsval_t
builtin_fs_rmdir
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_mkerr
(
js
,
"rmdir() requires a path argument"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"rmdir() path must be a string"
);
size_t
path_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
if
(
!
path
)
return
js_mkerr
(
js
,
"Failed to get path string"
);
ensure_fs_loop
();
fs_request_t
*
req
=
calloc
(
1
,
sizeof
(
fs_request_t
));
if
(
!
req
)
return
js_mkerr
(
js
,
"Out of memory"
);
req
->
js
=
js
;
req
->
op_type
=
FS_OP_RMDIR
;
req
->
promise
=
js_mkpromise
(
js
);
req
->
path
=
strndup
(
path
,
path_len
);
req
->
uv_req
.
data
=
req
;
utarray_push_back
(
pending_requests
,
&
req
);
int
result
=
uv_fs_rmdir
(
fs_loop
,
&
req
->
uv_req
,
req
->
path
,
on_rmdir_complete
);
if
(
result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
result
));
req
->
completed
=
1
;
complete_request
(
req
);
}
return
req
->
promise
;
}
static
jsval_t
stat_isFile
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
jsval_t
this
=
js_getthis
(
js
);
jsval_t
val
=
js_get
(
js
,
this
,
"_isFile"
);
return
js_type
(
val
)
==
JS_TRUE
?
js_mktrue
()
:
js_mkfalse
();
}
static
jsval_t
stat_isDirectory
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
jsval_t
this
=
js_getthis
(
js
);
jsval_t
val
=
js_get
(
js
,
this
,
"_isDirectory"
);
return
js_type
(
val
)
==
JS_TRUE
?
js_mktrue
()
:
js_mkfalse
();
}
static
jsval_t
builtin_fs_statSync
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_mkerr
(
js
,
"statSync() requires a path argument"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"statSync() path must be a string"
);
size_t
path_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
if
(
!
path
)
return
js_mkerr
(
js
,
"Failed to get path string"
);
char
*
path_cstr
=
strndup
(
path
,
path_len
);
if
(
!
path_cstr
)
return
js_mkerr
(
js
,
"Out of memory"
);
struct
stat
st
;
int
result
=
stat
(
path_cstr
,
&
st
);
free
(
path_cstr
);
if
(
result
!=
0
)
{
char
err_msg
[
256
];
snprintf
(
err_msg
,
sizeof
(
err_msg
),
"Failed to stat file: %s"
,
strerror
(
errno
));
return
js_mkerr
(
js
,
err_msg
);
}
jsval_t
stat_obj
=
js_mkobj
(
js
);
js_set
(
js
,
stat_obj
,
"size"
,
js_mknum
((
double
)
st
.
st_size
));
js_set
(
js
,
stat_obj
,
"mode"
,
js_mknum
((
double
)
st
.
st_mode
));
js_set
(
js
,
stat_obj
,
"_isFile"
,
S_ISREG
(
st
.
st_mode
)
?
js_mktrue
()
:
js_mkfalse
());
js_set
(
js
,
stat_obj
,
"_isDirectory"
,
S_ISDIR
(
st
.
st_mode
)
?
js_mktrue
()
:
js_mkfalse
());
js_set
(
js
,
stat_obj
,
"isFile"
,
js_mkfun
(
stat_isFile
));
js_set
(
js
,
stat_obj
,
"isDirectory"
,
js_mkfun
(
stat_isDirectory
));
return
stat_obj
;
}
static
jsval_t
builtin_fs_stat
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_mkerr
(
js
,
"stat() requires a path argument"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"stat() path must be a string"
);
size_t
path_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
if
(
!
path
)
return
js_mkerr
(
js
,
"Failed to get path string"
);
ensure_fs_loop
();
fs_request_t
*
req
=
calloc
(
1
,
sizeof
(
fs_request_t
));
if
(
!
req
)
return
js_mkerr
(
js
,
"Out of memory"
);
req
->
js
=
js
;
req
->
op_type
=
FS_OP_STAT
;
req
->
promise
=
js_mkpromise
(
js
);
req
->
path
=
strndup
(
path
,
path_len
);
req
->
uv_req
.
data
=
req
;
utarray_push_back
(
pending_requests
,
&
req
);
int
result
=
uv_fs_stat
(
fs_loop
,
&
req
->
uv_req
,
req
->
path
,
on_stat_complete
);
if
(
result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
result
));
req
->
completed
=
1
;
complete_request
(
req
);
}
return
req
->
promise
;
}
static
jsval_t
builtin_fs_existsSync
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_mkerr
(
js
,
"existsSync() requires a path argument"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"existsSync() path must be a string"
);
size_t
path_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
if
(
!
path
)
return
js_mkerr
(
js
,
"Failed to get path string"
);
char
*
path_cstr
=
strndup
(
path
,
path_len
);
if
(
!
path_cstr
)
return
js_mkerr
(
js
,
"Out of memory"
);
struct
stat
st
;
int
result
=
stat
(
path_cstr
,
&
st
);
free
(
path_cstr
);
return
(
result
==
0
)
?
js_mktrue
()
:
js_mkfalse
();
}
static
jsval_t
builtin_fs_exists
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_mkerr
(
js
,
"exists() requires a path argument"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"exists() path must be a string"
);
size_t
path_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
if
(
!
path
)
return
js_mkerr
(
js
,
"Failed to get path string"
);
ensure_fs_loop
();
fs_request_t
*
req
=
calloc
(
1
,
sizeof
(
fs_request_t
));
if
(
!
req
)
return
js_mkerr
(
js
,
"Out of memory"
);
req
->
js
=
js
;
req
->
op_type
=
FS_OP_EXISTS
;
req
->
promise
=
js_mkpromise
(
js
);
req
->
path
=
strndup
(
path
,
path_len
);
req
->
uv_req
.
data
=
req
;
utarray_push_back
(
pending_requests
,
&
req
);
int
result
=
uv_fs_stat
(
fs_loop
,
&
req
->
uv_req
,
req
->
path
,
on_exists_complete
);
if
(
result
<
0
)
{
req
->
completed
=
1
;
js_resolve_promise
(
req
->
js
,
req
->
promise
,
js_mkfalse
());
remove_pending_request
(
req
);
free_fs_request
(
req
);
}
return
req
->
promise
;
}
static
jsval_t
builtin_fs_readdirSync
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_mkerr
(
js
,
"readdirSync() requires a path argument"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"readdirSync() path must be a string"
);
size_t
path_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
if
(
!
path
)
return
js_mkerr
(
js
,
"Failed to get path string"
);
char
*
path_cstr
=
strndup
(
path
,
path_len
);
if
(
!
path_cstr
)
return
js_mkerr
(
js
,
"Out of memory"
);
uv_fs_t
req
;
int
result
=
uv_fs_scandir
(
NULL
,
&
req
,
path_cstr
,
0
,
NULL
);
free
(
path_cstr
);
if
(
result
<
0
)
{
char
err_msg
[
256
];
snprintf
(
err_msg
,
sizeof
(
err_msg
),
"Failed to read directory: %s"
,
uv_strerror
(
result
));
uv_fs_req_cleanup
(
&
req
);
return
js_mkerr
(
js
,
err_msg
);
}
jsval_t
arr
=
js_mkarr
(
js
);
uv_dirent_t
dirent
;
while
(
uv_fs_scandir_next
(
&
req
,
&
dirent
)
!=
UV_EOF
)
{
jsval_t
name
=
js_mkstr
(
js
,
dirent
.
name
,
strlen
(
dirent
.
name
));
js_arr_push
(
js
,
arr
,
name
);
}
uv_fs_req_cleanup
(
&
req
);
return
arr
;
}
static
jsval_t
builtin_fs_readdir
(
struct
js
*
js
,
jsval_t
*
args
,
int
nargs
)
{
if
(
nargs
<
1
)
return
js_mkerr
(
js
,
"readdir() requires a path argument"
);
if
(
js_type
(
args
[
0
])
!=
JS_STR
)
return
js_mkerr
(
js
,
"readdir() path must be a string"
);
size_t
path_len
;
char
*
path
=
js_getstr
(
js
,
args
[
0
],
&
path_len
);
if
(
!
path
)
return
js_mkerr
(
js
,
"Failed to get path string"
);
ensure_fs_loop
();
fs_request_t
*
req
=
calloc
(
1
,
sizeof
(
fs_request_t
));
if
(
!
req
)
return
js_mkerr
(
js
,
"Out of memory"
);
req
->
js
=
js
;
req
->
op_type
=
FS_OP_READDIR
;
req
->
promise
=
js_mkpromise
(
js
);
req
->
path
=
strndup
(
path
,
path_len
);
req
->
uv_req
.
data
=
req
;
utarray_push_back
(
pending_requests
,
&
req
);
int
result
=
uv_fs_scandir
(
fs_loop
,
&
req
->
uv_req
,
req
->
path
,
0
,
on_readdir_complete
);
if
(
result
<
0
)
{
req
->
failed
=
1
;
req
->
error_msg
=
strdup
(
uv_strerror
(
result
));
req
->
completed
=
1
;
complete_request
(
req
);
}
return
req
->
promise
;
}
jsval_t
fs_library
(
struct
js
*
js
)
{
jsval_t
lib
=
js_mkobj
(
js
);
js_set
(
js
,
lib
,
"readFile"
,
js_mkfun
(
builtin_fs_readFile
));
js_set
(
js
,
lib
,
"readFileSync"
,
js_mkfun
(
builtin_fs_readFileSync
));
js_set
(
js
,
lib
,
"stream"
,
js_mkfun
(
builtin_fs_readBytes
));
js_set
(
js
,
lib
,
"open"
,
js_mkfun
(
builtin_fs_readBytesSync
));
js_set
(
js
,
lib
,
"writeFile"
,
js_mkfun
(
builtin_fs_writeFile
));
js_set
(
js
,
lib
,
"writeFileSync"
,
js_mkfun
(
builtin_fs_writeFileSync
));
js_set
(
js
,
lib
,
"appendFileSync"
,
js_mkfun
(
builtin_fs_appendFileSync
));
js_set
(
js
,
lib
,
"copyFileSync"
,
js_mkfun
(
builtin_fs_copyFileSync
));
js_set
(
js
,
lib
,
"renameSync"
,
js_mkfun
(
builtin_fs_renameSync
));
js_set
(
js
,
lib
,
"unlink"
,
js_mkfun
(
builtin_fs_unlink
));
js_set
(
js
,
lib
,
"unlinkSync"
,
js_mkfun
(
builtin_fs_unlinkSync
));
js_set
(
js
,
lib
,
"mkdir"
,
js_mkfun
(
builtin_fs_mkdir
));
js_set
(
js
,
lib
,
"mkdirSync"
,
js_mkfun
(
builtin_fs_mkdirSync
));
js_set
(
js
,
lib
,
"rmdir"
,
js_mkfun
(
builtin_fs_rmdir
));
js_set
(
js
,
lib
,
"rmdirSync"
,
js_mkfun
(
builtin_fs_rmdirSync
));
js_set
(
js
,
lib
,
"stat"
,
js_mkfun
(
builtin_fs_stat
));
js_set
(
js
,
lib
,
"statSync"
,
js_mkfun
(
builtin_fs_statSync
));
js_set
(
js
,
lib
,
"exists"
,
js_mkfun
(
builtin_fs_exists
));
js_set
(
js
,
lib
,
"existsSync"
,
js_mkfun
(
builtin_fs_existsSync
));
js_set
(
js
,
lib
,
"readdir"
,
js_mkfun
(
builtin_fs_readdir
));
js_set
(
js
,
lib
,
"readdirSync"
,
js_mkfun
(
builtin_fs_readdirSync
));
js_set
(
js
,
lib
,
get_toStringTag_sym_key
(),
js_mkstr
(
js
,
"fs"
,
2
));
return
lib
;
}
int
has_pending_fs_ops
(
void
)
{
return
(
pending_requests
&&
utarray_len
(
pending_requests
)
>
0
)
||
(
fs_loop
&&
uv_loop_alive
(
fs_loop
));
}
void
fs_poll_events
(
void
)
{
if
(
fs_loop
&&
fs_loop
==
uv_default_loop
()
&&
(
rt
->
flags
&
ANT_RUNTIME_EXT_EVENT_LOOP
))
return
;
if
(
fs_loop
&&
uv_loop_alive
(
fs_loop
))
{
uv_run
(
fs_loop
,
UV_RUN_ONCE
);
if
(
pending_requests
&&
utarray_len
(
pending_requests
)
>
0
)
usleep
(
1000
);
}
}
void
fs_gc_update_roots
(
GC_FWD_ARGS
)
{
if
(
!
pending_requests
)
return
;
unsigned
int
len
=
utarray_len
(
pending_requests
);
for
(
unsigned
int
i
=
0
;
i
<
len
;
i
++
)
{
fs_request_t
**
reqp
=
(
fs_request_t
**
)
utarray_eltptr
(
pending_requests
,
i
);
if
(
reqp
&&
*
reqp
)
{
(
*
reqp
)
->
promise
=
fwd_val
(
ctx
,
(
*
reqp
)
->
promise
);
}
}
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Fri, Mar 27, 12:22 PM (2 d)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
512816
Default Alt Text
fs.c (33 KB)
Attached To
Mode
rANT Ant
Attached
Detach File
Event Timeline
Log In to Comment