ext/libuv/src/unix/fs.c in libuv-2.0.1 vs ext/libuv/src/unix/fs.c in libuv-2.0.2
- old
+ new
@@ -56,56 +56,67 @@
#if defined(__linux__) || defined(__sun)
# include <sys/sendfile.h>
#endif
-#define INIT(type) \
+#define INIT(subtype) \
do { \
- uv__req_init((loop), (req), UV_FS); \
- (req)->fs_type = UV_FS_ ## type; \
- (req)->result = 0; \
- (req)->ptr = NULL; \
- (req)->loop = loop; \
- (req)->path = NULL; \
- (req)->new_path = NULL; \
- (req)->cb = (cb); \
+ req->type = UV_FS; \
+ if (cb != NULL) \
+ uv__req_init(loop, req, UV_FS); \
+ req->fs_type = UV_FS_ ## subtype; \
+ req->result = 0; \
+ req->ptr = NULL; \
+ req->loop = loop; \
+ req->path = NULL; \
+ req->new_path = NULL; \
+ req->cb = cb; \
} \
while (0)
#define PATH \
do { \
- (req)->path = uv__strdup(path); \
- if ((req)->path == NULL) \
- return -ENOMEM; \
+ assert(path != NULL); \
+ if (cb == NULL) { \
+ req->path = path; \
+ } else { \
+ req->path = uv__strdup(path); \
+ if (req->path == NULL) \
+ return -ENOMEM; \
+ } \
} \
while (0)
#define PATH2 \
do { \
- size_t path_len; \
- size_t new_path_len; \
- path_len = strlen((path)) + 1; \
- new_path_len = strlen((new_path)) + 1; \
- (req)->path = uv__malloc(path_len + new_path_len); \
- if ((req)->path == NULL) \
- return -ENOMEM; \
- (req)->new_path = (req)->path + path_len; \
- memcpy((void*) (req)->path, (path), path_len); \
- memcpy((void*) (req)->new_path, (new_path), new_path_len); \
+ if (cb == NULL) { \
+ req->path = path; \
+ req->new_path = new_path; \
+ } else { \
+ size_t path_len; \
+ size_t new_path_len; \
+ path_len = strlen(path) + 1; \
+ new_path_len = strlen(new_path) + 1; \
+ req->path = uv__malloc(path_len + new_path_len); \
+ if (req->path == NULL) \
+ return -ENOMEM; \
+ req->new_path = req->path + path_len; \
+ memcpy((void*) req->path, path, path_len); \
+ memcpy((void*) req->new_path, new_path, new_path_len); \
+ } \
} \
while (0)
#define POST \
do { \
- if ((cb) != NULL) { \
- uv__work_submit((loop), &(req)->work_req, uv__fs_work, uv__fs_done); \
+ if (cb != NULL) { \
+ uv__work_submit(loop, &req->work_req, uv__fs_work, uv__fs_done); \
return 0; \
} \
else { \
- uv__fs_work(&(req)->work_req); \
- uv__fs_done(&(req)->work_req, 0); \
- return (req)->result; \
+ uv__fs_work(&req->work_req); \
+ return req->result; \
} \
} \
while (0)
@@ -884,12 +895,11 @@
if (status == -ECANCELED) {
assert(req->result == 0);
req->result = -ECANCELED;
}
- if (req->cb != NULL)
- req->cb(req);
+ req->cb(req);
}
int uv_fs_access(uv_loop_t* loop,
uv_fs_t* req,
@@ -1069,10 +1079,13 @@
uv_file file,
const uv_buf_t bufs[],
unsigned int nbufs,
int64_t off,
uv_fs_cb cb) {
+ if (bufs == NULL || nbufs == 0)
+ return -EINVAL;
+
INIT(READ);
req->file = file;
req->nbufs = nbufs;
req->bufs = req->bufsml;
@@ -1191,10 +1204,13 @@
uv_file file,
const uv_buf_t bufs[],
unsigned int nbufs,
int64_t off,
uv_fs_cb cb) {
+ if (bufs == NULL || nbufs == 0)
+ return -EINVAL;
+
INIT(WRITE);
req->file = file;
req->nbufs = nbufs;
req->bufs = req->bufsml;
@@ -1210,10 +1226,17 @@
POST;
}
void uv_fs_req_cleanup(uv_fs_t* req) {
- uv__free((void*)req->path);
+ /* Only necessary for asychronous requests, i.e., requests with a callback.
+ * Synchronous ones don't copy their arguments and have req->path and
+ * req->new_path pointing to user-owned memory. UV_FS_MKDTEMP is the
+ * exception to the rule, it always allocates memory.
+ */
+ if (req->path != NULL && (req->cb != NULL || req->fs_type == UV_FS_MKDTEMP))
+ uv__free((void*) req->path); /* Memory is shared with req->new_path. */
+
req->path = NULL;
req->new_path = NULL;
if (req->fs_type == UV_FS_SCANDIR && req->ptr != NULL)
uv__fs_scandir_cleanup(req);