From d4b2a5603d628ed00a764cb526df02e3a382a0c1 Mon Sep 17 00:00:00 2001 From: midipix Date: Feb 19 2024 03:43:05 +0000 Subject: slbt_util_real_path(): rewrite as a wrapper around an internal slbt_realpath(). --- diff --git a/project/common.mk b/project/common.mk index 7e48395..56a4364 100644 --- a/project/common.mk +++ b/project/common.mk @@ -60,6 +60,7 @@ INTERNAL_SRCS = \ src/internal/$(PACKAGE)_mapfile_impl.c \ src/internal/$(PACKAGE)_objlist_impl.c \ src/internal/$(PACKAGE)_objmeta_impl.c \ + src/internal/$(PACKAGE)_realpath_impl.c \ src/internal/$(PACKAGE)_snprintf_impl.c \ src/internal/$(PACKAGE)_symlink_impl.c \ diff --git a/project/headers.mk b/project/headers.mk index 4a732de..75a59b8 100644 --- a/project/headers.mk +++ b/project/headers.mk @@ -18,6 +18,7 @@ INTERNAL_HEADERS = \ $(PROJECT_DIR)/src/internal/$(PACKAGE)_mkdir_impl.h \ $(PROJECT_DIR)/src/internal/$(PACKAGE)_objlist_impl.h \ $(PROJECT_DIR)/src/internal/$(PACKAGE)_readlink_impl.h \ + $(PROJECT_DIR)/src/internal/$(PACKAGE)_realpath_impl.h \ $(PROJECT_DIR)/src/internal/$(PACKAGE)_snprintf_impl.h \ $(PROJECT_DIR)/src/internal/$(PACKAGE)_spawn_impl.h \ $(PROJECT_DIR)/src/internal/$(PACKAGE)_symlink_impl.h \ diff --git a/src/fallback/slbt_archive_import_mri.c b/src/fallback/slbt_archive_import_mri.c index 6217859..705cb88 100644 --- a/src/fallback/slbt_archive_import_mri.c +++ b/src/fallback/slbt_archive_import_mri.c @@ -42,7 +42,7 @@ static char * slbt_mri_argument( if (arg[0] == '/') { target = arg; } else { - if (slbt_util_real_path( + if (slbt_realpath( fdat,".",O_DIRECTORY, mricwd,sizeof(mricwd)) < 0) return 0; diff --git a/src/internal/slibtool_lconf_impl.c b/src/internal/slibtool_lconf_impl.c index 82904d2..298cb12 100644 --- a/src/internal/slibtool_lconf_impl.c +++ b/src/internal/slibtool_lconf_impl.c @@ -18,6 +18,7 @@ #include "slibtool_errinfo_impl.h" #include "slibtool_symlink_impl.h" #include "slibtool_readlink_impl.h" +#include "slibtool_realpath_impl.h" #include "slibtool_visibility_impl.h" enum slbt_lconf_opt { @@ -387,7 +388,7 @@ static int slbt_lconf_trace_result_plain( fderr = slbt_driver_fderr(dctx); - cpath = !(slbt_util_real_path(fdat,lconf,0,path,sizeof(path))) + cpath = !(slbt_realpath(fdat,lconf,0,path,sizeof(path))) ? path : lconf; switch (err) { @@ -435,7 +436,7 @@ static int slbt_lconf_trace_result_annotated( fderr = slbt_driver_fderr(dctx); - cpath = !(slbt_util_real_path(fdat,lconf,0,path,sizeof(path))) + cpath = !(slbt_realpath(fdat,lconf,0,path,sizeof(path))) ? path : lconf; switch (err) { diff --git a/src/internal/slibtool_realpath_impl.c b/src/internal/slibtool_realpath_impl.c new file mode 100644 index 0000000..e1e47b5 --- /dev/null +++ b/src/internal/slibtool_realpath_impl.c @@ -0,0 +1,103 @@ +/*******************************************************************/ +/* slibtool: a skinny libtool implementation, written in C */ +/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */ +/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ +/*******************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "slibtool_driver_impl.h" +#include "slibtool_readlink_impl.h" +#include "slibtool_realpath_impl.h" +#include "slibtool_visibility_impl.h" + +#ifdef HAVE_SYS_SYSCALL_H +#include +#endif + +#ifdef _MIDIPIX_ABI +#include +#endif + +#ifndef ENOTSUP +#define ENOTSUP EOPNOTSUPP +#endif + +#ifdef SYS___realpathat +extern long syscall(int, ...); +#endif + +slbt_hidden int slbt_realpath( + int fdat, + const char * path, + int options, + char * buf, + size_t buflen) +{ + int ret; + int fd; + int fdproc; + struct stat st; + struct stat stproc; + char procfspath[36]; + + /* common validation */ + if (!buf || (options & O_CREAT)) { + errno = EINVAL; + return -1; + } + + /* framework-based wrapper */ +#ifdef _MIDIPIX_ABI + return __fs_rpath(fdat,path,options,buf,buflen); +#endif + +#ifdef SYS___realpathat + return syscall(SYS___realpathat,fdat,path,buf,buflen,0); +#endif + + /* buflen */ + if (buflen < PATH_MAX) { + errno = ENOBUFS; + return -1; + } + + /* AT_FDCWD */ + if (fdat == AT_FDCWD) { + return realpath(path,buf) ? 0 : -1; + } + + /* /proc/self/fd */ + if ((fd = openat(fdat,path,options,0)) < 0) + return -1; + + sprintf(procfspath,"/proc/self/fd/%d",fd); + + if (slbt_readlinkat(fdat,procfspath,buf,buflen)) { + close(fd); + return -1; + } + + if ((fdproc = openat(AT_FDCWD,buf,options|O_NOFOLLOW,0)) < 0) { + close(fd); + errno = ELOOP; + return -1; + } + + ret = fstat(fd,&st) || fstat(fdproc,&stproc); + + close(fd); + close(fdproc); + + if (ret || (st.st_dev != stproc.st_dev) || (st.st_ino != stproc.st_ino)) { + errno = ENOTSUP; + return -1; + } + + return 0; +} diff --git a/src/internal/slibtool_realpath_impl.h b/src/internal/slibtool_realpath_impl.h new file mode 100644 index 0000000..01df1c1 --- /dev/null +++ b/src/internal/slibtool_realpath_impl.h @@ -0,0 +1,13 @@ +#ifndef SLIBTOOL_REALPATH_IMPL_H +#define SLIBTOOL_REALPATH_IMPL_H + +#include + +int slbt_realpath( + int fdat, + const char * path, + int options, + char * buf, + size_t buflen); + +#endif diff --git a/src/logic/linkcmd/slbt_linkcmd_dsolib.c b/src/logic/linkcmd/slbt_linkcmd_dsolib.c index 2d68c32..938c0ef 100644 --- a/src/logic/linkcmd/slbt_linkcmd_dsolib.c +++ b/src/logic/linkcmd/slbt_linkcmd_dsolib.c @@ -17,6 +17,7 @@ #include "slibtool_linkcmd_impl.h" #include "slibtool_mapfile_impl.h" #include "slibtool_metafile_impl.h" +#include "slibtool_realpath_impl.h" #include "slibtool_snprintf_impl.h" #include "slibtool_symlink_impl.h" #include "slibtool_spawn_impl.h" @@ -243,7 +244,7 @@ slbt_hidden int slbt_exec_link_create_library( } /* cwd */ - if (slbt_util_real_path(fdcwd,".",O_DIRECTORY,cwd,sizeof(cwd))) + if (slbt_realpath(fdcwd,".",O_DIRECTORY,cwd,sizeof(cwd))) return SLBT_SYSTEM_ERROR(dctx,0); /* .libs/libfoo.so --> -L.libs -lfoo */ diff --git a/src/logic/linkcmd/slbt_linkcmd_executable.c b/src/logic/linkcmd/slbt_linkcmd_executable.c index eae0769..6ad6994 100644 --- a/src/logic/linkcmd/slbt_linkcmd_executable.c +++ b/src/logic/linkcmd/slbt_linkcmd_executable.c @@ -17,6 +17,7 @@ #include "slibtool_linkcmd_impl.h" #include "slibtool_mapfile_impl.h" #include "slibtool_metafile_impl.h" +#include "slibtool_realpath_impl.h" #include "slibtool_snprintf_impl.h" #include "slibtool_symlink_impl.h" #include "slibtool_spawn_impl.h" @@ -136,7 +137,7 @@ slbt_hidden int slbt_exec_link_create_executable( verinfo = slbt_api_source_version(); /* cwd, DL_PATH fixup */ - if (slbt_util_real_path(fdcwd,".",O_DIRECTORY,cwd,sizeof(cwd))) + if (slbt_realpath(fdcwd,".",O_DIRECTORY,cwd,sizeof(cwd))) return SLBT_SYSTEM_ERROR(dctx,0); slbt_emit_fdwrap_dl_path_fixup( diff --git a/src/output/slbt_output_fdcwd.c b/src/output/slbt_output_fdcwd.c index 1d07892..6f2c9a4 100644 --- a/src/output/slbt_output_fdcwd.c +++ b/src/output/slbt_output_fdcwd.c @@ -13,6 +13,7 @@ #include "slibtool_driver_impl.h" #include "slibtool_dprintf_impl.h" +#include "slibtool_realpath_impl.h" static const char aclr_reset[] = "\x1b[0m"; static const char aclr_bold[] = "\x1b[1m"; @@ -36,7 +37,7 @@ static int slbt_output_fdcwd_plain(const struct slbt_driver_ctx * dctx) sprintf(scwd,"%d",fdcwd); } - if (slbt_util_real_path(fdcwd,".",0,path,sizeof(path)) < 0) { + if (slbt_realpath(fdcwd,".",0,path,sizeof(path)) < 0) { ferror = 1; memset(path,0,sizeof(path)); strerror_r(errno,path,sizeof(path)); @@ -72,7 +73,7 @@ static int slbt_output_fdcwd_annotated(const struct slbt_driver_ctx * dctx) sprintf(scwd,"%d",fdcwd); } - if (slbt_util_real_path(fdcwd,".",0,path,sizeof(path)) < 0) { + if (slbt_realpath(fdcwd,".",0,path,sizeof(path)) < 0) { ferror = 1; memset(path,0,sizeof(path)); strerror_r(errno,path,sizeof(path)); diff --git a/src/util/slbt_realpath.c b/src/util/slbt_realpath.c index 9e97427..a21a986 100644 --- a/src/util/slbt_realpath.c +++ b/src/util/slbt_realpath.c @@ -4,31 +4,7 @@ /* Released under the Standard MIT License; see COPYING.SLIBTOOL. */ /*******************************************************************/ -#include -#include -#include -#include -#include -#include - -#include "slibtool_driver_impl.h" -#include "slibtool_readlink_impl.h" - -#ifdef HAVE_SYS_SYSCALL_H -#include -#endif - -#ifdef _MIDIPIX_ABI -#include -#endif - -#ifndef ENOTSUP -#define ENOTSUP EOPNOTSUPP -#endif - -#ifdef SYS___realpathat -extern long syscall(int, ...); -#endif +#include "slibtool_realpath_impl.h" int slbt_util_real_path( int fdat, @@ -37,65 +13,5 @@ int slbt_util_real_path( char * buf, size_t buflen) { - int ret; - int fd; - int fdproc; - struct stat st; - struct stat stproc; - char procfspath[36]; - - /* common validation */ - if (!buf || (options & O_CREAT)) { - errno = EINVAL; - return -1; - } - - /* framework-based wrapper */ -#ifdef _MIDIPIX_ABI - return __fs_rpath(fdat,path,options,buf,buflen); -#endif - -#ifdef SYS___realpathat - return syscall(SYS___realpathat,fdat,path,buf,buflen,0); -#endif - - /* buflen */ - if (buflen < PATH_MAX) { - errno = ENOBUFS; - return -1; - } - - /* AT_FDCWD */ - if (fdat == AT_FDCWD) { - return realpath(path,buf) ? 0 : -1; - } - - /* /proc/self/fd */ - if ((fd = openat(fdat,path,options,0)) < 0) - return -1; - - sprintf(procfspath,"/proc/self/fd/%d",fd); - - if (slbt_readlinkat(fdat,procfspath,buf,buflen)) { - close(fd); - return -1; - } - - if ((fdproc = openat(AT_FDCWD,buf,options|O_NOFOLLOW,0)) < 0) { - close(fd); - errno = ELOOP; - return -1; - } - - ret = fstat(fd,&st) || fstat(fdproc,&stproc); - - close(fd); - close(fdproc); - - if (ret || (st.st_dev != stproc.st_dev) || (st.st_ino != stproc.st_ino)) { - errno = ENOTSUP; - return -1; - } - - return 0; + return slbt_realpath(fdat,path,options,buf,buflen); }