aboutsummaryrefslogtreecommitdiff
path: root/src/node_file.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/node_file.cc')
-rw-r--r--src/node_file.cc43
1 files changed, 30 insertions, 13 deletions
diff --git a/src/node_file.cc b/src/node_file.cc
index 36bb326aa5..510689607e 100644
--- a/src/node_file.cc
+++ b/src/node_file.cc
@@ -1527,7 +1527,6 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
const auto enc = ParseEncoding(env->isolate(), args[3], UTF8);
- std::unique_ptr<char[]> delete_on_return;
Local<Value> value = args[1];
char* buf = nullptr;
size_t len;
@@ -1555,24 +1554,42 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
}
}
- if (buf == nullptr) {
+ if (is_async) { // write(fd, string, pos, enc, req)
+ CHECK_NE(req_wrap, nullptr);
len = StringBytes::StorageSize(env->isolate(), value, enc);
- buf = new char[len];
- // SYNC_CALL returns on error. Make sure to always free the memory.
- if (!is_async) delete_on_return.reset(buf);
+ FSReqBase::FSReqBuffer& stack_buffer =
+ req_wrap->Init("write", len, enc);
// StorageSize may return too large a char, so correct the actual length
// by the write size
- len = StringBytes::Write(env->isolate(), buf, len, args[1], enc);
- }
-
- uv_buf_t uvbuf = uv_buf_init(buf, len);
-
- if (is_async) { // write(fd, string, pos, enc, req)
- AsyncCall(env, req_wrap, args, "write", UTF8, AfterInteger,
- uv_fs_write, fd, &uvbuf, 1, pos);
+ len = StringBytes::Write(env->isolate(), *stack_buffer, len, args[1], enc);
+ stack_buffer.SetLengthAndZeroTerminate(len);
+ uv_buf_t uvbuf = uv_buf_init(*stack_buffer, len);
+ int err = uv_fs_write(env->event_loop(), req_wrap->req(),
+ fd, &uvbuf, 1, pos, AfterInteger);
+ req_wrap->Dispatched();
+ if (err < 0) {
+ uv_fs_t* uv_req = req_wrap->req();
+ uv_req->result = err;
+ uv_req->path = nullptr;
+ AfterInteger(uv_req); // after may delete req_wrap if there is an error
+ } else {
+ req_wrap->SetReturnValue(args);
+ }
} else { // write(fd, string, pos, enc, undefined, ctx)
CHECK_EQ(argc, 6);
fs_req_wrap req_wrap;
+ FSReqBase::FSReqBuffer stack_buffer;
+ if (buf == nullptr) {
+ len = StringBytes::StorageSize(env->isolate(), value, enc);
+ stack_buffer.AllocateSufficientStorage(len + 1);
+ // StorageSize may return too large a char, so correct the actual length
+ // by the write size
+ len = StringBytes::Write(env->isolate(), *stack_buffer,
+ len, args[1], enc);
+ stack_buffer.SetLengthAndZeroTerminate(len);
+ buf = *stack_buffer;
+ }
+ uv_buf_t uvbuf = uv_buf_init(buf, len);
int bytesWritten = SyncCall(env, args[5], &req_wrap, "write",
uv_fs_write, fd, &uvbuf, 1, pos);
args.GetReturnValue().Set(bytesWritten);