📄 xsh_chap03.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta name="generator" content="HTML Tidy, see www.w3.org"><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"><link type="text/css" rel="stylesheet" href="style.css"><!-- Generated by The Open Group's rhtm tool v1.2.1 --><!-- Copyright (c) 2001-2003 The Open Group, All Rights Reserved --><title>Rationale</title></head><body><basefont size="3"> <center><font size="2">The Open Group Base Specifications Issue 6<br>IEEE Std 1003.1, 2003 Edition<br>Copyright © 2001-2003 The IEEE and The Open Group</font></center><hr size="2" noshade><h3><a name="tag_03_03"></a>System Interfaces</h3><p>See the RATIONALE sections on the individual reference pages.</p><h4><a name="tag_03_03_01"></a>Examples for Spawn</h4><p>The following long examples are provided in the Rationale (Informative) volume of IEEE Std 1003.1-2001 as a supplementto the reference page for <a href="../functions/posix_spawn.html"><i>posix_spawn</i>()</a>.</p><h5><a name="tag_03_03_01_01"></a>Example Library Implementation of Spawn</h5><p>The <a href="../functions/posix_spawn.html"><i>posix_spawn</i>()</a> or <a href="../functions/posix_spawnp.html"><i>posix_spawnp</i>()</a> functions provide the following:</p><ul><li><p>Simply start a process executing a process image. This is the simplest application for process creation, and it may cover mostexecutions of <a href="../functions/fork.html"><i>fork</i>()</a>.</p></li><li><p>Support I/O redirection, including pipes.</p></li><li><p>Run the child under a user and group ID in the domain of the parent.</p></li><li><p>Run the child at any priority in the domain of the parent.</p></li></ul><p>The <a href="../functions/posix_spawn.html"><i>posix_spawn</i>()</a> or <a href="../functions/posix_spawnp.html"><i>posix_spawnp</i>()</a> functions do not cover every possible use of the <a href="../functions/fork.html"><i>fork</i>()</a> function, but they do span the common applications: typical use by a shell and a loginutility.</p><p>The price for an application is that before it calls <a href="../functions/posix_spawn.html"><i>posix_spawn</i>()</a> or <ahref="../functions/posix_spawnp.html"><i>posix_spawnp</i>()</a>, the parent must adjust to a state that <a href="../functions/posix_spawn.html"><i>posix_spawn</i>()</a> or <a href="../functions/posix_spawnp.html"><i>posix_spawnp</i>()</a> canmap to the desired state for the child. Environment changes require the parent to save some of its state and restore it afterwards.The effective behavior of a successful invocation of <a href="../functions/posix_spawn.html"><i>posix_spawn</i>()</a> is as if theoperation were implemented with POSIX operations as follows:</p><pre><tt>#include <sys/types.h>#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <sched.h>#include <fcntl.h>#include <signal.h>#include <errno.h>#include <string.h>#include <signal.h><br>/* #include <spawn.h> *//*******************************************//* Things that could be defined in spawn.h *//*******************************************/typedef struct{ short posix_attr_flags;#define POSIX_SPAWN_SETPGROUP 0x1#define POSIX_SPAWN_SETSIGMASK 0x2#define POSIX_SPAWN_SETSIGDEF 0x4#define POSIX_SPAWN_SETSCHEDULER 0x8#define POSIX_SPAWN_SETSCHEDPARAM 0x10#define POSIX_SPAWN_RESETIDS 0x20 pid_t posix_attr_pgroup; sigset_t posix_attr_sigmask; sigset_t posix_attr_sigdefault; int posix_attr_schedpolicy; struct sched_param posix_attr_schedparam;} posix_spawnattr_t;<br>typedef char *posix_spawn_file_actions_t;<br>int posix_spawn_file_actions_init( posix_spawn_file_actions_t *file_actions);int posix_spawn_file_actions_destroy( posix_spawn_file_actions_t *file_actions);int posix_spawn_file_actions_addclose( posix_spawn_file_actions_t *file_actions, int fildes);int posix_spawn_file_actions_adddup2( posix_spawn_file_actions_t *file_actions, int fildes, int newfildes);int posix_spawn_file_actions_addopen( posix_spawn_file_actions_t *file_actions, int fildes, const char *path, int oflag, mode_t mode);int posix_spawnattr_init(posix_spawnattr_t *attr);int posix_spawnattr_destroy(posix_spawnattr_t *attr);int posix_spawnattr_getflags(const posix_spawnattr_t *attr, short *lags);int posix_spawnattr_setflags(posix_spawnattr_t *attr, short flags);int posix_spawnattr_getpgroup(const posix_spawnattr_t *attr, pid_t *pgroup);int posix_spawnattr_setpgroup(posix_spawnattr_t *attr, pid_t pgroup);int posix_spawnattr_getschedpolicy(const posix_spawnattr_t *attr, int *schedpolicy);int posix_spawnattr_setschedpolicy(posix_spawnattr_t *attr, int schedpolicy);int posix_spawnattr_getschedparam(const posix_spawnattr_t *attr, struct sched_param *schedparam);int posix_spawnattr_setschedparam(posix_spawnattr_t *attr, const struct sched_param *schedparam);int posix_spawnattr_getsigmask(const posix_spawnattr_t *attr, sigset_t *sigmask);int posix_spawnattr_setsigmask(posix_spawnattr_t *attr, const sigset_t *sigmask);int posix_spawnattr_getdefault(const posix_spawnattr_t *attr, sigset_t *sigdefault);int posix_spawnattr_setsigdefault(posix_spawnattr_t *attr, const sigset_t *sigdefault);int posix_spawn(pid_t *pid, const char *path, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *attrp, char *const argv[], char *const envp[]);int posix_spawnp(pid_t *pid, const char *file, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *attrp, char *const argv[], char *const envp[]);<br>/*****************************************//* Example posix_spawn() library routine *//*****************************************/int posix_spawn(pid_t *pid, const char *path, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *attrp, char *const argv[], char *const envp[]){ /* Create process */ if ((*pid = fork()) == (pid_t) 0) { /* This is the child process */ /* Worry about process group */ if (attrp->posix_attr_flags & POSIX_SPAWN_SETPGROUP) { /* Override inherited process group */ if (setpgid(0, attrp->posix_attr_pgroup) != 0) { /* Failed */ exit(127); } }<br> /* Worry about thread signal mask */ if (attrp->posix_attr_flags & POSIX_SPAWN_SETSIGMASK) { /* Set the signal mask (can't fail) */ sigprocmask(SIG_SETMASK, &attrp->posix_attr_sigmask, NULL); }<br> /* Worry about resetting effective user and group IDs */ if (attrp->posix_attr_flags & POSIX_SPAWN_RESETIDS) { /* None of these can fail for this case. */ setuid(getuid()); setgid(getgid()); }<br> /* Worry about defaulted signals */ if (attrp->posix_attr_flags & POSIX_SPAWN_SETSIGDEF) { struct sigaction deflt; sigset_t all_signals;<br> int s;<br> /* Construct default signal action */ deflt.sa_handler = SIG_DFL; deflt.sa_flags = 0;<br> /* Construct the set of all signals */ sigfillset(&all_signals);<br> /* Loop for all signals */ for (s = 0; sigismember(&all_signals, s); s++) { /* Signal to be defaulted? */ if (sigismember(&attrp->posix_attr_sigdefault, s)) { /* Yes; default this signal */ if (sigaction(s, &deflt, NULL) == -1) { /* Failed */ exit(127); } } } }<br> /* Worry about the fds if they are to be mapped */ if (file_actions != NULL) { /* Loop for all actions in object file_actions */ /* (implementation dives beneath abstraction) */ char *p = *file_actions;<br> while (*p != '\0') { if (strncmp(p, "close(", 6) == 0) { int fd;<br> if (sscanf(p + 6, "%d)", &fd) != 1) { exit(127); } if (close(fd) == -1) exit(127); } else if (strncmp(p, "dup2(", 5) == 0) { int fd, newfd;<br> if (sscanf(p + 5, "%d,%d)", &fd, &newfd) != 2) { exit(127); } if (dup2(fd, newfd) == -1) exit(127); } else if (strncmp(p, "open(", 5) == 0) { int fd, oflag; mode_t mode; int tempfd; char path[1000]; /* Should be dynamic */ char *q;<br> if (sscanf(p + 5, "%d,", &fd) != 1) { exit(127); } p = strchr(p, ',') + 1; q = strchr(p, '*'); if (q == NULL) exit(127); strncpy(path, p, q - p); path[q - p] = '\0'; if (sscanf(q + 1, "%o,%o)", &oflag, &mode) != 2) { exit(127); } if (close(fd) == -1) { if (errno != EBADF) exit(127); } tempfd = open(path, oflag, mode); if (tempfd == -1) exit(127); if (tempfd != fd) { if (dup2(tempfd, fd) == -1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -