// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #pragma once #include "pal_compiler.h" #include "pal_types.h" #include #include /** * Used by System.Diagnostics.Process.Start to fork/exec a new process. * * This function takes the place of directly using fork and execve from managed code, * in order to avoid executing managed code in the child process in the window between * fork and execve, which is not safe. * * As would have been the case with fork/execve, a return value of 0 is success and -1 * is failure; if failure, error information is provided in errno. */ PALEXPORT int32_t SystemNative_ForkAndExecProcess( const char* filename, // filename argument to execve char* const argv[], // argv argument to execve char* const envp[], // envp argument to execve const char* cwd, // path passed to chdir in child process int32_t redirectStdin, // whether to redirect standard input from the parent int32_t redirectStdout, // whether to redirect standard output to the parent int32_t redirectStderr, // whether to redirect standard error to the parent int32_t setCredentials, // whether to set the userId and groupId for the child process uint32_t userId, // the user id under which the child process should run uint32_t groupId, // the group id under which the child process should run uint32_t* groups, // the groups under which the child process should run int32_t groupsLength, // the length of groups int32_t* childPid, // [out] the child process' id int32_t* stdinFd, // [out] if redirectStdin, the parent's fd for the child's stdin int32_t* stdoutFd, // [out] if redirectStdout, the parent's fd for the child's stdout int32_t* stderrFd); // [out] if redirectStderr, the parent's fd for the child's stderr /************ * The values below in the header are fixed and correct for managed callers to use forever. * We must never change them. The implementation must either static_assert that they are equal * to the native equivalent OR convert them appropriately. */ /** * These values differ from OS to OS, so make a constant contract. * These values apply for the current process only */ typedef enum { PAL_RLIMIT_CPU = 0, // CPU limit in seconds PAL_RLIMIT_FSIZE = 1, // Largest file that can be created, in bytes PAL_RLIMIT_DATA = 2, // Maximum size of data segment, in bytes PAL_RLIMIT_STACK = 3, // Maximum size of stack segment, in bytes PAL_RLIMIT_CORE = 4, // Largest core file that can be created, in bytes PAL_RLIMIT_AS = 5, // Address space limit PAL_RLIMIT_RSS = 6, // Largest resident set size, in bytes PAL_RLIMIT_MEMLOCK = 7, // Locked-in-memory address space PAL_RLIMIT_NPROC = 8, // Number of processes PAL_RLIMIT_NOFILE = 9, // Number of open files } RLimitResources; typedef enum { PAL_NONE = 0, PAL_SIGKILL = 9, /* kill the specified process */ PAL_SIGSTOP = 19, } Signals; /** * Constants for passing to the first parameter of syslog. * These are a combination of flags where the lower bits are * the priority and the higher bits are the facility. The lower * bits cannot be OR'd together; they must be OR'd with the higer bits. * * These values keep their original definition and are taken from syslog.h */ typedef enum { // Priorities PAL_LOG_EMERG = 0, /* system is unusable */ PAL_LOG_ALERT = 1, /* action must be taken immediately */ PAL_LOG_CRIT = 2, /* critical conditions */ PAL_LOG_ERR = 3, /* error conditions */ PAL_LOG_WARNING = 4, /* warning conditions */ PAL_LOG_NOTICE = 5, /* normal but significant condition */ PAL_LOG_INFO = 6, /* informational */ PAL_LOG_DEBUG = 7, /* debug-level messages */ } SysLogPriority; /** * Constants to pass into pathconf. * * Note - these differ per OS so these values are the PAL-specific * values; they must be converted to the correct platform * values before passing to pathconf. */ typedef enum { PAL_PC_LINK_MAX = 1, PAL_PC_MAX_CANON = 2, PAL_PC_MAX_INPUT = 3, PAL_PC_NAME_MAX = 4, PAL_PC_PATH_MAX = 5, PAL_PC_PIPE_BUF = 6, PAL_PC_CHOWN_RESTRICTED = 7, PAL_PC_NO_TRUNC = 8, PAL_PC_VDISABLE = 9, } PathConfName; /** * Constants for passing to GetPriority and SetPriority. */ typedef enum { PAL_PRIO_PROCESS = 0, PAL_PRIO_PGRP = 1, PAL_PRIO_USER = 2, } PriorityWhich; /** * The current and maximum resource values for the current process. * These values are depict the resource according to the above enum. */ typedef struct { uint64_t CurrentLimit; uint64_t MaximumLimit; } RLimit; /** * The native struct is dependent on the size of a numeric type * so make it the largest possible value here and then we will * copy to native as necessary */ typedef struct { uint64_t Bits[16]; // __CPU_SETSIZE / (8 * sizeof(int64_t)) } CpuSetBits; /** * Get the current limit for the specified resource of the current process. * Returns 0 on success; returns -1 on failure and errno is set to the error reason. */ PALEXPORT int32_t SystemNative_GetRLimit(RLimitResources resourceType, RLimit* limits); /** * Set the soft and hard limits for the specified resource. * Only a super-user can increase hard limits for the current process. * Returns 0 on success; returns -1 on failure and errno is set to the error reason. */ PALEXPORT int32_t SystemNative_SetRLimit(RLimitResources resourceType, const RLimit* limits); /** * Kill the specified process (or process group) identified by the supplied pid; the * process or process group will be killed by the specified signal. * Returns 0 on success; on failure, -1 is returned and errno is set */ PALEXPORT int32_t SystemNative_Kill(int32_t pid, int32_t signal); /** * Returns the Process ID of the current executing process. * This call should never fail */ PALEXPORT int32_t SystemNative_GetPid(void); /** * Returns the sessions ID of the specified process; if 0 is passed in, returns the * session ID of the current process. * Returns a session ID on success; otherwise, returns -1 and sets errno. */ PALEXPORT int32_t SystemNative_GetSid(int32_t pid); /** * Write a message to the system logger, which in turn writes the message to the system console, log files, etc. * See man 3 syslog for more info */ PALEXPORT void SystemNative_SysLog(SysLogPriority priority, const char* message, const char* arg1); /** * Returns the pid of a terminated child without reaping it. * * 1) returns the process id of a terminated child process * 2) if no children are terminated, 0 is returned * 3) on error, -1 is returned */ PALEXPORT int32_t SystemNative_WaitIdAnyExitedNoHangNoWait(void); /** * Reaps a terminated child. * * 1) when a child is reaped, its process id is returned * 2) if pid is not a child or there are no unwaited-for children, -1 is returned (errno=ECHILD) * 3) if the child has not yet terminated, 0 is returned * 4) on error, -1 is returned. */ PALEXPORT int32_t SystemNative_WaitPidExitedNoHang(int32_t pid, int32_t* exitCode); /** * Gets the configurable limit or variable for system path or file descriptor options. * * Returns the requested variable value on success; if the variable does not have a limit, -1 is returned and errno * is not set; otherwise, -1 is returned and errno is set. */ PALEXPORT int64_t SystemNative_PathConf(const char* path, PathConfName name); /** * Gets the priority (nice value) of a certain execution group. * * Returns the nice value (from -20 to 20) of the group on success; otherwise, returns -1. Unfortunately, -1 is also a * valid nice value, meaning we can't use that value to determine valid output or not. Errno is set on failure so * we need to reset errno before a call and check the value if we get -1. */ PALEXPORT int32_t SystemNative_GetPriority(PriorityWhich which, int32_t who); /** * Sets the priority (nice value) of a certain execution group. * * Returns 0 on success; otherwise, -1 and errno is set. */ PALEXPORT int32_t SystemNative_SetPriority(PriorityWhich which, int32_t who, int32_t nice); /** * Gets the current working directory of the currently executing process. */ PALEXPORT char* SystemNative_GetCwd(char* buffer, int32_t bufferSize); /** * Sets the CPU affinity mask for a specified thread (or the current thread if 0). * * Returns 0 on success; otherwise, -1 is returned and errno is set */ PALEXPORT int32_t SystemNative_SchedSetAffinity(int32_t pid, intptr_t* mask); /** * Gets the affinity mask of the specified thread (or the current thread if 0). * * Returns 0 on success; otherwise, -1 is returned and errno is set. */ PALEXPORT int32_t SystemNative_SchedGetAffinity(int32_t pid, intptr_t* mask); /** * Returns the path of the executable that started the currently executing process, * resolving symbolic links. The caller is responsible for releasing the buffer. */ PALEXPORT char* SystemNative_GetProcessPath(void);