Completo

Anuncio
Examen de Fundamentos de Sistemas Operativos
Problema: Compilator en Rc
Cree un script llamado compilator.rc que reciba el nombre de un directorio, y para todos los ficheros
fuente en C contenidos en dicho directorio o en cualquier subdirectorio, compile dichos fuentes; y deje en
un fichero llamado errores (en el directorio donde está el fuente) las líneas causantes de errores de
compilación (el texto de las líneas y no el número de línea).
Problema: Compilator lite en C
Implemente el programa anterior en C, de tal forma que las compilaciones ejecuten en paralelo. En este
caso, el fichero errores debe contener los mensajes de error de compilación y no el texto de las líneas
que han causado los errores.
NOTA: Puede ignorarse todo lo relacionado con la concurrencia. Si no sabes lo que es ‘‘la
concurrencia’’, puedes ignorar esta nota.
-2-
Solución

___________
_compilator.rc
#!/bin/rc
rfork e
if(! ~ $#* 1){
echo ’usage: compilator.rc dir’ >[1=2]
exit usage
}
cd $1 || exit ’cd’
dirs=‘{du | awk ’{print $2}’ | sort -u}
for(d in $dirs){
cd $d
for(f in ‘{ls *.c >[2] /dev/null}){
lines=‘{8c -FVw $f | sed -n ’s/^’^$f^’:([0-9]+)[’ ].*/\1/p’}
for(l in $lines)
sed -n $l^’p’ $f >> errors
}
cd $1
}
exit ’’

compilator.c 
____________
#include <u.h>
#include <libc.h>
static void
usage(void)
{
fprint(2, "usage: %s dir\n", argv0);
exits("usage");
}
static int
fderrors(void)
{
int fd;
if(access("errors", AEXIST) == 0)
fd = open("errors", OWRITE);
else
fd = create("errors", OWRITE, 0660);
if(fd < 0)
return -1;
seek(fd, 0, 2);
return fd;
}
-3-
static void
compile(char *dir, char *file)
{
int fd;
switch(fork()){
case -1:
sysfatal("exec failed: %r");
case 0:
if(chdir(dir) < 0)
sysfatal("can’t change wd to %s:%r", dir);
fd = fderrors();
if(fd < 0)
sysfatal("can’t open/create the errors file: %r");
dup(fd, 1);
close(fd);
execl("/bin/8c", "8c", "-FVw", file, nil);
sysfatal("exec failed: %r");
}
}
static int
issource(Dir *d)
{
char *p;
if(d->mode & DMDIR)
return 0;
p = strrchr(d->name, ’.’);
if(p == nil)
return 0;
if(strcmp(".c", p) != 0)
return 0;
return 1;
}
static int
compilator(char *path)
{
int fd, err, i;
Dir *d;
long nd;
char *npath;
-4-
err = 0;
fd = open(path, OREAD);
if(fd < 0)
return -1;
nd = dirreadall(fd, &d);
close(fd);
for(i = 0; i < nd; i++){
if(d[i].mode & DMDIR){
npath = smprint("%s/%s", path, d[i].name);
err -= compilator(npath);
free(npath);
}
if(issource(&d[i]))
compile(path, d[i].name);
}
free(d);
return err;
}
void
main(int argc, char *argv[])
{
int err;
Waitmsg *m;
ARGBEGIN{
default:
usage();
}ARGEND
if(argc != 1)
usage();
err = compilator(argv[0]);
while((m = wait()) != nil){
if(m->msg[0] != ’\0’)
err--;
free(m);
}
if(err)
exits("some errors");
exits(nil);
}
Descargar