-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Environment
Windows Version: Microsoft Windows [Version 10.0.19041.329]
Distribution: ubuntu 20.04 (same issue in debian 10)
WSL: WSL 1
Version: Linux version 4.4.0-19041-Microsoft (Microsoft@Microsoft.com) (gcc version 5.4.0 (GCC) ) #1-Microsoft Fri Dec 06 14:06:00 PST 2019
Uname: Linux weilin0 4.4.0-19041-Microsoft #1-Microsoft Fri Dec 06 14:06:00 PST 2019 x86_64 x86_64 x86_64 GNU/Linux
Steps to reproduce
- Create a new file named
test_rename.cwith the content:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
int main(void)
{
printf("rename: %d\n", rename("not_exist_file", "not_exist_file"));
printf("errno: %d\n", errno);
return 0;
}- Compile & run:
gcc test_rename.c -o test_rename
./test_renameoutput:
rename: 0
errno: 0
Expected behavior
In a real linux, for example:
Linux version 4.19.0-9-amd64 (debian-kernel@lists.debian.org) (gcc version 8.3.0 (Debian 8.3.0-6)) #1 SMP Debian 4.19.118-2+deb10u1 (2020-06-07)
The program should output:
rename: -1
errno: 2
Because rename() on a non-existing file should return -1 and set errno to ENOENT.
Actual behavior
WSL's rename() always returns 0 if source file name equals to the dest file name no matter the file exists or not. This happens in the recently updates on windows 2004, the previous WSL in windows 1909 behaves correctly.
Summary
rename() should always return -1 and set ENOENT to errno if the file doesn't exist. This incorrect return code will break applications which rely on the rename return code:
I am the maintainer of a command productivity tool z.lua, an issue related to WSL 1 has been reported recently: skywind3000/z.lua#104
Lua is lack of system APIs to detect file existence, a portable way for this is using rename:
function exists(name)
if type(name)~="string" then return false end
return os.rename(name,name) and true or false
endThis is a widely used method to detect file existence in lua, it is also mentioned in stackoverflow.
While the latest WSL1's rename() system call always returns zero and break this function, which breaks z.lua in WSL1.