10d4c16e0SAxel Dörfler /*
2e8d3eff9SIngo Weinhold * Copyright 2004-2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3e1b4aed0SAxel Dörfler * Copyright 2008-2017, Axel Dörfler, axeld@pinc-software.de.
40d4c16e0SAxel Dörfler * Distributed under the terms of the MIT License.
50d4c16e0SAxel Dörfler */
62d690920SAxel Dörfler
73582d4feSAxel Dörfler
83582d4feSAxel Dörfler /*! A simple class wrapping a path. Has a fixed-sized buffer. */
93582d4feSAxel Dörfler
102d690920SAxel Dörfler
1123a60f42SAxel Dörfler #include <fs/KPath.h>
122d690920SAxel Dörfler
130d4c16e0SAxel Dörfler #include <stdlib.h>
140d4c16e0SAxel Dörfler #include <string.h>
152d690920SAxel Dörfler
1623a60f42SAxel Dörfler #include <team.h>
1723a60f42SAxel Dörfler #include <vfs.h>
1842e3c6f9SAugustin Cavalier #include <slab/Slab.h>
1923a60f42SAxel Dörfler
200d4c16e0SAxel Dörfler
210d4c16e0SAxel Dörfler // debugging
220d4c16e0SAxel Dörfler #define TRACE(x) ;
230d4c16e0SAxel Dörfler //#define TRACE(x) dprintf x
240d4c16e0SAxel Dörfler
250d4c16e0SAxel Dörfler
2642e3c6f9SAugustin Cavalier #ifdef _KERNEL_MODE
2742e3c6f9SAugustin Cavalier extern object_cache* sPathNameCache;
2842e3c6f9SAugustin Cavalier #endif
2942e3c6f9SAugustin Cavalier
3042e3c6f9SAugustin Cavalier
KPath(size_t bufferSize)310d4c16e0SAxel Dörfler KPath::KPath(size_t bufferSize)
320d4c16e0SAxel Dörfler :
330d4c16e0SAxel Dörfler fBuffer(NULL),
342d690920SAxel Dörfler fBufferSize(0),
352d690920SAxel Dörfler fPathLength(0),
36e9843da3SAxel Dörfler fLocked(false),
37e9843da3SAxel Dörfler fLazy(false),
38e9843da3SAxel Dörfler fFailed(false),
39e9843da3SAxel Dörfler fIsNull(false)
402d690920SAxel Dörfler {
41e9843da3SAxel Dörfler SetTo(NULL, DEFAULT, bufferSize);
422d690920SAxel Dörfler }
432d690920SAxel Dörfler
440d4c16e0SAxel Dörfler
KPath(const char * path,int32 flags,size_t bufferSize)45eac83fb3SAxel Dörfler KPath::KPath(const char* path, int32 flags, size_t bufferSize)
460d4c16e0SAxel Dörfler :
470d4c16e0SAxel Dörfler fBuffer(NULL),
482d690920SAxel Dörfler fBufferSize(0),
492d690920SAxel Dörfler fPathLength(0),
50e9843da3SAxel Dörfler fLocked(false),
51e9843da3SAxel Dörfler fLazy(false),
52e9843da3SAxel Dörfler fFailed(false),
53e9843da3SAxel Dörfler fIsNull(false)
542d690920SAxel Dörfler {
55eac83fb3SAxel Dörfler SetTo(path, flags, bufferSize);
562d690920SAxel Dörfler }
572d690920SAxel Dörfler
580d4c16e0SAxel Dörfler
KPath(const KPath & other)592d690920SAxel Dörfler KPath::KPath(const KPath& other)
600d4c16e0SAxel Dörfler :
610d4c16e0SAxel Dörfler fBuffer(NULL),
622d690920SAxel Dörfler fBufferSize(0),
632d690920SAxel Dörfler fPathLength(0),
64e9843da3SAxel Dörfler fLocked(false),
65e9843da3SAxel Dörfler fLazy(false),
66e9843da3SAxel Dörfler fFailed(false),
67e9843da3SAxel Dörfler fIsNull(false)
682d690920SAxel Dörfler {
692d690920SAxel Dörfler *this = other;
702d690920SAxel Dörfler }
712d690920SAxel Dörfler
720d4c16e0SAxel Dörfler
~KPath()732d690920SAxel Dörfler KPath::~KPath()
742d690920SAxel Dörfler {
7542e3c6f9SAugustin Cavalier _FreeBuffer();
762d690920SAxel Dörfler }
772d690920SAxel Dörfler
780d4c16e0SAxel Dörfler
792d690920SAxel Dörfler status_t
SetTo(const char * path,int32 flags,size_t bufferSize)80eac83fb3SAxel Dörfler KPath::SetTo(const char* path, int32 flags, size_t bufferSize)
812d690920SAxel Dörfler {
820d4c16e0SAxel Dörfler if (bufferSize == 0)
83*9708b080SAugustin Cavalier bufferSize = B_PATH_NAME_LENGTH;
840d4c16e0SAxel Dörfler
852d690920SAxel Dörfler // free the previous buffer, if the buffer size differs
863582d4feSAxel Dörfler if (fBuffer != NULL && fBufferSize != bufferSize) {
8742e3c6f9SAugustin Cavalier _FreeBuffer();
882d690920SAxel Dörfler fBufferSize = 0;
892d690920SAxel Dörfler }
90e9843da3SAxel Dörfler
912d690920SAxel Dörfler fPathLength = 0;
922d690920SAxel Dörfler fLocked = false;
932d690920SAxel Dörfler fBufferSize = bufferSize;
94e9843da3SAxel Dörfler fLazy = (flags & LAZY_ALLOC) != 0;
95e9843da3SAxel Dörfler fIsNull = path == NULL;
96e9843da3SAxel Dörfler
97e9843da3SAxel Dörfler if (path != NULL || !fLazy) {
98e9843da3SAxel Dörfler status_t status = _AllocateBuffer();
99e9843da3SAxel Dörfler if (status != B_OK)
100e9843da3SAxel Dörfler return status;
101e9843da3SAxel Dörfler }
1023582d4feSAxel Dörfler
103eac83fb3SAxel Dörfler return SetPath(path, flags);
1042d690920SAxel Dörfler }
1052d690920SAxel Dörfler
1060d4c16e0SAxel Dörfler
10756bbbbc9SAxel Dörfler void
Adopt(KPath & other)10856bbbbc9SAxel Dörfler KPath::Adopt(KPath& other)
10956bbbbc9SAxel Dörfler {
11042e3c6f9SAugustin Cavalier _FreeBuffer();
11156bbbbc9SAxel Dörfler
11256bbbbc9SAxel Dörfler fBuffer = other.fBuffer;
11356bbbbc9SAxel Dörfler fBufferSize = other.fBufferSize;
114f94671c3SAxel Dörfler fPathLength = other.fPathLength;
115e9843da3SAxel Dörfler fLazy = other.fLazy;
116e9843da3SAxel Dörfler fFailed = other.fFailed;
117e9843da3SAxel Dörfler fIsNull = other.fIsNull;
11856bbbbc9SAxel Dörfler
11956bbbbc9SAxel Dörfler other.fBuffer = NULL;
120e9843da3SAxel Dörfler if (!other.fLazy)
1214be51875SAxel Dörfler other.fBufferSize = 0;
1224be51875SAxel Dörfler other.fPathLength = 0;
123e9843da3SAxel Dörfler other.fFailed = false;
124e9843da3SAxel Dörfler other.fIsNull = other.fLazy;
12556bbbbc9SAxel Dörfler }
12656bbbbc9SAxel Dörfler
12756bbbbc9SAxel Dörfler
1282d690920SAxel Dörfler status_t
InitCheck() const1292d690920SAxel Dörfler KPath::InitCheck() const
1302d690920SAxel Dörfler {
131655aae6aSAxel Dörfler if (fBuffer != NULL || (fLazy && !fFailed && fBufferSize != 0))
132e9843da3SAxel Dörfler return B_OK;
133e9843da3SAxel Dörfler
134e9843da3SAxel Dörfler return fFailed ? B_NO_MEMORY : B_NO_INIT;
1352d690920SAxel Dörfler }
1362d690920SAxel Dörfler
1370d4c16e0SAxel Dörfler
138e9843da3SAxel Dörfler /*! \brief Sets the buffer to \a path.
139e9843da3SAxel Dörfler
140e9843da3SAxel Dörfler \param flags Understands the following two options:
141e9843da3SAxel Dörfler - \c NORMALIZE
142e9843da3SAxel Dörfler - \c TRAVERSE_LEAF_LINK
143e9843da3SAxel Dörfler */
1442d690920SAxel Dörfler status_t
SetPath(const char * path,int32 flags)145eac83fb3SAxel Dörfler KPath::SetPath(const char* path, int32 flags)
1462d690920SAxel Dörfler {
147e9843da3SAxel Dörfler if (path == NULL && fLazy && fBuffer == NULL) {
148e9843da3SAxel Dörfler fIsNull = true;
149e9843da3SAxel Dörfler return B_OK;
150e9843da3SAxel Dörfler }
151e9843da3SAxel Dörfler
152e9843da3SAxel Dörfler if (fBuffer == NULL) {
153e9843da3SAxel Dörfler if (fLazy) {
154e9843da3SAxel Dörfler status_t status = _AllocateBuffer();
155e9843da3SAxel Dörfler if (status != B_OK)
156e9843da3SAxel Dörfler return B_NO_MEMORY;
157e9843da3SAxel Dörfler } else
1582d690920SAxel Dörfler return B_NO_INIT;
159e9843da3SAxel Dörfler }
160e9843da3SAxel Dörfler
161e9843da3SAxel Dörfler fIsNull = false;
1620d4c16e0SAxel Dörfler
1639abf4591Sczeidler if (path != NULL) {
164eac83fb3SAxel Dörfler if ((flags & NORMALIZE) != 0) {
1652d690920SAxel Dörfler // normalize path
166e9843da3SAxel Dörfler status_t status = _Normalize(path,
167e9843da3SAxel Dörfler (flags & TRAVERSE_LEAF_LINK) != 0);
168e9843da3SAxel Dörfler if (status != B_OK)
169e9843da3SAxel Dörfler return status;
1702d690920SAxel Dörfler } else {
1712d690920SAxel Dörfler // don't normalize path
1720d4c16e0SAxel Dörfler size_t length = strlen(path);
1730d4c16e0SAxel Dörfler if (length >= fBufferSize)
1742d690920SAxel Dörfler return B_BUFFER_OVERFLOW;
1750d4c16e0SAxel Dörfler
1760d4c16e0SAxel Dörfler memcpy(fBuffer, path, length + 1);
1770d4c16e0SAxel Dörfler fPathLength = length;
1782d690920SAxel Dörfler _ChopTrailingSlashes();
1792d690920SAxel Dörfler }
1802d690920SAxel Dörfler } else {
1812d690920SAxel Dörfler fBuffer[0] = '\0';
1822d690920SAxel Dörfler fPathLength = 0;
183e9843da3SAxel Dörfler if (fLazy)
184e9843da3SAxel Dörfler fIsNull = true;
1852d690920SAxel Dörfler }
1862d690920SAxel Dörfler return B_OK;
1872d690920SAxel Dörfler }
1882d690920SAxel Dörfler
1890d4c16e0SAxel Dörfler
1902d690920SAxel Dörfler const char*
Path() const1912d690920SAxel Dörfler KPath::Path() const
1922d690920SAxel Dörfler {
193e9843da3SAxel Dörfler return fIsNull ? NULL : fBuffer;
1942d690920SAxel Dörfler }
1952d690920SAxel Dörfler
1962d690920SAxel Dörfler
197e9843da3SAxel Dörfler /*! \brief Locks the buffer for external changes.
198e9843da3SAxel Dörfler
199e9843da3SAxel Dörfler \param force In lazy mode, this will allocate a buffer when set.
200e9843da3SAxel Dörfler Otherwise, \c NULL will be returned if set to NULL.
201e9843da3SAxel Dörfler */
2022d690920SAxel Dörfler char*
LockBuffer(bool force)203e9843da3SAxel Dörfler KPath::LockBuffer(bool force)
2042d690920SAxel Dörfler {
205e9843da3SAxel Dörfler if (fBuffer == NULL && fLazy) {
206e9843da3SAxel Dörfler if (fIsNull && !force)
207e9843da3SAxel Dörfler return NULL;
208e9843da3SAxel Dörfler
209e9843da3SAxel Dörfler _AllocateBuffer();
210e9843da3SAxel Dörfler }
211e9843da3SAxel Dörfler
2129abf4591Sczeidler if (fBuffer == NULL || fLocked)
2132d690920SAxel Dörfler return NULL;
2140d4c16e0SAxel Dörfler
2152d690920SAxel Dörfler fLocked = true;
216e9843da3SAxel Dörfler fIsNull = false;
217e9843da3SAxel Dörfler
2182d690920SAxel Dörfler return fBuffer;
2192d690920SAxel Dörfler }
2202d690920SAxel Dörfler
2210d4c16e0SAxel Dörfler
2222d690920SAxel Dörfler void
UnlockBuffer()2232d690920SAxel Dörfler KPath::UnlockBuffer()
2242d690920SAxel Dörfler {
2252d690920SAxel Dörfler if (!fLocked) {
22642e3c6f9SAugustin Cavalier #ifdef _KERNEL_MODE
22742e3c6f9SAugustin Cavalier panic("KPath::UnlockBuffer(): Buffer not locked!");
22842e3c6f9SAugustin Cavalier #endif
2292d690920SAxel Dörfler return;
2302d690920SAxel Dörfler }
231e9843da3SAxel Dörfler
2322d690920SAxel Dörfler fLocked = false;
233e9843da3SAxel Dörfler
234e9843da3SAxel Dörfler if (fBuffer == NULL)
235e9843da3SAxel Dörfler return;
236e9843da3SAxel Dörfler
2372d690920SAxel Dörfler fPathLength = strnlen(fBuffer, fBufferSize);
2382d690920SAxel Dörfler if (fPathLength == fBufferSize) {
2390d4c16e0SAxel Dörfler TRACE(("KPath::UnlockBuffer(): WARNING: Unterminated buffer!\n"));
2402d690920SAxel Dörfler fPathLength--;
2412d690920SAxel Dörfler fBuffer[fPathLength] = '\0';
2422d690920SAxel Dörfler }
2432d690920SAxel Dörfler _ChopTrailingSlashes();
2442d690920SAxel Dörfler }
2452d690920SAxel Dörfler
2460d4c16e0SAxel Dörfler
247e8d3eff9SIngo Weinhold char*
DetachBuffer()248e8d3eff9SIngo Weinhold KPath::DetachBuffer()
249e8d3eff9SIngo Weinhold {
250e8d3eff9SIngo Weinhold char* buffer = fBuffer;
251e8d3eff9SIngo Weinhold
252*9708b080SAugustin Cavalier #ifdef _KERNEL_MODE
253*9708b080SAugustin Cavalier if (fBufferSize == B_PATH_NAME_LENGTH) {
25442e3c6f9SAugustin Cavalier buffer = (char*)malloc(fBufferSize);
25542e3c6f9SAugustin Cavalier memcpy(buffer, fBuffer, fBufferSize);
25642e3c6f9SAugustin Cavalier _FreeBuffer();
25742e3c6f9SAugustin Cavalier }
258*9708b080SAugustin Cavalier #endif
25942e3c6f9SAugustin Cavalier
260e8d3eff9SIngo Weinhold if (fBuffer != NULL) {
261e8d3eff9SIngo Weinhold fBuffer = NULL;
262e8d3eff9SIngo Weinhold fPathLength = 0;
263e8d3eff9SIngo Weinhold fLocked = false;
264e8d3eff9SIngo Weinhold }
265e8d3eff9SIngo Weinhold
266e8d3eff9SIngo Weinhold return buffer;
267e8d3eff9SIngo Weinhold }
268e8d3eff9SIngo Weinhold
269e8d3eff9SIngo Weinhold
2702d690920SAxel Dörfler const char*
Leaf() const2712d690920SAxel Dörfler KPath::Leaf() const
2722d690920SAxel Dörfler {
2733582d4feSAxel Dörfler if (fBuffer == NULL)
2742d690920SAxel Dörfler return NULL;
2750d4c16e0SAxel Dörfler
2762d690920SAxel Dörfler for (int32 i = fPathLength - 1; i >= 0; i--) {
2772d690920SAxel Dörfler if (fBuffer[i] == '/')
2782d690920SAxel Dörfler return fBuffer + i + 1;
2792d690920SAxel Dörfler }
280e1b4aed0SAxel Dörfler
2812d690920SAxel Dörfler return fBuffer;
2822d690920SAxel Dörfler }
2832d690920SAxel Dörfler
2840d4c16e0SAxel Dörfler
2852d690920SAxel Dörfler status_t
ReplaceLeaf(const char * newLeaf)2862d690920SAxel Dörfler KPath::ReplaceLeaf(const char* newLeaf)
2872d690920SAxel Dörfler {
2882d690920SAxel Dörfler const char* leaf = Leaf();
2893582d4feSAxel Dörfler if (leaf == NULL)
2902d690920SAxel Dörfler return B_NO_INIT;
2910d4c16e0SAxel Dörfler
2922d690920SAxel Dörfler int32 leafIndex = leaf - fBuffer;
2932d690920SAxel Dörfler // chop off the current leaf (don't replace "/", though)
2942d690920SAxel Dörfler if (leafIndex != 0 || fBuffer[leafIndex - 1]) {
2952d690920SAxel Dörfler fBuffer[leafIndex] = '\0';
2962d690920SAxel Dörfler fPathLength = leafIndex;
2972d690920SAxel Dörfler _ChopTrailingSlashes();
2982d690920SAxel Dörfler }
2990d4c16e0SAxel Dörfler
3002d690920SAxel Dörfler // if a leaf was given, append it
3013582d4feSAxel Dörfler if (newLeaf != NULL)
3022d690920SAxel Dörfler return Append(newLeaf);
3032d690920SAxel Dörfler return B_OK;
3042d690920SAxel Dörfler }
3052d690920SAxel Dörfler
3060d4c16e0SAxel Dörfler
3073532662eSIngo Weinhold bool
RemoveLeaf()3083532662eSIngo Weinhold KPath::RemoveLeaf()
3093532662eSIngo Weinhold {
3103532662eSIngo Weinhold // get the leaf -- bail out, if not initialized or only the "/" is left
3113532662eSIngo Weinhold const char* leaf = Leaf();
312e1b4aed0SAxel Dörfler if (leaf == NULL || leaf == fBuffer || leaf[0] == '\0')
3133532662eSIngo Weinhold return false;
3143532662eSIngo Weinhold
3153532662eSIngo Weinhold // chop off the leaf
3163532662eSIngo Weinhold int32 leafIndex = leaf - fBuffer;
3173532662eSIngo Weinhold fBuffer[leafIndex] = '\0';
3183532662eSIngo Weinhold fPathLength = leafIndex;
3193532662eSIngo Weinhold _ChopTrailingSlashes();
3203532662eSIngo Weinhold
3213532662eSIngo Weinhold return true;
3223532662eSIngo Weinhold }
3233532662eSIngo Weinhold
3243532662eSIngo Weinhold
3252d690920SAxel Dörfler status_t
Append(const char * component,bool isComponent)3262d690920SAxel Dörfler KPath::Append(const char* component, bool isComponent)
3272d690920SAxel Dörfler {
3282d690920SAxel Dörfler // check initialization and parameter
3299abf4591Sczeidler if (fBuffer == NULL)
3302d690920SAxel Dörfler return B_NO_INIT;
3319abf4591Sczeidler if (component == NULL)
3322d690920SAxel Dörfler return B_BAD_VALUE;
3332d690920SAxel Dörfler if (fPathLength == 0)
3342d690920SAxel Dörfler return SetPath(component);
3350d4c16e0SAxel Dörfler
3362d690920SAxel Dörfler // get component length
3370d4c16e0SAxel Dörfler size_t componentLength = strlen(component);
3380d4c16e0SAxel Dörfler if (componentLength < 1)
3392d690920SAxel Dörfler return B_OK;
3400d4c16e0SAxel Dörfler
3412d690920SAxel Dörfler // if our current path is empty, we just copy the supplied one
3422d690920SAxel Dörfler // compute the result path len
3432d690920SAxel Dörfler bool insertSlash = isComponent && fBuffer[fPathLength - 1] != '/'
3442d690920SAxel Dörfler && component[0] != '/';
345ea26d9f0SStephan Aßmus size_t resultPathLength = fPathLength + componentLength
346ea26d9f0SStephan Aßmus + (insertSlash ? 1 : 0);
3470d4c16e0SAxel Dörfler if (resultPathLength >= fBufferSize)
3482d690920SAxel Dörfler return B_BUFFER_OVERFLOW;
3490d4c16e0SAxel Dörfler
3502d690920SAxel Dörfler // compose the result path
3512d690920SAxel Dörfler if (insertSlash)
3522d690920SAxel Dörfler fBuffer[fPathLength++] = '/';
3530d4c16e0SAxel Dörfler memcpy(fBuffer + fPathLength, component, componentLength + 1);
3540d4c16e0SAxel Dörfler fPathLength = resultPathLength;
3552d690920SAxel Dörfler return B_OK;
3562d690920SAxel Dörfler }
3572d690920SAxel Dörfler
3580d4c16e0SAxel Dörfler
359e8d3eff9SIngo Weinhold status_t
Normalize(bool traverseLeafLink)360e8d3eff9SIngo Weinhold KPath::Normalize(bool traverseLeafLink)
361e8d3eff9SIngo Weinhold {
362e8d3eff9SIngo Weinhold if (fBuffer == NULL)
363e8d3eff9SIngo Weinhold return B_NO_INIT;
364e8d3eff9SIngo Weinhold if (fPathLength == 0)
365e8d3eff9SIngo Weinhold return B_BAD_VALUE;
366e8d3eff9SIngo Weinhold
367e9843da3SAxel Dörfler return _Normalize(fBuffer, traverseLeafLink);
368e8d3eff9SIngo Weinhold }
369e8d3eff9SIngo Weinhold
370e8d3eff9SIngo Weinhold
3712d690920SAxel Dörfler KPath&
operator =(const KPath & other)3722d690920SAxel Dörfler KPath::operator=(const KPath& other)
3732d690920SAxel Dörfler {
374a07f133eSAugustin Cavalier if (other.fBuffer == fBuffer)
375a07f133eSAugustin Cavalier return *this;
376a07f133eSAugustin Cavalier
377e9843da3SAxel Dörfler SetTo(other.fBuffer, fLazy ? KPath::LAZY_ALLOC : KPath::DEFAULT,
378e9843da3SAxel Dörfler other.fBufferSize);
3792d690920SAxel Dörfler return *this;
3802d690920SAxel Dörfler }
3812d690920SAxel Dörfler
3820d4c16e0SAxel Dörfler
3832d690920SAxel Dörfler KPath&
operator =(const char * path)3842d690920SAxel Dörfler KPath::operator=(const char* path)
3852d690920SAxel Dörfler {
386e1b4aed0SAxel Dörfler SetPath(path);
3872d690920SAxel Dörfler return *this;
3882d690920SAxel Dörfler }
3892d690920SAxel Dörfler
3900d4c16e0SAxel Dörfler
3912d690920SAxel Dörfler bool
operator ==(const KPath & other) const3922d690920SAxel Dörfler KPath::operator==(const KPath& other) const
3932d690920SAxel Dörfler {
394e1b4aed0SAxel Dörfler if (fBuffer == NULL)
3950d4c16e0SAxel Dörfler return !other.fBuffer;
3960d4c16e0SAxel Dörfler
397e9843da3SAxel Dörfler return other.fBuffer != NULL
3982d690920SAxel Dörfler && fPathLength == other.fPathLength
3993582d4feSAxel Dörfler && strcmp(fBuffer, other.fBuffer) == 0;
4002d690920SAxel Dörfler }
4012d690920SAxel Dörfler
4020d4c16e0SAxel Dörfler
4032d690920SAxel Dörfler bool
operator ==(const char * path) const4042d690920SAxel Dörfler KPath::operator==(const char* path) const
4052d690920SAxel Dörfler {
406e1b4aed0SAxel Dörfler if (fBuffer == NULL)
407e9843da3SAxel Dörfler return path == NULL;
4080d4c16e0SAxel Dörfler
409e9843da3SAxel Dörfler return path != NULL && strcmp(fBuffer, path) == 0;
4102d690920SAxel Dörfler }
4112d690920SAxel Dörfler
4120d4c16e0SAxel Dörfler
4132d690920SAxel Dörfler bool
operator !=(const KPath & other) const4142d690920SAxel Dörfler KPath::operator!=(const KPath& other) const
4152d690920SAxel Dörfler {
4162d690920SAxel Dörfler return !(*this == other);
4172d690920SAxel Dörfler }
4182d690920SAxel Dörfler
4190d4c16e0SAxel Dörfler
4202d690920SAxel Dörfler bool
operator !=(const char * path) const4212d690920SAxel Dörfler KPath::operator!=(const char* path) const
4222d690920SAxel Dörfler {
4232d690920SAxel Dörfler return !(*this == path);
4242d690920SAxel Dörfler }
4252d690920SAxel Dörfler
4260d4c16e0SAxel Dörfler
427e9843da3SAxel Dörfler status_t
_AllocateBuffer()428e9843da3SAxel Dörfler KPath::_AllocateBuffer()
429e9843da3SAxel Dörfler {
43042e3c6f9SAugustin Cavalier if (fBuffer == NULL && fBufferSize != 0) {
43142e3c6f9SAugustin Cavalier #ifdef _KERNEL_MODE
432*9708b080SAugustin Cavalier if (fBufferSize == B_PATH_NAME_LENGTH)
43342e3c6f9SAugustin Cavalier fBuffer = (char*)object_cache_alloc(sPathNameCache, 0);
43442e3c6f9SAugustin Cavalier else
43542e3c6f9SAugustin Cavalier #endif
436e9843da3SAxel Dörfler fBuffer = (char*)malloc(fBufferSize);
43742e3c6f9SAugustin Cavalier }
438e9843da3SAxel Dörfler if (fBuffer == NULL) {
439e9843da3SAxel Dörfler fFailed = true;
440e9843da3SAxel Dörfler return B_NO_MEMORY;
441e9843da3SAxel Dörfler }
442e9843da3SAxel Dörfler
44390bf90faSwaddlesplash memset(fBuffer, 0, fBufferSize);
444e9843da3SAxel Dörfler fFailed = false;
445e9843da3SAxel Dörfler return B_OK;
446e9843da3SAxel Dörfler }
447e9843da3SAxel Dörfler
448e9843da3SAxel Dörfler
44942e3c6f9SAugustin Cavalier void
_FreeBuffer()45042e3c6f9SAugustin Cavalier KPath::_FreeBuffer()
45142e3c6f9SAugustin Cavalier {
45242e3c6f9SAugustin Cavalier #ifdef _KERNEL_MODE
453*9708b080SAugustin Cavalier if (fBufferSize == B_PATH_NAME_LENGTH)
45442e3c6f9SAugustin Cavalier object_cache_free(sPathNameCache, fBuffer, 0);
45542e3c6f9SAugustin Cavalier else
45642e3c6f9SAugustin Cavalier #endif
45742e3c6f9SAugustin Cavalier free(fBuffer);
45842e3c6f9SAugustin Cavalier fBuffer = NULL;
45942e3c6f9SAugustin Cavalier }
46042e3c6f9SAugustin Cavalier
46142e3c6f9SAugustin Cavalier
462e9843da3SAxel Dörfler status_t
_Normalize(const char * path,bool traverseLeafLink)463e9843da3SAxel Dörfler KPath::_Normalize(const char* path, bool traverseLeafLink)
464e9843da3SAxel Dörfler {
465e9843da3SAxel Dörfler status_t error = vfs_normalize_path(path, fBuffer, fBufferSize,
466e9843da3SAxel Dörfler traverseLeafLink,
467e9843da3SAxel Dörfler team_get_kernel_team_id() == team_get_current_team_id());
468e9843da3SAxel Dörfler if (error != B_OK) {
469e9843da3SAxel Dörfler // vfs_normalize_path() might have screwed up the previous
470e9843da3SAxel Dörfler // path -- unset it completely to avoid weird problems.
471e9843da3SAxel Dörfler fBuffer[0] = '\0';
472e9843da3SAxel Dörfler fPathLength = 0;
473e9843da3SAxel Dörfler return error;
474e9843da3SAxel Dörfler }
475e9843da3SAxel Dörfler
476e9843da3SAxel Dörfler fPathLength = strlen(fBuffer);
477e9843da3SAxel Dörfler return B_OK;
478e9843da3SAxel Dörfler }
479e9843da3SAxel Dörfler
480e9843da3SAxel Dörfler
4812d690920SAxel Dörfler void
_ChopTrailingSlashes()4822d690920SAxel Dörfler KPath::_ChopTrailingSlashes()
4832d690920SAxel Dörfler {
4843582d4feSAxel Dörfler if (fBuffer != NULL) {
4852d690920SAxel Dörfler while (fPathLength > 1 && fBuffer[fPathLength - 1] == '/')
4862d690920SAxel Dörfler fBuffer[--fPathLength] = '\0';
4872d690920SAxel Dörfler }
4882d690920SAxel Dörfler }
4892d690920SAxel Dörfler
490