Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions src/detection/initsystem/initsystem_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "util/stringUtils.h"

#include <libgen.h>
#include <string.h>
#include <unistd.h>

FF_MAYBE_UNUSED static bool extractSystemdVersion(const char* str, uint32_t len, void* userdata)
Expand Down Expand Up @@ -37,6 +38,20 @@ const char* ffDetectInitSystem(FFInitSystemResult* result)
ffProcessGetInfoLinux((int) result->pid, &result->name, &result->exe, &_, NULL);
if (result->exe.chars[0] == '/')
{
if (ffStrbufEqualS(&result->name, "shepherd") ||
ffStrbufEqualS(&result->name, "guile"))
{
// guile --no-auto-compile shepherd
// find the shepherd script in /proc/1/cmdline
const char* tmp = result->exe.chars;
while(!ffStrbufEndsWithS(&result->exe, "/shepherd"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this loop?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition, as what I said before, you should search for /path/to/shepherd, instead of assuming it's the 2nd argument

this iterates the args until it finds the one that points to the script.

Or what else did you mean by your previous comment?

{
tmp += result->exe.length + 1;
memmove(result->exe.chars, tmp, strlen(tmp) + 1);
ffStrbufRecalculateLength(&result->exe);
}
}

// In some old system, /sbin/init is a symlink
char buf[PATH_MAX];
if (realpath(result->exe.chars, buf))
Expand Down Expand Up @@ -84,16 +99,19 @@ const char* ffDetectInitSystem(FFInitSystemResult* result)
ffStrbufSubstrAfterLastC(&result->version, ' ');
}
}
else if (ffStrbufEqualS(&result->name, "guile"))
else if (ffStrbufEqualS(&result->name, "shepherd"))
{
// TODO: guile is actually shepherd
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
ffStrbufEndsWithS(&result->exe, "/guile") ? result->exe.chars : "guile",
"--version",
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
ffStrbufEndsWithS(&result->exe, "/shepherd") ? result->exe.chars : "shepherd",
"--version",
NULL,
}) == NULL && result->version.length)
{
// guile (GNU Guile) 3.0.9
// shepherd (GNU Shepherd) 1.0.6
// The first line in the output might not contain the version
if (!ffStrbufStartsWithS(&result->version, "shepherd"))
ffStrbufSubstrAfterFirstC(&result->version, '\n');

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This skips over the warning about missing signalfd support on Hurd

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If shepherd version always comes at the end, I prefer ffStrbufSubstrAfterLastC(&result->version, ' ');

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is some licensing information in the lines afterwards that I ommitted.

 shepherd --version
shepherd (GNU Shepherd) 1.0.6
Copyright (C) 2025 the Shepherd authors
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

ffStrbufSubstrBeforeFirstC(&result->version, '\n');
ffStrbufSubstrAfterLastC(&result->version, ' ');
}
Expand Down
Loading