2011-08-23 15 views
6

Estoy intentando un programa con fork y execlp donde el espacio de direcciones principal se reemplaza con el comando "ls".Fork y Execlp

#include<stdio.h> 
main() 
{ 
    int pid,j=10,fd; 
    pid=fork(); 
    if(pid==0) 
    { 
     printf("\nI am the child\n"); 
     execlp("/bin/ls","ls",NULL); 
     printf("\nStill I am the child\n"); 

    } 
    else if (pid > 0) 
    { 
     printf("\n I am the parent\n"); 
     wait(); 
    } 
} 

Cuando ejecuto el programa de la última línea del niño

printf("\nStill I am the child\n"); 

no se imprime. ¿Por qué?

Respuesta

16

exec las funciones de la familia no se devuelven cuando se realiza correctamente.

http://pubs.opengroup.org/onlinepubs/009604499/functions/exec.html

La familia de funciones exec deberá sustituir la imagen actual proceso de imagen un nuevo proceso con. La nueva imagen se construirá a partir de un archivo ejecutable regular llamado archivo de imagen de proceso nuevo. No habrá devolución de un ejecutivo exitoso, porque la imagen del proceso llamante se superpone con la nueva imagen de proceso.

Si una de las funciones de ejecución vuelve a la imagen del proceso de llamada, se ha producido un error; el valor de retorno será -1, y errno se configurará para indicar el error.

4

exec funciones no solo ejecutarán su comando. En realidad, reemplazarán el contexto de ejecución del proceso por el ejecutable seleccionado (en su caso /bin/ls).

En otras palabras, como la función ls finaliza al finalizar su proceso (a través de 'exit' o devolver la función principal o lo que sea), el proceso secundario se eliminará al final de la ejecución ls.

En realidad se puede utilizar esta llamada printf para imprimir algunos errores, por ejemplo:

if(pid==0) 
    { 
     printf("\nI am the child\n"); 
     execlp("/bin/ls","ls",NULL); 
     printf("\nError: Could not execute function %s\n", "/bin/ls"); 
     _exit(0); //make sure you kill your process, it won't disappear by itself. 
    } 
0

después de la execlp función() no se ejecutan de acuerdo con la documentación de execlp por lo tanto, su instrucción printf() " Todavía soy el niño "¡no se ejecuta ...!

-3
  1. usted está tomando identificador de proceso como int tipo, pero en realidad, a la Identificación del proceso de almacenamiento se debe utilizar pid_t
  2. Cuando se utiliza la función de la familia exec todo el espacio de direcciones del proceso llamado sustituye al proceso de llamada. Por lo tanto, ahora el último printf declaración no está allí en el nuevo proceso, de hecho incluso el identificador de proceso del proceso tampoco se cambia
+0

Varios puntos buenos, pero el pid es definitivamente diferente en el nuevo proceso. Además, el ejecutivo solo reemplaza el proceso si tiene éxito, de lo contrario continuará después de la llamada del ejecutivo – techdude

1

La razón es simple: El exec() funciona sólo volver si un error tiene tiene ocurrió. Para las mismas páginas de manual de referencia de las funciones de exec().

Lo que está ocurriendo exactamente cuando exec() funciones se llaman:

execl() no crea un nuevo proceso - que modifica las VADS y contenidos asociados - además, el contexto de ejecución también se modifica.

  • antiguo contexto de ejecución ya no se utiliza - se crea un nuevo contexto de ejecución.
    • se crea un nuevo contexto fresco para la aplicación recién cargado y se pasa el control al programador scheduler- reanuda el mismo proceso hijo con el contexto de ejecución nuevamente disponible - el uso de este, un salto se ejecuta a la entrada punto de la nueva aplicación, en user-space - la nueva aplicación comienza a ejecutarse en el mismo proceso hijo.
      • la pila del sistema se sobrescribe con el nuevo contexto hw para reanudando el main() del nuevo programa en el espacio de usuario.
    • contexto de ejecución y código/datos/montón/pila de la aplicación anterior en el proceso hijo se destruyen por completo - ya no está disponible.
    • solo el tiempo execve() o execl() volverá a la misma aplicación/código del proceso actual cuando execve() o execl() no carga una nueva aplicación en el proceso actual - es decir, el único el tiempo execv()/execvl() o la familia de llamadas volverá es cuando hay es un error al completar execv()/execl()/familia de llamadas.

Nota: debe validar el valor de retorno de la API de llamadas Exec System familia() para errores de códigos de error/- sobre la base de los códigos de error/error, que puede finalizar el proceso actual o tomar alguna otra acción .