dorkos 0.98.0 → 0.101.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -13
- package/dist/bin/cli.js +10649 -8676
- package/dist/browser/fresh-verifier.mjs +3 -2
- package/dist/browser/native/darwin-journal-worker.mjs +2244 -0
- package/dist/browser/native/darwin-process-observer +0 -0
- package/dist/browser/native/darwin-process-observer.c +252 -0
- package/dist/browser/native/darwin-process-observer.h +37 -0
- package/dist/browser/native/darwin-process-observer.manifest.json +1 -0
- package/dist/browser/native/darwin-supervisor-worker.mjs +1996 -0
- package/dist/browser/native/package-manifest.json +1 -0
- package/dist/browser/source-manifest.json +1 -1
- package/dist/client/assets/{AboutPage-DqTcRYx5.js → AboutPage-CwxCTicf.js} +1 -1
- package/dist/client/assets/ActivityRow-D0QQ0SFu.js +1 -0
- package/dist/client/assets/AdapterIcon-CL-MyyKy.js +1 -0
- package/dist/client/assets/AdapterSetupWizard-C8HOvHLF.js +2 -0
- package/dist/client/assets/AgentRequestCard-BLLmoAES.js +12 -0
- package/dist/client/assets/AppearancePage-GqrWckTQ.js +1 -0
- package/dist/client/assets/AttentionSignalRow-sEhnIPBB.js +1 -0
- package/dist/client/assets/{BaseTanStackRouterDevtoolsPanel-B-iktbLX-Bmlsorom.js → BaseTanStackRouterDevtoolsPanel-B-iktbLX-BXjzhT_D.js} +1 -1
- package/dist/client/assets/{BlintzCanvas-BBW7iNEC.js → BlintzCanvas-CXi0fvcM.js} +1 -1
- package/dist/client/assets/{CanvasCsvContent-D6qWSQm4.js → CanvasCsvContent-QhDSf8Pd.js} +2 -2
- package/dist/client/assets/CanvasFileContent-ZZhdofR4.js +2 -0
- package/dist/client/assets/CanvasModel3dContent-DMMMZh4o.js +2 -0
- package/dist/client/assets/{CodeMirrorDiff-DsOh9sIB.js → CodeMirrorDiff-BMG7DBg2.js} +1 -1
- package/dist/client/assets/{CodeMirrorEditor-BxIWDXqr.js → CodeMirrorEditor-BYdz0ipX.js} +1 -1
- package/dist/client/assets/ConnectionAccessLists-PW1uzcGU.js +1 -0
- package/dist/client/assets/{ConnectionsPage-DvxSfsfG.js → ConnectionsPage-EwitZwOE.js} +3 -3
- package/dist/client/assets/ConventionPage-y-Zq3Klp.js +11 -0
- package/dist/client/assets/ExtensionPageRoute-gZKKPhaj.js +6 -0
- package/dist/client/assets/{FloatingTanStackRouterDevtools-CqogiFob-BCrkUo51.js → FloatingTanStackRouterDevtools-CqogiFob-CbKIa11X.js} +1 -1
- package/dist/client/assets/HandlePage-CL3_n1CI.js +1 -0
- package/dist/client/assets/{LexicalField-mvJHHMqo.js → LexicalField-Ceoa9flp.js} +13 -13
- package/dist/client/assets/{ManagesPage-DScJn5uY.js → ManagesPage-Dcqdm6I8.js} +1 -1
- package/dist/client/assets/Marketplace-DsU-q1ZZ.js +36 -0
- package/dist/client/assets/MarketplaceSourcesView-D72YoKNR.js +1 -0
- package/dist/client/assets/McpAppFrame-B1ThSf2U.js +6 -0
- package/dist/client/assets/McpSigninBody-Btg3PnYN.js +1 -0
- package/dist/client/assets/{Model3dViewer-BYNxJNRV.js → Model3dViewer-DlcQ3-LS.js} +1 -1
- package/dist/client/assets/NamePage-Bzqj4Eob.js +1 -0
- package/dist/client/assets/NewDirectMessageMenu-89yeGqvy.js +1 -0
- package/dist/client/assets/{NotificationsPage-CU6oIOwb.js → NotificationsPage-CQQIdLtI.js} +1 -1
- package/dist/client/assets/OperatorIdentityForm-BhiB9tQp.js +1 -0
- package/dist/client/assets/{PermissionsPage-BIatOhyg.js → PermissionsPage-TX-d7aVQ.js} +1 -1
- package/dist/client/assets/PersonalityPicker-C_9JVOva.js +1 -0
- package/dist/client/assets/PersonalityPopover-BoTED73t.js +1 -0
- package/dist/client/assets/PhotoPage-C3fMlebQ.js +1 -0
- package/dist/client/assets/PreviewRefusedNotice-ChCgdKWN.js +1 -0
- package/dist/client/assets/PromptSuggestionChips-B_oUtFMI.js +1 -0
- package/dist/client/assets/RoomSurface-CgtNuYhl.js +39 -0
- package/dist/client/assets/RoomsPage-zOjjpHdA.js +1 -0
- package/dist/client/assets/RunsOnPopover-JTm1cYuw.js +1 -0
- package/dist/client/assets/SessionsPage-D4kyvHQf.js +6 -0
- package/dist/client/assets/SkillsPage-KYUVzuVa.js +1 -0
- package/dist/client/assets/TasksPage-BZapA_v6.js +1 -0
- package/dist/client/assets/{ToolsPage-BMW27c-X.js → ToolsPage-CWpHMlrR.js} +2 -2
- package/dist/client/assets/{TopologyGraph-u-ihEvQa.js → TopologyGraph-BMcPxZsA.js} +3 -3
- package/dist/client/assets/TourHost-VY1-sy1Y.js +1 -0
- package/dist/client/assets/UnlinkDialog-3p38G_9q.js +1 -0
- package/dist/client/assets/UnreadDivider-KSqqcHKN.js +1 -0
- package/dist/client/assets/_shell-DAjwimLg.js +93 -0
- package/dist/client/assets/_shell._home-Bp_p1VUv.js +1 -0
- package/dist/client/assets/_shell._home.activity-tk-XApvX.js +1 -0
- package/dist/client/assets/_shell._home.index-BNVhSN0y.js +3 -0
- package/dist/client/assets/_shell._home.tasks-BsBH_4tZ.js +1 -0
- package/dist/client/assets/_shell._home.workspaces-DuXnjQh0.js +1 -0
- package/dist/client/assets/_shell.channels-DWAHkDPV.js +10 -0
- package/dist/client/assets/_shell.connections-DIm3mUHy.js +6 -0
- package/dist/client/assets/_shell.feedback-requests-Hjv640j9.js +2 -0
- package/dist/client/assets/_shell.marketplace-DF6Y7mc0.js +1 -0
- package/dist/client/assets/_shell.marketplace_.sources-Do8cm7kq.js +1 -0
- package/dist/client/assets/_shell.session-DlN8iOl-.js +43 -0
- package/dist/client/assets/_shell.team-ctLQztjw.js +28 -0
- package/dist/client/assets/_shell.x._extensionId-0Q1rJtud.js +1 -0
- package/dist/client/assets/_shell.x._extensionId_._-0Q1rJtud.js +1 -0
- package/dist/client/assets/agent-attention-Dn__3LQE.js +5 -0
- package/dist/client/assets/{agent-browser-Bn5EG403.js → agent-browser-CCN16ZOz.js} +1 -1
- package/dist/client/assets/banner-DOm9_4l-.js +6 -0
- package/dist/client/assets/composer-insert-BpyATrmR.js +1 -0
- package/dist/client/assets/dorkbot-templates-cu4wApxb.js +1 -0
- package/dist/client/assets/file-drag-GDx2qhdk.js +1 -0
- package/dist/client/assets/file-exclamation-point-BKzL0QhY.js +6 -0
- package/dist/client/assets/format-duration-BCr6uzby.js +1 -0
- package/dist/client/assets/hand-DLUdsiuR.js +6 -0
- package/dist/client/assets/{highlighted-body-KPVGNVTW-CL9x-9e4.js → highlighted-body-KPVGNVTW-DTxMTVdP.js} +1 -1
- package/dist/client/assets/hover-card-qzuFUCaR.js +1 -0
- package/dist/client/assets/{index-nEOi__50.js → index-3lQkXKcq.js} +1 -1
- package/dist/client/assets/{index-CpJvQdyn.js → index-B-z7hA9x.js} +1 -1
- package/dist/client/assets/{index-C-wQjAlh.js → index-BIMClIrX.js} +1 -1
- package/dist/client/assets/{index-lrzDDn8S.js → index-BMOfHKE0.js} +1 -1
- package/dist/client/assets/{index-CK35WFBO.js → index-BPcwoJoz.js} +1 -1
- package/dist/client/assets/{index-CsQv_9cY.js → index-BW5ce4t8.js} +1 -1
- package/dist/client/assets/{index-C2L0bOg6.js → index-BaB-skF0.js} +3 -3
- package/dist/client/assets/{index-DAXybyxB.js → index-Bk98IpMn.js} +1 -1
- package/dist/client/assets/{index-62aJQhJd.js → index-C3XnoXTY.js} +1 -1
- package/dist/client/assets/{index-tY8nAJmx.js → index-C7B2uRgo.js} +2 -2
- package/dist/client/assets/index-C8ZMfyGc.js +1 -0
- package/dist/client/assets/{index-BSl_jWtK.js → index-CDTumWMC.js} +1 -1
- package/dist/client/assets/{index-DuWGfUC7.js → index-CF9fqPef.js} +5 -5
- package/dist/client/assets/{index-DEYZcwYZ.js → index-CIPHHziB.js} +1 -1
- package/dist/client/assets/{index-DOVEs6Rq.js → index-CIfwPLXd.js} +1 -1
- package/dist/client/assets/{index-DnjFcJhW.js → index-CLhD0Bno.js} +36 -36
- package/dist/client/assets/index-CQWqpw_G.js +1 -0
- package/dist/client/assets/index-CScfHuKF.js +1 -0
- package/dist/client/assets/index-CTXNRyRE.js +1 -0
- package/dist/client/assets/{index-C3fr7zOo.js → index-CTai_TxZ.js} +1 -1
- package/dist/client/assets/{index-CniKYwdp.js → index-CVl132_4.js} +1 -1
- package/dist/client/assets/index-CejezM4U.js +1 -0
- package/dist/client/assets/{index-Bc9XDEj8.js → index-CmlaXay_.js} +1 -1
- package/dist/client/assets/{index-KIOfBCox.js → index-CtOB9fS3.js} +1 -1
- package/dist/client/assets/{index-DyFf2nbN.js → index-D3DXMH4x.js} +1 -1
- package/dist/client/assets/index-D5uYwabS.js +1 -0
- package/dist/client/assets/{index-CaEda4s3.js → index-DA-i3I4q.js} +1 -1
- package/dist/client/assets/index-DFMDv6qR.js +1 -0
- package/dist/client/assets/index-DMYBI16t.js +1252 -0
- package/dist/client/assets/{index-DzBsotRj.js → index-DOxEmnH2.js} +1 -1
- package/dist/client/assets/{index-Dxkj6c9m.js → index-DR1JT9Uz.js} +12 -12
- package/dist/client/assets/{index-BO-CpekL.js → index-DT_v3O-B.js} +1 -1
- package/dist/client/assets/index-DbbZNAKk.js +5 -0
- package/dist/client/assets/{index-BBz-vkiB.js → index-Dcs6e-U_.js} +1 -1
- package/dist/client/assets/{index-BE54c4kA.js → index-DgH_dl1a.js} +2 -2
- package/dist/client/assets/{index-DPGgujWh.js → index-DgtF-nBt.js} +1 -1
- package/dist/client/assets/{index-BlbBz069.js → index-DwzSdOh3.js} +1 -1
- package/dist/client/assets/index-IgIVF9T_.js +1 -0
- package/dist/client/assets/{index-aFkVVlMJ.js → index-WjW-NUCp.js} +1 -1
- package/dist/client/assets/layers-CJHXSEKK.js +6 -0
- package/dist/client/assets/lightbulb-DWjxw7lb.js +6 -0
- package/dist/client/assets/mention-pill-akMU3IVs.js +1 -0
- package/dist/client/assets/message-square-off-DEagHpQY.js +6 -0
- package/dist/client/assets/owner-notice-CLsx0s7q.js +1 -0
- package/dist/client/assets/page-container-W7byjRmk.js +1 -0
- package/dist/client/assets/primer-trigger-DuM9vVnV.js +3 -0
- package/dist/client/assets/radio-B8Ozjv9U.js +6 -0
- package/dist/client/assets/{room-files-source-BXJ2jlgd.js → room-files-source-Bsc3YA91.js} +2 -2
- package/dist/client/assets/rotate-ccw-clock-CNcDcTvq.js +6 -0
- package/dist/client/assets/rotate-cw-xvfipJLN.js +6 -0
- package/dist/client/assets/scroll-area-C95q3ss7.js +1 -0
- package/dist/client/assets/search-x-C6SAxw7a.js +6 -0
- package/dist/client/assets/session-strategy-labels-C7Wduch3.js +1 -0
- package/dist/client/assets/shield-x-DxOGc0dW.js +6 -0
- package/dist/client/assets/{soul-file-11avkxYV.js → soul-file-pg0ShYy3.js} +1 -1
- package/dist/client/assets/untrusted-text-1hXdPgLA.js +1 -0
- package/dist/client/assets/use-delete-binding-CZVeHqn0.js +1 -0
- package/dist/client/assets/use-dev-links-Df2WkCic.js +1 -0
- package/dist/client/assets/use-external-adapter-catalog-B0gcY-k7.js +1 -0
- package/dist/client/assets/use-full-activity-feed-SYcgdMZu.js +1 -0
- package/dist/client/assets/use-is-below-desktop-C5_YenEp.js +1 -0
- package/dist/client/assets/use-jump-back-in-DWUPb1gi.js +11 -0
- package/dist/client/assets/use-mesh-topology-HLzZIgis.js +1 -0
- package/dist/client/assets/use-pending-read-BuJknrxG.js +1 -0
- package/dist/client/assets/{use-personality-commit-PCN2Kh8p.js → use-personality-commit-OH7d0xl_.js} +1 -1
- package/dist/client/assets/use-promo-activation-BgdGasXE.js +11 -0
- package/dist/client/assets/use-pulse-freshness-BlD-dM_g.js +1 -0
- package/dist/client/assets/use-rename-session-D3MuyK-F.js +1 -0
- package/dist/client/assets/use-room-follow-claim-CyjhzbRJ.js +1 -0
- package/dist/client/assets/use-roving-tab-list-Be60AWK3.js +1 -0
- package/dist/client/assets/use-session-canvas-Bqs6IQO7.js +64 -0
- package/dist/client/assets/use-session-diagnostics-CfKdB2iY.js +16 -0
- package/dist/client/assets/use-unclaimed-chats-lqMhotUB.js +1 -0
- package/dist/client/index.html +1 -1
- package/dist/client/manifest.webmanifest +1 -1
- package/dist/drizzle/20261005194144_connector_auth_flow_failure_code.sql +1 -0
- package/dist/drizzle/20261005230915_task_run_occurrence.sql +2 -0
- package/dist/drizzle/20261006231015_audit_events.sql +63 -0
- package/dist/drizzle/20261007230701_private_session_identity.sql +15 -0
- package/dist/drizzle/meta/20261005194144_snapshot.json +12238 -0
- package/dist/drizzle/meta/20261005230915_snapshot.json +12252 -0
- package/dist/drizzle/meta/20261006231015_snapshot.json +12519 -0
- package/dist/drizzle/meta/20261007230701_snapshot.json +12611 -0
- package/dist/drizzle/meta/_journal.json +28 -0
- package/dist/server/index.js +161811 -97213
- package/dist/server/index.js.map +2 -2
- package/package.json +5 -5
- package/dist/client/assets/AdapterIcon-CiK683Vv.js +0 -1
- package/dist/client/assets/AppearancePage-CBq2_KUY.js +0 -1
- package/dist/client/assets/CanvasFileContent-jV63reY5.js +0 -2
- package/dist/client/assets/CanvasModel3dContent-DzvsEWGD.js +0 -2
- package/dist/client/assets/ConnectionAccessLists-BWuegEtZ.js +0 -1
- package/dist/client/assets/ConventionPage-CYV7X_nF.js +0 -11
- package/dist/client/assets/HandlePage-CJpRpaLw.js +0 -1
- package/dist/client/assets/NamePage-KoYyo25o.js +0 -1
- package/dist/client/assets/PersonalityPopover-CFRYfO5E.js +0 -1
- package/dist/client/assets/PhotoPage-DkGyFlWQ.js +0 -1
- package/dist/client/assets/RoomsPage-ClT030eV.js +0 -1
- package/dist/client/assets/RunsOnPopover-CNCO9sZk.js +0 -1
- package/dist/client/assets/SessionsPage-5xEcQImi.js +0 -6
- package/dist/client/assets/SkillsPage-ic4TDV4I.js +0 -1
- package/dist/client/assets/TasksPage-C_GFpRgB.js +0 -1
- package/dist/client/assets/index-6COO_Ljw.js +0 -1
- package/dist/client/assets/index-BKl9b2dT.js +0 -1
- package/dist/client/assets/index-BVtk6Sb_.js +0 -1
- package/dist/client/assets/index-Bxrxl2HH.js +0 -1
- package/dist/client/assets/index-C6uVMs3w.js +0 -1
- package/dist/client/assets/index-DEvFAO8t.js +0 -1
- package/dist/client/assets/index-DpSk7iO1.js +0 -1680
|
Binary file
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
#include "darwin-process-observer.h"
|
|
2
|
+
|
|
3
|
+
#include <errno.h>
|
|
4
|
+
#include <inttypes.h>
|
|
5
|
+
#include <limits.h>
|
|
6
|
+
#include <libproc.h>
|
|
7
|
+
#include <stdio.h>
|
|
8
|
+
#include <stdlib.h>
|
|
9
|
+
#include <string.h>
|
|
10
|
+
#include <sys/proc.h>
|
|
11
|
+
#include <sys/proc_info.h>
|
|
12
|
+
#include <sys/sysctl.h>
|
|
13
|
+
#include <sys/time.h>
|
|
14
|
+
#include <unistd.h>
|
|
15
|
+
|
|
16
|
+
struct pid_list { pid_t *pids; size_t count; };
|
|
17
|
+
|
|
18
|
+
static int compare_pid(const void *a, const void *b) {
|
|
19
|
+
const pid_t left = *(const pid_t *)a, right = *(const pid_t *)b;
|
|
20
|
+
return (left > right) - (left < right);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static int boot_time(struct timeval *value) {
|
|
24
|
+
int mib[] = { CTL_KERN, KERN_BOOTTIME };
|
|
25
|
+
size_t bytes = sizeof(*value);
|
|
26
|
+
memset(value, 0, sizeof(*value)); errno = 0;
|
|
27
|
+
if (sysctl(mib, 2, value, &bytes, NULL, 0) != 0) return errno ? errno : EIO;
|
|
28
|
+
if (bytes != sizeof(*value) || value->tv_sec <= 0 || value->tv_usec < 0 || value->tv_usec >= 1000000)
|
|
29
|
+
return EIO;
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static int list_pids(struct pid_list *list) {
|
|
34
|
+
const size_t capacity = DORKOS_DARWIN_ENUMERATION_MAX;
|
|
35
|
+
const int bytes = (int)(capacity * sizeof(pid_t));
|
|
36
|
+
errno = 0;
|
|
37
|
+
/* Apple XNU's PROC_ALL_PIDS walks both allproc and zombproc. A full
|
|
38
|
+
* buffer may have been truncated and is refused, not treated as complete. */
|
|
39
|
+
const int got = proc_listpids(PROC_ALL_PIDS, 0, list->pids, bytes);
|
|
40
|
+
if (got <= 0) return errno ? errno : EIO;
|
|
41
|
+
if (got >= bytes || got % (int)sizeof(pid_t) != 0) return EOVERFLOW;
|
|
42
|
+
list->count = (size_t)got / sizeof(pid_t);
|
|
43
|
+
qsort(list->pids, list->count, sizeof(pid_t), compare_pid);
|
|
44
|
+
for (size_t i = 0; i < list->count; i++) {
|
|
45
|
+
if (list->pids[i] < 0 || (i && list->pids[i] == list->pids[i - 1])) return EIO;
|
|
46
|
+
}
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static int listed(const struct pid_list *list, pid_t pid) {
|
|
51
|
+
return bsearch(&pid, list->pids, list->count, sizeof(pid_t), compare_pid) != NULL;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static int read_process(pid_t pid, struct proc_bsdinfo *value) {
|
|
55
|
+
memset(value, 0, sizeof(*value)); errno = 0;
|
|
56
|
+
/* arg=1 explicitly includes zombies in PROC_PIDTBSDINFO. arg=0 would
|
|
57
|
+
* make a retained zombie look like ESRCH. Neither error proves absence. */
|
|
58
|
+
const int got = proc_pidinfo(pid, PROC_PIDTBSDINFO, 1, value, (int)sizeof(*value));
|
|
59
|
+
if (got != (int)sizeof(*value)) return errno ? errno : EIO;
|
|
60
|
+
if (value->pbi_pid != (uint32_t)pid || value->pbi_ppid > INT_MAX ||
|
|
61
|
+
!value->pbi_start_tvsec || value->pbi_start_tvusec >= 1000000 ||
|
|
62
|
+
value->pbi_status < SIDL || value->pbi_status > SZOMB) return EIO;
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
int dorkos_darwin_inspect(const pid_t *pids, size_t count, struct dorkos_darwin_batch *batch) {
|
|
67
|
+
if (!pids || !batch || !count || count > DORKOS_DARWIN_REQUEST_MAX) return EINVAL;
|
|
68
|
+
for (size_t i = 0; i < count; i++) {
|
|
69
|
+
if (pids[i] < 1) return EINVAL;
|
|
70
|
+
for (size_t j = 0; j < i; j++) if (pids[i] == pids[j]) return EINVAL;
|
|
71
|
+
}
|
|
72
|
+
memset(batch, 0, sizeof(*batch));
|
|
73
|
+
int absence_eligible[DORKOS_DARWIN_REQUEST_MAX] = { 0 };
|
|
74
|
+
struct timeval before_boot, after_boot;
|
|
75
|
+
int error = boot_time(&before_boot);
|
|
76
|
+
if (error) return error;
|
|
77
|
+
struct pid_list before = { calloc(DORKOS_DARWIN_ENUMERATION_MAX, sizeof(pid_t)), 0 };
|
|
78
|
+
struct pid_list after = { calloc(DORKOS_DARWIN_ENUMERATION_MAX, sizeof(pid_t)), 0 };
|
|
79
|
+
if (!before.pids || !after.pids) { free(before.pids); free(after.pids); return ENOMEM; }
|
|
80
|
+
error = list_pids(&before);
|
|
81
|
+
if (error) goto done;
|
|
82
|
+
batch->count = count;
|
|
83
|
+
for (size_t i = 0; i < count; i++) {
|
|
84
|
+
struct dorkos_darwin_process *fact = &batch->processes[i];
|
|
85
|
+
struct proc_bsdinfo first, second;
|
|
86
|
+
fact->pid = pids[i]; fact->kind = DORKOS_DARWIN_UNKNOWN;
|
|
87
|
+
const int first_error = read_process(pids[i], &first);
|
|
88
|
+
const int second_error = read_process(pids[i], &second);
|
|
89
|
+
absence_eligible[i] = first_error == ESRCH && second_error == ESRCH;
|
|
90
|
+
if (first_error || second_error) { fact->error = first_error ? first_error : second_error; continue; }
|
|
91
|
+
if (first.pbi_start_tvsec != second.pbi_start_tvsec || first.pbi_start_tvusec != second.pbi_start_tvusec ||
|
|
92
|
+
first.pbi_ppid != second.pbi_ppid || (first.pbi_status == SZOMB) != (second.pbi_status == SZOMB)) {
|
|
93
|
+
fact->error = EAGAIN; continue;
|
|
94
|
+
}
|
|
95
|
+
fact->kind = DORKOS_DARWIN_PRESENT;
|
|
96
|
+
fact->seconds = first.pbi_start_tvsec; fact->microseconds = first.pbi_start_tvusec;
|
|
97
|
+
fact->parent_pid = (pid_t)first.pbi_ppid; fact->zombie = first.pbi_status == SZOMB;
|
|
98
|
+
}
|
|
99
|
+
error = list_pids(&after);
|
|
100
|
+
if (error) goto done;
|
|
101
|
+
error = boot_time(&after_boot);
|
|
102
|
+
if (error) goto done;
|
|
103
|
+
if (before_boot.tv_sec != after_boot.tv_sec || before_boot.tv_usec != after_boot.tv_usec) {
|
|
104
|
+
error = EAGAIN; goto done;
|
|
105
|
+
}
|
|
106
|
+
batch->boot_seconds = (uint64_t)before_boot.tv_sec;
|
|
107
|
+
batch->boot_microseconds = (uint64_t)before_boot.tv_usec;
|
|
108
|
+
for (size_t i = 0; i < count; i++) {
|
|
109
|
+
struct dorkos_darwin_process *fact = &batch->processes[i];
|
|
110
|
+
const int seen_before = listed(&before, fact->pid), seen_after = listed(&after, fact->pid);
|
|
111
|
+
if (!seen_before && !seen_after && fact->kind != DORKOS_DARWIN_PRESENT) {
|
|
112
|
+
/* ESRCH alone is not used. Other query errors (e.g. permission denial)
|
|
113
|
+
* remain unknown even when the PID was missing from the sampled lists. */
|
|
114
|
+
if (absence_eligible[i]) { fact->kind = DORKOS_DARWIN_ABSENT; fact->error = 0; }
|
|
115
|
+
} else if (!seen_before || !seen_after) {
|
|
116
|
+
fact->kind = DORKOS_DARWIN_UNKNOWN; fact->error = EAGAIN;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
done:
|
|
120
|
+
free(before.pids); free(after.pids);
|
|
121
|
+
if (error) memset(batch, 0, sizeof(*batch));
|
|
122
|
+
return error;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
static void parent_fact(const struct proc_bsdinfo *value, struct dorkos_darwin_process *fact) {
|
|
126
|
+
fact->pid = (pid_t)value->pbi_pid; fact->kind = DORKOS_DARWIN_PRESENT;
|
|
127
|
+
fact->seconds = value->pbi_start_tvsec; fact->microseconds = value->pbi_start_tvusec;
|
|
128
|
+
fact->parent_pid = (pid_t)value->pbi_ppid; fact->zombie = value->pbi_status == SZOMB;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
static int child_pids(pid_t parent, pid_t *pids, size_t *count) {
|
|
132
|
+
const int capacity = DORKOS_DARWIN_REQUEST_MAX + 2;
|
|
133
|
+
errno = 0;
|
|
134
|
+
/* Use the byte-returning API explicitly. PROC_PPID_ONLY also walks zombies;
|
|
135
|
+
* traced historical-parent matches are later checked against current ppid. */
|
|
136
|
+
const int got = proc_listpids(PROC_PPID_ONLY, (uint32_t)parent, pids, capacity * (int)sizeof(pid_t));
|
|
137
|
+
if (got < 0 || (got == 0 && errno)) return errno ? errno : EIO;
|
|
138
|
+
if (got >= capacity * (int)sizeof(pid_t) || got % (int)sizeof(pid_t)) return EOVERFLOW;
|
|
139
|
+
*count = (size_t)got / sizeof(pid_t);
|
|
140
|
+
qsort(pids, *count, sizeof(pid_t), compare_pid);
|
|
141
|
+
for (size_t i = 0; i < *count; i++)
|
|
142
|
+
if (pids[i] <= 0 || (i && pids[i] == pids[i - 1])) return EIO;
|
|
143
|
+
// This exact helper is the caller's owned observation auxiliary, not a
|
|
144
|
+
// browser descendant. No other PID, command name or lifetime is excluded.
|
|
145
|
+
if (parent == getppid()) {
|
|
146
|
+
for (size_t i = 0; i < *count; i++) if (pids[i] == getpid()) {
|
|
147
|
+
memmove(pids + i, pids + i + 1, (*count - i - 1) * sizeof(pid_t));
|
|
148
|
+
--*count; break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (*count > DORKOS_DARWIN_REQUEST_MAX) return EOVERFLOW;
|
|
152
|
+
return 0;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
int dorkos_darwin_children(pid_t parent, struct dorkos_darwin_children *result) {
|
|
156
|
+
if (parent <= 0 || !result) return EINVAL;
|
|
157
|
+
memset(result, 0, sizeof(*result));
|
|
158
|
+
struct timeval before_boot, after_boot;
|
|
159
|
+
int error = boot_time(&before_boot);
|
|
160
|
+
if (error) return error;
|
|
161
|
+
struct proc_bsdinfo before_parent, after_parent;
|
|
162
|
+
result->have_parent_before = read_process(parent, &before_parent) == 0;
|
|
163
|
+
if (result->have_parent_before) parent_fact(&before_parent, &result->parent_before);
|
|
164
|
+
pid_t before[DORKOS_DARWIN_REQUEST_MAX + 2], after[DORKOS_DARWIN_REQUEST_MAX + 2];
|
|
165
|
+
size_t before_count = 0, after_count = 0;
|
|
166
|
+
const int before_error = child_pids(parent, before, &before_count);
|
|
167
|
+
int complete = result->have_parent_before && !result->parent_before.zombie && !before_error;
|
|
168
|
+
if (!before_error) {
|
|
169
|
+
result->batch.count = before_count;
|
|
170
|
+
for (size_t i = 0; i < before_count; i++) {
|
|
171
|
+
struct dorkos_darwin_process *fact = &result->batch.processes[i];
|
|
172
|
+
struct proc_bsdinfo first, second;
|
|
173
|
+
fact->pid = before[i]; fact->kind = DORKOS_DARWIN_UNKNOWN;
|
|
174
|
+
const int first_error = read_process(before[i], &first), second_error = read_process(before[i], &second);
|
|
175
|
+
if (first_error || second_error) {
|
|
176
|
+
fact->error = first_error ? first_error : second_error; complete = 0; continue;
|
|
177
|
+
}
|
|
178
|
+
if (first.pbi_start_tvsec != second.pbi_start_tvsec || first.pbi_start_tvusec != second.pbi_start_tvusec ||
|
|
179
|
+
first.pbi_ppid != (uint32_t)parent || second.pbi_ppid != (uint32_t)parent ||
|
|
180
|
+
(first.pbi_status == SZOMB) != (second.pbi_status == SZOMB)) {
|
|
181
|
+
fact->error = EAGAIN; complete = 0; continue;
|
|
182
|
+
}
|
|
183
|
+
parent_fact(&second, fact);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const int after_error = child_pids(parent, after, &after_count);
|
|
187
|
+
if (before_error || after_error || before_count != after_count ||
|
|
188
|
+
memcmp(before, after, before_count * sizeof(pid_t))) complete = 0;
|
|
189
|
+
result->have_parent_after = read_process(parent, &after_parent) == 0;
|
|
190
|
+
if (result->have_parent_after) parent_fact(&after_parent, &result->parent_after);
|
|
191
|
+
/* The retained parent may reparent after its manager dies. Its own ppid is
|
|
192
|
+
* not the parent-to-child relationship sampled above; only its lifetime
|
|
193
|
+
* and zombie status must remain valid around enumeration. */
|
|
194
|
+
if (!result->have_parent_before || !result->have_parent_after || result->parent_after.zombie ||
|
|
195
|
+
before_parent.pbi_start_tvsec != after_parent.pbi_start_tvsec ||
|
|
196
|
+
before_parent.pbi_start_tvusec != after_parent.pbi_start_tvusec)
|
|
197
|
+
complete = 0;
|
|
198
|
+
error = boot_time(&after_boot);
|
|
199
|
+
if (error) return error;
|
|
200
|
+
if (before_boot.tv_sec != after_boot.tv_sec || before_boot.tv_usec != after_boot.tv_usec) return EAGAIN;
|
|
201
|
+
result->batch.boot_seconds = (uint64_t)before_boot.tv_sec;
|
|
202
|
+
result->batch.boot_microseconds = (uint64_t)before_boot.tv_usec;
|
|
203
|
+
result->complete = complete;
|
|
204
|
+
return 0;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
#ifndef DORKOS_DARWIN_OBSERVER_NO_MAIN
|
|
208
|
+
static void print_identity(const struct dorkos_darwin_process *fact) {
|
|
209
|
+
printf("{\"pid\":%d,\"seconds\":\"%" PRIu64 "\",\"microseconds\":\"%" PRIu64 "\"}",
|
|
210
|
+
fact->pid, fact->seconds, fact->microseconds);
|
|
211
|
+
}
|
|
212
|
+
int main(int argc, char **argv) {
|
|
213
|
+
if (argc < 3 || argc > DORKOS_DARWIN_REQUEST_MAX + 2 ||
|
|
214
|
+
(strcmp(argv[1], "inspect") && strcmp(argv[1], "children"))) return 2;
|
|
215
|
+
const int children = !strcmp(argv[1], "children");
|
|
216
|
+
if (children && argc != 3) return 2;
|
|
217
|
+
pid_t pids[DORKOS_DARWIN_REQUEST_MAX];
|
|
218
|
+
for (int i = 2; i < argc; i++) {
|
|
219
|
+
if (!argv[i][0]) return 2;
|
|
220
|
+
for (const char *c = argv[i]; *c; c++) if (*c < '0' || *c > '9') return 2;
|
|
221
|
+
char *end; errno = 0; const unsigned long value = strtoul(argv[i], &end, 10);
|
|
222
|
+
if (errno || *end || !value || value > INT_MAX) return 2;
|
|
223
|
+
pids[i - 2] = (pid_t)value;
|
|
224
|
+
}
|
|
225
|
+
struct dorkos_darwin_batch batch;
|
|
226
|
+
struct dorkos_darwin_children result;
|
|
227
|
+
const int error = children ? dorkos_darwin_children(pids[0], &result) : dorkos_darwin_inspect(pids, (size_t)argc - 2, &batch);
|
|
228
|
+
if (error) { fprintf(stderr, "Darwin observation unavailable: %d\n", error); return 1; }
|
|
229
|
+
if (children) batch = result.batch;
|
|
230
|
+
printf("{\"version\":1,\"bootSeconds\":\"%" PRIu64 "\",\"bootMicroseconds\":\"%" PRIu64 "\"",
|
|
231
|
+
batch.boot_seconds, batch.boot_microseconds);
|
|
232
|
+
if (children) {
|
|
233
|
+
printf(",\"parentBefore\":");
|
|
234
|
+
if (result.have_parent_before) print_identity(&result.parent_before); else printf("null");
|
|
235
|
+
printf(",\"parentAfter\":");
|
|
236
|
+
if (result.have_parent_after) print_identity(&result.parent_after); else printf("null");
|
|
237
|
+
printf(",\"complete\":%s", result.complete ? "true" : "false");
|
|
238
|
+
}
|
|
239
|
+
printf(",\"processes\":[");
|
|
240
|
+
for (size_t i = 0; i < batch.count; i++) {
|
|
241
|
+
const struct dorkos_darwin_process *fact = &batch.processes[i];
|
|
242
|
+
if (i) putchar(',');
|
|
243
|
+
if (fact->kind == DORKOS_DARWIN_PRESENT)
|
|
244
|
+
printf("{\"kind\":\"present\",\"identity\":{\"pid\":%d,\"seconds\":\"%" PRIu64 "\",\"microseconds\":\"%" PRIu64
|
|
245
|
+
"\"},\"parentPid\":%d,\"zombie\":%s}", fact->pid, fact->seconds, fact->microseconds, fact->parent_pid, fact->zombie ? "true" : "false");
|
|
246
|
+
else if (fact->kind == DORKOS_DARWIN_ABSENT) printf("{\"kind\":\"absent\",\"pid\":%d}", fact->pid);
|
|
247
|
+
else printf("{\"kind\":\"unknown\",\"pid\":%d,\"error\":%d}", fact->pid, fact->error);
|
|
248
|
+
}
|
|
249
|
+
puts("]}");
|
|
250
|
+
return ferror(stdout) ? 1 : 0;
|
|
251
|
+
}
|
|
252
|
+
#endif
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#ifndef DORKOS_DARWIN_PROCESS_OBSERVER_H
|
|
2
|
+
#define DORKOS_DARWIN_PROCESS_OBSERVER_H
|
|
3
|
+
|
|
4
|
+
#include <stddef.h>
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
#include <sys/types.h>
|
|
7
|
+
|
|
8
|
+
#define DORKOS_DARWIN_REQUEST_MAX 512
|
|
9
|
+
#define DORKOS_DARWIN_ENUMERATION_MAX 16384
|
|
10
|
+
|
|
11
|
+
enum dorkos_darwin_kind { DORKOS_DARWIN_PRESENT, DORKOS_DARWIN_ABSENT, DORKOS_DARWIN_UNKNOWN };
|
|
12
|
+
struct dorkos_darwin_process {
|
|
13
|
+
pid_t pid;
|
|
14
|
+
enum dorkos_darwin_kind kind;
|
|
15
|
+
uint64_t seconds, microseconds;
|
|
16
|
+
pid_t parent_pid;
|
|
17
|
+
int zombie, error;
|
|
18
|
+
};
|
|
19
|
+
struct dorkos_darwin_batch {
|
|
20
|
+
uint64_t boot_seconds, boot_microseconds;
|
|
21
|
+
size_t count;
|
|
22
|
+
struct dorkos_darwin_process processes[DORKOS_DARWIN_REQUEST_MAX];
|
|
23
|
+
};
|
|
24
|
+
struct dorkos_darwin_children {
|
|
25
|
+
struct dorkos_darwin_batch batch;
|
|
26
|
+
struct dorkos_darwin_process parent_before, parent_after;
|
|
27
|
+
int have_parent_before, have_parent_after, complete;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/* Read-only sampled evidence, not an atomic process tree or a signal authority.
|
|
31
|
+
* Absent requires missing from two complete zombie-inclusive enumerations.
|
|
32
|
+
* Query errors, short reads, PID birth changes and enumeration gaps are unknown.
|
|
33
|
+
* Returns an errno value on batch-wide failure; no partial batch is admitted. */
|
|
34
|
+
int dorkos_darwin_inspect(const pid_t *pids, size_t count, struct dorkos_darwin_batch *batch);
|
|
35
|
+
int dorkos_darwin_children(pid_t parent, struct dorkos_darwin_children *result);
|
|
36
|
+
|
|
37
|
+
#endif
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":1,"platform":"darwin","arch":"arm64","availability":"available","reason":null,"sourceDigest":"68246813c3656f2a53ab9344773f07659b4325c033a3d4b8863ea2bea99884b7","sources":[{"name":"darwin-process-observer.c","sha256":"ee928cb7bf4df694ea78bdc1a1e9b17cccdd24089a44fde3ce005474655f5999","bytes":12250},{"name":"darwin-process-observer.h","sha256":"e0b6c2ffb09a78291a894f6278a6c3f99771d204ce60ea84c233324946d0eaee","bytes":1333}],"binary":{"name":"darwin-process-observer","sha256":"ef8a563d0c507a7ed9907a4eb24e850f2707d8909b90b3a4a1e770bb14ac6e99","bytes":35064}}
|