1 // Copyright (c) 1999-2018 David Muse 2 // See the COPYING file for more information. 3 4 #ifndef RUDIMENTS_PROCESS_H 5 #define RUDIMENTS_PROCESS_H 6 7 #include <rudiments/private/processincludes.h> 8 9 enum childstatechange { 10 EXIT_CHILDSTATECHANGE=0, 11 TERMINATED_CHILDSTATECHANGE, 12 STOPPED_CHILDSTATECHANGE, 13 CONTINUED_CHILDSTATECHANGE 14 }; 15 16 /** The process class provides static methods for accessing information about 17 * and controlling processes, including methods for forking, spawning and 18 * executing child processes. */ 19 class RUDIMENTS_DLLSPEC process { 20 public: 21 22 /** Returns the process id of the current process. */ 23 static pid_t getProcessId(); 24 25 /** Returns the process id of the parent process 26 * of the current process. */ 27 static pid_t getParentProcessId(); 28 29 /** Returns the process group id of the 30 * current process. */ 31 static pid_t getProcessGroupId(); 32 33 /** Returns the process group id of the 34 * process pid. */ 35 static pid_t getProcessGroupId(pid_t pid); 36 37 /** Sets the process group id of the current 38 * process to the current process id. */ 39 static bool setProcessGroupId(); 40 41 /** Sets the process group id of the current process to pgid. */ 42 static bool setProcessGroupId(pid_t pgid); 43 44 /** Sets the process group id of the process pid to pgid. */ 45 static bool setProcessGroupId(pid_t pid, pid_t pgid); 46 47 /** Returns the session id of the current process. */ 48 static pid_t getSessionId(); 49 50 /** Returns the session id of the process pid. */ 51 static pid_t getSessionId(pid_t pid); 52 53 /** Creates a new session, sets the calling process to be the 54 * process group leader and detaches from the controlling 55 * terminal. Returns the session id on success or -1 if an 56 * error occurred. */ 57 static pid_t newSession(); 58 59 /** Returns the real user id of the current process. */ 60 static uid_t getUserId(); 61 62 /** Returns the effective user id of the current process. */ 63 static uid_t getEffectiveUserId(); 64 65 /** Sets the effective user id of the current process to uid. 66 * If the effective user id is root, the real and saved user 67 * ids are also set. 68 * 69 * Returns true on success and false on failure. */ 70 static bool setUserId(uid_t uid); 71 72 /** Sets the effective user id of the current process to the 73 * user id of "username". If the effective user id is root, 74 * the real and saved user ids are also set. 75 * 76 * Returns true on success and false on failure. */ 77 static bool setUser(const char *username); 78 79 /** Sets the effective user id of the current process to uid. 80 * Does not set the real or saved user ids. 81 * 82 * Returns true on success and false on failure. */ 83 static bool setEffectiveUserId(uid_t uid); 84 85 /** Sets the effective user id of the current process to the 86 * user id of "username". Does not set the real or saved 87 * user ids. 88 * 89 * Returns true on success and false on failure. */ 90 static bool setEffectiveUser(const char *username); 91 92 /** Sets the real user id of the current process to uid and the 93 * effective user id of the current process to euid. If the 94 * real user id is set or the effective user id is set to a 95 * value not equal to the previous real user id, the saved 96 * user id is set to the new effective user id. 97 * 98 * Returns true on success and false on failure. */ 99 static bool setRealAndEffectiveUserId(uid_t uid, 100 uid_t euid); 101 102 /** Returns the real group id of the current process. */ 103 static gid_t getGroupId(); 104 105 /** Returns the effective group id of the current process. */ 106 static gid_t getEffectiveGroupId(); 107 108 /** Sets the effective group id of the current process to gid. 109 * If the effective group id is root, the real and saved group 110 * ids are also set. 111 * 112 * Returns true on success and false on failure. */ 113 static bool setGroupId(gid_t gid); 114 115 /** Sets the effective group id of the current process to the 116 * group id of "groupname". If the effective group id is root, 117 * the real and saved group ids are also set. 118 * 119 * Returns true on success and false on failure. */ 120 static bool setGroup(const char *groupname); 121 122 /** Sets the effective group id of the current process to gid. 123 * Does not set the real or saved group ids. 124 * 125 * Returns true on success and false on failure. */ 126 static bool setEffectiveGroupId(gid_t gid); 127 128 /** Sets the effective group id of the current process to the 129 * group id of "groupname". Does not set the real or saved 130 * group ids. 131 * 132 * Returns true on success and false on failure. */ 133 static bool setEffectiveGroup(const char *groupname); 134 135 /** Sets the real group id of the current process to gid and 136 * the effective group id of the current process to egid. If 137 * the real group id is set or the effective group id is set 138 * to a value not equal to the previous real group id, the 139 * saved group id is set to the new effective group id. 140 * 141 * Returns true on success and false on failure. */ 142 static bool setRealAndEffectiveGroupId(gid_t gid, 143 gid_t egid); 144 145 /** Set file/directory creation mode mask to "mask". Returns 146 * the mask that was previously in effect. */ 147 static mode_t setFileCreationMask(mode_t mask); 148 149 /** Creates a child process. The child is a duplicate of the 150 * parent inheriting file descriptors and a copy of the 151 * parent's address space. The child does not have access to 152 * the parent's address space. In the parent process, the 153 * process id of the child is returned. In the child process, 154 * 0 is returned. -1 is returned if an error occurred and no 155 * child is forked. */ 156 static pid_t fork(); 157 158 /** Returns true of this platform supports fork() and false 159 * otherwise. */ 160 static bool supportsFork(); 161 162 /** Runs "command" with arguments "args", replacing the current 163 * running process with this new process. Whether the new 164 * process retains the process id of the current process is 165 * platform-specific. Note that the first element of array 166 * "args" should be the name of the command that you want to 167 * run, typically the same as "command". "args" should be NULL 168 * terminated. Returns false if an error occurred and 169 * otherwise does not return at all. */ 170 static bool exec(const char *command, 171 const char * const *args); 172 173 /** Runs "command" with arguments "args" as a new process. 174 * If "detached" is true then the process is started in 175 * the background. 176 * Use this instead of a combinination of fork() and exec() 177 * as it is more efficient on some platforms. 178 * Note that the first element of array "args" should be the 179 * name of the command that you want to run, typically the 180 * same as "command". "args" should be NULL terminated. 181 * Returns the process id of the child process or -1 if an 182 * error occurred. */ 183 static pid_t spawn(const char *command, 184 const char * const *args, 185 bool detached); 186 187 /** Detaches the current process from the controlling tty, 188 * creates a new session, changes directory to / and sets the 189 * file creation mask to 0. Use this method to "fork your 190 * process into the background." Returns true on success and 191 * false on failure. */ 192 static bool detach(); 193 194 /** Terminates the calling process and sets the exit status to 195 * "status". */ 196 static void exit(int32_t status); 197 198 /** Terminates the calling process "immediately" (without 199 * calling any functions registered to run at exit) and sets 200 * the exit status to "status". */ 201 static void exitImmediately(int32_t status); 202 203 /** Send signal "signum" to process "processid". 204 * Returns true on success and false on failure. */ 205 static bool sendSignal(pid_t processid, int32_t signum); 206 207 /** Send signal "signum" to self. 208 * Returns true on success and false on failure. */ 209 static bool raiseSignal(int32_t signum); 210 211 /** Registers "function" to be called when the process 212 * exits normally. Returns true on success and false on 213 * failure. */ 214 static bool atExit(void (*function)(void)); 215 216 /** Calls exitOnShutDown(), exitOnCrash() and 217 * waitForChildren() below. */ 218 static void exitOnCrashOrShutDown(); 219 220 /** Checks for filename "filename" and reads the 221 * process id out of it, if it exists. Returns 222 * the process id on success or -1 on failure. */ 223 static int64_t checkForPidFile(const char *filename); 224 225 /** Create's file "filename" with permissions 226 * "permissions" and puts the current process 227 * id in it. Note that when you delete this 228 * file during shutdown you must use the full 229 * pathname since the process::detach() method 230 * changes directories to "/". Returns true on 231 * success and false on failure. */ 232 static bool createPidFile(const char *filename, 233 mode_t permissions); 234 235 /** Sets up a default handler that exits cleanly when the 236 * process is killed with a termination signal - 237 * SIGINT, SIGTERM, SIGQUIT or SIGHUP. 238 * NOTE: The default handler calls waitForChildren() before 239 * exiting to prevent zombie processes. */ 240 static void exitOnShutDown(); 241 242 /** Allows you to designate a function to run when the 243 * process is killed with a termination signal - 244 * SIGINT, SIGTERM, SIGQUIT or SIGHUP. */ 245 static void handleShutDown( 246 void (*shutdownfunction)(int32_t)); 247 248 /** Sets up a default handler that exits cleanly if the 249 * process crashes with a program error signal - 250 * SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGIOT, 251 * SIGEMT or SIGSYS. 252 * NOTE: The default handler calls waitForChildren() before 253 * exiting to prevent zombie processes. */ 254 static void exitOnCrash(); 255 256 /** Allows you to designate a function to run if the 257 * process crashes with a program error signal - 258 * SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGIOT, 259 * SIGEMT or SIGSYS. */ 260 static void handleCrash(void (*crashfunction)(int32_t)); 261 262 /** This method causes the process to wait on child processes 263 * which have exited, preventing so-called "zombie" processes 264 * from occurring. */ 265 static void waitForChildren(); 266 267 /** This method causes the process not to wait on child 268 * processes which have exited. Ordinarily, you'd want to 269 * wait on child processes, but this interferes with the 270 * behavior of WEXITSTATUS() after a call to system() (and 271 * possibly other calls). This method allows you to disable 272 * waiting on child processes. */ 273 static void dontWaitForChildren(); 274 275 /** This methods causes the process to wait until child 276 * process "pid" exits. Returns true on success and false 277 * on failure. */ 278 static bool wait(pid_t pid); 279 280 /** This methods causes the process to wait until child 281 * process "pid" exits. If "exitstatus" is non-null then it 282 * is populated with the exit status of the child process. 283 * Returns true on success and false on failure. */ 284 static bool wait(pid_t pid, int32_t *exitstatus); 285 286 /** This method causes the process to get information about 287 * a change in process state for the specified child process 288 * id "pid" (ie. whether it was stopped, continued or killed). 289 * 290 * Returns the process id of the child that changed state, -1 291 * if an error occurred, and 0 if "wait" is set false and no 292 * child has changed state. 293 * 294 * Setting "pid" to -1 causes the method to get information on 295 * any child of the current process. 296 * 297 * Waiting on child processes to exit prevents so-called 298 * "zombie" processes from occurring. However, this method 299 * only waits when called. To configure a process to 300 * automatically wait on and respond when any child process 301 * exits, use waitForChildren(). 302 * 303 * If "wait" is set true then the method waits until a child 304 * state-change occurs. Otherwise the method returns 305 * immediately. 306 * 307 * If "ignorestop" is set true then the method ignores when 308 * a child process has been stopped. 309 * 310 * If "ignorecontinue" is set true then the method ignores when 311 * a child process has been continued. 312 * 313 * On exit, if "newstate" is non-NULL then it is populated with 314 * one of the members of the childstatechange enum, indicating 315 * the new state of the child process. 316 * 317 * If "newstate" is EXIT_CHILDSTATECHANGE and "exitstatus" is 318 * non-null then "exitstatus" is populated with the exit status 319 * of the child process. 320 * 321 * If "newstate" is TERMINATED_CHILDSTATECHANGE or 322 * STOPPED_CHILDSTATECHANGE and "signum" is non-null then 323 * "signum" is populated with the signum that terminated or 324 * stopped the child process. 325 * 326 * If "newstate" is TERMINATED_CHILDSTATECHANGE and 327 * "coredump" is non-null then "coredump" is set true if a 328 * core dump was produced and false otherwise. */ 329 static pid_t getChildStateChange(pid_t pid, 330 bool wait, 331 bool ignorestop, 332 bool ignorecontinue, 333 childstatechange *newstate, 334 int32_t *exitstatus, 335 int32_t *signum, 336 bool *coredump); 337 338 /** Returns true if the platform supports waiting for a child 339 * process to exit or change state and false otherwise. */ 340 static bool supportsGetChildStateChange(); 341 342 /** Causes fork() calls to be automatically retried if they 343 * fail because of insufficient system resources. This 344 * is the default behavior. Otherwise, if a fork() fails, 345 * the system error is set to EAGAIN and the fork() must 346 * be retried by the calling program. */ 347 static void retryFailedFork(); 348 349 /** Causes fork() calls not to be automatically retried if 350 * they fail because of insufficient system resources. If 351 * set, if a fork() fails, the system error is set to EAGAIN 352 * and the fork() must be retried by the calling program. */ 353 static void dontRetryFailedFork(); 354 355 /** Returns true if failed fork() calls will be retried and 356 * false otherwise. */ 357 static bool getRetryFailedFork(); 358 359 /** Writes the backtrace for the current thread to "buffer". 360 * 361 * "maxframes" indicates the maximum number of stack frames 362 * to include in the backtrace. 363 * 364 * (Not supported on all platforms.) */ 365 static void backtrace(output *out, uint32_t maxframes); 366 367 /** Writes the backtrace for the current thread to "buffer". 368 * 369 * A maximum of 128 stack frames will be included in the 370 * backtrace. 371 * 372 * (Not supported on all platforms.) */ 373 static void backtrace(output *out); 374 375 /** Appends the backtrace for the current thread to "filename". 376 * 377 * A maximum of 128 stack frames will be included in the 378 * backtrace. 379 * 380 * (Not supported on all platforms.) */ 381 static void backtrace(const char *filename); 382 383 /** Appends the backtrace for the current thread to "filename". 384 * 385 * If "filename" doesn't already exist then it will be created 386 * with "perms" permissions. 387 * 388 * "maxframes" indicates the maximum number of stack frames 389 * to include in the backtrace. 390 * 391 * (Not supported on all platforms.) */ 392 static void backtrace(const char *filename, 393 mode_t perms, 394 uint32_t maxframes); 395 396 #include <rudiments/private/process.h> 397 }; 398 399 #endif 400