aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-06-09 09:51:46 +0100
committerRon Yorston <rmy@pobox.com>2018-06-09 09:51:46 +0100
commit83f299376147a26436bc668ebcf0966a05010951 (patch)
tree4c5570695a931afa2a97f5769657fc096f5c20ec
parente6863d2959f6c85998b1bff5557e35f568332bc6 (diff)
downloadbusybox-w32-realpath.tar.gz
busybox-w32-realpath.tar.bz2
busybox-w32-realpath.zip
realpath: implement realpath(3) and enable realpath(1)realpath
The implementation of realpath(3) is based on code by Stuart Dootson (studoot on GitHub).
-rw-r--r--configs/mingw32_defconfig2
-rw-r--r--configs/mingw64_defconfig2
-rw-r--r--win32/mingw.c59
3 files changed, 58 insertions, 5 deletions
diff --git a/configs/mingw32_defconfig b/configs/mingw32_defconfig
index b0bdb25cb..249ae2072 100644
--- a/configs/mingw32_defconfig
+++ b/configs/mingw32_defconfig
@@ -288,7 +288,7 @@ CONFIG_PRINTF=y
288CONFIG_PWD=y 288CONFIG_PWD=y
289# CONFIG_READLINK is not set 289# CONFIG_READLINK is not set
290# CONFIG_FEATURE_READLINK_FOLLOW is not set 290# CONFIG_FEATURE_READLINK_FOLLOW is not set
291# CONFIG_REALPATH is not set 291CONFIG_REALPATH=y
292CONFIG_RM=y 292CONFIG_RM=y
293CONFIG_RMDIR=y 293CONFIG_RMDIR=y
294CONFIG_SEQ=y 294CONFIG_SEQ=y
diff --git a/configs/mingw64_defconfig b/configs/mingw64_defconfig
index 8cb8431d0..147e1e266 100644
--- a/configs/mingw64_defconfig
+++ b/configs/mingw64_defconfig
@@ -288,7 +288,7 @@ CONFIG_PRINTF=y
288CONFIG_PWD=y 288CONFIG_PWD=y
289# CONFIG_READLINK is not set 289# CONFIG_READLINK is not set
290# CONFIG_FEATURE_READLINK_FOLLOW is not set 290# CONFIG_FEATURE_READLINK_FOLLOW is not set
291# CONFIG_REALPATH is not set 291CONFIG_REALPATH=y
292CONFIG_RM=y 292CONFIG_RM=y
293CONFIG_RMDIR=y 293CONFIG_RMDIR=y
294CONFIG_SEQ=y 294CONFIG_SEQ=y
diff --git a/win32/mingw.c b/win32/mingw.c
index 8141e45a5..b75565fc2 100644
--- a/win32/mingw.c
+++ b/win32/mingw.c
@@ -1,5 +1,6 @@
1#include "libbb.h" 1#include "libbb.h"
2#include <userenv.h> 2#include <userenv.h>
3#include "lazyload.h"
3 4
4#if defined(__MINGW64_VERSION_MAJOR) 5#if defined(__MINGW64_VERSION_MAJOR)
5#if ENABLE_GLOBBING 6#if ENABLE_GLOBBING
@@ -886,10 +887,63 @@ int link(const char *oldpath, const char *newpath)
886 return 0; 887 return 0;
887} 888}
888 889
890static char *resolve_symlinks(char *path)
891{
892 HANDLE h = INVALID_HANDLE_VALUE;
893 DECLARE_PROC_ADDR(kernel32.dll, DWORD, GetFinalPathNameByHandleA, HANDLE,
894 LPSTR, DWORD, DWORD);
895
896 if (!INIT_PROC_ADDR(GetFinalPathNameByHandleA)) {
897 errno = ENOSYS;
898 return NULL;
899 }
900
901 /* need a file handle to resolve symlinks */
902 h = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL,
903 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
904 NULL);
905 if (h != INVALID_HANDLE_VALUE) {
906 /* normalize the path and return it on success */
907 DWORD status = GetFinalPathNameByHandleA(h, path, MAX_PATH,
908 FILE_NAME_NORMALIZED|VOLUME_NAME_DOS);
909 CloseHandle(h);
910 if (status != 0 && status < MAX_PATH) {
911 /* skip '\\?\' prefix */
912 return (!strncmp(path, "\\\\?\\", 4)) ? (path + 4) : path;
913 }
914 }
915
916 errno = err_win_to_posix(GetLastError());
917 return NULL;
918}
919
920/*
921 * Emulate realpath in two stages:
922 *
923 * - _fullpath handles './', '../' and extra '/' characters. The
924 * resulting path may not refer to an actual file.
925 *
926 * - resolve_symlinks checks that the file exists (by opening it) and
927 * resolves symlinks by calling GetFinalPathNameByHandleA.
928 */
889char *realpath(const char *path, char *resolved_path) 929char *realpath(const char *path, char *resolved_path)
890{ 930{
891 /* FIXME: need normalization */ 931 char buffer[MAX_PATH];
892 return strcpy(resolved_path, path); 932 char *real_path;
933
934 /* enforce glibc pre-2.3 behaviour */
935 if (path == NULL || resolved_path == NULL) {
936 errno = EINVAL;
937 return NULL;
938 }
939
940 if (_fullpath(buffer, path, MAX_PATH) &&
941 (real_path=resolve_symlinks(buffer))) {
942 strcpy(resolved_path, real_path);
943 convert_slashes(resolved_path);
944 return resolved_path;
945 }
946 return NULL;
893} 947}
894 948
895const char *get_busybox_exec_path(void) 949const char *get_busybox_exec_path(void)
@@ -1208,7 +1262,6 @@ off_t mingw_lseek(int fd, off_t offset, int whence)
1208 1262
1209#if ENABLE_FEATURE_PS_TIME || ENABLE_FEATURE_PS_LONG 1263#if ENABLE_FEATURE_PS_TIME || ENABLE_FEATURE_PS_LONG
1210#undef GetTickCount64 1264#undef GetTickCount64
1211#include "lazyload.h"
1212 1265
1213ULONGLONG CompatGetTickCount64(void) 1266ULONGLONG CompatGetTickCount64(void)
1214{ 1267{