hrev46381 adds 3 changesets to branch 'master' old head: b38fed9370deb68349657e011e27d59e693d51dc new head: 04c6cb37bb8e0115f90974e99d6d823857c6836e overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=04c6cb3+%5Eb38fed9 ---------------------------------------------------------------------------- 8a3fe6d: Add private __getenv_reentrant() A reentrant variant of getenv(). 7fb0d6c: find_path*(): Fix B_FIND_PATH_MEDIA_NODES_DIRECTORY It is architecture specific as well. 04c6cb3: find_directory(): Add architecture support * Move PathBuffer helper class out of find_paths.cpp into its own header. * find_directory(): - Make use of MemoryDeleter to simplify things. - Make use of PathBuffer for a simpler and more correct handling. - Make B_UTILITIES_DIRECTORY to B_APPS_DIRECTORY. /boot/utilities doesn't exist anyway. - Resolve the concerned constants to the architecture specific subdirectory, when called in a secondary architecture context, just like find_path*(). [ Ingo Weinhold <ingo_weinhold@xxxxxx> ] ---------------------------------------------------------------------------- 6 files changed, 261 insertions(+), 150 deletions(-) headers/private/libroot/stdlib_private.h | 23 +++ src/system/kernel/lib/Jamfile | 24 +-- src/system/libroot/os/PathBuffer.h | 75 +++++++++ src/system/libroot/os/find_directory.cpp | 219 ++++++++++++++++----------- src/system/libroot/os/find_paths.cpp | 51 +------ src/system/libroot/posix/stdlib/env.cpp | 19 +++ ############################################################################ Commit: 8a3fe6d1bf6502b31df2e1094ae06f72e15789cb URL: http://cgit.haiku-os.org/haiku/commit/?id=8a3fe6d Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sun Nov 17 18:00:51 2013 UTC Add private __getenv_reentrant() A reentrant variant of getenv(). ---------------------------------------------------------------------------- diff --git a/headers/private/libroot/stdlib_private.h b/headers/private/libroot/stdlib_private.h new file mode 100644 index 0000000..b2b2057 --- /dev/null +++ b/headers/private/libroot/stdlib_private.h @@ -0,0 +1,23 @@ +/* + * Copyright 2013, Ingo Weinhold, ingo_weinhold@xxxxxx. + * Distributed under the terms of the MIT License. + */ +#ifndef _LIBROOT_STDLIB_PRIVATE_H +#define _LIBROOT_STDLIB_PRIVATE_H + + +#include <sys/cdefs.h> +#include <sys/types.h> + + +__BEGIN_DECLS + + +ssize_t __getenv_reentrant(const char* name, char* buffer, + size_t bufferSize); + + +__END_DECLS + + +#endif /* _LIBROOT_STDLIB_PRIVATE_H */ diff --git a/src/system/libroot/posix/stdlib/env.cpp b/src/system/libroot/posix/stdlib/env.cpp index d27a66f..578a255 100644 --- a/src/system/libroot/posix/stdlib/env.cpp +++ b/src/system/libroot/posix/stdlib/env.cpp @@ -15,6 +15,7 @@ #include <libroot_private.h> #include <locks.h> #include <runtime_loader.h> +#include <stdlib_private.h> #include <syscall_utils.h> #include <user_runtime.h> @@ -315,3 +316,21 @@ putenv(const char *string) RETURN_AND_SET_ERRNO(status); } + +ssize_t +__getenv_reentrant(const char* name, char* buffer, size_t bufferSize) +{ + size_t nameLength = strlen(name); + + lock_variables(); + + char* value = find_variable(name, nameLength, NULL); + ssize_t result = value != NULL + ? strlcpy(buffer, value + nameLength + 1, bufferSize) + : B_NAME_NOT_FOUND; + + unlock_variables(); + + return result; +} + ############################################################################ Commit: 7fb0d6c269dea0f977a249af6e7c8991d1ae743f URL: http://cgit.haiku-os.org/haiku/commit/?id=7fb0d6c Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sun Nov 17 18:01:45 2013 UTC find_path*(): Fix B_FIND_PATH_MEDIA_NODES_DIRECTORY It is architecture specific as well. ---------------------------------------------------------------------------- diff --git a/src/system/libroot/os/find_paths.cpp b/src/system/libroot/os/find_paths.cpp index f3360a2..717fb2e 100644 --- a/src/system/libroot/os/find_paths.cpp +++ b/src/system/libroot/os/find_paths.cpp @@ -131,7 +131,7 @@ get_relative_directory_path(size_t installationLocationIndex, case B_FIND_PATH_LOG_DIRECTORY: return "/log"; case B_FIND_PATH_MEDIA_NODES_DIRECTORY: - return "/add-ons/media"; + return "/add-ons%/media"; case B_FIND_PATH_PACKAGES_DIRECTORY: return "/packages"; case B_FIND_PATH_PREFERENCES_DIRECTORY: ############################################################################ Revision: hrev46381 Commit: 04c6cb37bb8e0115f90974e99d6d823857c6836e URL: http://cgit.haiku-os.org/haiku/commit/?id=04c6cb3 Author: Ingo Weinhold <ingo_weinhold@xxxxxx> Date: Sun Nov 17 18:10:18 2013 UTC find_directory(): Add architecture support * Move PathBuffer helper class out of find_paths.cpp into its own header. * find_directory(): - Make use of MemoryDeleter to simplify things. - Make use of PathBuffer for a simpler and more correct handling. - Make B_UTILITIES_DIRECTORY to B_APPS_DIRECTORY. /boot/utilities doesn't exist anyway. - Resolve the concerned constants to the architecture specific subdirectory, when called in a secondary architecture context, just like find_path*(). ---------------------------------------------------------------------------- diff --git a/src/system/kernel/lib/Jamfile b/src/system/kernel/lib/Jamfile index 58b88c2..bcaa986 100644 --- a/src/system/kernel/lib/Jamfile +++ b/src/system/kernel/lib/Jamfile @@ -9,30 +9,32 @@ CCFLAGS += -include $(kernelLibHeader) ; C++FLAGS += -include $(kernelLibHeader) ; +local librootSources = [ FDirName $(HAIKU_TOP) src system libroot ] ; +local librootOSSources = [ FDirName $(librootSources) os ] ; +local posixSources = [ FDirName $(librootSources) posix ] ; + + # kernel libroot os files -KernelMergeObject kernel_os_main.o : +local sources = driver_settings.cpp find_directory.cpp fs_info.c system_revision.c wait_for_objects.cpp + ; + +SourceHdrs $(sources) : $(librootOSSources) ; + +KernelMergeObject kernel_os_main.o : $(sources) : $(TARGET_KERNEL_PIC_CCFLAGS) ; -SEARCH on [ FGristFiles - driver_settings.cpp - find_directory.cpp - fs_info.c - system_revision.c - wait_for_objects.cpp - ] = [ FDirName $(HAIKU_TOP) src system libroot os ] ; +SEARCH on [ FGristFiles $(sources) ] + = [ FDirName $(HAIKU_TOP) src system libroot os ] ; # kernel libroot posix files -local librootSources = [ FDirName $(HAIKU_TOP) src system libroot ] ; -local posixSources = [ FDirName $(librootSources) posix ] ; - SEARCH_SOURCE += [ FDirName $(posixSources) ] ; SEARCH_SOURCE += [ FDirName $(posixSources) locale ] ; SEARCH_SOURCE += [ FDirName $(posixSources) stdio ] ; diff --git a/src/system/libroot/os/PathBuffer.h b/src/system/libroot/os/PathBuffer.h new file mode 100644 index 0000000..0fc0f95 --- /dev/null +++ b/src/system/libroot/os/PathBuffer.h @@ -0,0 +1,75 @@ +/* + * Copyright 2013, Ingo Weinhold, ingo_weinhold@xxxxxx. + * Distributed under the terms of the MIT License. + */ +#ifndef PATH_BUFFER_H +#define PATH_BUFFER_H + + +#include <string.h> + +#include <algorithm> + + +namespace { + +struct PathBuffer { + PathBuffer() + : + fBuffer(NULL), + fSize(0), + fLength(0) + { + } + + PathBuffer(char* buffer, size_t size, size_t length = 0) + { + SetTo(buffer, size, length); + } + + void SetTo(char* buffer, size_t size, size_t length = 0) + { + fBuffer = buffer; + fSize = size; + fLength = length; + if (fLength < fSize) + fBuffer[fLength] = '\0'; + } + + bool Append(const char* toAppend, size_t length) + { + if (length > 0 && fLength + 1 < fSize) { + size_t toCopy = std::min(length, fSize - fLength - 1); + memcpy(fBuffer + fLength, toAppend, toCopy); + fBuffer[fLength + toCopy] = '\0'; + } + + fLength += length; + return fLength < fSize; + } + + bool Append(const char* toAppend) + { + return Append(toAppend, strlen(toAppend)); + } + + bool Append(char c) + { + return Append(&c, 1); + } + + size_t Length() const + { + return fLength; + } + +private: + char* fBuffer; + size_t fSize; + size_t fLength; +}; + +} + + +#endif // PATH_BUFFER_H diff --git a/src/system/libroot/os/find_directory.cpp b/src/system/libroot/os/find_directory.cpp index c7272fd..dd1c489 100644 --- a/src/system/libroot/os/find_directory.cpp +++ b/src/system/libroot/os/find_directory.cpp @@ -1,7 +1,8 @@ /* * Copyright 2004, François Revol. * Copyright 2007-2010, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx. - * Copyright 2011, Oliver Tappe <zooey@xxxxxxxxxxxxxxx> + * Copyright 2011, Oliver Tappe, zooey@xxxxxxxxxxxxxxx. + * Copyright 2013, Ingo Weinhold, ingo_weinhold@xxxxxx. * * Distributed under the terms of the MIT license. */ @@ -26,11 +27,18 @@ #include <stdlib.h> #include <unistd.h> +#include <architecture_private.h> #include <errno_private.h> #include <find_directory_private.h> +#include <stdlib_private.h> #include <symbol_versioning.h> #include <user_group.h> +#include <AutoDeleter.h> + +#include "PathBuffer.h" + + /* use pwents to find home */ #define USE_PWENTS @@ -77,23 +85,23 @@ enum { static const char *kSystemDirectories[] = { SYSTEM, // B_SYSTEM_DIRECTORY SYSTEM, // B_BEOS_SYSTEM_DIRECTORY - SYSTEM "/add-ons", + SYSTEM "/add-ons$a", SYSTEM "/boot", SYSTEM "/data/fonts", - SYSTEM "/lib", + SYSTEM "/lib$a", SYSTEM "/servers", SYSTEM "/apps", - SYSTEM "/bin", + SYSTEM "/bin$a", SYSTEM "/settings/etc", SYSTEM "/documentation", SYSTEM "/preferences", - SYSTEM "/add-ons/Translators", - SYSTEM "/add-ons/media", + SYSTEM "/add-ons$a/Translators", + SYSTEM "/add-ons$a/media", SYSTEM "/data/sounds", SYSTEM "/data", SYSTEM "/develop", SYSTEM "/packages", - SYSTEM "/develop/headers", + SYSTEM "/develop/headers$a", }; /* Common directories, shared among users */ @@ -101,12 +109,12 @@ static const char *kSystemDirectories[] = { static const char *kCommonDirectories[] = { COMMON, // B_COMMON_DIRECTORY COMMON, // B_COMMON_SYSTEM_DIRECTORY - COMMON "/add-ons", + COMMON "/add-ons$a", COMMON "/boot", COMMON "/data/fonts", - COMMON "/lib", + COMMON "/lib$a", COMMON "/servers", - COMMON "/bin", + COMMON "/bin$a", SYSTEM "/settings/etc", // B_SYSTEM_ETC_DIRECTORY COMMON "/documentation", SYSTEM "/settings", // B_SYSTEM_SETTINGS_DIRECTORY @@ -115,24 +123,24 @@ static const char *kCommonDirectories[] = { SYSTEM "/var/spool", // B_SYSTEM_SPOOL_DIRECTORY SYSTEM "/cache/tmp", // B_SYSTEM_TEMP_DIRECTORY SYSTEM "/var", // B_SYSTEM_VAR_DIRECTORY - COMMON "/add-ons/Translators", - COMMON "/add-ons/media", + COMMON "/add-ons$a/Translators", + COMMON "/add-ons$a/media", COMMON "/data/sounds", COMMON "/data", SYSTEM "/cache", // B_SYSTEM_CACHE_DIRECTORY COMMON "/packages", - COMMON "/develop/headers", + COMMON "/develop/headers$a", SYSTEM NON_PACKAGED, - SYSTEM NON_PACKAGED "/add-ons", - SYSTEM NON_PACKAGED "/add-ons/Translators", - SYSTEM NON_PACKAGED "/add-ons/media", - SYSTEM NON_PACKAGED "/bin", + SYSTEM NON_PACKAGED "/add-ons$a", + SYSTEM NON_PACKAGED "/add-ons$a/Translators", + SYSTEM NON_PACKAGED "/add-ons$a/media", + SYSTEM NON_PACKAGED "/bin$a", SYSTEM NON_PACKAGED "/data", SYSTEM NON_PACKAGED "/data/fonts", SYSTEM NON_PACKAGED "/data/sounds", SYSTEM NON_PACKAGED "/documentation", - SYSTEM NON_PACKAGED "/lib", - SYSTEM NON_PACKAGED "/develop/headers", + SYSTEM NON_PACKAGED "/lib$a", + SYSTEM NON_PACKAGED "/develop/headers$a", SYSTEM NON_PACKAGED "/develop", }; @@ -144,37 +152,37 @@ static const char *kCommonDirectories[] = { static const char *kUserDirectories[] = { HOME, // B_USER_DIRECTORY HOME CONFIG, // B_USER_CONFIG_DIRECTORY - HOME CONFIG "/add-ons", + HOME CONFIG "/add-ons$a", HOME CONFIG "/boot", HOME CONFIG "/data/fonts", - HOME CONFIG "/lib", + HOME CONFIG "/lib$a", HOME CONFIG "/settings", HOME CONFIG "/settings/deskbar/menu", HOME CONFIG "/settings/printers", - HOME CONFIG "/add-ons/Translators", - HOME CONFIG "/add-ons/media", + HOME CONFIG "/add-ons$a/Translators", + HOME CONFIG "/add-ons$a/media", HOME CONFIG "/data/sounds", HOME CONFIG "/data", HOME CONFIG "/cache", HOME CONFIG "/packages", - HOME CONFIG "/develop/headers", + HOME CONFIG "/develop/headers$a", HOME CONFIG NON_PACKAGED, - HOME CONFIG NON_PACKAGED "/add-ons", - HOME CONFIG NON_PACKAGED "/add-ons/Translators", - HOME CONFIG NON_PACKAGED "/add-ons/media", - HOME CONFIG NON_PACKAGED "/bin", + HOME CONFIG NON_PACKAGED "/add-ons$a", + HOME CONFIG NON_PACKAGED "/add-ons$a/Translators", + HOME CONFIG NON_PACKAGED "/add-ons$a/media", + HOME CONFIG NON_PACKAGED "/bin$a", HOME CONFIG NON_PACKAGED "/data", HOME CONFIG NON_PACKAGED "/data/fonts", HOME CONFIG NON_PACKAGED "/data/sounds", HOME CONFIG NON_PACKAGED "/documentation", - HOME CONFIG NON_PACKAGED "/lib", - HOME CONFIG NON_PACKAGED "/develop/headers", + HOME CONFIG NON_PACKAGED "/lib$a", + HOME CONFIG NON_PACKAGED "/develop/headers$a", HOME CONFIG NON_PACKAGED "/develop", HOME CONFIG "/develop", HOME CONFIG "/documentation", HOME CONFIG "/servers", HOME CONFIG "/apps", - HOME CONFIG "/bin", + HOME CONFIG "/bin$a", HOME CONFIG "/preferences", HOME CONFIG "/settings/etc", HOME CONFIG "/var/log", @@ -217,23 +225,59 @@ create_path(const char *path, mode_t mode) } +static size_t +get_user_home_path(char* buffer, size_t bufferSize) +{ + const char* home = NULL; +#ifndef _KERNEL_MODE +#ifdef USE_PWENTS + struct passwd pwBuffer; + char pwStringBuffer[MAX_PASSWD_BUFFER_SIZE]; + struct passwd* pw; + + if (getpwuid_r(geteuid(), &pwBuffer, pwStringBuffer, + sizeof(pwStringBuffer), &pw) == 0 + && pw != NULL) { + home = pw->pw_dir; + } +#endif // USE_PWENTS + if (home == NULL) { + /* use env var */ + ssize_t result = __getenv_reentrant("HOME", buffer, bufferSize); + if (result >= 0) + return result; + } +#endif // !_KERNEL_MODE + if (home == NULL) + home = kUserDirectory; + + return strlcpy(buffer, home, bufferSize); +} + + // #pragma mark - status_t __find_directory(directory_which which, dev_t device, bool createIt, - char *returnedPath, int32 pathLength) + char *returnedPath, int32 _pathLength) { + if (_pathLength <= 0) + return E2BIG; + size_t pathLength = _pathLength; + status_t err = B_OK; dev_t bootDevice = -1; struct fs_info fsInfo; struct stat st; - char *buffer = NULL; - const char *home = NULL; const char *templatePath = NULL; /* as with the R5 version, no on-stack buffer */ - buffer = (char *)malloc(pathLength); + char *buffer = (char*)malloc(pathLength); + if (buffer == NULL) + return B_NO_MEMORY; + MemoryDeleter bufferDeleter(buffer); + memset(buffer, 0, pathLength); /* fiddle with non-boot volume for items that need it */ @@ -243,10 +287,8 @@ __find_directory(directory_which which, dev_t device, bool createIt, bootDevice = dev_for_path("/boot"); if (device <= 0) device = bootDevice; - if (fs_stat_dev(device, &fsInfo) < B_OK) { - free(buffer); + if (fs_stat_dev(device, &fsInfo) != B_OK) return ENODEV; - } if (device != bootDevice) { #ifdef _KERNEL_MODE err = _user_entry_ref_to_path(device, fsInfo.root, /*"."*/ @@ -255,6 +297,8 @@ __find_directory(directory_which which, dev_t device, bool createIt, err = _kern_entry_ref_to_path(device, fsInfo.root, /*"."*/ NULL, buffer, pathLength); #endif + if (err != B_OK) + return err; } else { /* use the user id to find the home folder */ /* done later */ @@ -269,11 +313,6 @@ __find_directory(directory_which which, dev_t device, bool createIt, break; } - if (err < B_OK) { - free(buffer); - return err; - } - switch ((int)which) { /* Per volume directories */ case B_DESKTOP_DIRECTORY: @@ -394,71 +433,69 @@ __find_directory(directory_which which, dev_t device, bool createIt, /* Global directories */ case B_APPS_DIRECTORY: + case B_UTILITIES_DIRECTORY: templatePath = SYSTEM "/apps"; break; case B_PREFERENCES_DIRECTORY: templatePath = SYSTEM "/preferences"; break; - case B_UTILITIES_DIRECTORY: - templatePath = "utilities"; - break; case B_PACKAGE_LINKS_DIRECTORY: templatePath = "packages"; break; default: - free(buffer); return EINVAL; } - err = B_OK; - if (templatePath) { - if (!strncmp(templatePath, "$h", 2)) { - if (bootDevice > -1 && device != bootDevice) { - int l = pathLength - strlen(buffer); - if (l > 5) - strncat(buffer, "/home", 5); - } else { + if (templatePath == NULL) + return ENOENT; + + PathBuffer pathBuffer(buffer, pathLength, strlen(buffer)); + + // resolve "$h" placeholder to the user's home directory + if (!strncmp(templatePath, "$h", 2)) { + if (bootDevice > -1 && device != bootDevice) { + pathBuffer.Append("/home"); + } else { + size_t length = get_user_home_path(buffer, pathLength); + if (length >= pathLength) + return E2BIG; + pathBuffer.SetTo(buffer, pathLength, length); + } + templatePath += 2; + } else if (templatePath[0] != '\0') + pathBuffer.Append('/'); + + // resolve "$a" placeholder to the architecture subdirectory, if not + // primary + if (char* dollar = strchr(templatePath, '$')) { + if (dollar[1] == 'a') { + pathBuffer.Append(templatePath, dollar - templatePath); #ifndef _KERNEL_MODE -#ifdef USE_PWENTS - struct passwd pwBuffer; - char pwStringBuffer[MAX_PASSWD_BUFFER_SIZE]; - struct passwd *pw; - - if (getpwuid_r(geteuid(), &pwBuffer, pwStringBuffer, - sizeof(pwStringBuffer), &pw) == 0 - && pw != NULL) { - home = pw->pw_dir; - } -#endif // USE_PWENTS - if (!home) { - /* use env var */ - home = getenv("HOME"); - } -#endif // !_KERNEL_MODE - if (!home) - home = kUserDirectory; - strncpy(buffer, home, pathLength); + const char* architecture = __get_architecture(); + if (strcmp(architecture, __get_primary_architecture()) != 0) { + pathBuffer.Append('/'); + pathBuffer.Append(architecture); } - templatePath += 2; - } else - strlcat(buffer, "/", pathLength); - - if (!err && strlen(buffer) + 2 + strlen(templatePath) - < (uint32)pathLength) { - strcat(buffer, templatePath); - } else - err = err ? err : E2BIG; - } else - err = err ? err : ENOENT; - - if (!err && createIt && stat(buffer, &st) < 0) +#endif + templatePath = dollar + 2; + } + } + + // append (remainder of) template path + pathBuffer.Append(templatePath); + + if (pathBuffer.Length() >= pathLength) + return E2BIG; + + if (createIt && stat(buffer, &st) < 0) { err = create_path(buffer, 0755); - if (!err) - strlcpy(returnedPath, buffer, pathLength); + if (err != B_OK) + return err; + } - free(buffer); - return err; + strlcpy(returnedPath, buffer, pathLength); + return B_OK; } diff --git a/src/system/libroot/os/find_paths.cpp b/src/system/libroot/os/find_paths.cpp index 717fb2e..35e628c 100644 --- a/src/system/libroot/os/find_paths.cpp +++ b/src/system/libroot/os/find_paths.cpp @@ -19,6 +19,8 @@ #include <AutoDeleter.h> #include <syscalls.h> +#include "PathBuffer.h" + static const char* const kInstallationLocations[] = { "/boot/home/config/non-packaged", @@ -43,53 +45,6 @@ static size_t kArchitectureSpecificBaseDirectoryCount = / sizeof(kArchitectureSpecificBaseDirectories[0]); -namespace { - -struct PathBuffer { - PathBuffer(char* buffer, size_t size) - : - fBuffer(buffer), - fSize(size), - fLength(0) - { - if (fSize > 0) - fBuffer[0] = '\0'; - } - - bool Append(const char* toAppend, size_t length) - { - if (fLength < fSize) { - size_t toCopy = std::min(length, fSize - fLength); - if (toCopy > 0) { - memcpy(fBuffer + fLength, toAppend, toCopy); - fBuffer[fLength + toCopy] = '\0'; - } - } - - fLength += length; - return fLength < fSize; - } - - bool Append(const char* toAppend) - { - return Append(toAppend, strlen(toAppend)); - } - - size_t Length() const - { - return fLength; - } - -private: - char* fBuffer; - size_t fSize; - size_t fLength; -}; - -} - - - /*! Returns the installation location relative path for the given base directory constant and installation location index. A '%' in the returned path must be replaced by "" for the primary architecture and by "/<arch>" for a secondary