Skip to content

Commit bdbaed5

Browse files
committed
InitSystem (GNU): support shepherd detection
1 parent 00f163b commit bdbaed5

File tree

2 files changed

+41
-12
lines changed

2 files changed

+41
-12
lines changed

src/common/processing_linux.c

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,35 @@ void ffProcessGetInfoLinux(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, cons
241241

242242
if(ffReadFileBuffer(filePath, exe))
243243
{
244-
ffStrbufRecalculateLength(exe); //Trim the arguments
245-
ffStrbufTrimRightSpace(exe);
244+
// Interpreter. Try to find the real script path in the arguments
245+
const char* p = exe->chars;
246+
uint32_t len = (uint32_t) strlen(p);
247+
248+
if (len + 1 < exe->length)
249+
{
250+
const char* name = memrchr(p, '/', len);
251+
if (name) name++; else name = p;
252+
253+
if (ffStrStartsWith(name, "python")
254+
#ifndef __ANDROID__
255+
|| ffStrEquals(name, "guile") // for shepherd
256+
#endif
257+
)
258+
{
259+
// `cmdline` always ends with a trailing '\0', and ffReadFileBuffer appends another \0
260+
// So `exe->chars` is always double '\0' terminated
261+
for (p = p + len + 1; *p && *p == '-'; p += strlen(p) + 1) // Skip argumets
262+
assert(p - exe->chars < exe->allocated);
263+
if (*p)
264+
{
265+
len = (uint32_t) strlen(p);
266+
memmove(exe->chars, p, len + 1);
267+
}
268+
}
269+
}
270+
271+
assert(len < exe->allocated);
272+
exe->length = len;
246273
ffStrbufTrimLeft(exe, '-'); //Login shells start with a dash
247274
}
248275

@@ -463,6 +490,8 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
463490
return "memrchr(stat, ')') failed";
464491
ffStrbufSetNS(name, (uint32_t) (end - start), start);
465492
ffStrbufTrimRightSpace(name);
493+
if (name->chars[0] == '\0')
494+
return "process name is empty";
466495
pState = end + 2; // skip ") "
467496
}
468497

@@ -471,10 +500,7 @@ const char* ffProcessGetBasicInfoLinux(pid_t pid, FFstrbuf* name, pid_t* ppid, i
471500
#endif
472501
{
473502
int ppid_, tty_;
474-
if(
475-
sscanf(pState + 2, "%d %*d %*d %d", &ppid_, &tty_) < 2 ||
476-
name->chars[0] == '\0'
477-
)
503+
if(sscanf(pState + 2, "%d %*d %*d %d", &ppid_, &tty_) < 2)
478504
return "sscanf(stat) failed";
479505

480506
if (ppid)

src/detection/initsystem/initsystem_linux.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,19 @@ const char* ffDetectInitSystem(FFInitSystemResult* result)
8484
ffStrbufSubstrAfterLastC(&result->version, ' ');
8585
}
8686
}
87-
else if (ffStrbufEqualS(&result->name, "guile"))
87+
else if (ffStrbufEqualS(&result->name, "shepherd"))
8888
{
89-
// TODO: guile is actually shepherd
90-
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
91-
ffStrbufEndsWithS(&result->exe, "/guile") ? result->exe.chars : "guile",
92-
"--version",
89+
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
90+
ffStrbufEndsWithS(&result->exe, "/shepherd") ? result->exe.chars : "shepherd",
91+
"--version",
9392
NULL,
9493
}) == NULL && result->version.length)
9594
{
96-
// guile (GNU Guile) 3.0.9
95+
// shepherd (GNU Shepherd) 1.0.6
96+
// The first line in the output might not contain the version
97+
if (!ffStrbufStartsWithS(&result->version, "shepherd"))
98+
ffStrbufSubstrAfterFirstC(&result->version, '\n');
99+
97100
ffStrbufSubstrBeforeFirstC(&result->version, '\n');
98101
ffStrbufSubstrAfterLastC(&result->version, ' ');
99102
}

0 commit comments

Comments
 (0)