Skip to content

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

Description

@skywind3000

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions