/filesystems/grabfs/GetPID.c

http://macfuse.googlecode.com/ · C · 136 lines · 104 code · 29 blank · 3 comment · 34 complexity · 83963e87bdab1f7af42b83b5cad93cf4 MD5 · raw file

  1. /*
  2. * From Apple DTS Sample Code.
  3. */
  4. #include "GetPID.h"
  5. #include <errno.h>
  6. #include <string.h>
  7. #include <sys/sysctl.h>
  8. int
  9. GetAllPIDsForProcessName(const char* ProcessName,
  10. pid_t ArrayOfReturnedPIDs[],
  11. const unsigned int NumberOfPossiblePIDsInArray,
  12. unsigned int* NumberOfMatchesFound,
  13. int* SysctlError)
  14. {
  15. int mib[6] = { 0,0,0,0,0,0 };
  16. int SuccessfullyGotProcessInformation;
  17. size_t sizeOfBufferRequired = 0;
  18. int error = 0;
  19. long NumberOfRunningProcesses = 0;
  20. int Counter = 0;
  21. struct kinfo_proc* BSDProcessInformationStructure = NULL;
  22. pid_t CurrentExaminedProcessPID = 0;
  23. char* CurrentExaminedProcessName = NULL;
  24. if (ProcessName == NULL) {
  25. return kInvalidArgumentsError;
  26. }
  27. if (ArrayOfReturnedPIDs == NULL) {
  28. return kInvalidArgumentsError;
  29. }
  30. if (NumberOfPossiblePIDsInArray <= 0) {
  31. return kInvalidArgumentsError;
  32. }
  33. if (NumberOfMatchesFound == NULL) {
  34. return kInvalidArgumentsError;
  35. }
  36. memset(ArrayOfReturnedPIDs, 0, NumberOfPossiblePIDsInArray * sizeof(pid_t));
  37. *NumberOfMatchesFound = 0;
  38. if (SysctlError != NULL) {
  39. *SysctlError = 0;
  40. }
  41. mib[0] = CTL_KERN;
  42. mib[1] = KERN_PROC;
  43. mib[2] = KERN_PROC_ALL;
  44. SuccessfullyGotProcessInformation = FALSE;
  45. while (SuccessfullyGotProcessInformation == FALSE) {
  46. error = sysctl(mib, 3, NULL, &sizeOfBufferRequired, NULL, NULL);
  47. if (error != 0) {
  48. if (SysctlError != NULL) {
  49. *SysctlError = errno;
  50. }
  51. return kErrorGettingSizeOfBufferRequired;
  52. }
  53. BSDProcessInformationStructure =
  54. (struct kinfo_proc*)malloc(sizeOfBufferRequired);
  55. if (BSDProcessInformationStructure == NULL) {
  56. if (SysctlError != NULL) {
  57. *SysctlError = ENOMEM;
  58. }
  59. return kUnableToAllocateMemoryForBuffer;
  60. }
  61. error = sysctl(mib, 3, BSDProcessInformationStructure,
  62. &sizeOfBufferRequired, NULL, NULL);
  63. if (error == 0) {
  64. SuccessfullyGotProcessInformation = TRUE;
  65. } else {
  66. free(BSDProcessInformationStructure);
  67. }
  68. }
  69. NumberOfRunningProcesses = sizeOfBufferRequired / sizeof(struct kinfo_proc);
  70. for (Counter = 0; Counter < NumberOfRunningProcesses; Counter++) {
  71. CurrentExaminedProcessPID =
  72. BSDProcessInformationStructure[Counter].kp_proc.p_pid;
  73. CurrentExaminedProcessName =
  74. BSDProcessInformationStructure[Counter].kp_proc.p_comm;
  75. if ((CurrentExaminedProcessPID > 0) &&
  76. ((strncmp(CurrentExaminedProcessName, ProcessName, MAXCOMLEN) == 0))
  77. ) {
  78. if ((*NumberOfMatchesFound + 1) > NumberOfPossiblePIDsInArray) {
  79. free(BSDProcessInformationStructure);
  80. return(kPIDBufferOverrunError);
  81. }
  82. ArrayOfReturnedPIDs[*NumberOfMatchesFound] =
  83. CurrentExaminedProcessPID;
  84. *NumberOfMatchesFound = *NumberOfMatchesFound + 1;
  85. }
  86. }
  87. free(BSDProcessInformationStructure);
  88. if (*NumberOfMatchesFound == 0) {
  89. return kCouldNotFindRequestedProcess;
  90. } else {
  91. return kSuccess;
  92. }
  93. }
  94. int
  95. GetPIDForProcessName(const char* ProcessName)
  96. {
  97. pid_t PIDArray[1] = { 0 };
  98. int Error = 0;
  99. unsigned int NumberOfMatches = 0;
  100. Error = GetAllPIDsForProcessName(ProcessName, PIDArray, 1,
  101. &NumberOfMatches, NULL);
  102. if ((Error == 0) && (NumberOfMatches == 1)) {
  103. return (int)PIDArray[0];
  104. } else {
  105. return -1;
  106. }
  107. }