1919#include < signal.h>
2020#include < unistd.h>
2121
22+ #ifdef __APPLE__
23+ #include < sys/sysctl.h>
24+ #include < libproc.h>
25+ #endif
26+
2227namespace
2328{
24- int _getProcIdByName (const char * procName)
29+
30+
31+ #ifdef __APPLE__ // macOS
32+
33+ int _getProcIdByName (const char * procName)
2534 {
26- constexpr char const fmt[] { " /proc/%s/cmdline" };
27- constexpr char const dirProc[] { " /proc" };
28- int pid = -1 ;
35+ if (NEString::isEmpty<char >(procName))
36+ return -1 ;
37+
38+ // macOS implementation using sysctl
39+ int mib[4 ] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
40+ size_t size {0 };
41+
42+ if (sysctl (mib, 4 , nullptr , &size, nullptr , 0 ) < 0 )
43+ return -1 ;
44+
45+ uint8_t * buffer = size != 0 ? DEBUG_NEW uint8_t [size] : nullptr ;
46+ struct kinfo_proc * procs = reinterpret_cast <struct kinfo_proc *>(buffer);
47+ if (procs == nullptr )
48+ return -1 ;
49+
50+ if (sysctl (mib, 4 , procs, &size, nullptr , 0 ) < 0 )
51+ {
52+ delete [] buffer;
53+ return -1 ;
54+ }
55+
56+ int count = size / sizeof (struct kinfo_proc );
57+ int pid {-1 };
58+
59+ for (int i = 0 ; i < count && pid < 0 ; ++i)
60+ {
61+ if (NEString::compareIgnoreCase<char , char >(procName, procs[i].kp_proc .p_comm ) == NEMath::eCompare::Equal)
62+ {
63+ pid = procs[i].kp_proc .p_pid ;
64+ }
65+ }
66+
67+ delete[] buffer;
68+ return pid;
69+ }
70+
71+ #else // Linux
72+
73+ int _getProcIdByName (const char * procName)
74+ {
75+ if (NEString::isEmpty<char >(procName))
76+ return -1 ;
77+
78+ // Linux implementation using /proc
79+ constexpr char const fmt[]{ " /proc/%s/cmdline" };
80+ constexpr char const dirProc[]{ " /proc" };
81+ int pid {-1 };
2982
3083 DIR* dir = opendir (dirProc);
3184 char * buffer = dir != nullptr ? DEBUG_NEW char [File::MAXIMUM_PATH + 1 ] : nullptr ;
32- if (( buffer == nullptr ) || NEString::isEmpty< char >(procName) )
85+ if (buffer == nullptr )
3386 return pid;
3487
3588 for (struct dirent * dirEntry = readdir (dir); (pid < 0 ) && (dirEntry != nullptr ); dirEntry = readdir (dir))
3689 {
37- // skip non-numeric directories.
38- if ((dirEntry->d_type == DT_REG) && (NEString::isNumeric<char >(dirEntry->d_name [0 ])))
90+ if (NEString::isNumeric<char >(dirEntry->d_name [0 ]))
3991 {
4092 String name;
4193 name.format (fmt, dirEntry->d_name );
@@ -44,11 +96,11 @@ namespace
4496 {
4597 if (fgets (buffer, File::MAXIMUM_PATH + 1 , file) != nullptr )
4698 {
47- NEString::CharPos pos = NEString::findLast<char >( File::PATH_SEPARATOR, buffer);
99+ NEString::CharPos pos = NEString::findLast<char >(File::PATH_SEPARATOR, buffer);
48100 if (NEString::isPositionValid (pos))
49101 {
50- char * name = buffer + pos + 1 ;
51- if (NEString::compareIgnoreCase<char , char >(procName, name ) == NEMath::eCompare::Equal)
102+ char * procPath = buffer + pos + 1 ;
103+ if (NEString::compareIgnoreCase<char , char >(procName, procPath ) == NEMath::eCompare::Equal)
52104 {
53105 pid = NEString::makeInteger<char >(dirEntry->d_name , nullptr );
54106 }
@@ -60,8 +112,11 @@ namespace
60112 }
61113 }
62114
115+ delete[] buffer;
116+ closedir (dir);
63117 return pid;
64118 }
119+ #endif // Linux
65120
66121 DEF_LOG_SCOPE (areg_appbase_ApplicationPosix__handleSignalBrokenPipe);
67122 void _handleSignalBrokenPipe (int s)
0 commit comments