mirror of
https://github.com/libuv/libuv
synced 2025-03-28 21:13:16 +00:00
fs: report original error
Exposes the original system error of the filesystem syscalls. Adds a new uv_fs_get_system_error which returns orignal errno on Linux or GetLastError on Windows. Ref: https://github.com/libuv/libuv/issues/2348 PR-URL: https://github.com/libuv/libuv/pull/2810 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
This commit is contained in:
parent
2bbf7d5c8c
commit
457285827c
@ -492,6 +492,13 @@ API
|
||||
|
||||
.. versionadded:: 1.19.0
|
||||
|
||||
.. c:function:: int uv_fs_get_system_error(const uv_fs_t* req)
|
||||
|
||||
Returns the platform specific error code - `GetLastError()` value on Windows
|
||||
and `-(req->result)` on other platforms.
|
||||
|
||||
.. versionadded:: 1.38.0
|
||||
|
||||
.. c:function:: void* uv_fs_get_ptr(const uv_fs_t* req)
|
||||
|
||||
Returns `req->ptr`.
|
||||
|
@ -1307,6 +1307,7 @@ struct uv_fs_s {
|
||||
|
||||
UV_EXTERN uv_fs_type uv_fs_get_type(const uv_fs_t*);
|
||||
UV_EXTERN ssize_t uv_fs_get_result(const uv_fs_t*);
|
||||
UV_EXTERN int uv_fs_get_system_error(const uv_fs_t*);
|
||||
UV_EXTERN void* uv_fs_get_ptr(const uv_fs_t*);
|
||||
UV_EXTERN const char* uv_fs_get_path(const uv_fs_t*);
|
||||
UV_EXTERN uv_stat_t* uv_fs_get_statbuf(uv_fs_t*);
|
||||
|
@ -2086,3 +2086,7 @@ int uv_fs_statfs(uv_loop_t* loop,
|
||||
PATH;
|
||||
POST;
|
||||
}
|
||||
|
||||
int uv_fs_get_system_error(const uv_fs_t* req) {
|
||||
return -req->result;
|
||||
}
|
||||
|
117
src/win/fs.c
117
src/win/fs.c
@ -257,6 +257,7 @@ INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req,
|
||||
req->loop = loop;
|
||||
req->flags = 0;
|
||||
req->fs_type = fs_type;
|
||||
req->sys_errno_ = 0;
|
||||
req->result = 0;
|
||||
req->ptr = NULL;
|
||||
req->path = NULL;
|
||||
@ -2840,7 +2841,8 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
|
||||
INIT(UV_FS_OPEN);
|
||||
err = fs__capture_path(req, path, NULL, cb != NULL);
|
||||
if (err) {
|
||||
return uv_translate_sys_error(err);
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
req->fs.info.file_flags = flags;
|
||||
@ -2865,8 +2867,10 @@ int uv_fs_read(uv_loop_t* loop,
|
||||
uv_fs_cb cb) {
|
||||
INIT(UV_FS_READ);
|
||||
|
||||
if (bufs == NULL || nbufs == 0)
|
||||
if (bufs == NULL || nbufs == 0) {
|
||||
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
req->file.fd = fd;
|
||||
|
||||
@ -2875,8 +2879,10 @@ int uv_fs_read(uv_loop_t* loop,
|
||||
if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
|
||||
req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs));
|
||||
|
||||
if (req->fs.info.bufs == NULL)
|
||||
if (req->fs.info.bufs == NULL) {
|
||||
SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
|
||||
return UV_ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
|
||||
|
||||
@ -2894,8 +2900,10 @@ int uv_fs_write(uv_loop_t* loop,
|
||||
uv_fs_cb cb) {
|
||||
INIT(UV_FS_WRITE);
|
||||
|
||||
if (bufs == NULL || nbufs == 0)
|
||||
if (bufs == NULL || nbufs == 0) {
|
||||
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
req->file.fd = fd;
|
||||
|
||||
@ -2904,8 +2912,10 @@ int uv_fs_write(uv_loop_t* loop,
|
||||
if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
|
||||
req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs));
|
||||
|
||||
if (req->fs.info.bufs == NULL)
|
||||
if (req->fs.info.bufs == NULL) {
|
||||
SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
|
||||
return UV_ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
|
||||
|
||||
@ -2921,7 +2931,8 @@ int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
|
||||
INIT(UV_FS_UNLINK);
|
||||
err = fs__capture_path(req, path, NULL, cb != NULL);
|
||||
if (err) {
|
||||
return uv_translate_sys_error(err);
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
POST;
|
||||
@ -2935,7 +2946,8 @@ int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
|
||||
INIT(UV_FS_MKDIR);
|
||||
err = fs__capture_path(req, path, NULL, cb != NULL);
|
||||
if (err) {
|
||||
return uv_translate_sys_error(err);
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
req->fs.info.mode = mode;
|
||||
@ -2951,8 +2963,10 @@ int uv_fs_mkdtemp(uv_loop_t* loop,
|
||||
|
||||
INIT(UV_FS_MKDTEMP);
|
||||
err = fs__capture_path(req, tpl, NULL, TRUE);
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
if (err) {
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
POST;
|
||||
}
|
||||
@ -2966,8 +2980,10 @@ int uv_fs_mkstemp(uv_loop_t* loop,
|
||||
|
||||
INIT(UV_FS_MKSTEMP);
|
||||
err = fs__capture_path(req, tpl, NULL, TRUE);
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
if (err) {
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
POST;
|
||||
}
|
||||
@ -2979,7 +2995,8 @@ int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
|
||||
INIT(UV_FS_RMDIR);
|
||||
err = fs__capture_path(req, path, NULL, cb != NULL);
|
||||
if (err) {
|
||||
return uv_translate_sys_error(err);
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
POST;
|
||||
@ -2993,7 +3010,8 @@ int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
|
||||
INIT(UV_FS_SCANDIR);
|
||||
err = fs__capture_path(req, path, NULL, cb != NULL);
|
||||
if (err) {
|
||||
return uv_translate_sys_error(err);
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
req->fs.info.file_flags = flags;
|
||||
@ -3008,8 +3026,10 @@ int uv_fs_opendir(uv_loop_t* loop,
|
||||
|
||||
INIT(UV_FS_OPENDIR);
|
||||
err = fs__capture_path(req, path, NULL, cb != NULL);
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
if (err) {
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
POST;
|
||||
}
|
||||
|
||||
@ -3022,6 +3042,7 @@ int uv_fs_readdir(uv_loop_t* loop,
|
||||
if (dir == NULL ||
|
||||
dir->dirents == NULL ||
|
||||
dir->dir_handle == INVALID_HANDLE_VALUE) {
|
||||
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
@ -3034,8 +3055,10 @@ int uv_fs_closedir(uv_loop_t* loop,
|
||||
uv_dir_t* dir,
|
||||
uv_fs_cb cb) {
|
||||
INIT(UV_FS_CLOSEDIR);
|
||||
if (dir == NULL)
|
||||
if (dir == NULL) {
|
||||
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
|
||||
return UV_EINVAL;
|
||||
}
|
||||
req->ptr = dir;
|
||||
POST;
|
||||
}
|
||||
@ -3047,7 +3070,8 @@ int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
|
||||
INIT(UV_FS_LINK);
|
||||
err = fs__capture_path(req, path, new_path, cb != NULL);
|
||||
if (err) {
|
||||
return uv_translate_sys_error(err);
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
POST;
|
||||
@ -3061,7 +3085,8 @@ int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
|
||||
INIT(UV_FS_SYMLINK);
|
||||
err = fs__capture_path(req, path, new_path, cb != NULL);
|
||||
if (err) {
|
||||
return uv_translate_sys_error(err);
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
req->fs.info.file_flags = flags;
|
||||
@ -3076,7 +3101,8 @@ int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
|
||||
INIT(UV_FS_READLINK);
|
||||
err = fs__capture_path(req, path, NULL, cb != NULL);
|
||||
if (err) {
|
||||
return uv_translate_sys_error(err);
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
POST;
|
||||
@ -3090,12 +3116,14 @@ int uv_fs_realpath(uv_loop_t* loop, uv_fs_t* req, const char* path,
|
||||
INIT(UV_FS_REALPATH);
|
||||
|
||||
if (!path) {
|
||||
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
err = fs__capture_path(req, path, NULL, cb != NULL);
|
||||
if (err) {
|
||||
return uv_translate_sys_error(err);
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
POST;
|
||||
@ -3109,7 +3137,8 @@ int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid,
|
||||
INIT(UV_FS_CHOWN);
|
||||
err = fs__capture_path(req, path, NULL, cb != NULL);
|
||||
if (err) {
|
||||
return uv_translate_sys_error(err);
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
POST;
|
||||
@ -3130,8 +3159,10 @@ int uv_fs_lchown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid,
|
||||
INIT(UV_FS_LCHOWN);
|
||||
err = fs__capture_path(req, path, NULL, cb != NULL);
|
||||
if (err) {
|
||||
return uv_translate_sys_error(err);
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
POST;
|
||||
}
|
||||
|
||||
@ -3142,7 +3173,8 @@ int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
|
||||
INIT(UV_FS_STAT);
|
||||
err = fs__capture_path(req, path, NULL, cb != NULL);
|
||||
if (err) {
|
||||
return uv_translate_sys_error(err);
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
POST;
|
||||
@ -3155,7 +3187,8 @@ int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
|
||||
INIT(UV_FS_LSTAT);
|
||||
err = fs__capture_path(req, path, NULL, cb != NULL);
|
||||
if (err) {
|
||||
return uv_translate_sys_error(err);
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
POST;
|
||||
@ -3176,7 +3209,8 @@ int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
|
||||
INIT(UV_FS_RENAME);
|
||||
err = fs__capture_path(req, path, new_path, cb != NULL);
|
||||
if (err) {
|
||||
return uv_translate_sys_error(err);
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
POST;
|
||||
@ -3219,13 +3253,15 @@ int uv_fs_copyfile(uv_loop_t* loop,
|
||||
if (flags & ~(UV_FS_COPYFILE_EXCL |
|
||||
UV_FS_COPYFILE_FICLONE |
|
||||
UV_FS_COPYFILE_FICLONE_FORCE)) {
|
||||
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
err = fs__capture_path(req, path, new_path, cb != NULL);
|
||||
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
if (err) {
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
req->fs.info.file_flags = flags;
|
||||
POST;
|
||||
@ -3252,8 +3288,10 @@ int uv_fs_access(uv_loop_t* loop,
|
||||
|
||||
INIT(UV_FS_ACCESS);
|
||||
err = fs__capture_path(req, path, NULL, cb != NULL);
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
if (err) {
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
req->fs.info.mode = flags;
|
||||
POST;
|
||||
@ -3267,7 +3305,8 @@ int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
|
||||
INIT(UV_FS_CHMOD);
|
||||
err = fs__capture_path(req, path, NULL, cb != NULL);
|
||||
if (err) {
|
||||
return uv_translate_sys_error(err);
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
req->fs.info.mode = mode;
|
||||
@ -3291,7 +3330,8 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
|
||||
INIT(UV_FS_UTIME);
|
||||
err = fs__capture_path(req, path, NULL, cb != NULL);
|
||||
if (err) {
|
||||
return uv_translate_sys_error(err);
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
req->fs.time.atime = atime;
|
||||
@ -3316,7 +3356,8 @@ int uv_fs_lutime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
|
||||
INIT(UV_FS_LUTIME);
|
||||
err = fs__capture_path(req, path, NULL, cb != NULL);
|
||||
if (err) {
|
||||
return uv_translate_sys_error(err);
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
req->fs.time.atime = atime;
|
||||
@ -3333,8 +3374,14 @@ int uv_fs_statfs(uv_loop_t* loop,
|
||||
|
||||
INIT(UV_FS_STATFS);
|
||||
err = fs__capture_path(req, path, NULL, cb != NULL);
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
if (err) {
|
||||
SET_REQ_WIN32_ERROR(req, err);
|
||||
return req->result;
|
||||
}
|
||||
|
||||
POST;
|
||||
}
|
||||
|
||||
int uv_fs_get_system_error(const uv_fs_t* req) {
|
||||
return req->sys_errno_;
|
||||
}
|
||||
|
@ -4347,3 +4347,21 @@ TEST_IMPL(fs_statfs) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_get_system_error) {
|
||||
uv_fs_t req;
|
||||
int r;
|
||||
int system_error;
|
||||
|
||||
r = uv_fs_statfs(NULL, &req, "non_existing_file", NULL);
|
||||
ASSERT(r != 0);
|
||||
|
||||
system_error = uv_fs_get_system_error(&req);
|
||||
#ifdef _WIN32
|
||||
ASSERT(system_error == ERROR_FILE_NOT_FOUND);
|
||||
#else
|
||||
ASSERT(system_error == ENOENT);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -409,6 +409,7 @@ TEST_DECLARE (fs_open_readonly_acl)
|
||||
TEST_DECLARE (fs_fchmod_archive_readonly)
|
||||
TEST_DECLARE (fs_invalid_mkdir_name)
|
||||
#endif
|
||||
TEST_DECLARE (fs_get_system_error)
|
||||
TEST_DECLARE (strscpy)
|
||||
TEST_DECLARE (threadpool_queue_work_simple)
|
||||
TEST_DECLARE (threadpool_queue_work_einval)
|
||||
@ -1036,6 +1037,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (fs_fchmod_archive_readonly)
|
||||
TEST_ENTRY (fs_invalid_mkdir_name)
|
||||
#endif
|
||||
TEST_ENTRY (fs_get_system_error)
|
||||
TEST_ENTRY (get_osfhandle_valid_handle)
|
||||
TEST_ENTRY (open_osfhandle_valid_handle)
|
||||
TEST_ENTRY (strscpy)
|
||||
|
Loading…
x
Reference in New Issue
Block a user