Mtro. Carlos Alberto Román Zamitiz · 3 sep 2026 · Tema 1 — strerror() y perror(), control de flujo de fork(), procesos huérfanos y reapers, y la familia de funciones exec.
strerror(n) devuelve la cadena del mensaje de sistema para el código n; perror("txt") imprime txt: <mensaje del sistema> si la instrucción anterior falló (la P es de "personalizar").fork() abre tres caminos: error (-1), hijo (0) y padre (PID del hijo). Vive en <unistd.h> y devuelve pid_t (se imprime con %d).init/systemd); en Linux moderno hay subprocesos reapers que adoptan huérfanos, por eso a veces el PPID de adopción no es 1.exec (6 funciones): L = lista de args terminada en NULL · V = vector de punteros · E = entorno propio · P = busca en $PATH (no requiere ruta absoluta).exec exitoso reemplaza la imagen del proceso: el original muere ahí y el código de abajo es inalcanzable. Si falla, devuelve -1 y el proceso sigue → hay que envolverlo en if + exit(EXIT_FAILURE).1 en adelante son errores; 0 es éxito (success).argv[0]) de una llamada exec debe ser el nombre del ejecutable → por eso la cadena aparece repetida: execl("/bin/ls", "ls", "-l", "/", (char *)0).exec "suelto". Envolverlo en if (... == -1) { perror(...); exit(EXIT_FAILURE); }.fork() devuelva -1: falta de memoria para duplicar la imagen del proceso.strerror() y los códigos de error de Linuxstrerror(n) — "devuelve el mensaje de sistema correspondiente al código que le pasas como parámetro". El prefijo str es por string: devuelve la cadena de texto asociada al código numérico. Análisis de programa03_codigos_sistema.c:
int i;
for (i = 0; i <= 150; i++) /* el límite se puede subir a 200 para probar */
printf("%d: %s\n", i, strerror(i));
%d (o %i) se reemplaza con el entero i; %s con el string que devuelve strerror(i).
134 se imprime Unknown error.perror() — mensaje de error personalizadoRecibe una cadena personalizada; si la instrucción anterior generó error, perror toma esa cadena, le añade automáticamente ": " y concatena a la derecha el mensaje de error estándar del sistema. La P es de "personalizar".
Ejemplo: si un fork() falla, perror("fork") imprime fork: <mensaje del sistema>.
fork()Con condicionales, fork() abre tres caminos: el de error, el del hijo y el del padre.
Estilo compacto (paréntesis anidados):
if ((child = fork()) == -1) { ... }
El compilador lo resuelve así: 1) se invoca fork(); 2) su valor de retorno se asigna a child; 3) se compara child con -1.
Estilo descompuesto ("camino largo", prioriza claridad sobre rendimiento):
pid_t ch;
ch = fork();
if (ch == -1) { ... }
fork()"Open Group" fork → www.opengroup.org.fork(), getpid(), getppid(), getuid(), geteuid(), getgid(), getegid() están definidas en <unistd.h>.fork() devuelve pid_t, que internamente es un entero → se imprime con %d.0 al hijo y el PID del hijo al padre; ambos siguen ejecutando en paralelo las líneas posteriores.-1 al padre, no se crea hijo y se establece errno. Causa más común: falta de memoria para duplicar la imagen del proceso.exit() y macros de salidaCuando una llamada crítica (fork(), exec()) devuelve -1, se usa exit() para terminar el programa de inmediato y no seguir ejecutando código.
EXIT_FAILURE (en mayúsculas) ≡ exit(1) — salida no exitosa.EXIT_SUCCESS ≡ exit(0) — salida exitosa.Al correr programa08, la salida muestra in parent antes que in child, y el hijo, al llamar getppid(), obtiene 1 aunque su padre real era otro.
getppid().init en sistemas antiguos, systemd en modernos) los adopta automáticamente.1.cat /etc/os-release (la máquina del profesor: Fedora Linux Workstation 40).fork() es el padre; la terminal interactiva es el abuelo.execNo existe exec "a secas": es una familia de seis funciones que empiezan con esa palabra y añaden 1 o 2 letras que definen su comportamiento.
| Letra | Significado |
|---|---|
| L (list) | Los argumentos se escriben como lista explícita separada por comas, terminada en NULL o (char *)0. |
| V (vector) | Los argumentos van en un arreglo de punteros, también terminado en puntero nulo. |
| E (environment) | Permite pasar un vector de variables de entorno propias, válidas solo durante la ejecución del nuevo proceso. |
| P (PATH) | No requiere ruta absoluta: lee la variable PATH y busca el ejecutable en los directorios del sistema (/bin, /usr/bin…). |
execl, execv, execle, execve → parámetro path (ruta absoluta, ej. /bin/ls).execlp, execvp → parámetro file (nombre a secas, ej. ls).A diferencia de fork() (que duplica), cuando exec tiene éxito la imagen del proceso original en memoria se destruye y se reemplaza por completo por la del nuevo programa. El proceso original muere en ese punto y no recupera el control.
En C, argv[0] debe ser el nombre del ejecutable, por eso la cadena del comando aparece repetida:
execl("/bin/ls", "ls", "-l", "/", (char *)0);
/* ^ruta ^arg0 ^arg1 ^arg2 ^fin de lista */
Si el comando no existe o está mal escrito, exec falla, devuelve -1 y el proceso original sigue ejecutando las líneas de abajo. En una llamada exitosa, en cambio, esas líneas son inalcanzables (el proceso ya fue reemplazado).
Regla obligatoria — envolver en if y terminar si devuelve -1:
if (execl("/bin/ls", "ls", "-l", "/", (char *)0) == -1) {
perror("execl");
exit(EXIT_FAILURE);
}
programa10.cgcc programa10.c -o programa10
/bin/ls → muestra el listado de / y regresa el prompt. La línea de abajo del if ("esto no se imprime") no aparece./bin/lsa (no existe) y se comenta el exit(EXIT_FAILURE). Resultado: execl devuelve -1, perror("execl") imprime execl: No such file or directory y, como no hay exit, el proceso sigue vivo e imprime "esto no se imprime" — mostrando físicamente la falla por no manejar el error.Sin pase de lista y sin tarea formal de entrega. Tarea moral: repasar la familia exec, con énfasis en execl. El profesor termina de calificar la Tarea 2 durante el fin de semana. La próxima sesión (martes) arranca el Tema 2: Estados de proceso.
exec: el profesor adelantó que asignará una práctica donde se evaluará el manejo correcto de errores al invocar la familia exec, con la estructura if (exec(...) == -1) { perror(...); exit(EXIT_FAILURE); }.profesores.fi-b.unam.mx / IP 132.248.59.6). Mtro. Jorge Rodríguez Campos — subdirector de su tesis de licenciatura. Ing. Mena — compañero de generación ("ambos tenían cabello en ese entonces"). Mtra. Delia Bacs y Mtra. Tania Richi — las conoce desde la universidad.Teoría general de procesos, ejemplos en C y los programas del profesor están en el Tema 1.