Changeset 1387 in vbox for trunk/src/VBox/Runtime/r3/posix
- Timestamp:
- Mar 9, 2007 8:15:26 PM (18 years ago)
- Location:
- trunk/src/VBox/Runtime/r3/posix
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/fileio-posix.cpp
r1 r1387 380 380 381 381 382 RTR3DECL(int) RTFileLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t cbLock)383 {384 Assert(offLock >= 0);385 386 /* Check arguments. */387 if (fLock & ~RTFILE_LOCK_MASK)388 {389 AssertMsgFailed(("Invalid fLock=%08X\n", fLock));390 return VERR_INVALID_PARAMETER;391 }392 393 /*394 * Validate offset.395 */396 if ( sizeof(off_t) < sizeof(cbLock)397 && ( (offLock >> 32) != 0398 || (cbLock >> 32) != 0399 || ((offLock + cbLock) >> 32) != 0))400 {401 AssertMsgFailed(("64-bit file i/o not supported! offLock=%lld cbLock=%lld\n", offLock, cbLock));402 return VERR_NOT_SUPPORTED;403 }404 405 /* Prepare flock structure. */406 struct flock fl;407 Assert(RTFILE_LOCK_WRITE);408 fl.l_type = (fLock & RTFILE_LOCK_WRITE) ? F_WRLCK : F_RDLCK;409 fl.l_whence = SEEK_SET;410 fl.l_start = (off_t)offLock;411 fl.l_len = (off_t)cbLock;412 fl.l_pid = 0;413 414 Assert(RTFILE_LOCK_WAIT);415 if (fcntl(File, (fLock & RTFILE_LOCK_WAIT) ? F_SETLKW : F_SETLK, &fl) >= 0)416 return VINF_SUCCESS;417 418 int iErr = errno;419 if ( iErr == EAGAIN420 || iErr == EACCES)421 return VERR_FILE_LOCK_VIOLATION;422 423 return RTErrConvertFromErrno(iErr);424 }425 426 427 RTR3DECL(int) RTFileChangeLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t cbLock)428 {429 /* @todo We never returns VERR_FILE_NOT_LOCKED for now. */430 return RTFileLock(File, fLock, offLock, cbLock);431 }432 433 434 RTR3DECL(int) RTFileUnlock(RTFILE File, int64_t offLock, uint64_t cbLock)435 {436 Assert(offLock >= 0);437 438 /*439 * Validate offset.440 */441 if ( sizeof(off_t) < sizeof(cbLock)442 && ( (offLock >> 32) != 0443 || (cbLock >> 32) != 0444 || ((offLock + cbLock) >> 32) != 0))445 {446 AssertMsgFailed(("64-bit file i/o not supported! offLock=%lld cbLock=%lld\n", offLock, cbLock));447 return VERR_NOT_SUPPORTED;448 }449 450 /* Prepare flock structure. */451 struct flock fl;452 fl.l_type = F_UNLCK;453 fl.l_whence = SEEK_SET;454 fl.l_start = (off_t)offLock;455 fl.l_len = (off_t)cbLock;456 fl.l_pid = 0;457 458 if (fcntl(File, F_SETLK, &fl) >= 0)459 return VINF_SUCCESS;460 461 /* @todo check error codes for non existing lock. */462 int iErr = errno;463 if ( iErr == EAGAIN464 || iErr == EACCES)465 return VERR_FILE_LOCK_VIOLATION;466 467 return RTErrConvertFromErrno(iErr);468 }469 470 471 382 RTR3DECL(int) RTFileIoCtl(RTFILE File, int iRequest, void *pvData, unsigned cbData, int *piRet) 472 383 { -
trunk/src/VBox/Runtime/r3/posix/filelock-posix.cpp
r1350 r1387 1 1 /* $Id$ */ 2 2 /** @file 3 * InnoTek Portable Runtime - File I/O, POSIX.3 * InnoTek Portable Runtime - File Locking, POSIX. 4 4 */ 5 5 … … 27 27 28 28 #include <errno.h> 29 #include <sys/stat.h>30 29 #include <sys/types.h> 31 30 #include <sys/ioctl.h> 32 #include <sys/fcntl.h >31 #include <sys/fcntl.hs> 33 32 #include <fcntl.h> 34 #ifdef _MSC_VER 35 # include <io.h> 36 # include <stdio.h> 37 #else 38 # include <unistd.h> 39 # include <sys/time.h> 40 #endif 41 #if defined(__OS2__) && (!defined(__INNOTEK_LIBC__) || __INNOTEK_LIBC__ < 0x006) 42 # include <io.h> 43 #endif 44 #ifdef __L4__ 45 /* This is currently ifdef'ed out in the relevant L4 header file */ 46 /* Same as `utimes', but takes an open file descriptor instead of a name. */ 47 extern int futimes (int __fd, __const struct timeval __tvp[2]) __THROW; 48 #endif 33 #include <unistd.h> 34 #include <sys/time.h> 49 35 50 36 #include <iprt/file.h> 51 #include <iprt/path.h>52 37 #include <iprt/assert.h> 53 38 #include <iprt/string.h> … … 56 41 #include "internal/file.h" 57 42 #include "internal/fs.h" 58 #include "internal/path.h"59 43 60 44 61 62 /*******************************************************************************63 * Defined Constants And Macros *64 *******************************************************************************/65 /** @def RT_DONT_CONVERT_FILENAMES66 * Define this to pass UTF-8 unconverted to the kernel. */67 #ifdef __DOXYGEN__68 #define RT_DONT_CONVERT_FILENAMES 169 #endif70 71 /** Default file permissions for newly created files. */72 #if defined(S_IRUSR) && defined(S_IWUSR)73 # define RT_FILE_PERMISSION (S_IRUSR | S_IWUSR)74 #else75 # define RT_FILE_PERMISSION (00600)76 #endif77 78 79 RTR3DECL(int) RTFileOpen(PRTFILE pFile, const char *pszFilename, unsigned fOpen)80 {81 /*82 * Validate input.83 */84 if (!VALID_PTR(pFile))85 {86 AssertMsgFailed(("Invalid pFile %p\n", pFile));87 return VERR_INVALID_PARAMETER;88 }89 *pFile = NIL_RTFILE;90 if (!VALID_PTR(pszFilename))91 {92 AssertMsgFailed(("Invalid pszFilename %p\n", pszFilename));93 return VERR_INVALID_PARAMETER;94 }95 96 /*97 * Merge forced open flags and validate them.98 */99 int rc = rtFileRecalcAndValidateFlags(&fOpen);100 if (RT_FAILURE(rc))101 return rc;102 #ifndef O_NONBLOCK103 if (fOpen & RTFILE_O_NON_BLOCK)104 {105 AssertMsgFailed(("Invalid parameters! fOpen=%#x\n", fOpen));106 return VERR_INVALID_PARAMETER;107 }108 #endif109 110 /*111 * Calculate open mode flags.112 */113 int fOpenMode = 0;114 #ifdef O_BINARY115 fOpenMode |= O_BINARY; /* (pc) */116 #endif117 #ifdef O_LARGEFILE118 fOpenMode |= O_LARGEFILE; /* (linux) */119 #endif120 #ifdef O_NOINHERIT121 if (!(fOpen & RTFILE_O_INHERIT))122 fOpenMode |= O_NOINHERIT;123 #endif124 #ifndef O_NONBLOCK125 if (fOpen & RTFILE_O_NON_BLOCK)126 fOpenMode |= O_NONBLOCK127 #endif128 #ifdef O_SYNC129 if (fOpen & RTFILE_O_WRITE_THROUGH)130 fOpenMode |= O_SYNC;131 #endif132 133 /* create/truncate file */134 switch (fOpen & RTFILE_O_ACTION_MASK)135 {136 case RTFILE_O_OPEN: break;137 case RTFILE_O_OPEN_CREATE: fOpenMode |= O_CREAT; break;138 case RTFILE_O_CREATE: fOpenMode |= O_CREAT | O_EXCL; break;139 case RTFILE_O_CREATE_REPLACE: fOpenMode |= O_CREAT | O_TRUNC; break; /** @todo replacing needs fixing, this is *not* a 1:1 mapping! */140 }141 if (fOpen & RTFILE_O_TRUNCATE)142 fOpenMode |= O_TRUNC;143 144 switch (fOpen & RTFILE_O_ACCESS_MASK)145 {146 case RTFILE_O_READ: fOpenMode |= O_RDONLY; break;147 case RTFILE_O_WRITE: fOpenMode |= O_WRONLY; break;148 case RTFILE_O_READWRITE: fOpenMode |= O_RDWR; break;149 default:150 AssertMsgFailed(("RTFileOpen received an invalid RW value, fOpen=%#x\n", fOpen));151 return VERR_INVALID_PARAMETER;152 }153 154 /** @todo sharing! */155 156 /*157 * Open/create the file.158 */159 #ifdef RT_DONT_CONVERT_FILENAMES160 int fh = open(pszFilename, fOpenMode, RT_FILE_PERMISSION);161 int iErr = errno;162 #else163 char *pszNativeFilename;164 rc = rtPathToNative(&pszNativeFilename, pszFilename);165 if (RT_FAILURE(rc))166 return (rc);167 168 int fh = open(pszNativeFilename, fOpenMode, RT_FILE_PERMISSION);169 int iErr = errno;170 rtPathFreeNative(pszNativeFilename);171 #endif172 if (fh >= 0)173 {174 /*175 * Mark the file handle close on exec, unless inherit is specified.176 */177 if ( !(fOpen & RTFILE_O_INHERIT)178 #ifdef O_NOINHERIT179 || (fOpenMode & O_NOINHERIT) /* careful since it could be a dummy. */180 #endif181 || fcntl(fh, F_SETFD, FD_CLOEXEC) >= 0)182 {183 *pFile = (RTFILE)fh;184 Assert((int)*pFile == fh);185 LogFlow(("RTFileOpen(%p:{%RTfile}, %p:{%s}, %#x): returns %Rrc\n",186 pFile, *pFile, pszFilename, pszFilename, fOpen, rc));187 return VINF_SUCCESS;188 }189 iErr = errno;190 close(fh);191 }192 return RTErrConvertFromErrno(iErr);193 }194 195 196 RTR3DECL(int) RTFileClose(RTFILE File)197 {198 if (close((int)File) == 0)199 return VINF_SUCCESS;200 return RTErrConvertFromErrno(errno);201 }202 203 204 RTR3DECL(int) RTFileDelete(const char *pszFilename)205 {206 char *pszNativeFilename;207 int rc = rtPathToNative(&pszNativeFilename, pszFilename);208 if (RT_SUCCESS(rc))209 {210 if (unlink(pszNativeFilename) != 0)211 rc = RTErrConvertFromErrno(errno);212 rtPathFreeNative(pszNativeFilename);213 }214 return rc;215 }216 217 218 RTR3DECL(int) RTFileSeek(RTFILE File, int64_t offSeek, unsigned uMethod, uint64_t *poffActual)219 {220 static const unsigned aSeekRecode[] =221 {222 SEEK_SET,223 SEEK_CUR,224 SEEK_END,225 };226 227 /*228 * Validate input.229 */230 if (uMethod > RTFILE_SEEK_END)231 {232 AssertMsgFailed(("Invalid uMethod=%d\n", uMethod));233 return VERR_INVALID_PARAMETER;234 }235 236 /* check that within off_t range. */237 if ( sizeof(off_t) < sizeof(offSeek)238 && ( (offSeek > 0 && (unsigned)(offSeek >> 32) != 0)239 || (offSeek < 0 && (unsigned)(-offSeek >> 32) != 0)))240 {241 AssertMsgFailed(("64-bit search not supported\n"));242 return VERR_NOT_SUPPORTED;243 }244 245 off_t offCurrent = lseek((int)File, (off_t)offSeek, aSeekRecode[uMethod]);246 if (offCurrent != ~0)247 {248 if (poffActual)249 *poffActual = (uint64_t)offCurrent;250 return VINF_SUCCESS;251 }252 return RTErrConvertFromErrno(errno);253 }254 255 256 RTR3DECL(int) RTFileRead(RTFILE File, void *pvBuf, unsigned cbToRead, unsigned *pcbRead)257 {258 if (cbToRead <= 0)259 return VINF_SUCCESS;260 261 /*262 * Attempt read.263 */264 ssize_t cbRead = read((int)File, pvBuf, cbToRead);265 if (cbRead >= 0)266 {267 if (pcbRead)268 /* caller can handle partial read. */269 *pcbRead = cbRead;270 else271 {272 /* Caller expects all to be read. */273 while ((ssize_t)cbToRead > cbRead)274 {275 ssize_t cbReadPart = read((int)File, (char*)pvBuf + cbRead, cbToRead - cbRead);276 if (cbReadPart <= 0)277 {278 if (cbReadPart == 0)279 return VERR_EOF;280 else281 return RTErrConvertFromErrno(errno);282 }283 cbRead += cbReadPart;284 }285 }286 return VINF_SUCCESS;287 }288 289 return RTErrConvertFromErrno(errno);290 }291 292 293 RTR3DECL(int) RTFileWrite(RTFILE File, const void *pvBuf, unsigned cbToWrite, unsigned *pcbWritten)294 {295 if (cbToWrite <= 0)296 return VINF_SUCCESS;297 298 /*299 * Attempt write.300 */301 ssize_t cbWritten = write((int)File, pvBuf, cbToWrite);302 if (cbWritten >= 0)303 {304 if (pcbWritten)305 /* caller can handle partial write. */306 *pcbWritten = cbWritten;307 else308 {309 /* Caller expects all to be write. */310 while ((ssize_t)cbToWrite > cbWritten)311 {312 ssize_t cbWrittenPart = write((int)File, (const char *)pvBuf + cbWritten, cbToWrite - cbWritten);313 if (cbWrittenPart <= 0)314 return RTErrConvertFromErrno(errno);315 cbWritten += cbWrittenPart;316 }317 }318 return VINF_SUCCESS;319 }320 return RTErrConvertFromErrno(errno);321 }322 323 324 RTR3DECL(int) RTFileSetSize(RTFILE File, uint64_t cbSize)325 {326 /*327 * Validate offset.328 */329 if ( sizeof(off_t) < sizeof(cbSize)330 && (cbSize >> 32) != 0)331 {332 AssertMsgFailed(("64-bit filesize not supported! cbSize=%lld\n", cbSize));333 return VERR_NOT_SUPPORTED;334 }335 336 #if defined(_MSC_VER) || (defined(__OS2__) && (!defined(__INNOTEK_LIBC__) || __INNOTEK_LIBC__ < 0x006))337 if (chsize((int)File, (off_t)cbSize) == 0)338 #else339 /* This relies on a non-standard feature of FreeBSD, Linux, and OS/2340 * LIBC v0.6 and higher. (SuS doesn't define ftruncate() and size bigger341 * than the file.)342 */343 if (ftruncate((int)File, (off_t)cbSize) == 0)344 #endif345 return VINF_SUCCESS;346 return RTErrConvertFromErrno(errno);347 }348 349 350 RTR3DECL(int) RTFileGetSize(RTFILE File, uint64_t *pcbSize)351 {352 struct stat st;353 if (!fstat((int)File, &st))354 {355 *pcbSize = st.st_size;356 return VINF_SUCCESS;357 }358 return RTErrConvertFromErrno(errno);359 }360 361 362 RTR3DECL(bool) RTFileIsValid(RTFILE File)363 {364 if (File != NIL_RTFILE)365 {366 int fFlags = fcntl(File, F_GETFD);367 if (fFlags >= 0)368 return true;369 }370 return false;371 }372 373 374 RTR3DECL(int) RTFileFlush(RTFILE File)375 {376 if (fsync((int)File))377 return RTErrConvertFromErrno(errno);378 return VINF_SUCCESS;379 }380 45 381 46 … … 427 92 RTR3DECL(int) RTFileChangeLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t cbLock) 428 93 { 429 /* @todo We never returns VERR_FILE_NOT_LOCKED for now. */94 /** @todo We never returns VERR_FILE_NOT_LOCKED for now. */ 430 95 return RTFileLock(File, fLock, offLock, cbLock); 431 96 } … … 469 134 470 135 471 RTR3DECL(int) RTFileIoCtl(RTFILE File, int iRequest, void *pvData, unsigned cbData, int *piRet)472 {473 int rc = ioctl((int)File, iRequest, pvData);474 if (piRet)475 *piRet = rc;476 return rc >= 0 ? VINF_SUCCESS : RTErrConvertFromErrno(errno);477 }478 479 480 RTR3DECL(int) RTFileQueryInfo(RTFILE File, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs)481 {482 /*483 * Validate input.484 */485 if (File == NIL_RTFILE)486 {487 AssertMsgFailed(("Invalid File=%RTfile\n", File));488 return VERR_INVALID_PARAMETER;489 }490 if (!pObjInfo)491 {492 AssertMsgFailed(("Invalid pObjInfo=%p\n", pObjInfo));493 return VERR_INVALID_PARAMETER;494 }495 if ( enmAdditionalAttribs < RTFSOBJATTRADD_NOTHING496 || enmAdditionalAttribs > RTFSOBJATTRADD_LAST)497 {498 AssertMsgFailed(("Invalid enmAdditionalAttribs=%p\n", enmAdditionalAttribs));499 return VERR_INVALID_PARAMETER;500 }501 502 /*503 * Query file info.504 */505 struct stat Stat;506 if (fstat((int)File, &Stat))507 {508 int rc = RTErrConvertFromErrno(errno);509 Log(("RTFileQueryInfo(%RTfile,,%d): returns %Rrc\n", File, enmAdditionalAttribs, rc));510 return rc;511 }512 513 /*514 * Setup the returned data.515 */516 rtFsConvertStatToObjInfo(pObjInfo, &Stat);517 518 /*519 * Requested attributes (we cannot provide anything actually).520 */521 switch (enmAdditionalAttribs)522 {523 case RTFSOBJATTRADD_EASIZE:524 pObjInfo->Attr.enmAdditional = RTFSOBJATTRADD_EASIZE;525 pObjInfo->Attr.u.EASize.cb = 0;526 break;527 528 case RTFSOBJATTRADD_NOTHING:529 case RTFSOBJATTRADD_UNIX:530 /* done */531 break;532 533 default:534 AssertMsgFailed(("Impossible!\n"));535 return VERR_INTERNAL_ERROR;536 }537 538 LogFlow(("RTFileQueryInfo(%RTfile,,%d): returns VINF_SUCCESS\n", File, enmAdditionalAttribs));539 return VINF_SUCCESS;540 }541 542 543 RTR3DECL(int) RTFileSetTimes(RTFILE File, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,544 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime)545 {546 /*547 * We can only set AccessTime and ModificationTime, so if neither548 * are specified we can return immediately.549 */550 if (!pAccessTime && !pModificationTime)551 return VINF_SUCCESS;552 553 /*554 * Convert the input to timeval, getting the missing one if necessary,555 * and call the API which does the change.556 */557 struct timeval aTimevals[2];558 if (pAccessTime && pModificationTime)559 {560 RTTimeSpecGetTimeval(pAccessTime, &aTimevals[0]);561 RTTimeSpecGetTimeval(pModificationTime, &aTimevals[1]);562 }563 else564 {565 RTFSOBJINFO ObjInfo;566 int rc = RTFileQueryInfo(File, &ObjInfo, RTFSOBJATTRADD_UNIX);567 if (RT_FAILURE(rc))568 return rc;569 RTTimeSpecGetTimeval(pAccessTime ? pAccessTime : &ObjInfo.AccessTime, &aTimevals[0]);570 RTTimeSpecGetTimeval(pModificationTime ? pModificationTime : &ObjInfo.ModificationTime, &aTimevals[1]);571 }572 573 if (futimes((int)File, aTimevals))574 {575 int rc = RTErrConvertFromErrno(errno);576 Log(("RTFileSetTimes(%RTfile,%p,%p,,): returns %Rrc\n", File, pAccessTime, pModificationTime, rc));577 return rc;578 }579 return VINF_SUCCESS;580 }581 582 583 RTR3DECL(int) RTFileSetMode(RTFILE File, RTFMODE fMode)584 {585 /*586 * Normalize the mode and call the API.587 */588 fMode = rtFsModeNormalize(fMode, NULL, 0);589 if (!rtFsModeIsValid(fMode))590 return VERR_INVALID_PARAMETER;591 592 if (fchmod((int)File, fMode & RTFS_UNIX_MASK))593 {594 int rc = RTErrConvertFromErrno(errno);595 Log(("RTFileSetMode(%RTfile,%RTfmode): returns %Rrc\n", File, fMode));596 return rc;597 }598 return VINF_SUCCESS;599 }600 601 602 RTR3DECL(int) RTFileRename(const char *pszSrc, const char *pszDst, unsigned fRename)603 {604 /*605 * Validate input.606 */607 AssertMsgReturn(VALID_PTR(pszSrc), ("%p\n", pszSrc), VERR_INVALID_POINTER);608 AssertMsgReturn(VALID_PTR(pszDst), ("%p\n", pszDst), VERR_INVALID_POINTER);609 AssertMsgReturn(*pszSrc, ("%p\n", pszSrc), VERR_INVALID_PARAMETER);610 AssertMsgReturn(*pszDst, ("%p\n", pszDst), VERR_INVALID_PARAMETER);611 AssertMsgReturn(!(fRename & ~RTPATHRENAME_FLAGS_REPLACE), ("%#x\n", fRename), VERR_INVALID_PARAMETER);612 613 /*614 * Take common cause with RTPathRename.615 */616 int rc = rtPathPosixRename(pszSrc, pszDst, fRename, RTFS_TYPE_FILE);617 618 LogFlow(("RTDirRename(%p:{%s}, %p:{%s}, %#x): returns %Rrc\n",619 pszSrc, pszSrc, pszDst, pszDst, fRename, rc));620 return rc;621 }622 623
Note:
See TracChangeset
for help on using the changeset viewer.