/*++ Function: _open_osfhandle See MSDN doc. --*/ int __cdecl _open_osfhandle( INT_PTR osfhandle, int flags ) { PAL_ERROR palError = NO_ERROR; CPalThread *pthrCurrent = NULL; IPalObject *pobjFile = NULL; CFileProcessLocalData *pLocalData = NULL; IDataLock *pDataLock = NULL; INT nRetVal = -1; INT openFlags = 0; PERF_ENTRY(_open_osfhandle); ENTRY( "_open_osfhandle (osfhandle=%#x, flags=%#x)\n", osfhandle, flags ); pthrCurrent = InternalGetCurrentThread(); if (flags != _O_RDONLY) { ASSERT("flag(%#x) not supported\n", flags); goto EXIT; } openFlags |= O_RDONLY; palError = g_pObjectManager->ReferenceObjectByHandle( pthrCurrent, reinterpret_cast<HANDLE>(osfhandle), &aotFile, 0, &pobjFile ); if (NO_ERROR != palError) { ERROR("Error dereferencing file handle\n"); goto EXIT; } palError = pobjFile->GetProcessLocalData( pthrCurrent, ReadLock, &pDataLock, reinterpret_cast<void **>(&pLocalData) ); if (NO_ERROR == palError) { if ('\0' != pLocalData->unix_filename[0]) { nRetVal = InternalOpen(pthrCurrent, pLocalData->unix_filename, openFlags); } else /* the only file object with no unix_filename is a pipe */ { /* check if the file pipe descrptor is for read or write */ if (pLocalData->open_flags == O_WRONLY) { ERROR( "Couldn't open a write pipe on read mode\n"); goto EXIT; } nRetVal = pLocalData->unix_fd; } if ( nRetVal == -1 ) { ERROR( "Error: %s.\n", strerror( errno ) ); } } else { ASSERT("Unable to access file data"); } EXIT: if (NULL != pDataLock) { pDataLock->ReleaseLock(pthrCurrent, FALSE); } if (NULL != pobjFile) { pobjFile->ReleaseReference(pthrCurrent); } LOGEXIT( "_open_osfhandle return nRetVal:%d\n", nRetVal); PERF_EXIT(_open_osfhandle); return nRetVal; }
PAL_ERROR CorUnix::InternalGetFileTime( CPalThread *pThread, IN HANDLE hFile, OUT LPFILETIME lpCreationTime, OUT LPFILETIME lpLastAccessTime, OUT LPFILETIME lpLastWriteTime) { PAL_ERROR palError = NO_ERROR; IPalObject *pFileObject = NULL; CFileProcessLocalData *pLocalData = NULL; IDataLock *pLocalDataLock = NULL; int Fd = -1; struct stat StatData; if (INVALID_HANDLE_VALUE == hFile) { ERROR( "Invalid file handle\n" ); palError = ERROR_INVALID_HANDLE; goto InternalGetFileTimeExit; } palError = g_pObjectManager->ReferenceObjectByHandle( pThread, hFile, &aotFile, GENERIC_READ, &pFileObject ); if (NO_ERROR != palError) { goto InternalGetFileTimeExit; } palError = pFileObject->GetProcessLocalData( pThread, ReadLock, &pLocalDataLock, reinterpret_cast<void**>(&pLocalData) ); if (NO_ERROR != palError) { goto InternalGetFileTimeExit; } Fd = pLocalData->unix_fd; if ( Fd == -1 ) { TRACE("pLocalData = [%p], Fd = %d\n", pLocalData, Fd); palError = ERROR_INVALID_HANDLE; goto InternalGetFileTimeExit; } if ( fstat(Fd, &StatData) != 0 ) { TRACE("fstat failed on file descriptor %d\n", Fd); palError = FILEGetLastErrorFromErrno(); goto InternalGetFileTimeExit; } if ( lpCreationTime ) { *lpCreationTime = FILEUnixTimeToFileTime(StatData.st_ctime, ST_CTIME_NSEC(&StatData)); } if ( lpLastWriteTime ) { *lpLastWriteTime = FILEUnixTimeToFileTime(StatData.st_mtime, ST_MTIME_NSEC(&StatData)); } if ( lpLastAccessTime ) { *lpLastAccessTime = FILEUnixTimeToFileTime(StatData.st_atime, ST_ATIME_NSEC(&StatData)); /* if Unix mtime is greater than atime, return mtime as the last access time */ if ( lpLastWriteTime && CompareFileTime(lpLastAccessTime, lpLastWriteTime) < 0 ) { *lpLastAccessTime = *lpLastWriteTime; } } InternalGetFileTimeExit: if (NULL != pLocalDataLock) { pLocalDataLock->ReleaseLock(pThread, FALSE); } if (NULL != pFileObject) { pFileObject->ReleaseReference(pThread); } return palError; }
/*++ Function: DBGSetProcessAttached Abstract saves the current process Id in the attached process structure Parameter hProcess : process handle bAttach : true (false) to set the process as attached (as detached) Return returns the number of attachment left on attachedProcId, or -1 if it fails --*/ static int DBGSetProcessAttached( CPalThread *pThread, HANDLE hProcess, BOOL bAttach ) { PAL_ERROR palError = NO_ERROR; IPalObject *pobjProcess = NULL; IDataLock *pDataLock = NULL; CProcProcessLocalData *pLocalData = NULL; int ret = -1; CAllowedObjectTypes aotProcess(otiProcess); palError = g_pObjectManager->ReferenceObjectByHandle( pThread, hProcess, &aotProcess, 0, &pobjProcess ); if (NO_ERROR != palError) { goto DBGSetProcessAttachedExit; } palError = pobjProcess->GetProcessLocalData( pThread, WriteLock, &pDataLock, reinterpret_cast<void **>(&pLocalData) ); if (NO_ERROR != palError) { goto DBGSetProcessAttachedExit; } if (bAttach) { pLocalData->lAttachCount += 1; } else { pLocalData->lAttachCount -= 1; if (pLocalData->lAttachCount < 0) { ASSERT("pLocalData->lAttachCount < 0 check for extra DBGDetachProcess calls\n"); palError = ERROR_INTERNAL_ERROR; goto DBGSetProcessAttachedExit; } } ret = pLocalData->lAttachCount; DBGSetProcessAttachedExit: if (NULL != pDataLock) { pDataLock->ReleaseLock(pThread, TRUE); } if (NULL != pobjProcess) { pobjProcess->ReleaseReference(pThread); } return ret; }
PAL_ERROR CorUnix::InternalSetFileTime( CPalThread *pThread, IN HANDLE hFile, IN CONST FILETIME *lpCreationTime, IN CONST FILETIME *lpLastAccessTime, IN CONST FILETIME *lpLastWriteTime) { PAL_ERROR palError = NO_ERROR; IPalObject *pFileObject = NULL; CFileProcessLocalData *pLocalData = NULL; IDataLock *pLocalDataLock = NULL; struct timeval Times[2]; int fd; long nsec; struct stat stat_buf; if (INVALID_HANDLE_VALUE == hFile) { ERROR( "Invalid file handle\n" ); palError = ERROR_INVALID_HANDLE; goto InternalSetFileTimeExit; } palError = g_pObjectManager->ReferenceObjectByHandle( pThread, hFile, &aotFile, GENERIC_READ, &pFileObject ); if (NO_ERROR != palError) { goto InternalSetFileTimeExit; } palError = pFileObject->GetProcessLocalData( pThread, ReadLock, &pLocalDataLock, reinterpret_cast<void**>(&pLocalData) ); if (NO_ERROR != palError) { goto InternalSetFileTimeExit; } if (lpCreationTime) { palError = ERROR_NOT_SUPPORTED; goto InternalSetFileTimeExit; } if( !lpLastAccessTime && !lpLastWriteTime ) { // if both pointers are NULL, the function simply returns. goto InternalSetFileTimeExit; } else if( !lpLastAccessTime || !lpLastWriteTime ) { // if either pointer is NULL, fstat will need to be called. fd = pLocalData->unix_fd; if ( fd == -1 ) { TRACE("pLocalData = [%p], fd = %d\n", pLocalData, fd); palError = ERROR_INVALID_HANDLE; goto InternalSetFileTimeExit; } if ( fstat(fd, &stat_buf) != 0 ) { TRACE("fstat failed on file descriptor %d\n", fd); palError = FILEGetLastErrorFromErrno(); goto InternalSetFileTimeExit; } } if (lpLastAccessTime) { Times[0].tv_sec = FILEFileTimeToUnixTime( *lpLastAccessTime, &nsec ); Times[0].tv_usec = nsec / 1000; /* convert to microseconds */ } else { Times[0].tv_sec = stat_buf.st_atime; Times[0].tv_usec = ST_ATIME_NSEC(&stat_buf) / 1000; } if (lpLastWriteTime) { Times[1].tv_sec = FILEFileTimeToUnixTime( *lpLastWriteTime, &nsec ); Times[1].tv_usec = nsec / 1000; /* convert to microseconds */ } else { Times[1].tv_sec = stat_buf.st_mtime; Times[1].tv_usec = ST_MTIME_NSEC(&stat_buf) / 1000; } TRACE("Setting atime = [%ld.%ld], mtime = [%ld.%ld]\n", Times[0].tv_sec, Times[0].tv_usec, Times[1].tv_sec, Times[1].tv_usec); #if HAVE_FUTIMES if ( futimes(pLocalData->unix_fd, Times) != 0 ) #elif HAVE_UTIMES if ( utimes(pLocalData->unix_filename, Times) != 0 ) #else #error Operating system not supported #endif { palError = FILEGetLastErrorFromErrno(); } InternalSetFileTimeExit: if (NULL != pLocalDataLock) { pLocalDataLock->ReleaseLock(pThread, FALSE); } if (NULL != pFileObject) { pFileObject->ReleaseReference(pThread); } return palError; }