* dir_vnode_to_path() now uses B_* error codes instead of POSIX ones, and also
returns the correct error code if the buffer was too small (should be ERANGE instead of ENOBUF). * Also, it is now independent of B_PATH_NAME_LENGTH, and therefore should fulfill POSIX getcwd() requirements. This should also close ticket #3352. * Is there any reason to allocate another buffer instead of using memmove() at the end instead of memcpy()? git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34276 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
d52f7d5214
commit
432bb91f34
@ -112,6 +112,10 @@ const static uint32 kMaxUnusedVnodes = 8192;
|
|||||||
const static uint32 kMaxEntryCacheEntryCount = 8192;
|
const static uint32 kMaxEntryCacheEntryCount = 8192;
|
||||||
// Maximum number of entries per entry cache. It's a hard limit ATM.
|
// Maximum number of entries per entry cache. It's a hard limit ATM.
|
||||||
|
|
||||||
|
const static size_t kMaxPathLength = 65536;
|
||||||
|
// The absolute maximum path length (for getcwd() - this is not depending
|
||||||
|
// on PATH_MAX
|
||||||
|
|
||||||
struct EntryCacheKey {
|
struct EntryCacheKey {
|
||||||
EntryCacheKey(ino_t dirID, const char* name)
|
EntryCacheKey(ino_t dirID, const char* name)
|
||||||
:
|
:
|
||||||
@ -2624,14 +2628,13 @@ dir_vnode_to_path(struct vnode* vnode, char* buffer, size_t bufferSize,
|
|||||||
{
|
{
|
||||||
FUNCTION(("dir_vnode_to_path(%p, %p, %lu)\n", vnode, buffer, bufferSize));
|
FUNCTION(("dir_vnode_to_path(%p, %p, %lu)\n", vnode, buffer, bufferSize));
|
||||||
|
|
||||||
if (vnode == NULL || buffer == NULL)
|
if (vnode == NULL || buffer == NULL || bufferSize == 0)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
if (!S_ISDIR(vnode->type))
|
if (!S_ISDIR(vnode->type))
|
||||||
return B_NOT_A_DIRECTORY;
|
return B_NOT_A_DIRECTORY;
|
||||||
|
|
||||||
/* this implementation is currently bound to B_PATH_NAME_LENGTH */
|
KPath pathBuffer(bufferSize);
|
||||||
KPath pathBuffer;
|
|
||||||
if (pathBuffer.InitCheck() != B_OK)
|
if (pathBuffer.InitCheck() != B_OK)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@ -2657,6 +2660,7 @@ dir_vnode_to_path(struct vnode* vnode, char* buffer, size_t bufferSize,
|
|||||||
}
|
}
|
||||||
|
|
||||||
path[--insert] = '\0';
|
path[--insert] = '\0';
|
||||||
|
// the path is filled right to left
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// the name buffer is also used for fs_read_dir()
|
// the name buffer is also used for fs_read_dir()
|
||||||
@ -2707,12 +2711,12 @@ dir_vnode_to_path(struct vnode* vnode, char* buffer, size_t bufferSize,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToDo: add an explicit check for loops in about 10 levels to do
|
// TODO: add an explicit check for loops in about 10 levels to do
|
||||||
// real loop detection
|
// real loop detection
|
||||||
|
|
||||||
// don't go deeper as 'maxLevel' to prevent circular loops
|
// don't go deeper as 'maxLevel' to prevent circular loops
|
||||||
if (maxLevel-- < 0) {
|
if (maxLevel-- < 0) {
|
||||||
status = ELOOP;
|
status = B_LINK_LIMIT;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2721,7 +2725,7 @@ dir_vnode_to_path(struct vnode* vnode, char* buffer, size_t bufferSize,
|
|||||||
length = strlen(name);
|
length = strlen(name);
|
||||||
insert -= length;
|
insert -= length;
|
||||||
if (insert <= 0) {
|
if (insert <= 0) {
|
||||||
status = ENOBUFS;
|
status = B_RESULT_NOT_REPRESENTABLE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
memcpy(path + insert, name, length);
|
memcpy(path + insert, name, length);
|
||||||
@ -2739,7 +2743,7 @@ dir_vnode_to_path(struct vnode* vnode, char* buffer, size_t bufferSize,
|
|||||||
if (length <= (int)bufferSize)
|
if (length <= (int)bufferSize)
|
||||||
memcpy(buffer, path + insert, length);
|
memcpy(buffer, path + insert, length);
|
||||||
else
|
else
|
||||||
status = ENOBUFS;
|
status = B_RESULT_NOT_REPRESENTABLE;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
put_vnode(vnode);
|
put_vnode(vnode);
|
||||||
@ -9354,18 +9358,20 @@ _user_remove_index(dev_t device, const char* userName)
|
|||||||
status_t
|
status_t
|
||||||
_user_getcwd(char* userBuffer, size_t size)
|
_user_getcwd(char* userBuffer, size_t size)
|
||||||
{
|
{
|
||||||
|
if (size == 0)
|
||||||
|
return B_BAD_VALUE;
|
||||||
if (!IS_USER_ADDRESS(userBuffer))
|
if (!IS_USER_ADDRESS(userBuffer))
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
if (size > kMaxPathLength)
|
||||||
|
size = kMaxPathLength;
|
||||||
|
|
||||||
|
KPath pathBuffer(size);
|
||||||
if (pathBuffer.InitCheck() != B_OK)
|
if (pathBuffer.InitCheck() != B_OK)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
TRACE(("user_getcwd: buf %p, %ld\n", userBuffer, size));
|
TRACE(("user_getcwd: buf %p, %ld\n", userBuffer, size));
|
||||||
|
|
||||||
if (size > B_PATH_NAME_LENGTH)
|
|
||||||
size = B_PATH_NAME_LENGTH;
|
|
||||||
|
|
||||||
char* path = pathBuffer.LockBuffer();
|
char* path = pathBuffer.LockBuffer();
|
||||||
|
|
||||||
status_t status = get_cwd(path, size, false);
|
status_t status = get_cwd(path, size, false);
|
||||||
|
Loading…
Reference in New Issue
Block a user