ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
processinfo.cpp
1namespace alib { namespace system {
2
3// static instance representing current process
5
8 IF_ALIB_THREADS( static Lock lock; ALIB_DBG(lock.Dbg.Name= "ProcessInfo";) )
9 if( current.PID == 0 ) {
10 // Own global lock and check if still nulled.
11 // (If not, this was a very unlikely parallel access )
12 ALIB_LOCK_WITH( lock )
13 if ( ProcessInfo::current.PID == 0 )
14 ProcessInfo::current.get( 0 );
15 }
16 return current;
17}
18# include "ALib.Lang.CIMethods.H"
19
20
21#if defined(__GLIBC__) && defined(__unix__) || defined(__ANDROID_NDK__)
22bool readProcFile( const NCString& fileName, AString& result );
23bool readProcFile( const NCString& fileName, AString& result ) {
24 std::ifstream file( fileName );
25
26 std::string buffer;
27 getline(file, buffer);
28
29 // spaces are replaced with '\0'. Revert this.
30 if (buffer.size() > 2 )
31 for( size_t i= 0 ; i < buffer.size() -2 ; ++i )
32 if ( buffer[i] == '\0' )
33 buffer[i]= ' ';
34
35 result.Reset( buffer.c_str() );
36 file.close();
37 return true;
38}
39
40bool ProcessInfo::getStatField( int fieldNo, AString& target) {
41 Tokenizer tknzr( Stat, ' ');
42 bool result= true;
43 while ( --fieldNo >= 0 && (result= tknzr.HasNext()) )
44 tknzr.Next();
45
46 target.Reset( tknzr.Next() );
47 return result;
48}
49
50bool ProcessInfo::get( uinteger pid ) {
51 // use current thread if no PID given
52 uinteger newPID= 0;
53 if ( pid == 0 ) {
54 auto np= getpid();
55 if(np > 0 )
56 newPID= uinteger( np );
57 }
58 else
59 newPID= pid;
60
61 if ( newPID == 0 )
62 return false;
63
64
65 PID= newPID;
66
67 // cmdline, stat from proc
68 NString64 procDir("/proc/"); procDir._<NC>( PID )._( '/' );
69 integer procPathLen= procDir.Length();
70 {
71 // read things
72 procDir << "cmdline"; readProcFile( procDir, CmdLine ); procDir.ShortenTo(procPathLen);
73 procDir << "stat"; readProcFile( procDir, Stat ); procDir.ShortenTo(procPathLen);
74 }
75
76 getStatField( 3, Name ); // PPID
77 PPID= uinteger( Name.ParseInt() );
78 getStatField( 1, Name );
79 ALIB_ASSERT_ERROR( Name.IsEmpty()
80 || ( Name.Length() >= 2
81 && Name.CharAtStart<NC>()=='('
82 && Name.CharAtEnd <NC>()==')' ),
83 "CAMP", "Error reading process Info" )
84
85 if ( Name.CharAtEnd () == ')' ) Name.DeleteEnd <NC>( 1 );
86 if ( Name.CharAtStart() == '(' ) Name.DeleteStart<NC>( 1 );
89
90 // get executable path and name
91 ExecFileName.Reset();
92 ExecFilePath.Reset();
93
94 procDir << A_CHAR("exe");
95 nchar buffer[2048];
96 ssize_t length= readlink( procDir, buffer, 2048 );
97 procDir.ShortenTo(procPathLen);
98
99 if( length > 0 ) {
100 ExecFilePath.Append( buffer, length );
101 integer idx= ExecFilePath.LastIndexOf( '/' );
102 ALIB_ASSERT_ERROR( idx>= 0, "CAMP",
103 "Executable path does not contain directory separator character.\n"
104 " Path: {}", ExecFilePath )
105 ExecFileName._( ExecFilePath, idx + 1 );
106 ExecFilePath.ShortenTo( idx );
107 } else {
108 // obviously no rights to read the link. We use the process name
109 ExecFileName._( Name );
110 }
111 return true;
112}
113
114#elif defined (__APPLE__)
115
116 bool ProcessInfo::get( uinteger pid )
117 {
118 PID= PPID= 0;
119 if( pid == 0 )
120 pid= uinteger( getpid() );
121
122 struct proc_bsdinfo proc;
123 int st = proc_pidinfo( int(pid), PROC_PIDTBSDINFO, 0, &proc, PROC_PIDTBSDINFO_SIZE);
124 if (st != PROC_PIDTBSDINFO_SIZE)
125 return false;
126
127 // pid and parent pid
128 PID= pid;
129 PPID= uinteger( proc.pbi_ppid );
130
131 // get name
132 Name._(reinterpret_cast<const char*>( proc.pbi_comm ) );
133
134 // get executable filename and path
135 {
136 char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
137
138 if ( proc_pidpath (int( PID ), pathbuf, PROC_PIDPATHINFO_MAXSIZE) > 0 )
139 {
140 ExecFilePath._( reinterpret_cast<const char*>( pathbuf ) );
141 integer sepPos= ExecFilePath.LastIndexOf( '/' );
142 if( sepPos > 0 )
143 {
144 ExecFileName._(ExecFilePath, sepPos + 1 );
145 ExecFilePath.SetLength( sepPos );
146 }
147 }
148 }
149
150 return true;
151 }
152
153#elif defined (_WIN32)
154
156 {
157 // get pid
158 if (pid != 0 )
159 return false;
160
161 DWORD wPID= GetCurrentProcessId();
162 PID = (uinteger) wPID;
163
164
165 // get command-line
166 CmdLine.Reset( NString( GetCommandLineA()) );
167
168 // get executable filename and path
169 ExecFileName.Reset();
170 ExecFilePath.Reset();
171 Name.Reset();
172
173 char buf[MAX_PATH];
174 GetModuleFileNameA( NULL, buf, MAX_PATH );
175 ExecFilePath.Reset( (const char*) buf );
176 integer idx= ExecFilePath.LastIndexOf( '\\' );
177 ALIB_ASSERT_ERROR( idx>= 0, "CAMP",
178 "Executable path does not contain directory separator character: ",
180 Name= ExecFileName._( ExecFilePath, idx + 1 );
181 ExecFilePath.SetLength( idx );
182
183 // get console title
184 STARTUPINFOA startupInfo;
185 GetStartupInfoA( &startupInfo );
186 ConsoleTitle.Reset( NString(startupInfo.lpTitle) );
187
188 return true;
189 }
190
191#else
192 #pragma message ("Unknown Platform in file: " __FILE__ )
193#endif
194
195}} // namespace [alib::system]
#define IF_ALIB_THREADS(...)
#define A_CHAR(STR)
#define ALIB_DBG(...)
#define ALIB_ASSERT_ERROR(cond, domain,...)
#define ALIB_LOCK_WITH(lock)
This class represents process information.
AString StatPGRP
The process group field (4) within #"Stat". (Unix like OS only.).
ProcessInfo()
Default constructor to create an empty instance.
AString Stat
The contents of /proc/PID/stat file. (Unix like OS only.).
bool get(uinteger PID)
uinteger PPID
The parent's process id as AString. (Unix like OS / Mac OS only.).
AString ExecFilePath
The path of the executable (if available to us).
AString StatState
The state field (2) within #"Stat". (Unix like OS only.).
static ProcessInfo current
uinteger PID
The process id as AString.
static const ProcessInfo & Current()
AString CmdLine
The command-line which invoked this process.
AString ConsoleTitle
For console processes, this is the title displayed in the title bar. (Windows OS only....
bool getStatField(int fieldNo, AString &target)
Definition alox.cpp:14
threads::Lock Lock
Type alias in namespace #"%alib".
Definition lock.hpp:124
strings::TString< nchar > NString
Type alias in namespace #"%alib".
Definition string.hpp:2174
strings::TCString< nchar > NCString
Type alias in namespace #"%alib".
Definition cstring.hpp:408
strings::util::TTokenizer< character > Tokenizer
Type alias in namespace #"%alib".
lang::integer integer
Type alias in namespace #"%alib".
Definition integers.hpp:149
characters::nchar nchar
Type alias in namespace #"%alib".
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace #"%alib".
lang::uinteger uinteger
Type alias in namespace #"%alib".
Definition integers.hpp:152
NLocalString< 64 > NString64
Type alias name for #"TLocalString;TLocalString<nchar,64>".