* Added find_directory() to the kernel - it currently may not work as good as the

userland version, tbough.
* Small style cleanup in find_directory.c.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21194 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-05-21 22:28:02 +00:00
parent 252fb08a83
commit 6430c89618
2 changed files with 103 additions and 89 deletions
+2 -1
View File
@@ -4,11 +4,12 @@ SubDir HAIKU_TOP src system kernel lib ;
KernelMergeObject kernel_os_main.o : KernelMergeObject kernel_os_main.o :
driver_settings.c driver_settings.c
find_directory.c
fs_info.c fs_info.c
: $(TARGET_KERNEL_PIC_CCFLAGS) : $(TARGET_KERNEL_PIC_CCFLAGS)
; ;
SEARCH on [ FGristFiles driver_settings.c fs_info.c ] SEARCH on [ FGristFiles driver_settings.c find_directory.c fs_info.c ]
= [ FDirName $(HAIKU_TOP) src system libroot os ] ; = [ FDirName $(HAIKU_TOP) src system libroot os ] ;
# kernel libroot posix files # kernel libroot posix files
+100 -87
View File
@@ -1,13 +1,19 @@
/* /*
* Copyright (c) 2004, François Revol. * Copyright (c) 2004-2007, François Revol.
* Distributed under the terms of the MIT license. * Distributed under the terms of the MIT license.
*/ */
// ToDo: that call should probably implemented by and in the kernel as well. // TODO: this call is currently compiled for the kernel and libroot separately;
// they may not always return the same directory right now!
#ifdef _KERNEL_MODE
# include <vfs.h>
#else
# include <syscalls.h>
#endif
#include <FindDirectory.h> #include <FindDirectory.h>
#include <fs_info.h> #include <fs_info.h>
#include <syscalls.h>
#include <errno.h> #include <errno.h>
#include <pwd.h> #include <pwd.h>
@@ -21,77 +27,71 @@
#define USE_PWENTS #define USE_PWENTS
/* os root dir; just stick to 'beos' for now */ /* os root dir; just stick to 'beos' for now */
#define OSDIR "beos" #define OS "beos"
//#define OSDIR "haiku" // :) //#define OS "haiku" // :)
//#define OSDIR "os" //#define OS "os"
/* /bin/strings rox */ /* /bin/strings rox */
static const char *os_dirs[] = { static const char *os_dirs[] = {
OSDIR, OS,
OSDIR"/system", OS "/system",
OSDIR"/system/add-ons", OS "/system/add-ons",
OSDIR"/system/boot", OS "/system/boot",
OSDIR"/etc/fonts", OS "/etc/fonts",
OSDIR"/system/lib", OS "/system/lib",
OSDIR"/system/servers", OS "/system/servers",
OSDIR"/apps", OS "/apps",
OSDIR"/bin", OS "/bin",
OSDIR"/etc", OS "/etc",
OSDIR"/documentation", OS "/documentation",
OSDIR"/preferences", OS "/preferences",
OSDIR"/system/add-ons/Translators", OS "/system/add-ons/Translators",
OSDIR"/system/add-ons/media", OS "/system/add-ons/media",
OSDIR"/etc/sounds", OS "/etc/sounds",
}; };
/* R5 uses that, but it's *really* wrong, #define COMMON "common"
* we don't want "common" directories to depend on user's home !
* it should actually be something else than /boot/home even...
*/
//#define HOME "$h"
#define HOME "common"
// ToDo: this is for now and might be changed back to "home" // ToDo: this is for now and might be changed back to "home"
// (or even something else) later // (or even something else) later
static const char *common_dirs[] = { static const char *common_dirs[] = {
HOME"", COMMON "",
HOME"/config", COMMON "/config",
HOME"/config/add-ons", COMMON "/config/add-ons",
HOME"/config/boot", COMMON "/config/boot",
HOME"/config/fonts", COMMON "/config/fonts",
HOME"/config/lib", COMMON "/config/lib",
HOME"/config/servers", COMMON "/config/servers",
HOME"/config/bin", COMMON "/config/bin",
HOME"/config/etc", COMMON "/config/etc",
HOME"/config/documentation", COMMON "/config/documentation",
HOME"/config/settings", COMMON "/config/settings",
"develop", "develop",
"var/log", "var/log",
"var/spool", "var/spool",
"var/tmp", "var/tmp",
"var", "var",
HOME"/config/add-ons/Translators", COMMON "/config/add-ons/Translators",
HOME"/config/add-ons/media", COMMON "/config/add-ons/media",
HOME"/config/sounds", COMMON "/config/sounds",
}; };
#undef HOME
#define HOME "$h" #define HOME "$h"
static const char *user_dirs[] = { static const char *user_dirs[] = {
HOME"", HOME "",
HOME"/config", HOME "/config",
HOME"/config/add-ons", HOME "/config/add-ons",
HOME"/config/boot", HOME "/config/boot",
HOME"/config/fonts", HOME "/config/fonts",
HOME"/config/lib", HOME "/config/lib",
HOME"/config/settings", HOME "/config/settings",
HOME"/config/be", HOME "/config/be",
HOME"/config/settings/printers", HOME "/config/settings/printers",
HOME"/config/add-ons/Translators", HOME "/config/add-ons/Translators",
HOME"/config/add-ons/media", HOME "/config/add-ons/media",
HOME"/config/sounds", HOME "/config/sounds",
}; };
/* /*
@@ -100,10 +100,11 @@ preferences
apps apps
*/ */
/** make dir and parents if needed */
/*! make dir and its parents if needed */
static int static int
mkdir_p(const char *path, mode_t mode) create_path(const char *path, mode_t mode)
{ {
char buffer[B_PATH_NAME_LENGTH + 1]; char buffer[B_PATH_NAME_LENGTH + 1];
int slash = 0; int slash = 0;
@@ -129,7 +130,7 @@ mkdir_p(const char *path, mode_t mode)
else else
continue; continue;
strncpy(buffer, path, slash); strlcpy(buffer, path, slash);
if (stat(buffer, &st) < 0) { if (stat(buffer, &st) < 0) {
errno = 0; errno = 0;
if (mkdir(buffer, mode) < 0) if (mkdir(buffer, mode) < 0)
@@ -141,43 +142,52 @@ mkdir_p(const char *path, mode_t mode)
} }
// #pragma mark -
status_t status_t
find_directory(directory_which which, dev_t device, bool create_it, find_directory(directory_which which, dev_t device, bool createIt,
char *returned_path, int32 path_length) char *returnedPath, int32 pathLength)
{ {
status_t err = B_OK; status_t err = B_OK;
dev_t bootdev = -1; dev_t bootDevice = -1;
struct fs_info finfo; struct fs_info fsInfo;
struct stat st; struct stat st;
char *buffer = NULL; char *buffer = NULL;
char *home = NULL; char *home = NULL;
const char *template = NULL; const char *template = NULL;
/* as with the R5 version, no on-stack buffer */ /* as with the R5 version, no on-stack buffer */
buffer = (char *)malloc(path_length); buffer = (char *)malloc(pathLength);
memset(buffer, 0, path_length); memset(buffer, 0, pathLength);
/* fiddle with non-boot volume for items that need it */ /* fiddle with non-boot volume for items that need it */
switch (which) { switch (which) {
case B_DESKTOP_DIRECTORY: case B_DESKTOP_DIRECTORY:
case B_TRASH_DIRECTORY: case B_TRASH_DIRECTORY:
bootdev = dev_for_path("/boot"); bootDevice = dev_for_path("/boot");
if (device <= 0) if (device <= 0)
device = bootdev; device = bootDevice;
if (fs_stat_dev(device, &finfo) < B_OK) { if (fs_stat_dev(device, &fsInfo) < B_OK) {
free(buffer); free(buffer);
return ENODEV; return ENODEV;
} }
if (device != bootdev) { if (device != bootDevice) {
err = _kern_entry_ref_to_path(device, finfo.root, /*"."*/ NULL, buffer, path_length); #ifdef _KERNEL_MODE
err = _user_entry_ref_to_path(device, fsInfo.root, /*"."*/
NULL, buffer, pathLength);
#else
err = _kern_entry_ref_to_path(device, fsInfo.root, /*"."*/
NULL, buffer, pathLength);
#endif
} else { } else {
/* use the user id to find the home folder */ /* use the user id to find the home folder */
/* done later */ /* done later */
strncat(buffer, "/boot", path_length); strlcat(buffer, "/boot", pathLength);
} }
break; break;
default: default:
strncat(buffer, "/boot", path_length); strlcat(buffer, "/boot", pathLength);
break; break;
} }
@@ -188,13 +198,14 @@ find_directory(directory_which which, dev_t device, bool create_it,
switch (which) { switch (which) {
case B_DESKTOP_DIRECTORY: case B_DESKTOP_DIRECTORY:
if (!strcmp(finfo.fsh_name, "bfs")) if (!strcmp(fsInfo.fsh_name, "bfs"))
template = "$h/Desktop"; template = "$h/Desktop";
break; break;
case B_TRASH_DIRECTORY: case B_TRASH_DIRECTORY:
if (!strcmp(finfo.fsh_name, "bfs")) // TODO: eventually put that into the file system API?
if (!strcmp(fsInfo.fsh_name, "bfs"))
template = "$h/Desktop/Trash"; template = "$h/Desktop/Trash";
else if (!strcmp(finfo.fsh_name, "dos")) else if (!strcmp(fsInfo.fsh_name, "dos"))
template = "RECYCLED/_BEOS_"; template = "RECYCLED/_BEOS_";
break; break;
case B_BEOS_DIRECTORY: case B_BEOS_DIRECTORY:
@@ -266,41 +277,43 @@ find_directory(directory_which which, dev_t device, bool create_it,
err = B_OK; err = B_OK;
if (template) { if (template) {
if (!strncmp(template, "$h", 2)) { if (!strncmp(template, "$h", 2)) {
if ((bootdev > -1) && (device != bootdev)) { if (bootDevice > -1 && device != bootDevice) {
int l = path_length - strlen(buffer); int l = pathLength - strlen(buffer);
if (l > 5) if (l > 5)
strncat(buffer, "/home", 5); strncat(buffer, "/home", 5);
} else { } else {
#ifndef _KERNEL_MODE
#ifdef USE_PWENTS #ifdef USE_PWENTS
struct passwd *pw; struct passwd *pw;
// WARNING getpwuid() might not be threadsafe... // WARNING getpwuid() might not be threadsafe...
pw = getpwuid(getuid()); pw = getpwuid(getuid());
if (pw) if (pw)
home = pw->pw_dir; home = pw->pw_dir;
#endif #endif // USE_PWENTS
if (!home) { if (!home) {
/* use env var */ /* use env var */
home = getenv("HOME"); home = getenv("HOME");
} }
#endif // !_KERNEL_MODE
if (!home) if (!home)
home = "/boot/home"; home = "/boot/home";
strncpy(buffer, home, path_length); strncpy(buffer, home, pathLength);
} }
template += 2; template += 2;
} else } else
strcat(buffer, "/"); strlcat(buffer, "/", pathLength);
if (!err && strlen(buffer) + 2 + strlen(template) < (uint32)path_length) { if (!err && strlen(buffer) + 2 + strlen(template) < (uint32)pathLength) {
strcat(buffer, template); strcat(buffer, template);
} else } else
err = err ? err : E2BIG; err = err ? err : E2BIG;
} else } else
err = err ? err : ENOENT; err = err ? err : ENOENT;
if (!err && create_it && stat(buffer, &st) < 0) if (!err && createIt && stat(buffer, &st) < 0)
err = mkdir_p(buffer, 0755); err = create_path(buffer, 0755);
if (!err) if (!err)
strncpy(returned_path, buffer, path_length); strlcpy(returnedPath, buffer, pathLength);
free(buffer); free(buffer);
return err; return err;