Changeset 15805 in vbox
- Timestamp:
- Jan 5, 2009 3:03:36 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/path-posix.cpp
r15756 r15805 169 169 RTDECL(int) RTPathAbs(const char *pszPath, char *pszAbsPath, size_t cchAbsPath) 170 170 { 171 if (strlen(pszPath) > PATH_MAX) 172 { 173 LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, 174 pszPath, pszAbsPath, cchAbsPath, VERR_FILENAME_TOO_LONG)); 171 int rc; 172 173 /* 174 * Make a clean working copy of the input. 175 */ 176 size_t cchPath = strlen(pszPath); 177 if (cchPath > PATH_MAX) 178 { 179 LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, pszPath, pszAbsPath, cchAbsPath, VERR_FILENAME_TOO_LONG)); 175 180 return VERR_FILENAME_TOO_LONG; 176 181 } 177 182 178 183 char szTmpPath[PATH_MAX + 1]; 179 strcpy(szTmpPath, pszPath); 180 fsCleanPath(szTmpPath); 181 182 /* 183 * fsCleanPath will leave the single dot alone, we don't need it here. 184 */ 184 memcpy(szTmpPath, pszPath, cchPath + 1); 185 size_t cchTmpPath = fsCleanPath(szTmpPath); 186 187 /* fsCleanPath will leave the single dot alone, we don't need it here. */ 185 188 if (szTmpPath[0] == '.' && !szTmpPath[1]) 186 189 szTmpPath[0] = '\0'; 187 190 191 /* 192 * Do we have a root slash? 193 */ 188 194 char *pszCur = szTmpPath; 189 190 195 #ifdef HAVE_DRIVE 191 196 if (pszCur[0] && RTPATH_IS_VOLSEP(pszCur[1]) && pszCur[2] == '/') 192 197 pszCur += 3; 193 #ifdef HAVE_UNC 194 else 195 if (pszCur[0] == '/' && pszCur[1] == '/') 198 # ifdef HAVE_UNC 199 else if (pszCur[0] == '/' && pszCur[1] == '/') 196 200 pszCur += 2; 197 # endif198 #else 201 # endif 202 #else /* !HAVE_DRIVE */ 199 203 if (pszCur[0] == '/') 200 204 pszCur += 1; 201 #endif 205 #endif /* !HAVE_DRIVE */ 202 206 else 203 207 { 204 208 /* 205 * Prepend the current directory to the relative path.209 * No, prepend the current directory to the relative path. 206 210 */ 207 208 char szCurDir[PATH_MAX + 1]; 209 if (getcwd(szCurDir, sizeof(szCurDir)) == NULL) 210 { 211 AssertMsgFailed(("Couldn't get cwd!\n")); 212 213 int rc = RTErrConvertFromErrno(errno); 214 LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, 215 pszPath, pszAbsPath, cchAbsPath, rc)); 211 /** @todo use RTPathGetCurrent */ 212 char szNativeCurDir[PATH_MAX + 1]; 213 if (getcwd(szNativeCurDir, sizeof(szNativeCurDir)) == NULL) 214 { 215 rc = RTErrConvertFromErrno(errno); 216 AssertMsgFailedReturn(("Couldn't get cwd! rc=%Rrc errno=%d\n", rc, errno), rc); 217 } 218 219 char *pszCurDir; 220 rc = rtPathFromNative(&pszCurDir, szNativeCurDir); 221 if (RT_FAILURE(rc)) 222 { 223 LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, pszPath, pszAbsPath, cchAbsPath, rc)); 216 224 return rc; 217 225 } 218 226 219 fsCleanPath(szCurDir); 220 221 { 222 char *pszUtf8CurDir; 223 int rc = rtPathFromNative(&pszUtf8CurDir, szCurDir); 224 if (RT_FAILURE(rc)) 225 { 226 LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, 227 pszPath, pszAbsPath, cchAbsPath, rc)); 228 return rc; 229 } 230 231 size_t cchUtf8CurDir = strlen(pszUtf8CurDir); 232 if (cchUtf8CurDir + strlen(szTmpPath) + 1 > PATH_MAX) 233 { 234 RTStrFree(pszUtf8CurDir); 235 LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, 236 pszPath, pszAbsPath, cchAbsPath, VERR_FILENAME_TOO_LONG)); 237 return VERR_FILENAME_TOO_LONG; 238 } 239 240 strcpy(szTmpPath + cchUtf8CurDir + 1, szTmpPath); 241 strcpy(szTmpPath, pszUtf8CurDir); 242 szTmpPath[cchUtf8CurDir] = '/'; 243 244 RTStrFree(pszUtf8CurDir); 245 } 227 size_t cchCurDir = fsCleanPath(pszCurDir); /* paranoia */ 228 if (cchCurDir + cchTmpPath + 1 > PATH_MAX) 229 { 230 RTStrFree(pszCurDir); 231 LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, pszPath, pszAbsPath, cchAbsPath, VERR_FILENAME_TOO_LONG)); 232 return VERR_FILENAME_TOO_LONG; 233 } 234 235 memmove(szTmpPath + cchCurDir + 1, szTmpPath, cchTmpPath + 1); 236 memcpy(szTmpPath, pszCurDir, cchCurDir); 237 szTmpPath[cchCurDir] = '/'; 238 239 RTStrFree(pszCurDir); 246 240 247 241 #ifdef HAVE_DRIVE 248 242 if (pszCur[0] && RTPATH_IS_VOLSEP(pszCur[1]) && pszCur[2] == '/') 249 243 pszCur += 3; 250 #ifdef HAVE_UNC 251 else 252 if (pszCur[0] == '/' && pszCur[1] == '/') 244 # ifdef HAVE_UNC 245 else if (pszCur[0] == '/' && pszCur[1] == '/') 253 246 pszCur += 2; 254 # endif247 # endif 255 248 #else 256 249 if (pszCur[0] == '/') … … 258 251 #endif 259 252 else 260 { 261 AssertFailed(); 262 LogFlow(("RTPathAbs(%p:{%s}, %p, %d): returns %Rrc\n", pszPath, 263 pszPath, pszAbsPath, cchAbsPath, VERR_GENERAL_FAILURE)); 264 return VERR_GENERAL_FAILURE; 265 } 253 AssertMsgFailedReturn(("pszCur=%s\n", pszCur), VERR_INTERNAL_ERROR); 266 254 } 267 255 … … 271 259 * Get rid of double dot path components by evaluating them. 272 260 */ 273 274 261 for (;;) 275 262 { 276 if (pszCur[0] == '.' && pszCur[1] == '.' && 277 (!pszCur[2] || pszCur[2] == '/')) 263 if ( pszCur[0] == '.' 264 && pszCur[1] == '.' 265 && (!pszCur[2] || pszCur[2] == '/')) 278 266 { 279 267 /* rewind to the previous component if any */ … … 283 271 ; 284 272 285 AssertMsg(*pszPrev == '/', ("szTmpPath={%s}, pszPrev=+%u\n", 286 szTmpPath, pszPrev - szTmpPath)); 287 strcpy(pszPrev, pszCur + 2); 273 AssertMsg(*pszPrev == '/', ("szTmpPath={%s}, pszPrev=+%u\n", szTmpPath, pszPrev - szTmpPath)); 274 memmove(pszPrev, pszCur + 2, strlen(pszCur + 2) + 1); 288 275 289 276 pszCur = pszPrev; … … 291 278 else 292 279 { 280 /* advance to end of component. */ 293 281 while (*pszCur && *pszCur != '/') 294 ++pszCur;282 pszCur++; 295 283 } 296 284 … … 305 293 { 306 294 /* 307 * We overwrote the trailing slash of the root path with zero, restore 308 * it. 295 * We overwrote the root slash with '\0', restore it. 309 296 */ 310 297 *pszCur++ = '/'; 311 298 *pszCur = '\0'; 312 299 } 313 else if (pszCur > pszTop && *(pszCur - 1)== '/')300 else if (pszCur > pszTop && pszCur[-1] == '/') 314 301 { 315 302 /* 316 303 * Extra trailing slash in a non-root path, remove it. 304 * (A bit questionable...) 317 305 */ 318 306 *--pszCur = '\0'; 319 307 } 320 308 321 int rc = VINF_SUCCESS; 322 323 size_t cch = pszCur - szTmpPath + 1; 324 if (cch <= cchAbsPath) 325 memcpy(pszAbsPath, szTmpPath, cch); 309 /* 310 * Copy the result to the user buffer. 311 */ 312 cchTmpPath = pszCur - szTmpPath; 313 if (cchTmpPath < cchAbsPath) 314 { 315 memcpy(pszAbsPath, szTmpPath, cchTmpPath + 1); 316 rc = VINF_SUCCESS; 317 } 326 318 else 327 319 rc = VERR_BUFFER_OVERFLOW; 328 320 329 LogFlow(("RTPathAbs(%p:{%s}, %p:{%s}, %d): returns %Rrc\n", pszPath, 330 pszPath, pszAbsPath, RT_SUCCESS(rc) ? pszAbsPath : "<failed>", 331 cchAbsPath, rc)); 321 LogFlow(("RTPathAbs(%p:{%s}, %p:{%s}, %d): returns %Rrc\n", pszPath, pszPath, pszAbsPath, 322 RT_SUCCESS(rc) ? pszAbsPath : "<failed>", cchAbsPath, rc)); 332 323 return rc; 333 324 }
Note:
See TracChangeset
for help on using the changeset viewer.