Examen de Fundamentos de Sistemas Operativos Problema: Llamadas al sistema (7 puntos) Implemente un programa en C para Plan 9 que escriba por su salida el listado de ficheros de tamaño cero que se encuentran en el directorio de trabajo actual. No se deben imprimir nombres de directorios. Si se pasa el modificador ‘‘-o’’, se deben escribir únicamente los ficheros cuyo dueño sea el usuario que ejecuta el programa. Si se pasa el modificador ‘‘-r’’, se deben escribir únicamente los ficheros que sean legibles por el usuario que ejecuta el programa. Los modificadores se pueden conjugar. Se recuerda que el usuario se almacena en la variable de entorno user. Entrega: Copie un fichero llamado listzero-login.c, donde login es tu nombre de usuario, en el directorio /usr/elf/examen. ATENCIÓN: Sólo se puede efectuar la entrega una vez. Ponga un comentario con su nombre y apellidos en el fichero. -2- Solución _______ _listzero.c #include <u.h> #include <libc.h> void usage(void) { fprint(2, "usage: %s [-o] [-r]\n", argv0); exits("usage"); } int owner(Dir *d) { char *u; int ret; u = getenv("user"); ret = ! strcmp(u, d->uid); free(u); return ret; } void process(Dir *d, int oflag, int rflag) { int readable; if((d->mode & DMDIR) || d->length != 0) return; readable = access(d->name, AREAD) == 0; if(oflag && rflag){ if(! (readable && owner(d))) return; }else if(rflag){ if(! readable) return; }else if(oflag){ if(! owner(d)) return; } print("%s\n", d->name); } void main(int argc, char * argv[]) { int oflag; int rflag; int fd; int i; long n; Dir *dl; -3- oflag = 0; rflag = 0; ARGBEGIN{ case ’o’: oflag++; break; case ’r’: rflag++; break; default: usage(); }ARGEND if(argc != 0) usage(); fd = open(".", OREAD); if(fd < 0) sysfatal("can’t open . : %r"); n = dirreadall(fd, &dl); if(n < 0) sysfatal("can’t read dir: %r"); close(fd); for(i = 0; i < n; i++) process(&dl[i], oflag, rflag); free(dl); exits(nil); } Problema: Shell Script (3 puntos) Escriba un script de shell Rc que haga lo mismo que el programa anterior, pero únicamente contemplando el modificador ‘‘-o’’. Entrega: Copie un fichero llamado listzero-login.rc, donde login es tu nombre de usuario, en el directorio /usr/elf/examen. ATENCIÓN: Sólo se puede efectuar la entrega una vez. Ponga un comentario con su nombre y apellidos en el fichero. -4- Solución Este script hace lo indicado, pero es iterativo: _________ _listzero2.rc #!/bin/rc if(! ~ $#* 0 1){ echo ’usage listzero.rc [-o]’ >[1=2] exit usage } oflag=n if(~ $#* 1){ if(! ~ $1 ’-o’){ echo ’usage listzero.rc [-o]’ >[1=2] exit usage } oflag=y } for(f in *){ if(test -f $f && ~ ‘{du $f | awk ’{print $1}’} 0){ if(~ $oflag y){ owner=‘{ls -l $f | awk ’{print $4}’} if(~ $owner $user) echo $f } if not { echo $f } } } Este otro script no es iterativo (por tanto, es más adecuado): ________ _listzero.rc #!/bin/rc if(! ~ $#* 0 1){ echo ’usage listzero.rc [-o]’ >[1=2] exit usage } own=’’ if(~ $#* 1){ if(! ~ $1 ’-o’){ echo ’usage listzero.rc [-o]’ >[1=2] exit usage } own=’&& $4 ~ /^’^$user^’$/’ } ls -l | grep ’^[^d]’ | awk ’ $6 == "0" ’^$own^’ {print $NF}’