microsoft / WSL

Issues found on WSL

Home Page:https://docs.microsoft.com/windows/wsl

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Incorrect return code from "rename()" syscall on a non-existing file

skywind3000 opened this issue · comments

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.c with 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_rename

output:

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
end

This 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.

Confirmed on WSL1. That has to be a regress.

image

FYI, the old WSL1 on Windows 1909 works as expected:

图片

and

图片

Any plan for this ? When can we get this fixed ?

@therealkenc , has it been fixed ? or still pending ??
is it assigned to some engineer or still nobody is accountable for this ?

Any update after three months ??

Any update ?? After 5 month.

Any update ?? After 7 month.

Seems fixed (since unknown version) ? Testing on 21H2:

rename -1
errno 2
ver:      Microsoft Windows [Version 10.0.19044.1415]
uname:    Linux Namniav-PC 4.4.0-19041-Microsoft #1237-Microsoft Sat Sep 11 14:32:00 PST 2021 x86_64 x86_64 x86_64 GNU/Linux
neofetch: Ubuntu 20.04.3 LTS on Windows 10 x86_64

@namniav , very strange, I have exactly the same windows version as yours, but it still happen:

图片

@skywind3000, oh, there must be something really weird...
image

I can't use z.lua1.8.16
The bug is still there.
image

@liam-keepmove there is a work-around, install lua-filesystem package, z.lua can use it to detect file existence instead of rename

This issue has been automatically closed since it has not had any activity for the past year. If you're still experiencing this issue please re-file this as a new issue or feature request.

Thank you!