Skip to content
Merged
Show file tree
Hide file tree
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
7 changes: 7 additions & 0 deletions libpromises/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -206,18 +206,25 @@ libpromises_la_SOURCES += \
process_freebsd.c
endif

if MACOSX
libpromises_la_SOURCES += \
process_macos.c
endif

if !LINUX
if !AIX
if !HPUX
if !SOLARIS
if !FREEBSD
if !MACOSX
libpromises_la_SOURCES += \
process_unix_stub.c
endif
endif
endif
endif
endif
endif

endif # !NT

Expand Down
111 changes: 111 additions & 0 deletions libpromises/process_macos.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
Copyright 2026 Northern.tech AS

This file is part of CFEngine 3 - written and maintained by Northern.tech AS.

This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; version 3.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA

To the extent this program is licensed as part of the Enterprise
versions of CFEngine, the applicable Commercial Open Source License
(COSL) may apply to this file if you as a licensee so wish it. See
included file COSL.txt.
*/

#include <cf3.defs.h>
#include <process_lib.h>
#include <process_unix_priv.h>
#include <file_lib.h>

#include <sys/sysctl.h>
#include <sys/proc.h>

typedef struct
{
time_t starttime;
char state;
} ProcessStat;

/* macOS's kinfo_proc nests the BSD "extern_proc" struct (kp_proc), unlike
* FreeBSD's flattened kinfo_proc, but it still uses the same p_starttime /
* p_stat fields and S* state constants inherited from the shared BSD
* ancestry. */
static bool GetProcessStat(pid_t pid, ProcessStat *state)
{
int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
struct kinfo_proc psinfo;
size_t len = sizeof(psinfo);

/* A successful call with len == 0 means no matching process was found. */
if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &psinfo, &len, NULL, 0) != 0 ||
len == 0)
{
return false;
}

state->starttime = psinfo.kp_proc.p_starttime.tv_sec;

switch (psinfo.kp_proc.p_stat)
{
case SRUN:
case SIDL:
state->state = 'R';
break;
case SSTOP:
state->state = 'T';
break;
case SSLEEP:
state->state = 'S';
break;
case SZOMB:
state->state = 'Z';
break;
default:
state->state = 'X';
}
return true;
}

time_t GetProcessStartTime(pid_t pid)
{
ProcessStat st;
if (GetProcessStat(pid, &st))
{
return st.starttime;
}
else
{
return PROCESS_START_TIME_UNKNOWN;
}
}

ProcessState GetProcessState(pid_t pid)
{
ProcessStat st;
if (GetProcessStat(pid, &st))
{
switch (st.state)
{
case 'T':
return PROCESS_STATE_STOPPED;
case 'Z':
return PROCESS_STATE_ZOMBIE;
default:
return PROCESS_STATE_RUNNING;
}
}
else
{
return PROCESS_STATE_DOES_NOT_EXIST;
}
}
5 changes: 3 additions & 2 deletions tests/unit/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,10 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS)

if MACOSX
XFAIL_TESTS = set_domainname_test
XFAIL_TESTS += process_test
XFAIL_TESTS += mon_processes_test
XFAIL_TESTS += rlist_test
# NOTE: cf-monitord's own process-table gathering has a separate, real bug on
# macOS
XFAIL_TESTS += mon_processes_test
endif

if AIX
Expand Down
6 changes: 6 additions & 0 deletions tests/unit/mon_processes_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ static bool GetSysUsers( int *userListSz, int *numRootProcs, int *numOtherProcs)
xsnprintf(cbuff, CF_BUFSIZE, "UNIX95=1 /bin/ps -eo user,pid > %s/users.txt", CFWORKDIR);
/* SKIP on HP-UX since cf-monitord doesn't count processes correctly! */
return false;
#elif defined(__APPLE__)
/* macOS's BSD ps doesn't understand procps's "keyword:width" column
* sizing syntax used in the generic branch below (it errors out with
* "ps: user:30: keyword not found"). BSD ps doesn't truncate the "user"
* column the way Linux's does, so plain "user,pid" is enough here. */
xsnprintf(cbuff, CF_BUFSIZE, "ps -eo user,pid > %s/users.txt", CFWORKDIR);
#else
xsnprintf(cbuff, CF_BUFSIZE, "ps -eo user:30,pid > %s/users.txt", CFWORKDIR);
#endif
Expand Down
Loading