[haiku-commits] haiku: hrev46381 - src/system/libroot/os src/system/kernel/lib headers/private/libroot src/system/libroot/posix/stdlib

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 17 Nov 2013 19:11:23 +0100 (CET)

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


Other related posts:

  • » [haiku-commits] haiku: hrev46381 - src/system/libroot/os src/system/kernel/lib headers/private/libroot src/system/libroot/posix/stdlib - ingo_weinhold