[libc-commits] [libc] [libc][windows] implement unistd/rmdir (PR #123742)
Schrodinger ZHU Yifan via libc-commits
libc-commits at lists.llvm.org
Tue Jan 21 04:21:56 PST 2025
https://github.com/SchrodingerZhu created https://github.com/llvm/llvm-project/pull/123742
Implement `rmdir` for windows.
Additionally, implement a header utility to translate win32 error to POSIX errno.
No test other than build is provided: such test require `mkdir`, which demands a complicated translation between `mode_t` and `SECURITY_DESCRIPTOR` (todo).
>From e2708f53b64355f12d04c4d6821ff84d46aa0f0b Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Tue, 21 Jan 2025 12:18:20 +0000
Subject: [PATCH] [libc][windows] implement unistd/rmdir
---
libc/config/windows/entrypoints.txt | 1 +
.../__support/OSUtil/windows/CMakeLists.txt | 9 ++
libc/src/__support/OSUtil/windows/error.h | 134 ++++++++++++++++++
libc/src/unistd/windows/CMakeLists.txt | 12 ++
libc/src/unistd/windows/rmdir.cpp | 28 ++++
5 files changed, 184 insertions(+)
create mode 100644 libc/src/__support/OSUtil/windows/error.h
create mode 100644 libc/src/unistd/windows/rmdir.cpp
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index aad320995d339e..774008da5c48c3 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -104,6 +104,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# unistd.h entrypoints
libc.src.unistd.getentropy
+ libc.src.unistd.rmdir
)
set(TARGET_LIBM_ENTRYPOINTS
diff --git a/libc/src/__support/OSUtil/windows/CMakeLists.txt b/libc/src/__support/OSUtil/windows/CMakeLists.txt
index be316d77f5d06a..8fa35fd436e03c 100644
--- a/libc/src/__support/OSUtil/windows/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/windows/CMakeLists.txt
@@ -8,3 +8,12 @@ add_object_library(
DEPENDS
libc.src.__support.macros.config
)
+
+add_header_library(
+ error
+ HDRS
+ error.h
+ DEPENDS
+ libc.src.__support.common
+ libc.hdr.errno_macros
+)
diff --git a/libc/src/__support/OSUtil/windows/error.h b/libc/src/__support/OSUtil/windows/error.h
new file mode 100644
index 00000000000000..5a1737c62af41d
--- /dev/null
+++ b/libc/src/__support/OSUtil/windows/error.h
@@ -0,0 +1,134 @@
+//===------------- Convert Win32 Error to POSIX ---------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_WINDOWS_WINERROR_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_WINDOWS_WINERROR_H
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winerror.h>
+
+#include "hdr/errno_macros.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LIBC_INLINE constexpr int map_win_error_to_errno(DWORD error) {
+ // Translation based on
+ // https://github.com/llvm/llvm-project/blob/2b26ee6e790574e05c3c9a562bc37897daf0f384/libcxx/src/system_error.cpp
+
+ // For the relation between errc and errno, see:
+ // https://en.cppreference.com/w/cpp/error/errc
+ switch (error) {
+ case ERROR_ACCESS_DENIED:
+ return EPERM;
+ case ERROR_ALREADY_EXISTS:
+ return EEXIST;
+ case ERROR_BAD_NETPATH:
+ return ENOENT;
+ case ERROR_BAD_PATHNAME:
+ return ENOENT;
+ case ERROR_BAD_UNIT:
+ return ENODEV;
+ case ERROR_BROKEN_PIPE:
+ return EPIPE;
+ case ERROR_BUFFER_OVERFLOW:
+ return ENAMETOOLONG;
+ case ERROR_BUSY:
+ return EBUSY;
+ case ERROR_BUSY_DRIVE:
+ return EBUSY;
+ case ERROR_CANNOT_MAKE:
+ return EPERM;
+ case ERROR_CANTOPEN:
+ return EIO;
+ case ERROR_CANTREAD:
+ return EIO;
+ case ERROR_CANTWRITE:
+ return EIO;
+ case ERROR_CURRENT_DIRECTORY:
+ return EPERM;
+ case ERROR_DEV_NOT_EXIST:
+ return ENODEV;
+ case ERROR_DEVICE_IN_USE:
+ return EBUSY;
+ case ERROR_DIR_NOT_EMPTY:
+ return ENOTEMPTY;
+ case ERROR_DIRECTORY:
+ return EINVAL;
+ case ERROR_DISK_FULL:
+ return ENOSPC;
+ case ERROR_FILE_EXISTS:
+ return EEXIST;
+ case ERROR_FILE_NOT_FOUND:
+ return ENOENT;
+ case ERROR_HANDLE_DISK_FULL:
+ return ENOSPC;
+ case ERROR_INVALID_ACCESS:
+ return EPERM;
+ case ERROR_INVALID_DRIVE:
+ return ENODEV;
+ case ERROR_INVALID_FUNCTION:
+ return ENOSYS;
+ case ERROR_INVALID_HANDLE:
+ return EINVAL;
+ case ERROR_INVALID_NAME:
+ return ENOENT;
+ case ERROR_INVALID_PARAMETER:
+ return EINVAL;
+ case ERROR_LOCK_VIOLATION:
+ return ENOLCK;
+ case ERROR_LOCKED:
+ return ENOLCK;
+ case ERROR_NEGATIVE_SEEK:
+ return EINVAL;
+ case ERROR_NOACCESS:
+ return EPERM;
+ case ERROR_NOT_ENOUGH_MEMORY:
+ return ENOMEM;
+ case ERROR_NOT_READY:
+ return EAGAIN;
+ case ERROR_NOT_SAME_DEVICE:
+ return EXDEV;
+ case ERROR_NOT_SUPPORTED:
+ return ENOTSUP;
+ case ERROR_OPEN_FAILED:
+ return EIO;
+ case ERROR_OPEN_FILES:
+ return EBUSY;
+ case ERROR_OPERATION_ABORTED:
+ return ECANCELED;
+ case ERROR_OUTOFMEMORY:
+ return ENOMEM;
+ case ERROR_PATH_NOT_FOUND:
+ return ENOENT;
+ case ERROR_READ_FAULT:
+ return EIO;
+ case ERROR_REPARSE_TAG_INVALID:
+ return EINVAL;
+ case ERROR_RETRY:
+ return EAGAIN;
+ case ERROR_SEEK:
+ return EIO;
+ case ERROR_SHARING_VIOLATION:
+ return EPERM;
+ case ERROR_TOO_MANY_OPEN_FILES:
+ return EMFILE;
+ case ERROR_WRITE_FAULT:
+ return EIO;
+ case ERROR_WRITE_PROTECT:
+ return EPERM;
+ default:
+ // For unrecognized errno, default to ENOSYS
+ return ENOTSUP;
+ }
+}
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_WINDOWS_WINERROR_H
diff --git a/libc/src/unistd/windows/CMakeLists.txt b/libc/src/unistd/windows/CMakeLists.txt
index 195d98cdb51d4c..292fa67f235112 100644
--- a/libc/src/unistd/windows/CMakeLists.txt
+++ b/libc/src/unistd/windows/CMakeLists.txt
@@ -9,3 +9,15 @@ add_entrypoint_object(
libc.hdr.errno_macros
libc.src.errno.errno
)
+
+add_entrypoint_object(
+ rmdir
+ SRCS
+ rmdir.cpp
+ HDRS
+ ../rmdir.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.src.errno.errno
+ libc.src.__support.OSUtil.windows.error
+)
diff --git a/libc/src/unistd/windows/rmdir.cpp b/libc/src/unistd/windows/rmdir.cpp
new file mode 100644
index 00000000000000..9367d7959f729d
--- /dev/null
+++ b/libc/src/unistd/windows/rmdir.cpp
@@ -0,0 +1,28 @@
+//===-- Windows implementation of rmdir -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/unistd/rmdir.h"
+#include "src/__support/OSUtil/windows/error.h"
+#include "src/__support/common.h"
+#include "src/errno/libc_errno.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, rmdir, (const char *path)) {
+ if (::RemoveDirectoryA(path))
+ return 0;
+
+ DWORD error = ::GetLastError();
+ libc_errno = map_win_error_to_errno(error);
+ return -1;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
More information about the libc-commits
mailing list