Files

319 lines
12 KiB
C

// Native POSIX personality-server discovery, process identity, and shared-attribute protocol.
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <ntlite/status.h>
#include <ntlite/syscall.h>
#include <ntlite/posix_signal.h>
#define NTL_POSIX_SERVICE_PATH "/Services/posix"
#define NTL_POSIX_PROTOCOL_VERSION 15u
#define NTL_POSIX_REQUEST_FLAG_NONE 0u
#define NTL_POSIX_OP_QUERY 1u
#define NTL_POSIX_OP_BEGIN_TRANSACTION 2u
#define NTL_POSIX_OP_CANCEL_TRANSACTION 3u
#define NTL_POSIX_OP_REGISTER_PROCESS 4u
#define NTL_POSIX_OP_GET_PROCESS_ATTRIBUTES 5u
#define NTL_POSIX_OP_SET_CURRENT_DIRECTORY 6u
#define NTL_POSIX_OP_SET_UID 7u
#define NTL_POSIX_OP_SET_GID 8u
#define NTL_POSIX_OP_SET_PROCESS_GROUP 9u
#define NTL_POSIX_OP_CREATE_SESSION 10u
#define NTL_POSIX_OP_LOOKUP_USER 11u
#define NTL_POSIX_OP_LOOKUP_GROUP 12u
#define NTL_POSIX_OP_CREATE_OPEN_DESCRIPTION 13u
#define NTL_POSIX_OP_RELEASE_OPEN_DESCRIPTION 14u
#define NTL_POSIX_OP_SET_OPEN_STATUS 15u
#define NTL_POSIX_OP_CREATE_PIPE 16u
#define NTL_POSIX_OP_CREATE_FD_INHERITANCE 17u
#define NTL_POSIX_OP_IMPORT_FD_INHERITANCE 18u
#define NTL_POSIX_OP_CANCEL_FD_INHERITANCE 19u
#define NTL_POSIX_OP_CONSTRUCT_SET_EXECUTABLE 20u
#define NTL_POSIX_OP_CONSTRUCT_WRITE_VECTOR 21u
#define NTL_POSIX_OP_SPAWN_ADD_FILE_ACTION 22u
#define NTL_POSIX_OP_SPAWN_SET_ATTRIBUTES 23u
#define NTL_POSIX_OP_SPAWN_COMMIT 24u
#define NTL_POSIX_OP_BOOTSTRAP_READY 25u
#define NTL_POSIX_OP_WAIT_PROCESS 26u
#define NTL_POSIX_OP_REGISTER_THREAD 27u
#define NTL_POSIX_OP_UNREGISTER_THREAD 28u
#define NTL_POSIX_OP_UPDATE_SIGNAL_MASK 29u
#define NTL_POSIX_OP_SET_SIGNAL_DISPOSITION 30u
#define NTL_POSIX_OP_GET_PENDING_SIGNALS 31u
#define NTL_POSIX_OP_SEND_SIGNAL 32u
#define NTL_POSIX_OP_SET_ALARM 33u
#define NTL_POSIX_OP_EXEC_COMMIT 34u
#define NTL_POSIX_OP_VFORK_BEGIN 35u
#define NTL_POSIX_OP_VFORK_ATTACH 36u
#define NTL_POSIX_OP_VFORK_CANCEL 37u
#define NTL_POSIX_OP_VFORK_EXIT 38u
#define NTL_POSIX_TRANSACTION_NONE 0u
#define NTL_POSIX_TRANSACTION_SPAWN 1u
#define NTL_POSIX_TRANSACTION_EXEC 2u
#define NTL_POSIX_PROCESS_STATE_NONE 0u
#define NTL_POSIX_PROCESS_STATE_CONSTRUCTING 1u
#define NTL_POSIX_PROCESS_STATE_RUNNING 2u
#define NTL_POSIX_PROCESS_STATE_EXEC_PREPARING 3u
#define NTL_POSIX_PROCESS_STATE_EXEC_COMMITTING 4u
#define NTL_POSIX_PROCESS_STATE_EXITED 5u
#define NTL_POSIX_PROCESS_STATE_VFORK_BORROWED 6u
#define NTL_POSIX_LOOKUP_NONE 0u
#define NTL_POSIX_LOOKUP_BY_ID 1u
#define NTL_POSIX_LOOKUP_BY_NAME 2u
#define NTL_POSIX_TRANSACTION_CAPACITY 8u
#define NTL_POSIX_SUPPLEMENTARY_GROUP_MAX 16u
#define NTL_POSIX_IDENTITY_NAME_MAX 63u
#define NTL_POSIX_IDENTITY_HOME_MAX 255u
#define NTL_POSIX_IDENTITY_SHELL_MAX 255u
// POSIX open-description kinds shared between posix.dll and posixsrv.
#define NTL_POSIX_OPEN_TYPE_FILE 1u
#define NTL_POSIX_OPEN_TYPE_CONSOLE_READ 2u
#define NTL_POSIX_OPEN_TYPE_CONSOLE_WRITE 3u
#define NTL_POSIX_OPEN_TYPE_DEV_NULL 4u
#define NTL_POSIX_OPEN_TYPE_DEV_ZERO 5u
#define NTL_POSIX_OPEN_TYPE_SOCKET 6u
#define NTL_POSIX_OPEN_TYPE_PIPE_READ 7u
#define NTL_POSIX_OPEN_TYPE_PIPE_WRITE 8u
// Values intentionally match the public POSIX fcntl ABI; posixsrv owns policy but
// does not include personality headers.
#define NTL_POSIX_OPEN_STATUS_RDONLY 0x0000u
#define NTL_POSIX_OPEN_STATUS_WRONLY 0x0001u
#define NTL_POSIX_OPEN_STATUS_RDWR 0x0002u
#define NTL_POSIX_OPEN_STATUS_ACCMODE 0x0003u
#define NTL_POSIX_OPEN_STATUS_APPEND 0x0400u
#define NTL_POSIX_OPEN_STATUS_NONBLOCK 0x0800u
#define NTL_POSIX_OPEN_CREATE 0x0040u
#define NTL_POSIX_OPEN_TRUNCATE 0x0200u
#define NTL_POSIX_OPEN_STATUS_VALID_MASK \
(NTL_POSIX_OPEN_STATUS_ACCMODE | NTL_POSIX_OPEN_STATUS_APPEND | NTL_POSIX_OPEN_STATUS_NONBLOCK)
#define NTL_POSIX_SPAWN_OPEN_VALID_MASK \
(NTL_POSIX_OPEN_STATUS_VALID_MASK | NTL_POSIX_OPEN_CREATE | NTL_POSIX_OPEN_TRUNCATE)
#define NTL_POSIX_SHARED_OPEN_MAGIC 0x31444F50u
#define NTL_POSIX_SHARED_OPEN_VERSION 2u
#define NTL_POSIX_FD_INHERIT_MAX 64u
#define NTL_POSIX_FD_IMPORT_BATCH_MAX SYS_PORT_MAX_TRANSFER_HANDLES
#define NTL_POSIX_FD_INHERIT_FLAG_NONE 0u
#define NTL_POSIX_FD_DESCRIPTOR_CLOEXEC 0x00000001u
#define NTL_POSIX_FD_HANDLE_NONE UINT32_MAX
#define NTL_POSIX_CONSTRUCT_VECTOR_ARGUMENT 1u
#define NTL_POSIX_CONSTRUCT_VECTOR_ENVIRONMENT 2u
#define NTL_POSIX_CONSTRUCT_VECTOR_CHUNK_FINAL 0x00000001u
#define NTL_POSIX_CONSTRUCT_VECTOR_MAX 1024u
#define NTL_POSIX_CONSTRUCT_DATA_MAX (1024u * 1024u)
#define NTL_POSIX_SPAWN_ACTION_CLOSE 1u
#define NTL_POSIX_SPAWN_ACTION_DUP2 2u
#define NTL_POSIX_SPAWN_ACTION_OPEN 3u
#define NTL_POSIX_SPAWN_ACTION_MAX 64u
#define NTL_POSIX_SPAWN_ATTR_SETPGROUP 0x00000001u
#define NTL_POSIX_SPAWN_ATTR_SETSIGMASK 0x00000002u
#define NTL_POSIX_SPAWN_ATTR_SETSIGDEF 0x00000004u
#define NTL_POSIX_WAIT_NOHANG 0x00000001u
#define NTL_POSIX_SIGNAL_DISPOSITION_DEFAULT 0u
#define NTL_POSIX_SIGNAL_DISPOSITION_IGNORE 1u
#define NTL_POSIX_SIGNAL_DISPOSITION_CAUGHT 2u
#define NTL_POSIX_SIGNAL_ROUTE_PROCESS 1u
#define NTL_POSIX_SIGNAL_ROUTE_THREAD 2u
typedef struct NTL_POSIX_FD_MANIFEST_ENTRY {
int32_t Descriptor;
uint32_t DescriptorFlags;
uint64_t OpenDescriptionId;
} NTL_POSIX_FD_MANIFEST_ENTRY;
typedef struct NTL_POSIX_FD_DESCRIPTION_ENTRY {
uint64_t OpenDescriptionId;
uint64_t SharedOpenDescription;
uint32_t OpenDescriptionType;
uint32_t OpenStatusFlags;
uint32_t HandleIndex;
uint32_t Reserved;
} NTL_POSIX_FD_DESCRIPTION_ENTRY;
// Hot open-description state lives in posixsrv-owned userspace memory. In the
// single-address-space model clients use this pointer directly; lifetime remains
// authoritative in posixsrv rather than in writable shared fields.
typedef struct NTL_POSIX_SHARED_OPEN_DESCRIPTION {
uint32_t Magic;
uint32_t Version;
uint32_t Type;
uint32_t Reserved;
uint64_t DescriptionId;
volatile uint32_t StatusFlags;
uint32_t Reserved2;
// Optional server-owned userspace data-plane pointer. Pipe endpoint
// descriptions use this for SYS_PIPE_SHARED_STATE; other types leave it zero.
uint64_t SharedObjectData;
} NTL_POSIX_SHARED_OPEN_DESCRIPTION;
_Static_assert(offsetof(NTL_POSIX_SHARED_OPEN_DESCRIPTION, StatusFlags) == 24u,
"NTL_POSIX_SHARED_OPEN_DESCRIPTION status layout changed");
_Static_assert(offsetof(NTL_POSIX_SHARED_OPEN_DESCRIPTION, SharedObjectData) == 32u,
"NTL_POSIX_SHARED_OPEN_DESCRIPTION data layout changed");
_Static_assert(sizeof(NTL_POSIX_SHARED_OPEN_DESCRIPTION) == 40u,
"NTL_POSIX_SHARED_OPEN_DESCRIPTION ABI size changed");
// Server-owned spawn/exec builders place this opaque personality payload
// in the generic userspace process-loader startup data. Zero token/PID/generation
// means an ordinary process is self-registering for the first time.
#define NTL_POSIX_BOOTSTRAP_MAGIC 0x3258504Eu
#define NTL_POSIX_BOOTSTRAP_VERSION 3u
typedef struct NTL_POSIX_BOOTSTRAP_DATA {
uint32_t Magic;
uint32_t Version;
uint32_t Size;
uint32_t Reserved;
uint64_t Token;
uint32_t PosixPid;
uint32_t Generation;
uint64_t FdInheritanceToken;
uint64_t InitialSignalMask;
uint64_t IgnoredSignals;
} NTL_POSIX_BOOTSTRAP_DATA;
// Requests remain fixed-size through P4 open-description control. Later spawn/exec
// transactions may layer bounded multi-message payloads over this header.
typedef struct NTL_POSIX_REQUEST {
uint32_t Size;
uint32_t Version;
uint32_t Operation;
uint32_t Flags;
uint32_t TransactionId;
uint32_t TransactionKind;
uint64_t BootstrapToken;
uint32_t BootstrapPosixPid;
uint32_t BootstrapGeneration;
uint32_t TargetPosixPid;
uint32_t UserId;
uint32_t GroupId;
uint32_t ProcessGroupId;
uint32_t LookupKind;
uint32_t OpenDescriptionType;
uint32_t OpenStatusFlags;
uint64_t OpenDescriptionId;
uint32_t NameLength;
uint32_t PathLength;
uint64_t FdInheritanceToken;
uint32_t FdInheritanceIndex;
uint32_t FdInheritanceCount;
uint32_t FdInheritanceFlags;
uint32_t ConstructionVectorKind;
uint32_t ConstructionVectorIndex;
uint32_t ConstructionVectorOffset;
uint32_t ConstructionVectorFlags;
uint32_t SpawnActionKind;
int32_t SpawnFileDescriptor;
int32_t SpawnNewFileDescriptor;
uint32_t SpawnOpenFlags;
uint32_t SpawnOpenMode;
uint32_t SpawnAttributeFlags;
uint64_t SpawnSignalMask;
uint64_t SpawnSignalDefaultMask;
int32_t WaitPid;
uint32_t WaitOptions;
int32_t SignalTargetPid;
int32_t SignalNumber;
uint32_t SignalDisposition;
uint32_t SignalReserved;
uint64_t SignalMask;
uint64_t SignalApcRoutine;
uint32_t AlarmSeconds;
uint32_t AlarmReserved;
uint64_t VforkToken;
int32_t VforkExitCode;
uint32_t VforkReserved;
NTL_POSIX_FD_MANIFEST_ENTRY FdManifest[NTL_POSIX_FD_INHERIT_MAX];
char Name[NTL_POSIX_IDENTITY_NAME_MAX + 1u];
char Path[SYS_PATH_MAX + 1u];
} NTL_POSIX_REQUEST;
// Replies expose stable POSIX identity and the server-owned shared process
// attributes. Lookup operations reuse the identity strings and ID fields.
typedef struct NTL_POSIX_REPLY {
uint32_t Size;
uint32_t Version;
uint32_t Operation;
uint32_t Flags;
KSTATUS Status;
uint32_t TransactionId;
uint32_t ClientProcessId;
uint32_t ClientSecurityId;
uint32_t ActiveTransactions;
uint32_t TransactionCapacity;
uint32_t PosixPid;
uint32_t SpawnedPosixPid;
int32_t WaitedPosixPid;
int32_t ExitCode;
uint32_t NativeGeneration;
uint32_t ProcessState;
uint32_t RegisteredProcesses;
uint32_t RegisteredOpenDescriptions;
uint32_t RegisteredThreads;
uint32_t SignalReserved;
uint64_t PendingSignals;
uint32_t AlarmRemainingSeconds;
uint32_t AlarmReserved;
uint64_t VforkToken;
uint32_t OpenDescriptionType;
uint32_t OpenStatusFlags;
uint64_t OpenDescriptionId;
uint64_t SharedOpenDescription;
uint32_t OpenDescriptionType2;
uint32_t OpenStatusFlags2;
uint64_t OpenDescriptionId2;
uint64_t SharedOpenDescription2;
uint64_t FdInheritanceToken;
uint32_t FdInheritanceIndex;
uint32_t FdInheritanceCount;
uint32_t FdDescriptionIndex;
uint32_t FdDescriptionCount;
uint32_t FdDescriptionTotal;
NTL_POSIX_FD_MANIFEST_ENTRY FdManifest[NTL_POSIX_FD_INHERIT_MAX];
NTL_POSIX_FD_DESCRIPTION_ENTRY FdDescriptions[NTL_POSIX_FD_IMPORT_BATCH_MAX];
uint32_t ParentPosixPid;
uint32_t UserId;
uint32_t EffectiveUserId;
uint32_t GroupId;
uint32_t EffectiveGroupId;
uint32_t ProcessGroupId;
uint32_t SessionId;
uint32_t SupplementaryGroupCount;
uint32_t SupplementaryGroups[NTL_POSIX_SUPPLEMENTARY_GROUP_MAX];
uint32_t NameLength;
uint32_t HomeLength;
uint32_t ShellLength;
uint32_t CurrentDirectoryLength;
char Name[NTL_POSIX_IDENTITY_NAME_MAX + 1u];
char Home[NTL_POSIX_IDENTITY_HOME_MAX + 1u];
char Shell[NTL_POSIX_IDENTITY_SHELL_MAX + 1u];
char CurrentDirectory[SYS_PATH_MAX + 1u];
} NTL_POSIX_REPLY;
_Static_assert(sizeof(NTL_POSIX_REQUEST) <= SYS_PORT_MAX_INLINE_BYTES,
"POSIX request must fit in one Port inline payload.");
_Static_assert(sizeof(NTL_POSIX_REPLY) <= SYS_PORT_MAX_INLINE_BYTES,
"POSIX reply must fit in one Port inline payload.");