/* static */ int getDriveInfoFromSysfs(DriveInfoList *pList, bool isDVD, bool *pfSuccess) { AssertPtrReturn(pList, VERR_INVALID_POINTER); AssertPtrNullReturn(pfSuccess, VERR_INVALID_POINTER); /* Valid or Null */ LogFlowFunc (("pList=%p, isDVD=%u, pfSuccess=%p\n", pList, (unsigned) isDVD, pfSuccess)); RTDIR hDir; int rc; bool fSuccess = false; unsigned cFound = 0; if (!RTPathExists("/sys")) return VINF_SUCCESS; rc = RTDirOpen(&hDir, "/sys/block"); /* This might mean that sysfs semantics have changed */ AssertReturn(rc != VERR_FILE_NOT_FOUND, VINF_SUCCESS); fSuccess = true; if (RT_SUCCESS(rc)) { for (;;) { RTDIRENTRY entry; rc = RTDirRead(hDir, &entry, NULL); Assert(rc != VERR_BUFFER_OVERFLOW); /* Should never happen... */ if (RT_FAILURE(rc)) /* Including overflow and no more files */ break; if (entry.szName[0] == '.') continue; sysfsBlockDev dev(entry.szName, isDVD); /* This might mean that sysfs semantics have changed */ AssertBreakStmt(dev.isConsistent(), fSuccess = false); if (!dev.isValid()) continue; try { pList->push_back(DriveInfo(dev.getNode(), dev.getUdi(), dev.getDesc())); } catch(std::bad_alloc &e) { rc = VERR_NO_MEMORY; break; } ++cFound; } RTDirClose(hDir); } if (rc == VERR_NO_MORE_FILES) rc = VINF_SUCCESS; if (RT_FAILURE(rc)) /* Clean up again */ for (unsigned i = 0; i < cFound; ++i) pList->pop_back(); if (pfSuccess) *pfSuccess = fSuccess; LogFlow (("rc=%Rrc, fSuccess=%u\n", rc, (unsigned) fSuccess)); return rc; }
static int tstDirOpenFiltered(const char *pszFilter, unsigned *pcFilesMatch, int *pRc) { int rcRet = 0; unsigned cFilesMatch = 0; PRTDIR pDir; int rc = RTDirOpenFiltered(&pDir, pszFilter, RTDIRFILTER_WINNT, 0); if (RT_SUCCESS(rc)) { for (;;) { RTDIRENTRY DirEntry; rc = RTDirRead(pDir, &DirEntry, NULL); if (RT_FAILURE(rc)) break; cFilesMatch++; } if (rc != VERR_NO_MORE_FILES) { RTPrintf("tstDir-3: Enumeration '%s' failed! rc=%Rrc\n", pszFilter, rc); rcRet = 1; } /* close up */ rc = RTDirClose(pDir); if (RT_FAILURE(rc)) { RTPrintf("tstDir-3: Failed to close dir '%s'! rc=%Rrc\n", pszFilter, rc); rcRet = 1; } } else { RTPrintf("tstDir-3: Failed to open '%s', rc=%Rrc\n", pszFilter, rc); rcRet = 1; } *pcFilesMatch = cFilesMatch; *pRc = rc; return rcRet; }
int main(int argc, char **argv) { int rcRet = 0; RTR3InitExe(argc, &argv, 0); /* * Iterate arguments. */ bool fLong = false; bool fShortName = false; for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { for (int j = 1; argv[i][j]; j++) { switch (argv[i][j]) { case 'l': fLong = true; break; case 's': fShortName = true; break; default: RTPrintf("Unknown option '%c' ignored!\n", argv[i][j]); break; } } } else { /* open */ PRTDIR pDir; int rc = RTDirOpen(&pDir, argv[i]); if (RT_SUCCESS(rc)) { /* list */ if (!fLong) { for (;;) { RTDIRENTRY DirEntry; rc = RTDirRead(pDir, &DirEntry, NULL); if (RT_FAILURE(rc)) break; switch (DirEntry.enmType) { case RTDIRENTRYTYPE_UNKNOWN: RTPrintf("u"); break; case RTDIRENTRYTYPE_FIFO: RTPrintf("f"); break; case RTDIRENTRYTYPE_DEV_CHAR: RTPrintf("c"); break; case RTDIRENTRYTYPE_DIRECTORY: RTPrintf("d"); break; case RTDIRENTRYTYPE_DEV_BLOCK: RTPrintf("b"); break; case RTDIRENTRYTYPE_FILE: RTPrintf("-"); break; case RTDIRENTRYTYPE_SYMLINK: RTPrintf("l"); break; case RTDIRENTRYTYPE_SOCKET: RTPrintf("s"); break; case RTDIRENTRYTYPE_WHITEOUT: RTPrintf("w"); break; default: rcRet = 1; RTPrintf("?"); break; } RTPrintf(" %#18llx %3d %s\n", (uint64_t)DirEntry.INodeId, DirEntry.cbName, DirEntry.szName); } } else { for (;;) { RTDIRENTRYEX DirEntry; rc = RTDirReadEx(pDir, &DirEntry, NULL, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK); if (RT_FAILURE(rc)) break; RTFMODE fMode = DirEntry.Info.Attr.fMode; switch (fMode & RTFS_TYPE_MASK) { case RTFS_TYPE_FIFO: RTPrintf("f"); break; case RTFS_TYPE_DEV_CHAR: RTPrintf("c"); break; case RTFS_TYPE_DIRECTORY: RTPrintf("d"); break; case RTFS_TYPE_DEV_BLOCK: RTPrintf("b"); break; case RTFS_TYPE_FILE: RTPrintf("-"); break; case RTFS_TYPE_SYMLINK: RTPrintf("l"); break; case RTFS_TYPE_SOCKET: RTPrintf("s"); break; case RTFS_TYPE_WHITEOUT: RTPrintf("w"); break; default: rcRet = 1; RTPrintf("?"); break; } /** @todo sticy bits++ */ RTPrintf("%c%c%c", fMode & RTFS_UNIX_IRUSR ? 'r' : '-', fMode & RTFS_UNIX_IWUSR ? 'w' : '-', fMode & RTFS_UNIX_IXUSR ? 'x' : '-'); RTPrintf("%c%c%c", fMode & RTFS_UNIX_IRGRP ? 'r' : '-', fMode & RTFS_UNIX_IWGRP ? 'w' : '-', fMode & RTFS_UNIX_IXGRP ? 'x' : '-'); RTPrintf("%c%c%c", fMode & RTFS_UNIX_IROTH ? 'r' : '-', fMode & RTFS_UNIX_IWOTH ? 'w' : '-', fMode & RTFS_UNIX_IXOTH ? 'x' : '-'); RTPrintf(" %c%c%c%c%c%c%c%c%c%c%c%c%c%c", fMode & RTFS_DOS_READONLY ? 'R' : '-', fMode & RTFS_DOS_HIDDEN ? 'H' : '-', fMode & RTFS_DOS_SYSTEM ? 'S' : '-', fMode & RTFS_DOS_DIRECTORY ? 'D' : '-', fMode & RTFS_DOS_ARCHIVED ? 'A' : '-', fMode & RTFS_DOS_NT_DEVICE ? 'd' : '-', fMode & RTFS_DOS_NT_NORMAL ? 'N' : '-', fMode & RTFS_DOS_NT_TEMPORARY ? 'T' : '-', fMode & RTFS_DOS_NT_SPARSE_FILE ? 'P' : '-', fMode & RTFS_DOS_NT_REPARSE_POINT ? 'J' : '-', fMode & RTFS_DOS_NT_COMPRESSED ? 'C' : '-', fMode & RTFS_DOS_NT_OFFLINE ? 'O' : '-', fMode & RTFS_DOS_NT_NOT_CONTENT_INDEXED ? 'I' : '-', fMode & RTFS_DOS_NT_ENCRYPTED ? 'E' : '-'); RTPrintf(" %d %4d %4d %10lld %10lld %#llx %#llx %#llx %#llx", DirEntry.Info.Attr.u.Unix.cHardlinks, DirEntry.Info.Attr.u.Unix.uid, DirEntry.Info.Attr.u.Unix.gid, DirEntry.Info.cbObject, DirEntry.Info.cbAllocated, DirEntry.Info.BirthTime, DirEntry.Info.ChangeTime, DirEntry.Info.ModificationTime, DirEntry.Info.AccessTime); if (fShortName && DirEntry.cwcShortName) RTPrintf(" %2d %ls\n", DirEntry.cwcShortName, DirEntry.wszShortName); else RTPrintf(" %2d %s\n", DirEntry.cbName, DirEntry.szName); if (rc != VINF_SUCCESS) RTPrintf("^^ %Rrc\n", rc); } } if (rc != VERR_NO_MORE_FILES) { RTPrintf("tstDir: Enumeration failed! rc=%Rrc\n", rc); rcRet = 1; } /* close up */ rc = RTDirClose(pDir); if (RT_FAILURE(rc)) { RTPrintf("tstDir: Failed to close dir! rc=%Rrc\n", rc); rcRet = 1; } } else { RTPrintf("tstDir: Failed to open '%s', rc=%Rrc\n", argv[i], rc); rcRet = 1; } } } return rcRet; }
RTR3DECL(bool) RTProcIsRunningByName(const char *pszName) { /* * Quick validation. */ if (!pszName) return false; bool const fWithPath = RTPathHavePath(pszName); /* * Enumerate /proc. */ RTDIR hDir; int rc = RTDirOpen(&hDir, "/proc"); AssertMsgRCReturn(rc, ("RTDirOpen on /proc failed: rc=%Rrc\n", rc), false); if (RT_SUCCESS(rc)) { RTDIRENTRY DirEntry; while (RT_SUCCESS(RTDirRead(hDir, &DirEntry, NULL))) { /* * Filter numeric directory entries only. */ if ( ( DirEntry.enmType == RTDIRENTRYTYPE_DIRECTORY || DirEntry.enmType == RTDIRENTRYTYPE_UNKNOWN) && RTStrToUInt32(DirEntry.szName) > 0) { /* * Try readlink on exe first since it's more faster and reliable. * Fall back on reading the first line in cmdline if that fails * (access errors typically). cmdline is unreliable as it might * contain whatever the execv caller passes as argv[0]. */ char szName[RTPATH_MAX]; RTStrPrintf(szName, sizeof(szName), "/proc/%s/exe", &DirEntry.szName[0]); char szExe[RTPATH_MAX]; int cchLink = readlink(szName, szExe, sizeof(szExe) - 1); if ( cchLink > 0 && (size_t)cchLink < sizeof(szExe)) { szExe[cchLink] = '\0'; rc = VINF_SUCCESS; } else { RTStrPrintf(szName, sizeof(szName), "/proc/%s/cmdline", &DirEntry.szName[0]); PRTSTREAM pStream; rc = RTStrmOpen(szName, "r", &pStream); if (RT_SUCCESS(rc)) { rc = RTStrmGetLine(pStream, szExe, sizeof(szExe)); RTStrmClose(pStream); } } if (RT_SUCCESS(rc)) { /* * We are interested on the file name part only. */ char const *pszProcName = fWithPath ? szExe : RTPathFilename(szExe); if (RTStrCmp(pszProcName, pszName) == 0) { /* Found it! */ RTDirClose(hDir); return true; } } } } RTDirClose(hDir); } return false; }
/** * Recursive worker function to walk the /dev tree looking for DVD or floppy * devices. * @returns true if we have already found MAX_DEVICE_NODES devices, false * otherwise * @param pszPath the path to start recursing. The function can modify * this string at and after the terminating zero * @param cchPath the size of the buffer (not the string!) in @a pszPath * @param aDevices where to fill in information about devices that we have * found * @param wantDVD are we looking for DVD devices (or floppies)? */ static bool devFindDeviceRecursive(char *pszPath, size_t cchPath, deviceNodeArray aDevices, bool wantDVD) { /* * Check assumptions made by the code below. */ size_t const cchBasePath = strlen(pszPath); AssertReturn(cchBasePath < RTPATH_MAX - 10U, false); AssertReturn(pszPath[cchBasePath - 1] != '/', false); PRTDIR pDir; if (RT_FAILURE(RTDirOpen(&pDir, pszPath))) return false; for (;;) { RTDIRENTRY Entry; RTFSOBJINFO ObjInfo; int rc = RTDirRead(pDir, &Entry, NULL); if (RT_FAILURE(rc)) break; if (Entry.enmType == RTDIRENTRYTYPE_UNKNOWN) { if (RT_FAILURE(RTPathQueryInfo(pszPath, &ObjInfo, RTFSOBJATTRADD_UNIX))) continue; if (RTFS_IS_SYMLINK(ObjInfo.Attr.fMode)) continue; } if (Entry.enmType == RTDIRENTRYTYPE_SYMLINK) continue; pszPath[cchBasePath] = '\0'; if (RT_FAILURE(RTPathAppend(pszPath, cchPath, Entry.szName))) break; /* Do the matching. */ dev_t DevNode; char szDesc[256], szUdi[256]; if (!devValidateDevice(pszPath, wantDVD, &DevNode, szDesc, sizeof(szDesc), szUdi, sizeof(szUdi))) continue; unsigned i; for (i = 0; i < MAX_DEVICE_NODES; ++i) if (!aDevices[i].Device || (aDevices[i].Device == DevNode)) break; AssertBreak(i < MAX_DEVICE_NODES); if (aDevices[i].Device) continue; aDevices[i].Device = DevNode; RTStrPrintf(aDevices[i].szPath, sizeof(aDevices[i].szPath), "%s", pszPath); AssertCompile(sizeof(aDevices[i].szDesc) == sizeof(szDesc)); strcpy(aDevices[i].szDesc, szDesc); AssertCompile(sizeof(aDevices[i].szUdi) == sizeof(szUdi)); strcpy(aDevices[i].szUdi, szUdi); if (i == MAX_DEVICE_NODES - 1) break; continue; /* Recurse into subdirectories. */ if ( (Entry.enmType == RTDIRENTRYTYPE_UNKNOWN) && !RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode)) continue; if (Entry.enmType != RTDIRENTRYTYPE_DIRECTORY) continue; if (Entry.szName[0] == '.') continue; if (devFindDeviceRecursive(pszPath, cchPath, aDevices, wantDVD)) break; } RTDirClose(pDir); return aDevices[MAX_DEVICE_NODES - 1].Device ? true : false; }
int main(int argc, char **argv) { int rcRet = 0; RTR3InitExe(argc, &argv, 0); /* * Iterate arguments. */ for (int i = 1; i < argc; i++) { /* open */ PRTDIR pDir; int rc = RTDirOpenFiltered(&pDir, argv[i], RTDIRFILTER_WINNT, 0); if (RT_SUCCESS(rc)) { for (;;) { RTDIRENTRY DirEntry; rc = RTDirRead(pDir, &DirEntry, NULL); if (RT_FAILURE(rc)) break; switch (DirEntry.enmType) { case RTDIRENTRYTYPE_UNKNOWN: RTPrintf("u"); break; case RTDIRENTRYTYPE_FIFO: RTPrintf("f"); break; case RTDIRENTRYTYPE_DEV_CHAR: RTPrintf("c"); break; case RTDIRENTRYTYPE_DIRECTORY: RTPrintf("d"); break; case RTDIRENTRYTYPE_DEV_BLOCK: RTPrintf("b"); break; case RTDIRENTRYTYPE_FILE: RTPrintf("-"); break; case RTDIRENTRYTYPE_SYMLINK: RTPrintf("l"); break; case RTDIRENTRYTYPE_SOCKET: RTPrintf("s"); break; case RTDIRENTRYTYPE_WHITEOUT: RTPrintf("w"); break; default: rcRet = 1; RTPrintf("?"); break; } RTPrintf(" %#18llx %3d %s\n", (uint64_t)DirEntry.INodeId, DirEntry.cbName, DirEntry.szName); } if (rc != VERR_NO_MORE_FILES) { RTPrintf("tstDir-2: Enumeration failed! rc=%Rrc\n", rc); rcRet = 1; } /* close up */ rc = RTDirClose(pDir); if (RT_FAILURE(rc)) { RTPrintf("tstDir-2: Failed to close dir! rc=%Rrc\n", rc); rcRet = 1; } } else { RTPrintf("tstDir-2: Failed to open '%s', rc=%Rrc\n", argv[i], rc); rcRet = 1; } } return rcRet; }
/** * Handles VMMDevCpuEventType_Plug. * * @param idCpuCore The CPU core ID. * @param idCpuPackage The CPU package ID. */ static void VBoxServiceCpuHotPlugHandlePlugEvent(uint32_t idCpuCore, uint32_t idCpuPackage) { #ifdef RT_OS_LINUX /* * The topology directory (containing the physical and core id properties) * is not available until the CPU is online. So we just iterate over all directories * and enable every CPU which is not online already. * Because the directory might not be available immediately we try a few times. * * @todo: Maybe use udev to monitor hot-add events from the kernel */ bool fCpuOnline = false; unsigned cTries = 5; do { PRTDIR pDirDevices = NULL; int rc = RTDirOpen(&pDirDevices, SYSFS_CPU_PATH); if (RT_SUCCESS(rc)) { RTDIRENTRY DirFolderContent; while (RT_SUCCESS(RTDirRead(pDirDevices, &DirFolderContent, NULL))) /* Assumption that szName has always enough space */ { /** @todo r-bird: This code is bringing all CPUs online; the idCpuCore and * idCpuPackage parameters are unused! * aeichner: These files are not available at this point unfortunately. (see comment above) * bird: Yes, but isn't that easily dealt with by doing: * if (matching_topology() || !have_topology_directory()) * bring_cpu_online() * That could save you the cpu0 and cpuidle checks to. */ /* * Check if this is a CPU object. * cpu0 is excluded because it is not possible to change the state * of the first CPU on Linux (it doesn't even have an online file) * and cpuidle is no CPU device. Prevents error messages later. */ if( !strncmp(DirFolderContent.szName, "cpu", 3) && strncmp(DirFolderContent.szName, "cpu0", 4) && strncmp(DirFolderContent.szName, "cpuidle", 7)) { /* Get the sysdev */ RTFILE hFileCpuOnline = NIL_RTFILE; rc = RTFileOpenF(&hFileCpuOnline, RTFILE_O_WRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE, "%s/%s/online", SYSFS_CPU_PATH, DirFolderContent.szName); if (RT_SUCCESS(rc)) { /* Write a 1 to online the CPU */ rc = RTFileWrite(hFileCpuOnline, "1", 1, NULL); RTFileClose(hFileCpuOnline); if (RT_SUCCESS(rc)) { VBoxServiceVerbose(1, "CpuHotPlug: CPU %u/%u was brought online\n", idCpuPackage, idCpuCore); fCpuOnline = true; break; } /* Error means CPU not present or online already */ } else VBoxServiceError("CpuHotPlug: Failed to open \"%s/%s/online\" rc=%Rrc\n", SYSFS_CPU_PATH, DirFolderContent.szName, rc); } } } else VBoxServiceError("CpuHotPlug: Failed to open path %s rc=%Rrc\n", SYSFS_CPU_PATH, rc); /* Sleep a bit */ if (!fCpuOnline) RTThreadSleep(10); } while ( !fCpuOnline && cTries-- > 0); #else # error "Port me" #endif }
/** * Returns the path of the ACPI CPU device with the given core and package ID. * * @returns VBox status code. * @param ppszPath Where to store the path. * @param idCpuCore The core ID of the CPU. * @param idCpuPackage The package ID of the CPU. */ static int VBoxServiceCpuHotPlugGetACPIDevicePath(char **ppszPath, uint32_t idCpuCore, uint32_t idCpuPackage) { int rc = VINF_SUCCESS; AssertPtrReturn(ppszPath, VERR_INVALID_PARAMETER); rc = VBoxServiceCpuHotPlugProbePath(); if (RT_SUCCESS(rc)) { /* Build the path from all components. */ bool fFound = false; unsigned iLvlCurr = 0; char *pszPath = NULL; char *pszPathDir = NULL; PSYSFSCPUPATH pAcpiCpuPathLvl = &g_aAcpiCpuPath[iLvlCurr]; /* Init everything. */ Assert(pAcpiCpuPathLvl->uId != ACPI_CPU_PATH_NOT_PROBED); pszPath = RTPathJoinA(SYSFS_ACPI_CPU_PATH, pAcpiCpuPathLvl->aComponentsPossible[pAcpiCpuPathLvl->uId].pcszName); if (!pszPath) return VERR_NO_STR_MEMORY; pAcpiCpuPathLvl->pszPath = RTStrDup(SYSFS_ACPI_CPU_PATH); if (!pAcpiCpuPathLvl->pszPath) { RTStrFree(pszPath); return VERR_NO_STR_MEMORY; } /* Open the directory */ rc = RTDirOpenFiltered(&pAcpiCpuPathLvl->pDir, pszPath, RTDIRFILTER_WINNT, 0); if (RT_SUCCESS(rc)) { RTStrFree(pszPath); /* Search for CPU */ while (!fFound) { /* Get the next directory. */ RTDIRENTRY DirFolderContent; rc = RTDirRead(pAcpiCpuPathLvl->pDir, &DirFolderContent, NULL); if (RT_SUCCESS(rc)) { /* Create the new path. */ char *pszPathCurr = RTPathJoinA(pAcpiCpuPathLvl->pszPath, DirFolderContent.szName); if (!pszPathCurr) { rc = VERR_NO_STR_MEMORY; break; } /* If this is the last level check for the given core and package id. */ if (iLvlCurr == RT_ELEMENTS(g_aAcpiCpuPath) - 1) { /* Get the sysdev */ uint32_t idCore = RTLinuxSysFsReadIntFile(10, "%s/sysdev/topology/core_id", pszPathCurr); uint32_t idPackage = RTLinuxSysFsReadIntFile(10, "%s/sysdev/topology/physical_package_id", pszPathCurr); if ( idCore == idCpuCore && idPackage == idCpuPackage) { /* Return the path */ pszPath = pszPathCurr; fFound = true; VBoxServiceVerbose(3, "CPU found\n"); break; } else { /* Get the next directory. */ RTStrFree(pszPathCurr); VBoxServiceVerbose(3, "CPU doesn't match, next directory\n"); } } else { /* Go deeper */ iLvlCurr++; VBoxServiceVerbose(3, "Going deeper (iLvlCurr=%u)\n", iLvlCurr); pAcpiCpuPathLvl = &g_aAcpiCpuPath[iLvlCurr]; Assert(!pAcpiCpuPathLvl->pDir); Assert(!pAcpiCpuPathLvl->pszPath); pAcpiCpuPathLvl->pszPath = pszPathCurr; PCSYSFSCPUPATHCOMP pPathComponent = &pAcpiCpuPathLvl->aComponentsPossible[pAcpiCpuPathLvl->uId]; Assert(pAcpiCpuPathLvl->uId != ACPI_CPU_PATH_NOT_PROBED); pszPathDir = RTPathJoinA(pszPathCurr, pPathComponent->pcszName); if (!pszPathDir) { rc = VERR_NO_STR_MEMORY; break; } VBoxServiceVerbose(3, "New path %s\n", pszPathDir); /* Open the directory */ rc = RTDirOpenFiltered(&pAcpiCpuPathLvl->pDir, pszPathDir, RTDIRFILTER_WINNT, 0); if (RT_FAILURE(rc)) break; } } else { /* Go back one level and try to get the next entry. */ Assert(iLvlCurr > 0); RTDirClose(pAcpiCpuPathLvl->pDir); RTStrFree(pAcpiCpuPathLvl->pszPath); pAcpiCpuPathLvl->pDir = NULL; pAcpiCpuPathLvl->pszPath = NULL; iLvlCurr--; pAcpiCpuPathLvl = &g_aAcpiCpuPath[iLvlCurr]; VBoxServiceVerbose(3, "Directory not found, going back (iLvlCurr=%u)\n", iLvlCurr); } } /* while not found */ } /* Successful init */ /* Cleanup */ for (unsigned i = 0; i < RT_ELEMENTS(g_aAcpiCpuPath); i++) { if (g_aAcpiCpuPath[i].pDir) RTDirClose(g_aAcpiCpuPath[i].pDir); if (g_aAcpiCpuPath[i].pszPath) RTStrFree(g_aAcpiCpuPath[i].pszPath); g_aAcpiCpuPath[i].pDir = NULL; g_aAcpiCpuPath[i].pszPath = NULL; } if (pszPathDir) RTStrFree(pszPathDir); if (RT_FAILURE(rc) && pszPath) RTStrFree(pszPath); if (RT_SUCCESS(rc)) *ppszPath = pszPath; } return rc; }
/** * Probes for the correct path to the ACPI CPU object in sysfs for the * various different kernel versions and distro's. * * @returns VBox status code. */ static int VBoxServiceCpuHotPlugProbePath(void) { int rc = VINF_SUCCESS; /* Probe for the correct path if we didn't already. */ if (RT_UNLIKELY(g_aAcpiCpuPath[0].uId == ACPI_CPU_PATH_NOT_PROBED)) { char *pszPath = NULL; /** < Current path, increasing while we dig deeper. */ pszPath = RTStrDup(SYSFS_ACPI_CPU_PATH); if (!pszPath) return VERR_NO_MEMORY; /* * Simple algorithm to find the path. * Performance is not a real problem because it is * only executed once. */ for (unsigned iLvlCurr = 0; iLvlCurr < RT_ELEMENTS(g_aAcpiCpuPath); iLvlCurr++) { PSYSFSCPUPATH pAcpiCpuPathLvl = &g_aAcpiCpuPath[iLvlCurr]; for (unsigned iCompCurr = 0; iCompCurr < pAcpiCpuPathLvl->cComponents; iCompCurr++) { PCSYSFSCPUPATHCOMP pPathComponent = &pAcpiCpuPathLvl->aComponentsPossible[iCompCurr]; /* Open the directory */ PRTDIR pDirCurr = NULL; char *pszPathTmp = RTPathJoinA(pszPath, pPathComponent->pcszName); if (pszPathTmp) { rc = RTDirOpenFiltered(&pDirCurr, pszPathTmp, RTDIRFILTER_WINNT, 0); RTStrFree(pszPathTmp); } else rc = VERR_NO_STR_MEMORY; if (RT_FAILURE(rc)) break; /* Search if the current directory contains one of the possible parts. */ size_t cchName = strlen(pPathComponent->pcszName); RTDIRENTRY DirFolderContent; bool fFound = false; /* Get rid of the * filter which is in the path component. */ if (pPathComponent->fNumberedSuffix) cchName--; while (RT_SUCCESS(RTDirRead(pDirCurr, &DirFolderContent, NULL))) /* Assumption that szName has always enough space */ { if ( DirFolderContent.cbName >= cchName && !strncmp(DirFolderContent.szName, pPathComponent->pcszName, cchName)) { /* Found, use the complete name to dig deeper. */ fFound = true; pAcpiCpuPathLvl->uId = iCompCurr; char *pszPathLvl = RTPathJoinA(pszPath, DirFolderContent.szName); if (pszPathLvl) { RTStrFree(pszPath); pszPath = pszPathLvl; } else rc = VERR_NO_STR_MEMORY; break; } } RTDirClose(pDirCurr); if (fFound) break; } /* For every possible component. */ /* No matching component for this part, no need to continue */ if (RT_FAILURE(rc)) break; } /* For every level */ VBoxServiceVerbose(1, "Final path after probing %s rc=%Rrc\n", pszPath, rc); RTStrFree(pszPath); } return rc; }
/** * Process the testcases found in the filter. * * @param pszFilter The filter (winnt) to pass to RTDirOpenFiltered for * selecting the testcases. * @param pszDir The directory we're processing. */ static void Process(const char *pszFilter, const char *pszDir) { /* * Open and enumerate the directory. */ PRTDIR pDir; int rc = RTDirOpenFiltered(&pDir, pszFilter, RTDIRFILTER_WINNT, 0); if (RT_SUCCESS(rc)) { for (;;) { RTDIRENTRY DirEntry; rc = RTDirRead(pDir, &DirEntry, NULL); if (RT_FAILURE(rc)) { if (rc == VERR_NO_MORE_FILES) rc = VINF_SUCCESS; else RTPrintf("tstRunTestcases: reading '%s' -> %Rrc\n", pszFilter, rc); break; } /* * Construct the testcase name. */ char *pszTestcase; RTStrAPrintf(&pszTestcase, "%s/%s", pszDir, DirEntry.szName); if (!pszTestcase) { RTPrintf("tstRunTestcases: out of memory!\n"); rc = VERR_NO_MEMORY; break; } if (IsTestcaseIncluded(pszTestcase)) { /* * Execute the testcase. */ RTPrintf("*** %s: Executing...\n", pszTestcase); RTStrmFlush(g_pStdOut); const char *papszArgs[2]; papszArgs[0] = pszTestcase; papszArgs[1] = NULL; RTPROCESS Process; rc = RTProcCreate(pszTestcase, papszArgs, RTENV_DEFAULT, 0, &Process); if (RT_SUCCESS(rc)) { /* * Wait for the process and collect it's return code. * If it takes too long, we'll terminate it and continue. */ RTTIMESPEC Start; RTTimeNow(&Start); RTPROCSTATUS ProcStatus; for (;;) { rc = RTProcWait(Process, RTPROCWAIT_FLAGS_NOBLOCK, &ProcStatus); if (rc != VERR_PROCESS_RUNNING) break; RTTIMESPEC Now; if (RTTimeSpecGetMilli(RTTimeSpecSub(RTTimeNow(&Now), &Start)) > 120*1000 /* 1 min */) { RTPrintf("*** %s: FAILED - timed out. killing it.\n", pszTestcase); RTProcTerminate(Process); RTThreadSleep(100); RTProcWait(Process, RTPROCWAIT_FLAGS_NOBLOCK, &ProcStatus); g_cFailures++; break; } RTThreadSleep(100); } /* * Examin the exit status. */ if (RT_SUCCESS(rc)) { if ( ProcStatus.enmReason == RTPROCEXITREASON_NORMAL && ProcStatus.iStatus == 0) { RTPrintf("*** %s: PASSED\n", pszTestcase); g_cPasses++; } else { RTPrintf("*** %s: FAILED\n", pszTestcase); g_cFailures++; } } else if (rc != VERR_PROCESS_RUNNING) { RTPrintf("tstRunTestcases: %s: RTProcWait failed -> %Rrc\n", pszTestcase, rc); g_cFailures++; } } else { RTPrintf("tstRunTestcases: %s: failed to start -> %Rrc\n", pszTestcase, rc); g_cFailures++; } } else { RTPrintf("tstRunTestcases: %s: SKIPPED\n", pszTestcase); g_cSkipped++; } RTStrFree(pszTestcase); } /* enumeration loop */ RTDirClose(pDir); } else RTPrintf("tstRunTestcases: opening '%s' -> %Rrc\n", pszDir, rc); }
int DnDURIList::appendPathRecursive(const char *pcszPath, size_t cbBaseLen, uint32_t fFlags) { AssertPtrReturn(pcszPath, VERR_INVALID_POINTER); RTFSOBJINFO objInfo; int rc = RTPathQueryInfo(pcszPath, &objInfo, RTFSOBJATTRADD_NOTHING); if (RT_FAILURE(rc)) return rc; /* * These are the types we currently support. Symlinks are not directly * supported. First the guest could be an OS which doesn't support it and * second the symlink could point to a file which is out of the base tree. * Both things are hard to support. For now we just copy the target file in * this case. */ if (!( RTFS_IS_DIRECTORY(objInfo.Attr.fMode) || RTFS_IS_FILE(objInfo.Attr.fMode) || RTFS_IS_SYMLINK(objInfo.Attr.fMode))) return VINF_SUCCESS; uint64_t cbSize = 0; rc = RTFileQuerySize(pcszPath, &cbSize); if (rc == VERR_IS_A_DIRECTORY) rc = VINF_SUCCESS; if (RT_FAILURE(rc)) return rc; m_lstTree.append(DnDURIObject( RTFS_IS_DIRECTORY(objInfo.Attr.fMode) ? DnDURIObject::Directory : DnDURIObject::File, pcszPath, &pcszPath[cbBaseLen], objInfo.Attr.fMode, cbSize)); m_cbTotal += cbSize; #ifdef DEBUG_andy LogFlowFunc(("strSrcPath=%s, strDstPath=%s, fMode=0x%x, cbSize=%RU64, cbTotal=%zu\n", pcszPath, &pcszPath[cbBaseLen], objInfo.Attr.fMode, cbSize, m_cbTotal)); #endif PRTDIR hDir; /* We have to try to open even symlinks, cause they could * be symlinks to directories. */ rc = RTDirOpen(&hDir, pcszPath); /* The following error happens when this was a symlink * to an file or a regular file. */ if ( rc == VERR_PATH_NOT_FOUND || rc == VERR_NOT_A_DIRECTORY) return VINF_SUCCESS; if (RT_FAILURE(rc)) return rc; while (RT_SUCCESS(rc)) { RTDIRENTRY DirEntry; rc = RTDirRead(hDir, &DirEntry, NULL); if (RT_FAILURE(rc)) { if (rc == VERR_NO_MORE_FILES) rc = VINF_SUCCESS; break; } switch (DirEntry.enmType) { case RTDIRENTRYTYPE_DIRECTORY: { /* Skip "." and ".." entries. */ if ( RTStrCmp(DirEntry.szName, ".") == 0 || RTStrCmp(DirEntry.szName, "..") == 0) break; char *pszRecDir = RTPathJoinA(pcszPath, DirEntry.szName); if (pszRecDir) { rc = appendPathRecursive(pszRecDir, cbBaseLen, fFlags); RTStrFree(pszRecDir); } else rc = VERR_NO_MEMORY; break; } case RTDIRENTRYTYPE_SYMLINK: case RTDIRENTRYTYPE_FILE: { char *pszNewFile = RTPathJoinA(pcszPath, DirEntry.szName); if (pszNewFile) { /* We need the size and the mode of the file. */ RTFSOBJINFO objInfo1; rc = RTPathQueryInfo(pszNewFile, &objInfo1, RTFSOBJATTRADD_NOTHING); if (RT_FAILURE(rc)) return rc; rc = RTFileQuerySize(pszNewFile, &cbSize); if (rc == VERR_IS_A_DIRECTORY) /* Happens for symlinks. */ rc = VINF_SUCCESS; if (RT_FAILURE(rc)) break; if (RTFS_IS_FILE(objInfo.Attr.fMode)) { m_lstTree.append(DnDURIObject(DnDURIObject::File, pszNewFile, &pszNewFile[cbBaseLen], objInfo1.Attr.fMode, cbSize)); m_cbTotal += cbSize; } else /* Handle symlink directories. */ rc = appendPathRecursive(pszNewFile, cbBaseLen, fFlags); #ifdef DEBUG_andy LogFlowFunc(("strSrcPath=%s, strDstPath=%s, fMode=0x%x, cbSize=%RU64, cbTotal=%zu\n", pszNewFile, &pszNewFile[cbBaseLen], objInfo1.Attr.fMode, cbSize, m_cbTotal)); #endif RTStrFree(pszNewFile); } else rc = VERR_NO_MEMORY; break; } default: break; } } RTDirClose(hDir); return rc; }
int DnDURIList::appendPathRecursive(const char *pcszSrcPath, const char *pcszDstPath, const char *pcszDstBase, size_t cchDstBase, uint32_t fFlags) { AssertPtrReturn(pcszSrcPath, VERR_INVALID_POINTER); AssertPtrReturn(pcszDstBase, VERR_INVALID_POINTER); AssertPtrReturn(pcszDstPath, VERR_INVALID_POINTER); LogFlowFunc(("pcszSrcPath=%s, pcszDstPath=%s, pcszDstBase=%s, cchDstBase=%zu\n", pcszSrcPath, pcszDstPath, pcszDstBase, cchDstBase)); RTFSOBJINFO objInfo; int rc = RTPathQueryInfo(pcszSrcPath, &objInfo, RTFSOBJATTRADD_NOTHING); if (RT_SUCCESS(rc)) { if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode)) { rc = addEntry(pcszSrcPath, &pcszDstPath[cchDstBase], fFlags); if (RT_SUCCESS(rc)) { PRTDIR hDir; rc = RTDirOpen(&hDir, pcszSrcPath); if (RT_SUCCESS(rc)) { do { RTDIRENTRY DirEntry; rc = RTDirRead(hDir, &DirEntry, NULL); if (RT_FAILURE(rc)) { if (rc == VERR_NO_MORE_FILES) rc = VINF_SUCCESS; break; } switch (DirEntry.enmType) { case RTDIRENTRYTYPE_DIRECTORY: { /* Skip "." and ".." entries. */ if ( RTStrCmp(DirEntry.szName, ".") == 0 || RTStrCmp(DirEntry.szName, "..") == 0) break; char *pszSrc = RTPathJoinA(pcszSrcPath, DirEntry.szName); if (pszSrc) { char *pszDst = RTPathJoinA(pcszDstPath, DirEntry.szName); if (pszDst) { rc = appendPathRecursive(pszSrc, pszDst, pcszDstBase, cchDstBase, fFlags); RTStrFree(pszDst); } else rc = VERR_NO_MEMORY; RTStrFree(pszSrc); } else rc = VERR_NO_MEMORY; break; } case RTDIRENTRYTYPE_FILE: { char *pszSrc = RTPathJoinA(pcszSrcPath, DirEntry.szName); if (pszSrc) { char *pszDst = RTPathJoinA(pcszDstPath, DirEntry.szName); if (pszDst) { rc = addEntry(pszSrc, &pszDst[cchDstBase], fFlags); RTStrFree(pszDst); } else rc = VERR_NO_MEMORY; RTStrFree(pszSrc); } else rc = VERR_NO_MEMORY; break; } case RTDIRENTRYTYPE_SYMLINK: { if (fFlags & DNDURILIST_FLAGS_RESOLVE_SYMLINKS) { char *pszSrc = RTPathRealDup(pcszDstBase); if (pszSrc) { rc = RTPathQueryInfo(pszSrc, &objInfo, RTFSOBJATTRADD_NOTHING); if (RT_SUCCESS(rc)) { if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode)) { LogFlowFunc(("Directory entry is symlink to directory\n")); rc = appendPathRecursive(pszSrc, pcszDstPath, pcszDstBase, cchDstBase, fFlags); } else if (RTFS_IS_FILE(objInfo.Attr.fMode)) { LogFlowFunc(("Directory entry is symlink to file\n")); rc = addEntry(pszSrc, &pcszDstPath[cchDstBase], fFlags); } else rc = VERR_NOT_SUPPORTED; } RTStrFree(pszSrc); } else rc = VERR_NO_MEMORY; } break; } default: break; } } while (RT_SUCCESS(rc)); RTDirClose(hDir); } } } else if (RTFS_IS_FILE(objInfo.Attr.fMode)) { rc = addEntry(pcszSrcPath, &pcszDstPath[cchDstBase], fFlags); } else if (RTFS_IS_SYMLINK(objInfo.Attr.fMode)) { if (fFlags & DNDURILIST_FLAGS_RESOLVE_SYMLINKS) { char *pszSrc = RTPathRealDup(pcszSrcPath); if (pszSrc) { rc = RTPathQueryInfo(pszSrc, &objInfo, RTFSOBJATTRADD_NOTHING); if (RT_SUCCESS(rc)) { if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode)) { LogFlowFunc(("Symlink to directory\n")); rc = appendPathRecursive(pszSrc, pcszDstPath, pcszDstBase, cchDstBase, fFlags); } else if (RTFS_IS_FILE(objInfo.Attr.fMode)) { LogFlowFunc(("Symlink to file\n")); rc = addEntry(pszSrc, &pcszDstPath[cchDstBase], fFlags); } else rc = VERR_NOT_SUPPORTED; } RTStrFree(pszSrc); } else rc = VERR_NO_MEMORY; } } else rc = VERR_NOT_SUPPORTED; } LogFlowFuncLeaveRC(rc); return rc; }
/** * Recursion worker for RTDirRemoveRecursive. * * @returns IPRT status code. * @param pszBuf The path buffer. Contains the abs path to the * directory to recurse into. Trailing slash. * @param cchDir The length of the directory we're cursing into, * including the trailing slash. * @param pDirEntry The dir entry buffer. (Shared to save stack.) * @param pObjInfo The object info buffer. (ditto) */ static int rtDirRemoveRecursiveSub(char *pszBuf, size_t cchDir, PRTDIRENTRY pDirEntry, PRTFSOBJINFO pObjInfo) { AssertReturn(RTPATH_IS_SLASH(pszBuf[cchDir - 1]), VERR_INTERNAL_ERROR_4); /* * Enumerate the directory content and dispose of it. */ PRTDIR pDir; int rc = RTDirOpen(&pDir, pszBuf); if (RT_FAILURE(rc)) return rc; while (RT_SUCCESS(rc = RTDirRead(pDir, pDirEntry, NULL))) { if ( pDirEntry->szName[0] != '.' || pDirEntry->cbName > 2 || ( pDirEntry->cbName == 2 && pDirEntry->szName[1] != '.') ) { /* Construct the full name of the entry. */ if (cchDir + pDirEntry->cbName + 1 /* dir slash */ >= RTPATH_MAX) { rc = VERR_FILENAME_TOO_LONG; break; } memcpy(&pszBuf[cchDir], pDirEntry->szName, pDirEntry->cbName + 1); /* Deal with the unknown type. */ if (pDirEntry->enmType == RTDIRENTRYTYPE_UNKNOWN) { rc = RTPathQueryInfoEx(pszBuf, pObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); if (RT_SUCCESS(rc) && RTFS_IS_DIRECTORY(pObjInfo->Attr.fMode)) pDirEntry->enmType = RTDIRENTRYTYPE_DIRECTORY; else if (RT_SUCCESS(rc) && RTFS_IS_FILE(pObjInfo->Attr.fMode)) pDirEntry->enmType = RTDIRENTRYTYPE_FILE; else if (RT_SUCCESS(rc) && RTFS_IS_SYMLINK(pObjInfo->Attr.fMode)) pDirEntry->enmType = RTDIRENTRYTYPE_SYMLINK; } /* Try the delete the fs object. */ switch (pDirEntry->enmType) { case RTDIRENTRYTYPE_FILE: rc = RTFileDelete(pszBuf); break; case RTDIRENTRYTYPE_DIRECTORY: { size_t cchSubDir = cchDir + pDirEntry->cbName; pszBuf[cchSubDir++] = '/'; pszBuf[cchSubDir] = '\0'; rc = rtDirRemoveRecursiveSub(pszBuf, cchSubDir, pDirEntry, pObjInfo); if (RT_SUCCESS(rc)) { pszBuf[cchSubDir] = '\0'; rc = RTDirRemove(pszBuf); } break; } //case RTDIRENTRYTYPE_SYMLINK: // rc = RTSymlinkDelete(pszBuf, 0); // break; default: /** @todo not implemented yet. */ rc = VINF_SUCCESS; break; } if (RT_FAILURE(rc)) break; } } if (rc == VERR_NO_MORE_FILES) rc = VINF_SUCCESS; RTDirClose(pDir); return rc; }
int DnDHGSendDataMessage::buildFileTree(const char *pcszPath, size_t cbBaseLen) { RTFSOBJINFO objInfo; int rc = RTPathQueryInfo(pcszPath, &objInfo, RTFSOBJATTRADD_NOTHING); if (RT_FAILURE(rc)) return rc; /* These are the types we currently support. Symlinks are not directly * supported. First the guest could be an OS which doesn't support it and * second the symlink could point to a file which is out of the base tree. * Both things are hard to support. For now we just copy the target file in * this case. */ if (!( RTFS_IS_DIRECTORY(objInfo.Attr.fMode) || RTFS_IS_FILE(objInfo.Attr.fMode) || RTFS_IS_SYMLINK(objInfo.Attr.fMode))) return VINF_SUCCESS; uint64_t cbSize = 0; rc = RTFileQuerySize(pcszPath, &cbSize); if (rc == VERR_IS_A_DIRECTORY) rc = VINF_SUCCESS; if (RT_FAILURE(rc)) return rc; m_uriList.append(PathEntry(pcszPath, &pcszPath[cbBaseLen], objInfo.Attr.fMode, cbSize)); m_cbAll += cbSize; DO(("cbFile: %u\n", cbSize)); PRTDIR hDir; /* We have to try to open even symlinks, cause they could be symlinks * to directories. */ rc = RTDirOpen(&hDir, pcszPath); /* The following error happens when this was a symlink to an file or a * regular file. */ if (rc == VERR_PATH_NOT_FOUND) return VINF_SUCCESS; if (RT_FAILURE(rc)) return rc; while (RT_SUCCESS(rc)) { RTDIRENTRY DirEntry; rc = RTDirRead(hDir, &DirEntry, NULL); if (RT_FAILURE(rc)) { if (rc == VERR_NO_MORE_FILES) rc = VINF_SUCCESS; break; } switch (DirEntry.enmType) { case RTDIRENTRYTYPE_DIRECTORY: { /* Skip "." and ".." entries. */ if ( RTStrCmp(DirEntry.szName, ".") == 0 || RTStrCmp(DirEntry.szName, "..") == 0) break; if (char *pszRecDir = RTStrAPrintf2("%s%c%s", pcszPath, RTPATH_DELIMITER, DirEntry.szName)) { rc = buildFileTree(pszRecDir, cbBaseLen); RTStrFree(pszRecDir); } else rc = VERR_NO_MEMORY; break; } case RTDIRENTRYTYPE_SYMLINK: case RTDIRENTRYTYPE_FILE: { if (char *pszNewFile = RTStrAPrintf2("%s%c%s", pcszPath, RTPATH_DELIMITER, DirEntry.szName)) { /* We need the size and the mode of the file. */ RTFSOBJINFO objInfo1; rc = RTPathQueryInfo(pszNewFile, &objInfo1, RTFSOBJATTRADD_NOTHING); if (RT_FAILURE(rc)) return rc; rc = RTFileQuerySize(pszNewFile, &cbSize); if (RT_FAILURE(rc)) break; m_uriList.append(PathEntry(pszNewFile, &pszNewFile[cbBaseLen], objInfo1.Attr.fMode, cbSize)); m_cbAll += cbSize; RTStrFree(pszNewFile); } else rc = VERR_NO_MEMORY; break; } default: break; } } RTDirClose(hDir); return rc; }