Completo

Anuncio
Examen de Fundamentos de Sistemas Operativos, Ing. Teleco. Septiembre 2009
Problema: Llamadas al sistema
Escriba en C para Plan 9 un programa llamado inv que acepte como argumentos un nombre para una variable de entorno y un comando con un número indeterminado de argumentos. Tras ejecutar el programa, la
variable de entorno especificada debe contener la salida del comando pasado como argumento.
A continuación se muestra un ejemplo:
term% inv a echo uno dos tres
term% echo $a
uno dos tres
term%
-2-
Solución
_____
inv.c 

#include <u.h>
#include <libc.h>
void
main(int argc, char *argv[])
{
char** args;
char* cmd;
char* fname;
int fd;
int i;
argv0 = argv[0];
if(argc < 3){
fprint(2, "usage: %s var cmd...", argv0);
exits("usage");
}
fname = smprint("/env/%s", argv[1]);
if(argv[2][0] != ’/’ && (argv[2][0] != ’.’ || argv[2][1] != ’/’))
cmd = smprint("/bin/%s", argv[2]);
else
cmd = argv[2];
argv += 2;
argc -= 2;
args = malloc(sizeof(char*) * (argc + 1));
if(fname == nil || cmd == nil || args == nil)
sysfatal("no memory");
for(i = 0; i < argc; i++)
args[i] = argv[i];
args[i] = nil;
fd = create(fname, OWRITE, 0664);
if(fd < 0)
sysfatal("%s: %r", fname);
dup(fd, 1);
close(fd);
/*
* args, fname, cmd memory released during exec.
*/
exec(cmd, args);
remove(fname);
sysfatal("exec %s: failed", cmd);
}
No necesitamos crear ningún proceso. Podemos hacer que el comando escriba directamente su salida en la
variable. Podríamos haber utilizado otro proceso, un pipe y putenv.
-3-
Problema: Script de Shell
Crear un script llamado includes.rc que imprima todos los ficheros de cabecera incluidos en los
ficheros fuente en C que se encuentren en el directorio actual. Puede considerarse que los ficheros fuente
son aquellos con extensión ‘‘.c’’ o ‘‘.cpp’’. Puede haber ficheros que se incluyan más de una vez, pero
sólo deben imprimirse una única vez. No importa el orden de aparición.
Puede suponerse que las directivas #include no contienen espacios en blanco dentro de los ángulos o comillas y tampoco tienen espacio en blanco tras el carácter ‘‘#’’.
-4-
Solución
__________
includes.rc 

#!/bin/rc
rfork e
hdrs=‘{grep -h ’^#include[ ’]’ *.c *.cpp |\
sed ’s/[">][ ’]*$//’ |\
sed ’s|.*<|/sys/include/|’ |\
sed ’s/.*"//’ |\
sort -u
}
for(h in $hdrs)
cat $h
exit ’’
El comando cuya salida se asigna a la variable hdrs es el responsable de hacer todo el trabajo, luego resta
volcar el contenido de los ficheros a la salida estándar.
La llamada a grep se ocupa de imprimir sólo las líneas conteniendo declaraciones include, pero sin
imprimir (por el flag -h) el nombre de fichero ni número de línea. A partir de ahí, podemos eliminar el
último carácter tras el nombre del archivo y luego eliminar todo el texto hasta el carácter que indica el
comienzo del nombre de archivo. Al eliminar este último trozo de la linea (el prefijo hasta el nombre de
archivo) aprovechamos para reemplazar el texto por /sys/include si la directiva empleada se refiere a
ficheros estándar del sistema, dejando el nombre de fichero inalterado en otro caso.
Al final, sort ordena la lista de ficheros y el flag -u se ocupa de eliminar duplicados.
Descargar