curso00-01
www.ac.upc.es/homes/cristina/problemas_sol.pdf
Problemas resueltos
Arquitectura de Computadores y
Sistemas Operativos
(Ingeniería Electrónica)
Septiembre 2000
Cristina Barrado Muxí (D6-111)
1
ARISO (Ing. Electrónica)
1- Problemas de shell
2. Sistema de Ficheros
Explica que significa cada uno de los siguientes campos que resultan de eje-
cutar el comando ls -l
drwxr-x--- 2 ec1 asignat 1024 Dec 14 12:13 bin
drwxr-xr-x 3 ec1 asignat 1024 Dec 15 1998 carlos
drwx------ 7 ec1 asignat 1024 Jun 6 1997 dlx
-rw-r--r-- 1 ec1 asignat 51200 Feb 17 18:05 encuesta.fmk
-rw-r----- 1 ec1 asignat 5456 Sep 4 1996 fmMacros
-rwx------ 1 ec1 asignat 602 May 18 1993 fmconsole.log
-rw-r--r-- 1 ec1 asignat 81 Oct 15 1997 fmdictionary
-rw-r----- 1 ec1 asignat 333 Mar 24 17:46 fmfilesvisited
-rwx------ 1 ec1 asignat 360 Jan 13 1994 kbmacros
drwxr-x--- 3 ec1 asignat 1024 Feb 1 1999 win
|
|
|------|---|-última modificación
|- nombre del fichero
|
|
|
|- tamaño en bytes
|
|
|
|-grupo del propietario
|
|
|
|
|-propietario
|
|
|
|
|
|- número de links
|
|
|
|
|
|
|- tipo de fichero y protecciones
4. Procesos
Qué información útil podemos encontar al ejecutar el comans ps
UID PID PPID C STIME TTY TIME CMD
root 552 1 0.0 Mar 27 console 0:00.06 /usr/sbin/getty conso
eva 21367 26609 0.0 22:51:32 ttyp0 0:00.21 -zsh (zsh)
joanar 11193 30496 0.0 07:01:46 ttyp1 0:00.22 -zsh (zsh)
joanar 12582 11193 0.0 07:12:24 ttyp1 0:05.51 elm
|
|- comando
|-tiempo de CPU
|
|
|- terminal asociado
|
|
|
|- hora de inicio
|
|
|
|
|- factor de utilizacion de la CPU
|
|
|
|
|
|- identificador del proceso padre
|
|
|
|
|
|
|- identificador del proceso
|
|
|
|
|
|
|
|- propietario
curso00-01
7. shift y sort
a) Mostrar los parámetros de un shell script con su número de orden
#!/bin/sh
num=‘expr 1‘
for i
do
done
echo $i es el parametro $num
num=‘expr $num + 1‘
b) mostrar sólo los parámetros pares
#!/bin/sh
case $# in
0|1) exit
;;
*) echo $2
shift
shift
script_b $*
esac
c) mostrar los parámetros en orden inverso
#!/bin/sh
for i
do
echo $i
done | sort -r
#!/bin/sh
caso=I
for i
do
case $caso in
I) caso=P
;;
P) echo $i
caso=I
esac
done
2- Problemas de C
12. Subrutina contar’a’s
Escribe la subrutina que al llamarla con
n=contar_as(“busca cuantas as hay en este string”);
retorna el número de letras ‘a’ del string que recibe por parámetro.
2
3
ARISO (Ing. Electrónica)
curso00-01
int contar_as(char st[])
{
int n_as=0;
for (i=0; i<strlen(st); i++){
if (st[i] == ‘a’)
n_as++;
}
return (n_as);
}
13. Arrays por parámetro / punteros
Escribe un programa que lee un string y le añade por delante el prefijo
“super” sin necesidad de hacer copias de strings.
sol1-
main()
{
char st[100];
read (0, &st[5], 95);
st[0]=’s’; st[1]=’u’; st[2]=’p’;
st[3]=’e’; st[4]=’r’;
}
sol2-
main()
{
char st[100]=”super”;
read (0, &st[5], 95);
}
3- Problemas de E/S
16. printf y write
Escribe el siguiente programa substituyendo la llamada a la función printf
de la librería de C por la llamada a sistema de Unix write.
main(argc, argv)
int argc;
char *argv[];
{
}
}
int i;
for (i=0; i<argc; i++){
printf(“%s\n”,argv[i]);
char st[20];
sprintf (st, “%s\n”, argv[i]);
write (2, st, strlen(st));
La función printf en realidad no siempre realiza el write, sino que en
muchas ocasiones reserva los datos a escribir en un buffer interno (una varia-
ble como la st del ejemplo) y hace la escritura más adelante.
Podeis comprobarlo escribiendo y ejecutanto un programa en el que se usen
alternativamente las llamadas write y printf.
4- Comunicación entre procesos
23. Padre e hijo
Escribe un programa que crea un proceso hijo y
a) tanto el padre como el hijo escriben un mensaje y finalizan.
main()
{
int rt;
rt=fork();
if (rt==0)
else
}
write(1,”HIJO\n”,5);
write(1,”PADRRE\n”,6);
4
5
ARISO (Ing. Electrónica)
curso00-01
b) el padre espera que el hijo le envíe un carácter por una pipe. El hijo lee el
carácter de la entrada estándar.
main()
{
int rt, cp[2];
char c;
pipe(cp);
rt=fork();
if (rt==0){ /* hijo */
close(cp[0]);
read(0,&c,1);
write(cp[1],&c,1);
} else { /* padre */
close cp[1]);
read(cp[0], &c, 1);
write(1,&c,1); /* muestra en STDOUT */
}
}
c) lo mismo que en b) pero padre e hijo utilizan el programa “paso” para leer
y escribir un carácter:
main(){
char c;
}
sol:
read (0,&c,1);
write (1,&c,1);
exit(0);
main()
{
int rt, cp[2];
char c;
pipe(cp);
rt=fork();
if (rt==0){ /* hijo */
} else { /* padre */
close(cp[0]);
close(1); dup(cp[1]); close(cp[1]);
execlp(“paso”, “paso”, 0);
close cp[1]);
close(0); dup(cp[0]); close(cp[0]);
execlp(“paso”, “paso”, 0);
}
}
d) el hijo escribe mensajes de forma continuada mientras el padre espera que
le entren por la entrada estándar una tecla para enviarle al hijo una interrup-
ción (SIGUSR1) que lo mate.
main()
{
int rt;
char c;
rt=fork();
if (rt==0){ /* hijo */
while (1)
write(1,”.”,1);
} else { /* padre */
read(0,&c,1);
kill (rt, SIGUSR1);
}
}
e) igual que en d) pero ahora el hijo se programa la interrupción para que
cuando llegue se abandone el bucle de escritura de mensajes, se escribe un
mensaje de despedida y finaliza.
int fin=0; /* var. global */
void rut_at(int s){
fin=1;
}
main()
{
int rt;
char c;
rt=fork();
if (rt==0){ /* hijo */
signal(SIGUSR1, rut_at);
while (!fin)
write(1,”.”,1);
write(1,”ADIOS\n”,6);
exit(0);
} else { /* padre */
read(0,&c,1);
kill (rt, SIGUSR1);
}
}
6
7
ARISO (Ing. Electrónica)
curso00-01
24. Copiar/transferir ficheros
Hacer una copia del fichero F1 al fichero F2 usando 2 procesos (padre e hijo)
que se comunican por
a) una pipe
#define BKTAM 2000
void cat(int cin, int cout){
char buf[BKTAM];
int r;
b) una FIFO
#define BKTAM 2000
void cat(int cin, int cout){
/* idem que a) */
main()
{
int ret;
char cfitx, cfifo;
unlink(“./tmp/MIFIFO”);
mknod(“./tmp/MIFIFO”, S_IFIFO|0777,0);
ret=fork();
r=read(cin, buf, BKTAM);
while (r>0){
write (cout, buf, r);
r=read(cin, buf, BKTAM);
}
}
main()
{
int c, ret, tb[2];
pipe(tb);
ret=fork();
if (ret==0){ /* hijo: de pipe a F2 */
close(tb[1]);
c=open(“F2”,O_WRONLY|O_TRUNC|O_CREAT,
0777);
cat(tb[0],c);
exit(0);
} else { /* padre: de F1 a pipe */
close(tb[0]);
c=open(“F1”,O_RDONLY);
cat(c,tb[1]);
exit(0);
}
}
if (ret==0){ /* hijo: de FIFO a F2 */
cfifo=open(“./tmp/MIFIFO”, O_RDONLY);
cfitx=open(“F2”,
O_WRONLY|O_TRUNC|O_CREAT,
0777);
cat(cfifo, cfitx);
exit(0);
} else { /* padre: de F1 a FIFO */
cfitx=open(“F1”,O_RDONLY);
cfifo=open(“./tmp/MIFIFO”, O_WRONLY);
cat(cfitx, cfifo);
exit(0);
}
}
c) un socket DATAGRAMA
En comunicacion por paquetes, el protocolo de comunicación entre cliente y
servidor debe programarse. El sistema no ofrece mecanismos para saber
cuando un cliente ya no envia más peticiones al servidor. En este ejemplo
hemos usado las interrupciones para avisar al servidor que el fichero ya ha
sido totalmente transferido.
#include <fcntl.h>
#include <signal.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#define BKTAM 200
int fin=0;
8
9
ARISO (Ing. Electrónica)
curso00-01
d) un socket STREAM
void acabar(int s){
fin=1;
}
main(){
int ret, fdin, fout, i, mida, r;
char hostname[200], buf[200];
struct sockaddr_in server_add, client_add;
struct hostent *hostinfo;
/* pregunto por info. de la máquina local */
gethostname (hostname, sizeof (hostname));
hostinfo=gethostbyname(hostname);
/* construir Addr_IP=(IPhost + port=40000) */
server_add.sin_family=hostinfo->h_addrtype;
server_add.sin_addr.s_addr = ((int *)
(hostinfo->h_addr_list[0]))[0];
server_add.sin_port = htons (40000);
for (i=0; i < sizeof(server_add.sin_zero); i++)
server_add.sin_zero[i] = ’\0’;
ret=fork();
if (ret==0){ /* hijo=server: de socket a F2 */
signal(SIGUSR1, acabar); /*senyal de fin */
fout=open("F2",O_WRONLY|O_TRUNC|O_CREAT,
0660);
fdin = socket (AF_INET, SOCK_DGRAM, 0);
bind (fdin,&server_add,sizeof(server_add));
r=read(fdin, buf, sizeof(buf));
while (!fin && r>0){
write(fout, buf, r);
//r=recv(fdin, buf, sizeof(buf), 0);
r=read(fdin, buf, sizeof(buf));
}
exit(0);
} else {/* padre = cliente: de F1 a socket */
sleep(1); /* esperar al server */
fdin=open("F1",O_RDONLY);
fout = socket (AF_INET, SOCK_DGRAM, 0);
/* no es necesario el bind en el cliente */
r=read(fdin, buf, sizeof(buf));
while (r>0){
sendto(fout,
buf,
r,
0,&server_add,
sizeof(server_add));
r=read(fdin, buf, sizeof(buf));
}
sleep(1);/* server acaba */
kill (ret, SIGUSR1); /* señal EOF */
exit(0);
}
}
#include <fcntl.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
void cat(int cin, int cout){
/* idem que a) */
main(){
int ret, fd, fdc, i, mida;
char hostname[200];
struct sockaddr_in server_add, client_add;
struct hostent *hostinfo;
/* pregunto por info. de la máquina local */
gethostname (hostname, sizeof (hostname));
hostinfo=gethostbyname(hostname);
/* construir Addr_IP=(IPhost + port=40000) */
server_add.sin_family=hostinfo->h_addrtype;
server_add.sin_addr.s_addr = ((int *)
(hostinfo->h_addr_list[0]))[0];
server_add.sin_port = htons (40000);
for (i=0; i < sizeof(server_add.sin_zero); i++) {
server_add.sin_zero[i] = ’\0’;
}
ret=fork();
if (ret==0){ /* server: de socket a F2 */
/* canal 1: escritura en F2 */
fd=open(“F2”,O_WRONLY|O_TRUNC|O_CREAT, 0777);
close(1); dup(fd); close(fd);
/* canal 0: lectura del socket */
fd = socket (AF_INET, SOCK_STREAM, 0);
bind (fd, &server_add, sizeof (server_add));
listen (fd, 3);
mida = sizeof (client_add);
fdc = accept (fd, &client_add, &mida);
close(0); dup(fdc); close(fdc);
cat (0,1);
exit(0);
} else {
// Prob 24-a
/* padre = cliente: de F1 a socket */
sleep(3);/* server primero! */
/* canal 0: lectura de F1*/
fd=open(“F1”,
Comentarios de: Problemas resueltos - Arquitectura de Computación y Sistemas Operativos (0)
No hay comentarios