La llamada fork()
es suficiente. Es también es más flexible, le permite cosas como ajustar la redirección de E/S en el proceso secundario, en lugar de complicar la llamada al sistema para crear el proceso. Con los programas SUID o SGID, permite el niño pierde sus privilegios elevados antes de ejecutar el otro proceso.
Si desea una forma compleja de crear un proceso, busque la función posix_spawn()
.
#include <spawn.h>
int posix_spawn(pid_t *restrict pid, const char *restrict path,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *restrict attrp,
char *const argv[restrict], char *const envp[restrict]);
int posix_spawnp(pid_t *restrict pid, const char *restrict file,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *restrict attrp,
char *const argv[restrict], char *const envp[restrict]);
La diferencia es la posix_spawnp()
hace una búsqueda en el camino para el ejecutable.
Hay un conjunto completo de otras funciones para manejar los tipos posix_spawn_file_actions_t
y posix_spawnattr_t
(siga los enlaces 'Ver también' en la parte inferior de la página del manual al que se hace referencia).
Esto es bastante parecido a CreateProcess()
en Windows. En su mayor parte, sin embargo, el uso de fork()
seguido en breve por exec()
es más simple.
No entiendo lo que quieres decir. El código de proceso secundario será escrito por mí, entonces, ¿cuál es la diferencia entre escribir if (fork() == 0)
y poner este código al comienzo del main()
del niño?
Muy a menudo, el código que ejecuta no está escrito por usted, por lo que no puede modificar lo que sucede al principio del proceso del niño. Piensa en un caparazón; si los únicos programas que ejecuta desde el shell son los que ha escrito, la vida será muy pobre.
Muy a menudo, el código que ejecuta se llamará desde muchos lugares diferentes. En particular, piense en un shell y un programa que a veces se ejecutará en una canalización y, a veces, se ejecutará sin canalizaciones. El programa llamado no puede decir qué redirecciones y correcciones de E/S debería hacer; el programa que llama sabe.
Si el programa de llamada se está ejecutando con privilegios elevados (privilegios SUID o SGID), es normal querer desactivarlos antes de ejecutar otro programa. Confiar en el otro programa para saber qué hacer es ... tonto.
no entendí lo que quieres decir. código de proceso hijo será escrito por mí, entonces ¿cuál es la diferencia entre escribir if (fork() == 0) y poner este código al principio de main() del niño? –
hmm, entonces usted dice que es más fácil con fork() - exec() que la pareja haga tales cosas (redirección de E/S, quitar privilegios, etc.) ¿lo entendí correctamente? –
Sí: en comparación con las contorsiones requeridas para 'posix_spawn()', es mucho más simple usar 'fork()' y luego hacer que el niño realice las acciones que necesita, antes de usar 'exec()'. Lea la justificación para 'posix_spawn()'; es bastante esclarecedor (o, al menos, lo fue para mí). La lista de cosas que puede hacer con 'posix_spawn()' es impresionante, pero también es más compleja de lo que proporciona 'fork()'. –