📄 xsh_chap03.html
字号:
{ exit(127); } if (close(tempfd) == -1) { exit(127); } } } else { exit(127); } p = strchr(p, ')') + 1; } }<br> /* Worry about setting new scheduling policy and parameters */ if (attrp->posix_attr_flags & POSIX_SPAWN_SETSCHEDULER) { if (sched_setscheduler(0, attrp->posix_attr_schedpolicy, &attrp->posix_attr_schedparam) == -1) { exit(127); } }<br> /* Worry about setting only new scheduling parameters */ if (attrp->posix_attr_flags & POSIX_SPAWN_SETSCHEDPARAM) { if (sched_setparam(0, &attrp->posix_attr_schedparam) == -1) { exit(127); } }<br> /* Now execute the program at path */ /* Any fd that still has FD_CLOEXEC set will be closed */ execve(path, argv, envp); exit(127); /* exec failed */ } else { /* This is the parent (calling) process */ if (*pid == (pid_t) - 1) return errno; return 0; }}<br>/*******************************************************//* Here is a crude but effective implementation of the *//* file action object operators which store actions as *//* concatenated token-separated strings. *//*******************************************************//* Create object with no actions. */int posix_spawn_file_actions_init( posix_spawn_file_actions_t *file_actions){ *file_actions = malloc(sizeof(char)); if (*file_actions == NULL) return ENOMEM; strcpy(*file_actions, ""); return 0;}<br>/* Free object storage and make invalid. */int posix_spawn_file_actions_destroy( posix_spawn_file_actions_t *file_actions){ free(*file_actions); *file_actions = NULL; return 0;}<br>/* Add a new action string to object. */static int add_to_file_actions( posix_spawn_file_actions_t *file_actions, char *new_action){ *file_actions = realloc (*file_actions, strlen(*file_actions) + strlen(new_action) + 1); if (*file_actions == NULL) return ENOMEM; strcat(*file_actions, new_action); return 0;}<br>/* Add a close action to object. */int posix_spawn_file_actions_addclose( posix_spawn_file_actions_t *file_actions, int fildes){ char temp[100];<br> sprintf(temp, "close(%d)", fildes); return add_to_file_actions(file_actions, temp);}<br>/* Add a dup2 action to object. */int posix_spawn_file_actions_adddup2( posix_spawn_file_actions_t *file_actions, int fildes, int newfildes){ char temp[100];<br> sprintf(temp, "dup2(%d,%d)", fildes, newfildes); return add_to_file_actions(file_actions, temp);}<br>/* Add an open action to object. */int posix_spawn_file_actions_addopen( posix_spawn_file_actions_t *file_actions, int fildes, const char *path, int oflag, mode_t mode){ char temp[100];<br> sprintf(temp, "open(%d,%s*%o,%o)", fildes, path, oflag, mode); return add_to_file_actions(file_actions, temp);}<br>/*******************************************************//* Here is a crude but effective implementation of the *//* spawn attributes object functions which manipulate *//* the individual attributes. *//*******************************************************//* Initialize object with default values. */int posix_spawnattr_init(posix_spawnattr_t *attr){ attr->posix_attr_flags = 0; attr->posix_attr_pgroup = 0; /* Default value of signal mask is the parent's signal mask; */ /* other values are also allowed */ sigprocmask(0, NULL, &attr->posix_attr_sigmask); sigemptyset(&attr->posix_attr_sigdefault); /* Default values of scheduling attr inherited from the parent; */ /* other values are also allowed */ attr->posix_attr_schedpolicy = sched_getscheduler(0); sched_getparam(0, &attr->posix_attr_schedparam); return 0;}<br>int posix_spawnattr_destroy(posix_spawnattr_t *attr){ /* No action needed */ return 0;}<br>int posix_spawnattr_getflags(const posix_spawnattr_t *attr, short *flags){ *flags = attr->posix_attr_flags; return 0;}<br>int posix_spawnattr_setflags(posix_spawnattr_t *attr, short flags){ attr->posix_attr_flags = flags; return 0;}<br>int posix_spawnattr_getpgroup(const posix_spawnattr_t *attr, pid_t *pgroup){ *pgroup = attr->posix_attr_pgroup; return 0;}<br>int posix_spawnattr_setpgroup(posix_spawnattr_t *attr, pid_t pgroup){ attr->posix_attr_pgroup = pgroup; return 0;}<br>int posix_spawnattr_getschedpolicy(const posix_spawnattr_t *attr, int *schedpolicy){ *schedpolicy = attr->posix_attr_schedpolicy; return 0;}<br>int posix_spawnattr_setschedpolicy(posix_spawnattr_t *attr, int schedpolicy){ attr->posix_attr_schedpolicy = schedpolicy; return 0;}<br>int posix_spawnattr_getschedparam(const posix_spawnattr_t *attr, struct sched_param *schedparam){ *schedparam = attr->posix_attr_schedparam; return 0;}<br>int posix_spawnattr_setschedparam(posix_spawnattr_t *attr, const struct sched_param *schedparam){ attr->posix_attr_schedparam = *schedparam; return 0;}<br>int posix_spawnattr_getsigmask(const posix_spawnattr_t *attr, sigset_t *sigmask){ *sigmask = attr->posix_attr_sigmask; return 0;}<br>int posix_spawnattr_setsigmask(posix_spawnattr_t *attr, const sigset_t *sigmask){ attr->posix_attr_sigmask = *sigmask; return 0;}<br>int posix_spawnattr_getsigdefault(const posix_spawnattr_t *attr, sigset_t *sigdefault){ *sigdefault = attr->posix_attr_sigdefault; return 0;}<br>int posix_spawnattr_setsigdefault(posix_spawnattr_t *attr, const sigset_t *sigdefault){ attr->posix_attr_sigdefault = *sigdefault; return 0;}</tt></pre><h5><a name="tag_03_03_01_02"></a>I/O Redirection with Spawn</h5><p>I/O redirection with <a href="../functions/posix_spawn.html"><i>posix_spawn</i>()</a> or <a href="../functions/posix_spawnp.html"><i>posix_spawnp</i>()</a> is accomplished by crafting a <i>file_actions</i> argument to effect thedesired redirection. Such a redirection follows the general outline of the following example:</p><pre><tt>/* To redirect new standard output (fd 1) to a file, *//* and redirect new standard input (fd 0) from my fd socket_pair[1], *//* and close my fd socket_pair[0] in the new process. */posix_spawn_file_actions_t file_actions;posix_spawn_file_actions_init(&file_actions);posix_spawn_file_actions_addopen(&file_actions, 1, "newout", ...);posix_spawn_file_actions_dup2(&file_actions, socket_pair[1], 0);posix_spawn_file_actions_close(&file_actions, socket_pair[0]);posix_spawn_file_actions_close(&file_actions, socket_pair[1]);posix_spawn(..., &file_actions, ...);posix_spawn_file_actions_destroy(&file_actions);</tt></pre><h5><a name="tag_03_03_01_03"></a>Spawning a Process Under a New User ID</h5><p>Spawning a process under a new user ID follows the outline shown in the following example:</p><pre><tt>Save = getuid();setuid(newid);posix_spawn(...);setuid(Save);</tt></pre><hr size="2" noshade><center><font size="2"><!--footer start-->UNIX ® is a registered Trademark of The Open Group.<br>POSIX ® is a registered Trademark of The IEEE.<br>[ <a href="../mindex.html">Main Index</a> | <a href="../basedefs/contents.html">XBD</a> | <a href="../utilities/contents.html">XCU</a> | <a href="../functions/contents.html">XSH</a> | <a href="../xrat/contents.html">XRAT</a>]</font></center><!--footer end--><hr size="2" noshade></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -