* Reduced the stack usage of most of the I/O paths - there were several places
that put one or more full paths on the stack before, which could cause some problems under certain conditions. * Cleaned up KPath, ie. use size_t instead of int32 where appropriate, added license. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16585 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,56 +1,58 @@
|
|||||||
// KPath.h
|
/*
|
||||||
//
|
* Copyright 2004-2006, Ingo Weinhold, [email protected].
|
||||||
// A simple class wrapping a path. Has a fixed-sized buffer.
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
#ifndef _K_PATH_H
|
#ifndef _K_PATH_H
|
||||||
#define _K_PATH_H
|
#define _K_PATH_H
|
||||||
|
|
||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
namespace DiskDevice {
|
namespace DiskDevice {
|
||||||
|
|
||||||
class KPath {
|
class KPath {
|
||||||
public:
|
public:
|
||||||
KPath(int32 bufferSize = B_PATH_NAME_LENGTH);
|
KPath(size_t bufferSize = B_PATH_NAME_LENGTH);
|
||||||
KPath(const char* path, bool normalize = false,
|
KPath(const char* path, bool normalize = false,
|
||||||
int32 bufferSize = B_PATH_NAME_LENGTH);
|
size_t bufferSize = B_PATH_NAME_LENGTH);
|
||||||
KPath(const KPath& other);
|
KPath(const KPath& other);
|
||||||
~KPath();
|
~KPath();
|
||||||
|
|
||||||
status_t SetTo(const char *path, bool normalize = false,
|
status_t SetTo(const char *path, bool normalize = false,
|
||||||
int32 bufferSize = B_PATH_NAME_LENGTH);
|
size_t bufferSize = B_PATH_NAME_LENGTH);
|
||||||
|
|
||||||
status_t InitCheck() const;
|
status_t InitCheck() const;
|
||||||
|
|
||||||
status_t SetPath(const char *path, bool normalize = false);
|
status_t SetPath(const char *path, bool normalize = false);
|
||||||
const char *Path() const;
|
const char *Path() const;
|
||||||
int32 Length() const;
|
size_t Length() const { return fPathLength; }
|
||||||
|
|
||||||
int32 BufferSize() const;
|
size_t BufferSize() const { return fBufferSize; }
|
||||||
char *LockBuffer();
|
char *LockBuffer();
|
||||||
void UnlockBuffer();
|
void UnlockBuffer();
|
||||||
|
|
||||||
const char *Leaf() const;
|
const char *Leaf() const;
|
||||||
status_t ReplaceLeaf(const char *newLeaf);
|
status_t ReplaceLeaf(const char *newLeaf);
|
||||||
|
|
||||||
status_t Append(const char *toAppend, bool isComponent = true);
|
status_t Append(const char *toAppend, bool isComponent = true);
|
||||||
|
|
||||||
KPath& operator=(const KPath& other);
|
KPath& operator=(const KPath& other);
|
||||||
KPath& operator=(const char* path);
|
KPath& operator=(const char* path);
|
||||||
|
|
||||||
bool operator==(const KPath& other) const;
|
bool operator==(const KPath& other) const;
|
||||||
bool operator==(const char* path) const;
|
bool operator==(const char* path) const;
|
||||||
bool operator!=(const KPath& other) const;
|
bool operator!=(const KPath& other) const;
|
||||||
bool operator!=(const char* path) const;
|
bool operator!=(const char* path) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _ChopTrailingSlashes();
|
void _ChopTrailingSlashes();
|
||||||
|
|
||||||
char* fBuffer;
|
char* fBuffer;
|
||||||
int32 fBufferSize;
|
size_t fBufferSize;
|
||||||
int32 fPathLength;
|
size_t fPathLength;
|
||||||
bool fLocked;
|
bool fLocked;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace DiskDevice
|
} // namespace DiskDevice
|
||||||
|
|||||||
@@ -1,59 +1,68 @@
|
|||||||
// KPath.cpp
|
/*
|
||||||
|
* Copyright 2004-2006, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
/** A simple class wrapping a path. Has a fixed-sized buffer. */
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <KPath.h>
|
#include <KPath.h>
|
||||||
#include <team.h>
|
#include <team.h>
|
||||||
#include <vfs.h>
|
#include <vfs.h>
|
||||||
|
|
||||||
// debugging
|
#include <stdlib.h>
|
||||||
#define DBG(x)
|
#include <string.h>
|
||||||
//#define DBG(x) x
|
|
||||||
#define OUT dprintf
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
KPath::KPath(int32 bufferSize)
|
// debugging
|
||||||
: fBuffer(NULL),
|
#define TRACE(x) ;
|
||||||
fBufferSize(0),
|
//#define TRACE(x) dprintf x
|
||||||
fPathLength(0),
|
|
||||||
fLocked(false)
|
|
||||||
|
KPath::KPath(size_t bufferSize)
|
||||||
|
:
|
||||||
|
fBuffer(NULL),
|
||||||
|
fBufferSize(0),
|
||||||
|
fPathLength(0),
|
||||||
|
fLocked(false)
|
||||||
{
|
{
|
||||||
SetTo(NULL, bufferSize);
|
SetTo(NULL, bufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// constructor
|
|
||||||
KPath::KPath(const char* path, bool normalize, int32 bufferSize)
|
KPath::KPath(const char* path, bool normalize, size_t bufferSize)
|
||||||
: fBuffer(NULL),
|
:
|
||||||
fBufferSize(0),
|
fBuffer(NULL),
|
||||||
fPathLength(0),
|
fBufferSize(0),
|
||||||
fLocked(false)
|
fPathLength(0),
|
||||||
|
fLocked(false)
|
||||||
{
|
{
|
||||||
SetTo(path, normalize, bufferSize);
|
SetTo(path, normalize, bufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy constructor
|
|
||||||
KPath::KPath(const KPath& other)
|
KPath::KPath(const KPath& other)
|
||||||
: fBuffer(NULL),
|
:
|
||||||
fBufferSize(0),
|
fBuffer(NULL),
|
||||||
fPathLength(0),
|
fBufferSize(0),
|
||||||
fLocked(false)
|
fPathLength(0),
|
||||||
|
fLocked(false)
|
||||||
{
|
{
|
||||||
*this = other;
|
*this = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
// destructor
|
|
||||||
KPath::~KPath()
|
KPath::~KPath()
|
||||||
{
|
{
|
||||||
free(fBuffer);
|
free(fBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTo
|
|
||||||
status_t
|
status_t
|
||||||
KPath::SetTo(const char* path, bool normalize, int32 bufferSize)
|
KPath::SetTo(const char* path, bool normalize, size_t bufferSize)
|
||||||
{
|
{
|
||||||
if (bufferSize <= 0)
|
if (bufferSize == 0)
|
||||||
bufferSize = B_PATH_NAME_LENGTH;
|
bufferSize = B_PATH_NAME_LENGTH;
|
||||||
|
|
||||||
// free the previous buffer, if the buffer size differs
|
// free the previous buffer, if the buffer size differs
|
||||||
if (fBuffer && fBufferSize != bufferSize) {
|
if (fBuffer && fBufferSize != bufferSize) {
|
||||||
free(fBuffer);
|
free(fBuffer);
|
||||||
@@ -62,6 +71,7 @@ KPath::SetTo(const char* path, bool normalize, int32 bufferSize)
|
|||||||
}
|
}
|
||||||
fPathLength = 0;
|
fPathLength = 0;
|
||||||
fLocked = false;
|
fLocked = false;
|
||||||
|
|
||||||
// allocate buffer
|
// allocate buffer
|
||||||
if (!fBuffer)
|
if (!fBuffer)
|
||||||
fBuffer = (char*)malloc(bufferSize);
|
fBuffer = (char*)malloc(bufferSize);
|
||||||
@@ -74,19 +84,20 @@ KPath::SetTo(const char* path, bool normalize, int32 bufferSize)
|
|||||||
return SetPath(path, normalize);
|
return SetPath(path, normalize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitCheck
|
|
||||||
status_t
|
status_t
|
||||||
KPath::InitCheck() const
|
KPath::InitCheck() const
|
||||||
{
|
{
|
||||||
return (fBuffer ? B_OK : B_NO_MEMORY);
|
return fBuffer ? B_OK : B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPath
|
|
||||||
status_t
|
status_t
|
||||||
KPath::SetPath(const char *path, bool normalize)
|
KPath::SetPath(const char *path, bool normalize)
|
||||||
{
|
{
|
||||||
if (!fBuffer)
|
if (!fBuffer)
|
||||||
return B_NO_INIT;
|
return B_NO_INIT;
|
||||||
|
|
||||||
if (path) {
|
if (path) {
|
||||||
if (normalize) {
|
if (normalize) {
|
||||||
// normalize path
|
// normalize path
|
||||||
@@ -99,11 +110,12 @@ KPath::SetPath(const char *path, bool normalize)
|
|||||||
fPathLength = strlen(fBuffer);
|
fPathLength = strlen(fBuffer);
|
||||||
} else {
|
} else {
|
||||||
// don't normalize path
|
// don't normalize path
|
||||||
int32 len = strlen(path);
|
size_t length = strlen(path);
|
||||||
if (len >= fBufferSize)
|
if (length >= fBufferSize)
|
||||||
return B_BUFFER_OVERFLOW;
|
return B_BUFFER_OVERFLOW;
|
||||||
memcpy(fBuffer, path, len + 1);
|
|
||||||
fPathLength = len;
|
memcpy(fBuffer, path, length + 1);
|
||||||
|
fPathLength = length;
|
||||||
_ChopTrailingSlashes();
|
_ChopTrailingSlashes();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -113,61 +125,49 @@ KPath::SetPath(const char *path, bool normalize)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Path
|
|
||||||
const char*
|
const char*
|
||||||
KPath::Path() const
|
KPath::Path() const
|
||||||
{
|
{
|
||||||
return fBuffer;
|
return fBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Length
|
|
||||||
int32
|
|
||||||
KPath::Length() const
|
|
||||||
{
|
|
||||||
return fPathLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
// BufferSize
|
|
||||||
int32
|
|
||||||
KPath::BufferSize() const
|
|
||||||
{
|
|
||||||
return fBufferSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// LockBuffer
|
|
||||||
char *
|
char *
|
||||||
KPath::LockBuffer()
|
KPath::LockBuffer()
|
||||||
{
|
{
|
||||||
if (!fBuffer || fLocked)
|
if (!fBuffer || fLocked)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
fLocked = true;
|
fLocked = true;
|
||||||
return fBuffer;
|
return fBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnlockBuffer
|
|
||||||
void
|
void
|
||||||
KPath::UnlockBuffer()
|
KPath::UnlockBuffer()
|
||||||
{
|
{
|
||||||
if (!fLocked) {
|
if (!fLocked) {
|
||||||
DBG(OUT("KPath::UnlockBuffer(): ERROR: Buffer not locked!\n"));
|
TRACE(("KPath::UnlockBuffer(): ERROR: Buffer not locked!\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fLocked = false;
|
fLocked = false;
|
||||||
fPathLength = strnlen(fBuffer, fBufferSize);
|
fPathLength = strnlen(fBuffer, fBufferSize);
|
||||||
if (fPathLength == fBufferSize) {
|
if (fPathLength == fBufferSize) {
|
||||||
DBG(OUT("KPath::UnlockBuffer(): WARNING: Unterminated buffer!\n"));
|
TRACE(("KPath::UnlockBuffer(): WARNING: Unterminated buffer!\n"));
|
||||||
fPathLength--;
|
fPathLength--;
|
||||||
fBuffer[fPathLength] = '\0';
|
fBuffer[fPathLength] = '\0';
|
||||||
}
|
}
|
||||||
_ChopTrailingSlashes();
|
_ChopTrailingSlashes();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leaf
|
|
||||||
const char *
|
const char *
|
||||||
KPath::Leaf() const
|
KPath::Leaf() const
|
||||||
{
|
{
|
||||||
if (!fBuffer)
|
if (!fBuffer)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// only "/" has trailing slashes -- then we have to return the complete
|
// only "/" has trailing slashes -- then we have to return the complete
|
||||||
// buffer, as we have to do in case there are no slashes at all
|
// buffer, as we have to do in case there are no slashes at all
|
||||||
if (fPathLength != 1 || fBuffer[0] != '/') {
|
if (fPathLength != 1 || fBuffer[0] != '/') {
|
||||||
@@ -179,13 +179,14 @@ KPath::Leaf() const
|
|||||||
return fBuffer;
|
return fBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReplaceLeaf
|
|
||||||
status_t
|
status_t
|
||||||
KPath::ReplaceLeaf(const char *newLeaf)
|
KPath::ReplaceLeaf(const char *newLeaf)
|
||||||
{
|
{
|
||||||
const char *leaf = Leaf();
|
const char *leaf = Leaf();
|
||||||
if (!leaf)
|
if (!leaf)
|
||||||
return B_NO_INIT;
|
return B_NO_INIT;
|
||||||
|
|
||||||
int32 leafIndex = leaf - fBuffer;
|
int32 leafIndex = leaf - fBuffer;
|
||||||
// chop off the current leaf (don't replace "/", though)
|
// chop off the current leaf (don't replace "/", though)
|
||||||
if (leafIndex != 0 || fBuffer[leafIndex - 1]) {
|
if (leafIndex != 0 || fBuffer[leafIndex - 1]) {
|
||||||
@@ -193,13 +194,14 @@ KPath::ReplaceLeaf(const char *newLeaf)
|
|||||||
fPathLength = leafIndex;
|
fPathLength = leafIndex;
|
||||||
_ChopTrailingSlashes();
|
_ChopTrailingSlashes();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if a leaf was given, append it
|
// if a leaf was given, append it
|
||||||
if (newLeaf)
|
if (newLeaf)
|
||||||
return Append(newLeaf);
|
return Append(newLeaf);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append
|
|
||||||
status_t
|
status_t
|
||||||
KPath::Append(const char *component, bool isComponent)
|
KPath::Append(const char *component, bool isComponent)
|
||||||
{
|
{
|
||||||
@@ -210,26 +212,29 @@ KPath::Append(const char *component, bool isComponent)
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
if (fPathLength == 0)
|
if (fPathLength == 0)
|
||||||
return SetPath(component);
|
return SetPath(component);
|
||||||
|
|
||||||
// get component length
|
// get component length
|
||||||
int32 componentLen = strlen(component);
|
size_t componentLength = strlen(component);
|
||||||
if (componentLen < 1)
|
if (componentLength < 1)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
// if our current path is empty, we just copy the supplied one
|
// if our current path is empty, we just copy the supplied one
|
||||||
// compute the result path len
|
// compute the result path len
|
||||||
bool insertSlash = isComponent && fBuffer[fPathLength - 1] != '/'
|
bool insertSlash = isComponent && fBuffer[fPathLength - 1] != '/'
|
||||||
&& component[0] != '/';
|
&& component[0] != '/';
|
||||||
int32 resultPathLen = fPathLength + componentLen + (insertSlash ? 1 : 0);
|
size_t resultPathLength = fPathLength + componentLength + (insertSlash ? 1 : 0);
|
||||||
if (resultPathLen >= fBufferSize)
|
if (resultPathLength >= fBufferSize)
|
||||||
return B_BUFFER_OVERFLOW;
|
return B_BUFFER_OVERFLOW;
|
||||||
|
|
||||||
// compose the result path
|
// compose the result path
|
||||||
if (insertSlash)
|
if (insertSlash)
|
||||||
fBuffer[fPathLength++] = '/';
|
fBuffer[fPathLength++] = '/';
|
||||||
memcpy(fBuffer + fPathLength, component, componentLen + 1);
|
memcpy(fBuffer + fPathLength, component, componentLength + 1);
|
||||||
fPathLength = resultPathLen;
|
fPathLength = resultPathLength;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =
|
|
||||||
KPath&
|
KPath&
|
||||||
KPath::operator=(const KPath& other)
|
KPath::operator=(const KPath& other)
|
||||||
{
|
{
|
||||||
@@ -237,7 +242,7 @@ KPath::operator=(const KPath& other)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =
|
|
||||||
KPath&
|
KPath&
|
||||||
KPath::operator=(const char* path)
|
KPath::operator=(const char* path)
|
||||||
{
|
{
|
||||||
@@ -245,41 +250,43 @@ KPath::operator=(const char* path)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==
|
|
||||||
bool
|
bool
|
||||||
KPath::operator==(const KPath& other) const
|
KPath::operator==(const KPath& other) const
|
||||||
{
|
{
|
||||||
if (!fBuffer)
|
if (!fBuffer)
|
||||||
return (!other.fBuffer);
|
return !other.fBuffer;
|
||||||
|
|
||||||
return (other.fBuffer
|
return (other.fBuffer
|
||||||
&& fPathLength == other.fPathLength
|
&& fPathLength == other.fPathLength
|
||||||
&& strcmp(fBuffer, other.fBuffer) == 0);
|
&& strcmp(fBuffer, other.fBuffer) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==
|
|
||||||
bool
|
bool
|
||||||
KPath::operator==(const char* path) const
|
KPath::operator==(const char* path) const
|
||||||
{
|
{
|
||||||
if (!fBuffer)
|
if (!fBuffer)
|
||||||
return (!path);
|
return (!path);
|
||||||
return (path && strcmp(fBuffer, path) == 0);
|
|
||||||
|
return path && !strcmp(fBuffer, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// !=
|
|
||||||
bool
|
bool
|
||||||
KPath::operator!=(const KPath& other) const
|
KPath::operator!=(const KPath& other) const
|
||||||
{
|
{
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
// !=
|
|
||||||
bool
|
bool
|
||||||
KPath::operator!=(const char* path) const
|
KPath::operator!=(const char* path) const
|
||||||
{
|
{
|
||||||
return !(*this == path);
|
return !(*this == path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// _ChopTrailingSlashes
|
|
||||||
void
|
void
|
||||||
KPath::_ChopTrailingSlashes()
|
KPath::_ChopTrailingSlashes()
|
||||||
{
|
{
|
||||||
|
|||||||
+220
-168
@@ -1703,16 +1703,20 @@ 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)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
/* this implementation is currently bound to B_PATH_NAME_LENGTH */
|
/* this implementation is currently bound to B_PATH_NAME_LENGTH */
|
||||||
char path[B_PATH_NAME_LENGTH];
|
KPath pathBuffer;
|
||||||
int32 insert = sizeof(path);
|
if (pathBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
char *path = pathBuffer.LockBuffer();
|
||||||
|
int32 insert = pathBuffer.BufferSize();
|
||||||
int32 maxLevel = 256;
|
int32 maxLevel = 256;
|
||||||
int32 length;
|
int32 length;
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
if (vnode == NULL || buffer == NULL)
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
// we don't use get_vnode() here because this call is more
|
// we don't use get_vnode() here because this call is more
|
||||||
// efficient and does all we need from get_vnode()
|
// efficient and does all we need from get_vnode()
|
||||||
inc_vnode_ref_count(vnode);
|
inc_vnode_ref_count(vnode);
|
||||||
@@ -1735,7 +1739,8 @@ dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize)
|
|||||||
int type;
|
int type;
|
||||||
|
|
||||||
// lookup the parent vnode
|
// lookup the parent vnode
|
||||||
status = FS_CALL(vnode, lookup)(vnode->mount->cookie, vnode->private_node, "..", &parentID, &type);
|
status = FS_CALL(vnode, lookup)(vnode->mount->cookie, vnode->private_node, "..",
|
||||||
|
&parentID, &type);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@@ -1744,7 +1749,8 @@ dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize)
|
|||||||
mutex_unlock(&sVnodeMutex);
|
mutex_unlock(&sVnodeMutex);
|
||||||
|
|
||||||
if (parentVnode == NULL) {
|
if (parentVnode == NULL) {
|
||||||
panic("dir_vnode_to_path: could not lookup vnode (mountid 0x%lx vnid 0x%Lx)\n", vnode->device, parentID);
|
panic("dir_vnode_to_path: could not lookup vnode (mountid 0x%lx vnid 0x%Lx)\n",
|
||||||
|
vnode->device, parentID);
|
||||||
status = B_ENTRY_NOT_FOUND;
|
status = B_ENTRY_NOT_FOUND;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -1761,8 +1767,10 @@ dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize)
|
|||||||
|
|
||||||
// Does the file system support getting the name of a vnode?
|
// Does the file system support getting the name of a vnode?
|
||||||
// If so, get it here...
|
// If so, get it here...
|
||||||
if (status == B_OK && FS_CALL(vnode, get_vnode_name))
|
if (status == B_OK && FS_CALL(vnode, get_vnode_name)) {
|
||||||
status = FS_CALL(vnode, get_vnode_name)(vnode->mount->cookie, vnode->private_node, name, B_FILE_NAME_LENGTH);
|
status = FS_CALL(vnode, get_vnode_name)(vnode->mount->cookie, vnode->private_node,
|
||||||
|
name, B_FILE_NAME_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
// ... if not, find it out later (by iterating through
|
// ... if not, find it out later (by iterating through
|
||||||
// the parent directory, searching for the id)
|
// the parent directory, searching for the id)
|
||||||
@@ -1795,7 +1803,8 @@ dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize)
|
|||||||
// in the parent directory now
|
// in the parent directory now
|
||||||
fs_cookie cookie;
|
fs_cookie cookie;
|
||||||
|
|
||||||
status = FS_CALL(vnode, open_dir)(vnode->mount->cookie, vnode->private_node, &cookie);
|
status = FS_CALL(vnode, open_dir)(vnode->mount->cookie, vnode->private_node,
|
||||||
|
&cookie);
|
||||||
if (status >= B_OK) {
|
if (status >= B_OK) {
|
||||||
struct dirent *dirent = (struct dirent *)nameBuffer;
|
struct dirent *dirent = (struct dirent *)nameBuffer;
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -1836,7 +1845,7 @@ dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize)
|
|||||||
TRACE((" path is: %s\n", path + insert));
|
TRACE((" path is: %s\n", path + insert));
|
||||||
|
|
||||||
// copy the path to the output buffer
|
// copy the path to the output buffer
|
||||||
length = sizeof(path) - insert;
|
length = pathBuffer.BufferSize() - insert;
|
||||||
if (length <= (int)bufferSize)
|
if (length <= (int)bufferSize)
|
||||||
memcpy(buffer, path + insert, length);
|
memcpy(buffer, path + insert, length);
|
||||||
else
|
else
|
||||||
@@ -2488,15 +2497,17 @@ vfs_get_vnode_from_fd(int fd, bool kernel, void **vnode)
|
|||||||
extern "C" status_t
|
extern "C" status_t
|
||||||
vfs_get_vnode_from_path(const char *path, bool kernel, void **_vnode)
|
vfs_get_vnode_from_path(const char *path, bool kernel, void **_vnode)
|
||||||
{
|
{
|
||||||
struct vnode *vnode;
|
|
||||||
status_t status;
|
|
||||||
char buffer[B_PATH_NAME_LENGTH + 1];
|
|
||||||
|
|
||||||
TRACE(("vfs_get_vnode_from_path: entry. path = '%s', kernel %d\n", path, kernel));
|
TRACE(("vfs_get_vnode_from_path: entry. path = '%s', kernel %d\n", path, kernel));
|
||||||
|
|
||||||
strlcpy(buffer, path, sizeof(buffer));
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
|
if (pathBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
status = path_to_vnode(buffer, true, &vnode, NULL, kernel);
|
char *buffer = pathBuffer.LockBuffer();
|
||||||
|
strlcpy(buffer, path, pathBuffer.BufferSize());
|
||||||
|
|
||||||
|
struct vnode *vnode;
|
||||||
|
status_t status = path_to_vnode(buffer, true, &vnode, NULL, kernel);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -2561,14 +2572,18 @@ vfs_lookup_vnode(mount_id mountID, vnode_id vnodeID, void **_vnode)
|
|||||||
extern "C" status_t
|
extern "C" status_t
|
||||||
vfs_get_fs_node_from_path(mount_id mountID, const char *path, bool kernel, void **_node)
|
vfs_get_fs_node_from_path(mount_id mountID, const char *path, bool kernel, void **_node)
|
||||||
{
|
{
|
||||||
char buffer[B_PATH_NAME_LENGTH + 1];
|
TRACE(("vfs_get_fs_node_from_path(mountID = %ld, path = \"%s\", kernel %d)\n",
|
||||||
|
mountID, path, kernel));
|
||||||
|
|
||||||
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
|
if (pathBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
char *buffer = pathBuffer.LockBuffer();
|
||||||
|
strlcpy(buffer, path, pathBuffer.BufferSize());
|
||||||
|
|
||||||
struct vnode *vnode;
|
struct vnode *vnode;
|
||||||
status_t status;
|
status_t status = path_to_vnode(buffer, true, &vnode, NULL, kernel);
|
||||||
|
|
||||||
TRACE(("vfs_get_fs_node_from_path(mountID = %ld, path = \"%s\", kernel %d)\n", mountID, path, kernel));
|
|
||||||
|
|
||||||
strlcpy(buffer, path, sizeof(buffer));
|
|
||||||
status = path_to_vnode(buffer, true, &vnode, NULL, kernel);
|
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -2704,7 +2719,11 @@ vfs_normalize_path(const char *path, char *buffer, size_t bufferSize,
|
|||||||
TRACE(("vfs_normalize_path(`%s')\n", path));
|
TRACE(("vfs_normalize_path(`%s')\n", path));
|
||||||
|
|
||||||
// copy the supplied path to the stack, so it can be modified
|
// copy the supplied path to the stack, so it can be modified
|
||||||
char mutablePath[B_PATH_NAME_LENGTH + 1];
|
KPath mutablePathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
|
if (mutablePathBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
char *mutablePath = mutablePathBuffer.LockBuffer();
|
||||||
if (strlcpy(mutablePath, path, B_PATH_NAME_LENGTH) >= B_PATH_NAME_LENGTH)
|
if (strlcpy(mutablePath, path, B_PATH_NAME_LENGTH) >= B_PATH_NAME_LENGTH)
|
||||||
return B_NAME_TOO_LONG;
|
return B_NAME_TOO_LONG;
|
||||||
|
|
||||||
@@ -2723,7 +2742,8 @@ vfs_normalize_path(const char *path, char *buffer, size_t bufferSize,
|
|||||||
if (isDir)
|
if (isDir)
|
||||||
error = vnode_path_to_vnode(dirNode, leaf, false, 0, &dirNode, NULL, NULL);
|
error = vnode_path_to_vnode(dirNode, leaf, false, 0, &dirNode, NULL, NULL);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
TRACE(("vfs_normalize_path(): failed to get dir vnode for \".\" or \"..\": %s\n", strerror(error)));
|
TRACE(("vfs_normalize_path(): failed to get dir vnode for \".\" or \"..\": %s\n",
|
||||||
|
strerror(error)));
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6372,7 +6392,10 @@ status_t
|
|||||||
_user_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf,
|
_user_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf,
|
||||||
char *userPath, size_t pathLength)
|
char *userPath, size_t pathLength)
|
||||||
{
|
{
|
||||||
char path[B_PATH_NAME_LENGTH + 1];
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
|
if (pathBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
struct vnode *vnode;
|
struct vnode *vnode;
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
@@ -6408,8 +6431,10 @@ _user_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf,
|
|||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
char *path = pathBuffer.LockBuffer();
|
||||||
|
|
||||||
// get the directory path
|
// get the directory path
|
||||||
status = dir_vnode_to_path(vnode, path, sizeof(path));
|
status = dir_vnode_to_path(vnode, path, pathBuffer.BufferSize());
|
||||||
put_vnode(vnode);
|
put_vnode(vnode);
|
||||||
// we don't need the vnode anymore
|
// we don't need the vnode anymore
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
@@ -6418,8 +6443,9 @@ _user_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf,
|
|||||||
// append the leaf name
|
// append the leaf name
|
||||||
if (leaf) {
|
if (leaf) {
|
||||||
// insert a directory separator if this is not the file system root
|
// insert a directory separator if this is not the file system root
|
||||||
if ((strcmp(path, "/") && strlcat(path, "/", sizeof(path)) >= sizeof(path))
|
if ((strcmp(path, "/") && strlcat(path, "/", pathBuffer.BufferSize())
|
||||||
|| strlcat(path, leaf, sizeof(path)) >= sizeof(path)) {
|
>= pathBuffer.BufferSize())
|
||||||
|
|| strlcat(path, leaf, pathBuffer.BufferSize()) >= pathBuffer.BufferSize()) {
|
||||||
return B_NAME_TOO_LONG;
|
return B_NAME_TOO_LONG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6429,6 +6455,7 @@ _user_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf,
|
|||||||
return len;
|
return len;
|
||||||
if (len >= (int)pathLength)
|
if (len >= (int)pathLength)
|
||||||
return B_BUFFER_OVERFLOW;
|
return B_BUFFER_OVERFLOW;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6457,36 +6484,33 @@ _user_open_entry_ref(dev_t device, ino_t inode, const char *userName,
|
|||||||
int
|
int
|
||||||
_user_open(int fd, const char *userPath, int openMode, int perms)
|
_user_open(int fd, const char *userPath, int openMode, int perms)
|
||||||
{
|
{
|
||||||
char path[B_PATH_NAME_LENGTH + 1];
|
KPath path(B_PATH_NAME_LENGTH + 1);
|
||||||
int status;
|
if (path.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userPath))
|
char *buffer = path.LockBuffer();
|
||||||
|
|
||||||
|
if (!IS_USER_ADDRESS(userPath)
|
||||||
|
|| user_strlcpy(buffer, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
status = user_strlcpy(path, userPath, B_PATH_NAME_LENGTH);
|
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
if (openMode & O_CREAT)
|
if (openMode & O_CREAT)
|
||||||
return file_create(fd, path, openMode, perms, false);
|
return file_create(fd, buffer, openMode, perms, false);
|
||||||
|
|
||||||
return file_open(fd, path, openMode, false);
|
return file_open(fd, buffer, openMode, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
_user_open_dir_entry_ref(dev_t device, ino_t inode, const char *uname)
|
_user_open_dir_entry_ref(dev_t device, ino_t inode, const char *userName)
|
||||||
{
|
{
|
||||||
if (uname) {
|
if (userName != NULL) {
|
||||||
char name[B_FILE_NAME_LENGTH];
|
char name[B_FILE_NAME_LENGTH];
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(uname))
|
if (!IS_USER_ADDRESS(userName)
|
||||||
|
|| user_strlcpy(name, userName, sizeof(name)) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
int status = user_strlcpy(name, uname, sizeof(name));
|
|
||||||
if (status < B_OK)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
return dir_open_entry_ref(device, inode, name, false);
|
return dir_open_entry_ref(device, inode, name, false);
|
||||||
}
|
}
|
||||||
return dir_open_entry_ref(device, inode, NULL, false);
|
return dir_open_entry_ref(device, inode, NULL, false);
|
||||||
@@ -6496,17 +6520,17 @@ _user_open_dir_entry_ref(dev_t device, ino_t inode, const char *uname)
|
|||||||
int
|
int
|
||||||
_user_open_dir(int fd, const char *userPath)
|
_user_open_dir(int fd, const char *userPath)
|
||||||
{
|
{
|
||||||
char path[B_PATH_NAME_LENGTH + 1];
|
KPath path(B_PATH_NAME_LENGTH + 1);
|
||||||
int status;
|
if (path.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userPath))
|
char *buffer = path.LockBuffer();
|
||||||
|
|
||||||
|
if (!IS_USER_ADDRESS(userPath)
|
||||||
|
|| user_strlcpy(buffer, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
status = user_strlcpy(path, userPath, B_PATH_NAME_LENGTH);
|
return dir_open(fd, buffer, false);
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
return dir_open(fd, path, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -6618,16 +6642,16 @@ _user_create_dir_entry_ref(dev_t device, ino_t inode, const char *userName, int
|
|||||||
status_t
|
status_t
|
||||||
_user_create_dir(int fd, const char *userPath, int perms)
|
_user_create_dir(int fd, const char *userPath, int perms)
|
||||||
{
|
{
|
||||||
char path[B_PATH_NAME_LENGTH + 1];
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
status_t status;
|
if (pathBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userPath))
|
char *path = pathBuffer.LockBuffer();
|
||||||
|
|
||||||
|
if (!IS_USER_ADDRESS(userPath)
|
||||||
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
status = user_strlcpy(path, userPath, B_PATH_NAME_LENGTH);
|
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
return dir_create(fd, path, perms, false);
|
return dir_create(fd, path, perms, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6635,11 +6659,17 @@ _user_create_dir(int fd, const char *userPath, int perms)
|
|||||||
status_t
|
status_t
|
||||||
_user_remove_dir(int fd, const char *userPath)
|
_user_remove_dir(int fd, const char *userPath)
|
||||||
{
|
{
|
||||||
char path[B_PATH_NAME_LENGTH + 1];
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
|
if (pathBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
if ((userPath != NULL && !IS_USER_ADDRESS(userPath))
|
char *path = pathBuffer.LockBuffer();
|
||||||
|| (userPath != NULL && user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK))
|
|
||||||
return B_BAD_ADDRESS;
|
if (userPath != NULL) {
|
||||||
|
if (!IS_USER_ADDRESS(userPath)
|
||||||
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
}
|
||||||
|
|
||||||
return dir_remove(fd, userPath ? path : NULL, false);
|
return dir_remove(fd, userPath ? path : NULL, false);
|
||||||
}
|
}
|
||||||
@@ -6648,28 +6678,30 @@ _user_remove_dir(int fd, const char *userPath)
|
|||||||
status_t
|
status_t
|
||||||
_user_read_link(int fd, const char *userPath, char *userBuffer, size_t *userBufferSize)
|
_user_read_link(int fd, const char *userPath, char *userBuffer, size_t *userBufferSize)
|
||||||
{
|
{
|
||||||
char path[B_PATH_NAME_LENGTH + 1];
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1), linkBuffer;
|
||||||
char buffer[B_PATH_NAME_LENGTH];
|
if (pathBuffer.InitCheck() != B_OK || linkBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
size_t bufferSize;
|
size_t bufferSize;
|
||||||
status_t status;
|
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userBuffer) || !IS_USER_ADDRESS(userBufferSize)
|
if (!IS_USER_ADDRESS(userBuffer) || !IS_USER_ADDRESS(userBufferSize)
|
||||||
|| user_memcpy(&bufferSize, userBufferSize, sizeof(size_t)) < B_OK)
|
|| user_memcpy(&bufferSize, userBufferSize, sizeof(size_t)) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
if (userPath) {
|
char *path = pathBuffer.LockBuffer();
|
||||||
if (!IS_USER_ADDRESS(userPath))
|
char *buffer = linkBuffer.LockBuffer();
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
|
|
||||||
status = user_strlcpy(path, userPath, B_PATH_NAME_LENGTH);
|
if (userPath) {
|
||||||
if (status < 0)
|
if (!IS_USER_ADDRESS(userPath)
|
||||||
return status;
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
if (bufferSize > B_PATH_NAME_LENGTH)
|
if (bufferSize > B_PATH_NAME_LENGTH)
|
||||||
bufferSize = B_PATH_NAME_LENGTH;
|
bufferSize = B_PATH_NAME_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = common_read_link(fd, userPath ? path : NULL, buffer, &bufferSize, false);
|
status_t status = common_read_link(fd, userPath ? path : NULL, buffer,
|
||||||
|
&bufferSize, false);
|
||||||
|
|
||||||
// we also update the bufferSize in case of errors
|
// we also update the bufferSize in case of errors
|
||||||
// (the real length will be returned in case of B_BUFFER_OVERFLOW)
|
// (the real length will be returned in case of B_BUFFER_OVERFLOW)
|
||||||
@@ -6689,23 +6721,21 @@ _user_read_link(int fd, const char *userPath, char *userBuffer, size_t *userBuff
|
|||||||
status_t
|
status_t
|
||||||
_user_write_link(const char *userPath, const char *userToPath)
|
_user_write_link(const char *userPath, const char *userToPath)
|
||||||
{
|
{
|
||||||
char path[B_PATH_NAME_LENGTH + 1];
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
char toPath[B_PATH_NAME_LENGTH + 1];
|
KPath toPathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
status_t status;
|
if (pathBuffer.InitCheck() != B_OK || toPathBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
char *path = pathBuffer.LockBuffer();
|
||||||
|
char *toPath = toPathBuffer.LockBuffer();
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userPath)
|
if (!IS_USER_ADDRESS(userPath)
|
||||||
|| !IS_USER_ADDRESS(userToPath))
|
|| !IS_USER_ADDRESS(userToPath)
|
||||||
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK
|
||||||
|
|| user_strlcpy(toPath, userToPath, B_PATH_NAME_LENGTH) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
status = user_strlcpy(path, userPath, B_PATH_NAME_LENGTH);
|
status_t status = check_path(toPath);
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
status = user_strlcpy(toPath, userToPath, B_PATH_NAME_LENGTH);
|
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
status = check_path(toPath);
|
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -6717,23 +6747,21 @@ status_t
|
|||||||
_user_create_symlink(int fd, const char *userPath, const char *userToPath,
|
_user_create_symlink(int fd, const char *userPath, const char *userToPath,
|
||||||
int mode)
|
int mode)
|
||||||
{
|
{
|
||||||
char path[B_PATH_NAME_LENGTH + 1];
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
char toPath[B_PATH_NAME_LENGTH + 1];
|
KPath toPathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
status_t status;
|
if (pathBuffer.InitCheck() != B_OK || toPathBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
char *path = pathBuffer.LockBuffer();
|
||||||
|
char *toPath = toPathBuffer.LockBuffer();
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userPath)
|
if (!IS_USER_ADDRESS(userPath)
|
||||||
|| !IS_USER_ADDRESS(userToPath))
|
|| !IS_USER_ADDRESS(userToPath)
|
||||||
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK
|
||||||
|
|| user_strlcpy(toPath, userToPath, B_PATH_NAME_LENGTH) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
status = user_strlcpy(path, userPath, B_PATH_NAME_LENGTH);
|
status_t status = check_path(toPath);
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
status = user_strlcpy(toPath, userToPath, B_PATH_NAME_LENGTH);
|
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
status = check_path(toPath);
|
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -6744,23 +6772,21 @@ _user_create_symlink(int fd, const char *userPath, const char *userToPath,
|
|||||||
status_t
|
status_t
|
||||||
_user_create_link(const char *userPath, const char *userToPath)
|
_user_create_link(const char *userPath, const char *userToPath)
|
||||||
{
|
{
|
||||||
char path[B_PATH_NAME_LENGTH + 1];
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
char toPath[B_PATH_NAME_LENGTH + 1];
|
KPath toPathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
status_t status;
|
if (pathBuffer.InitCheck() != B_OK || toPathBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
char *path = pathBuffer.LockBuffer();
|
||||||
|
char *toPath = toPathBuffer.LockBuffer();
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userPath)
|
if (!IS_USER_ADDRESS(userPath)
|
||||||
|| !IS_USER_ADDRESS(userToPath))
|
|| !IS_USER_ADDRESS(userToPath)
|
||||||
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK
|
||||||
|
|| user_strlcpy(toPath, userToPath, B_PATH_NAME_LENGTH) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
status = user_strlcpy(path, userPath, B_PATH_NAME_LENGTH);
|
status_t status = check_path(toPath);
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
status = user_strlcpy(toPath, userToPath, B_PATH_NAME_LENGTH);
|
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
status = check_path(toPath);
|
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -6771,16 +6797,16 @@ _user_create_link(const char *userPath, const char *userToPath)
|
|||||||
status_t
|
status_t
|
||||||
_user_unlink(int fd, const char *userPath)
|
_user_unlink(int fd, const char *userPath)
|
||||||
{
|
{
|
||||||
char path[B_PATH_NAME_LENGTH + 1];
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
status_t status;
|
if (pathBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userPath))
|
char *path = pathBuffer.LockBuffer();
|
||||||
|
|
||||||
|
if (!IS_USER_ADDRESS(userPath)
|
||||||
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
status = user_strlcpy(path, userPath, B_PATH_NAME_LENGTH);
|
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
return common_unlink(fd, path, false);
|
return common_unlink(fd, path, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6789,21 +6815,19 @@ status_t
|
|||||||
_user_rename(int oldFD, const char *userOldPath, int newFD,
|
_user_rename(int oldFD, const char *userOldPath, int newFD,
|
||||||
const char *userNewPath)
|
const char *userNewPath)
|
||||||
{
|
{
|
||||||
char oldPath[B_PATH_NAME_LENGTH + 1];
|
KPath oldPathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
char newPath[B_PATH_NAME_LENGTH + 1];
|
KPath newPathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
status_t status;
|
if (oldPathBuffer.InitCheck() != B_OK || newPathBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userOldPath) || !IS_USER_ADDRESS(userNewPath))
|
char *oldPath = oldPathBuffer.LockBuffer();
|
||||||
|
char *newPath = newPathBuffer.LockBuffer();
|
||||||
|
|
||||||
|
if (!IS_USER_ADDRESS(userOldPath) || !IS_USER_ADDRESS(userNewPath)
|
||||||
|
|| user_strlcpy(oldPath, userOldPath, B_PATH_NAME_LENGTH) < B_OK
|
||||||
|
|| user_strlcpy(newPath, userNewPath, B_PATH_NAME_LENGTH) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
status = user_strlcpy(oldPath, userOldPath, B_PATH_NAME_LENGTH);
|
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
status = user_strlcpy(newPath, userNewPath, B_PATH_NAME_LENGTH);
|
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
return common_rename(oldFD, oldPath, newFD, newPath, false);
|
return common_rename(oldFD, oldPath, newFD, newPath, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6811,16 +6835,16 @@ _user_rename(int oldFD, const char *userOldPath, int newFD,
|
|||||||
status_t
|
status_t
|
||||||
_user_access(const char *userPath, int mode)
|
_user_access(const char *userPath, int mode)
|
||||||
{
|
{
|
||||||
char path[B_PATH_NAME_LENGTH + 1];
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
status_t status;
|
if (pathBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userPath))
|
char *path = pathBuffer.LockBuffer();
|
||||||
|
|
||||||
|
if (!IS_USER_ADDRESS(userPath)
|
||||||
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
status = user_strlcpy(path, userPath, B_PATH_NAME_LENGTH);
|
|
||||||
if (status < 0)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
return common_access(path, mode, false);
|
return common_access(path, mode, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6840,13 +6864,19 @@ _user_read_stat(int fd, const char *userPath, bool traverseLink,
|
|||||||
|
|
||||||
if (userPath) {
|
if (userPath) {
|
||||||
// path given: get the stat of the node referred to by (fd, path)
|
// path given: get the stat of the node referred to by (fd, path)
|
||||||
char path[B_PATH_NAME_LENGTH + 1];
|
|
||||||
if (!IS_USER_ADDRESS(userPath))
|
if (!IS_USER_ADDRESS(userPath))
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
int len = user_strlcpy(path, userPath, B_PATH_NAME_LENGTH);
|
|
||||||
if (len < 0)
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
return len;
|
if (pathBuffer.InitCheck() != B_OK)
|
||||||
if (len >= B_PATH_NAME_LENGTH)
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
char *path = pathBuffer.LockBuffer();
|
||||||
|
|
||||||
|
ssize_t length = user_strlcpy(path, userPath, B_PATH_NAME_LENGTH);
|
||||||
|
if (length < B_OK)
|
||||||
|
return length;
|
||||||
|
if (length >= B_PATH_NAME_LENGTH)
|
||||||
return B_NAME_TOO_LONG;
|
return B_NAME_TOO_LONG;
|
||||||
|
|
||||||
status = common_path_read_stat(fd, path, traverseLink, &stat, false);
|
status = common_path_read_stat(fd, path, traverseLink, &stat, false);
|
||||||
@@ -6876,12 +6906,11 @@ status_t
|
|||||||
_user_write_stat(int fd, const char *userPath, bool traverseLeafLink,
|
_user_write_stat(int fd, const char *userPath, bool traverseLeafLink,
|
||||||
const struct stat *userStat, size_t statSize, int statMask)
|
const struct stat *userStat, size_t statSize, int statMask)
|
||||||
{
|
{
|
||||||
char path[B_PATH_NAME_LENGTH + 1];
|
|
||||||
struct stat stat;
|
|
||||||
|
|
||||||
if (statSize > sizeof(struct stat))
|
if (statSize > sizeof(struct stat))
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
struct stat stat;
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userStat)
|
if (!IS_USER_ADDRESS(userStat)
|
||||||
|| user_memcpy(&stat, userStat, statSize) < B_OK)
|
|| user_memcpy(&stat, userStat, statSize) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
@@ -6896,10 +6925,17 @@ _user_write_stat(int fd, const char *userPath, bool traverseLeafLink,
|
|||||||
// path given: write the stat of the node referred to by (fd, path)
|
// path given: write the stat of the node referred to by (fd, path)
|
||||||
if (!IS_USER_ADDRESS(userPath))
|
if (!IS_USER_ADDRESS(userPath))
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
int len = user_strlcpy(path, userPath, B_PATH_NAME_LENGTH);
|
|
||||||
if (len < 0)
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
return len;
|
if (pathBuffer.InitCheck() != B_OK)
|
||||||
if (len >= B_PATH_NAME_LENGTH)
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
char *path = pathBuffer.LockBuffer();
|
||||||
|
|
||||||
|
ssize_t length = user_strlcpy(path, userPath, B_PATH_NAME_LENGTH);
|
||||||
|
if (length < B_OK)
|
||||||
|
return length;
|
||||||
|
if (length >= B_PATH_NAME_LENGTH)
|
||||||
return B_NAME_TOO_LONG;
|
return B_NAME_TOO_LONG;
|
||||||
|
|
||||||
status = common_path_write_stat(fd, path, traverseLeafLink, &stat,
|
status = common_path_write_stat(fd, path, traverseLeafLink, &stat,
|
||||||
@@ -6926,15 +6962,19 @@ _user_write_stat(int fd, const char *userPath, bool traverseLeafLink,
|
|||||||
int
|
int
|
||||||
_user_open_attr_dir(int fd, const char *userPath)
|
_user_open_attr_dir(int fd, const char *userPath)
|
||||||
{
|
{
|
||||||
char pathBuffer[B_PATH_NAME_LENGTH + 1];
|
KPath pathBuffer(B_PATH_NAME_LENGTH + 1);
|
||||||
|
if (pathBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
char *path = pathBuffer.LockBuffer();
|
||||||
|
|
||||||
if (userPath != NULL) {
|
if (userPath != NULL) {
|
||||||
if (!IS_USER_ADDRESS(userPath)
|
if (!IS_USER_ADDRESS(userPath)
|
||||||
|| user_strlcpy(pathBuffer, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return attr_dir_open(fd, userPath ? pathBuffer : NULL, false);
|
return attr_dir_open(fd, userPath ? path : NULL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -6980,13 +7020,18 @@ _user_remove_attr(int fd, const char *userName)
|
|||||||
status_t
|
status_t
|
||||||
_user_rename_attr(int fromFile, const char *userFromName, int toFile, const char *userToName)
|
_user_rename_attr(int fromFile, const char *userFromName, int toFile, const char *userToName)
|
||||||
{
|
{
|
||||||
char fromName[B_FILE_NAME_LENGTH];
|
|
||||||
char toName[B_FILE_NAME_LENGTH];
|
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userFromName)
|
if (!IS_USER_ADDRESS(userFromName)
|
||||||
|| !IS_USER_ADDRESS(userToName))
|
|| !IS_USER_ADDRESS(userToName))
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
|
KPath fromNameBuffer(B_FILE_NAME_LENGTH);
|
||||||
|
KPath toNameBuffer(B_FILE_NAME_LENGTH);
|
||||||
|
if (fromNameBuffer.InitCheck() != B_OK || toNameBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
char *fromName = fromNameBuffer.LockBuffer();
|
||||||
|
char *toName = toNameBuffer.LockBuffer();
|
||||||
|
|
||||||
if (user_strlcpy(fromName, userFromName, B_FILE_NAME_LENGTH) < B_OK
|
if (user_strlcpy(fromName, userFromName, B_FILE_NAME_LENGTH) < B_OK
|
||||||
|| user_strlcpy(toName, userToName, B_FILE_NAME_LENGTH) < B_OK)
|
|| user_strlcpy(toName, userToName, B_FILE_NAME_LENGTH) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
@@ -7053,23 +7098,26 @@ _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)
|
||||||
{
|
{
|
||||||
char buffer[B_PATH_NAME_LENGTH];
|
|
||||||
status_t status;
|
|
||||||
|
|
||||||
TRACE(("user_getcwd: buf %p, %ld\n", userBuffer, size));
|
|
||||||
|
|
||||||
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 (pathBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
TRACE(("user_getcwd: buf %p, %ld\n", userBuffer, size));
|
||||||
|
|
||||||
if (size > B_PATH_NAME_LENGTH)
|
if (size > B_PATH_NAME_LENGTH)
|
||||||
size = B_PATH_NAME_LENGTH;
|
size = B_PATH_NAME_LENGTH;
|
||||||
|
|
||||||
status = get_cwd(buffer, size, false);
|
char *path = pathBuffer.LockBuffer();
|
||||||
if (status < 0)
|
|
||||||
|
status_t status = get_cwd(path, size, false);
|
||||||
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
// Copy back the result
|
// Copy back the result
|
||||||
if (user_strlcpy(userBuffer, buffer, size) < B_OK)
|
if (user_strlcpy(userBuffer, path, size) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@@ -7079,10 +7127,14 @@ _user_getcwd(char *userBuffer, size_t size)
|
|||||||
status_t
|
status_t
|
||||||
_user_setcwd(int fd, const char *userPath)
|
_user_setcwd(int fd, const char *userPath)
|
||||||
{
|
{
|
||||||
char path[B_PATH_NAME_LENGTH];
|
|
||||||
|
|
||||||
TRACE(("user_setcwd: path = %p\n", userPath));
|
TRACE(("user_setcwd: path = %p\n", userPath));
|
||||||
|
|
||||||
|
KPath pathBuffer(B_PATH_NAME_LENGTH);
|
||||||
|
if (pathBuffer.InitCheck() != B_OK)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
char *path = pathBuffer.LockBuffer();
|
||||||
|
|
||||||
if (userPath != NULL) {
|
if (userPath != NULL) {
|
||||||
if (!IS_USER_ADDRESS(userPath)
|
if (!IS_USER_ADDRESS(userPath)
|
||||||
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
|| user_strlcpy(path, userPath, B_PATH_NAME_LENGTH) < B_OK)
|
||||||
|
|||||||
Reference in New Issue
Block a user