Está en la página 1de 21

Llamadas al Sistema en UNIX.

Gestin de ficheros: creat, open, read, write, close.


Un fichero en UNIX:
Es una secuencia de Byte sin formato, se accede a ellos de
forma directa.
La interpretacin del contenido depende de las variables
que use para lectura y escritura (enteros, caracteres,..).
Existe un puntero que indica la posicin del siguiente byte
a leer o escribir, se actualiza tras cada operacin.
Tiene asociados unos permisos: rwxrwxrwx (usuario,
grupo, otros) que se representan como un nmero en octal
Ejemplo: rwxrw-r-ser:
0764

Sistemas Operativos (IS11) Tema 1

57

Llamadas al Sistema en UNIX.


Un proceso o programa tiene asignada una tabla de
descriptores de ficheros.
La tabla tiene un tamao de 20 elementos.
El descriptor de fichero es un nmero entero (0-19) que
tiene asociado un fichero.
El proceso accede a un fichero a travs de un descriptor de
ficheros.
Un proceso slo puede usar a la vez 20 ficheros.
Inicialmente estn asignadas las posiciones:
0: entrada estndar,
0
1
1: salida estndar,
2
2: salida de error estndar.
19

Sistemas Operativos (IS11) Tema 1

58

Llamadas al Sistema en UNIX.


Creacin de nuevos ficheros: creat.
Sintaxis:

#include <fcntl.h>
int creat (nombre, mode_t permisos);
const char *nombre;
mode_t permisos;

Si existe el fichero :
No modifica los permisos.
Si tiene permiso de escritura borra el contenido.
Sino tiene permisos de escritura da un error.

Sino existe:
Lo crea y aade permisos de escritura.

Devuelve un entero:
Sino hay error: entre 0 y 19 (el descriptor del fichero). Devolver el
ms bajo que este libre (no asociado).
Si hay error: un nmero negativo.
Ejemplos:
fd=creat(prueba,0666);
fd=creat(/usr/prcticas/hola/prueba.c,0600);

Sistemas Operativos (IS11) Tema 1

59

Llamadas al Sistema en UNIX.


Escritura de datos en un fichero: write.
#include <unistd.h>
Sintaxis:
size_t write(desc_fich,dato,n_bytes);
int desc_fich;
const void *dato;
size_t n_bytes;

Devuelve:
El nmero de caracteres que ha podido escribir (n_escritos).
Un valor negativo si ha ocurrido un error en la llamada.

Ejemplos:
int n_escritos, fprueba;
fprueba =creat(fprueba,0666);
n_escritos= write(fprueba,Esto es el dato del fichero\0,28);

\0 es un carcter que delimita el final de una cadena


Sistemas Operativos (IS11) Tema 1

60

Llamadas al Sistema en UNIX.


Ejemplo 1: crear fichero y escribir en el del 0 al 9
a)

b)

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{ int i, fd;
fd=creat(prueba,0600);
for (i=0;i<10;i++) write(fd,&i,sizeof(i));
exit(0);
}
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{ int i, fd, vector[10];
fd=creat(prueba,0600);
for (i=0;i<10;i++) vector[i]=i ;
write(fd,vector,sizeof(vector));
exit(0);
}
!!!Faltara cerrar el fichero!!!
Sistemas Operativos (IS11) Tema 1

61

Llamadas al Sistema en UNIX.


Cerrar un fichero: close.
Cuando no se va a acceder a los datos de un fichero se
cierra.
La utilidad es dejar libre un descriptor de ficheros.
Sintaxis:
#include <unistd.h>
int close(descriptor_fichero);
int descriptor_fichero;

Devuelve:
0 si se ha cerrado el fichero

-1 en caso contrario.
Ejemplo 2: #include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{ int fd, i, vector[10];
fd=creat(prueba,0600);
for (i=0;i<10;i++) vector[i]=i;
write(fd,vector,sizeof(vector));
close(fd);
exit(0);
}
Sistemas Operativos (IS11) Tema 1

62

Llamadas al Sistema en UNIX.


Acceso a ficheros existentes: open.
Sintaxis: #include <fcntl.h>
int open(nombre, modo, permisos);
const char *nombre;
int modo, permisos;

Devuelve:

-1 si se produce un error
El nmero de descriptor asociado al fichero abierto (el ms
bajo libre en la tabla de descriptores).

Modos:

O_RDONLY (0) El fichero se abre para lectura. El puntero en byte 0.


O_WRONLY (1) El fichero se abre para escritura. Puntero en byte 0.
O_RDWR
(2) El fichero se abre en modo lectura/escritura
O_CREAT
Sino existe el fichero se crea.
O_TRUNC
Si existe se borra la informacin que contiene.
O_EXCL
Con O_CREAT la llamada falla si el fichero existe.
O_APPEND
El puntero del fichero apunta al final del mismo.
Para activar varios modos a la vez se usa un OR.
Ejemplos: fd=open(fichero,1|O_CREAT,0666);
fd=open(fichero,O_WRONLY|O_CREAT|O_TRUNC,0644);
Sistemas Operativos (IS11) Tema 1

63

Llamadas al Sistema en UNIX.


Lectura de datos de fichero: read.
Sintaxis:
#include <unistd.h>
size_t read(fd, dato, bytes);
int fd;
const void *dato;
size_t bytes;

Hay que abrir previamente el fichero.


El puntero del fichero quedar indicando el siguiente byte a
leer. Tras una operacin se avanza el puntero.
Devuelve:
El nmero de carcter ledo (puede ser menor que bytes
si se ha alcanzado el final del fichero).
-1 si ha ocurrido un error en la llamada.

Sistemas Operativos (IS11) Tema 1

64

Llamadas al Sistema en UNIX.


Ejemplo 3: escribir en prueba de 0 a 9 y despus leer el
contenido de prueba e imprimir en pantalla.
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{ int fd, i, vector[10], dato, leidos;
fd= creat(prueba,0600);
for (i=0;i<10;i++) vector[i];
write(fd,vector,sizeof(vector));
close(fd);
fd= open(prueba,O_RDONLY);
while ((leidos= read(fd,&dato,sizeof(int)))>0)
{ printf(Leido el nmero %d\n,dato); }
close(fd);
exit(0);
}

Sistemas Operativos (IS11) Tema 1

65

Llamadas al Sistema en UNIX.


Gestin de procesos: fork, wait, exit, execlp, execvp,
pipe y dup.
Hay una versin jerrquica de procesos:
Un proceso (hijo) aparece porque otro proceso lo genera
(padre) mediante una llamada al sistema.
Clases de llamadas:
Para generar y controlar procesos: fork, wait, exec.
Para reiniciar el cdigo del proceso: execlp, execvp.
Para comunicacin entre procesos: pipe, dup.

Crear un nuevo proceso: fork.


Sintaxis:
pid=fork();
int pid;

Si un proceso la ejecuta, se crea otro proceso que es rplica


de si mismo en memoria:
El cdigo (programa) de los dos procesos es el mismo.
Sistemas Operativos (IS11) Tema 1

66

Llamadas al Sistema en UNIX.


Cada proceso continua la ejecucin por separado (en el punto
de la llamada).
Todas las variables sern idnticas.
Los descriptores de ficheros son iguales.

Cmo se distingue entre el padre y el hijo?


fork() devuelve un entero:
Valdr cero en el hijo.
Valdr el identificador del proceso hijo en el padre.

Ejemplo 4:

#include <stdio.h>
main()
{ printf(Inicio de test\n);
if (fork() = = 0)
printf(Yo soy el hijo \n);
else
printf(Yo soy el padre \n);
exit(0);
}
Sistemas Operativos (IS11) Tema 1

67

Llamadas al Sistema en UNIX.


Ejemplo 5: #include <stdio.h>
int main()
{ int i, j;
if (fork()!=0)
{ for (i=0;i<100;i++)
{ for (j=0;j<100000;j++);
printf(Proceso padre. Indice i=%d\n,i);
}
}
else { for (i=0;i<100;i++)
{ for (j=0;j<100000;j++);
printf(Proceso hijo. Indice i=%d\n,i);
}
}
}

exit(0);

Sistemas Operativos (IS11) Tema 1

68

Llamadas al Sistema en UNIX.


Ejemplo 6: Dos procesos leen simultneamente de un fichero
...........

#include <stdio.h>
int main()
{ int i, j fd;
int dato;
fd= open(fprueba,O_RDONLY);
if (fork()!=0)
{ while (read(fd,&dato,sizeof(int))>0)
{ for (j=0;j<100000;j++); /*espera*/
printf(Proceso padre. Dato =%d\n,dato);}
}
else
{ while (read(fd,&dato,sizeof(int))>0)
{ for (j=0;j<100000;j++); /*espera*/
printf(Proceso hijo. Dato =%d\n,dato); }
}
close(fd);
exit(0);
}
Sistemas Operativos (IS11) Tema 1

69

Llamadas al Sistema en UNIX.


Reiniciar el cdigo del proceso: variantes de exec.
Permite cambiar el cdigo del programa que se ejecuta:
Cargar en memoria el cdigo de un programa que estar en
un fichero ejecutable.
Lo carga sobre el cdigo que exista en el proceso,
sustituyndolo.
Una vez cargado comienza a ejecutarse.

Qu ocurre con las instrucciones que hay despus de exec


en el programa original?
Hay 6 llamadas exec. Veremos dos: execlp y execvp.
Sintaxis: #include <unistd.h>
int execlp(fichero,arg0,arg1,arg2, , argN, (char *)0);
const char *fichero;
const char *arg0;
const char *arg1;
const char *arg2;
.
const char *argN;
Sistemas Operativos (IS11) Tema 1

70

Llamadas al Sistema en UNIX.


Sintaxis: #include <unistd.h>
int execvp(fichero, argv);
const char *fichero;
const char *argv[];

Ejemplo:

execlp(ls,ls,-l,NULL);
execvp(ls,ls -l);

Espera a que termine el proceso hijo: wait.


En ocasiones es necesario que el proceso padre espere a la
finalizacin de un proceso hijo.
#include <sys/wait.h>
Sintaxis:
pid_t wait(estado);
int *estado;

Devuelve: El valor del pid del proceso hijo que acaba.


El proceso padre se desbloquear cuando el hijo termine:
normal (exit(0)) o anormalmente.
Sistemas Operativos (IS11) Tema 1

71

Llamadas al Sistema en UNIX.


Ejemplo 7: #include <stdio.h>
int main()
{ int j, fd;
int dato, estado;
/* Diferencia ejemplo 6 */
fd= open(fprueba,O_RDONLY);
if (fork()!=0)
{ while (read(fd,&dato,sizeof(int))>0)
{ for (j=0;j<100000;j++);
printf(Proceso padre. Dato =%d\n,dato);
}
wait(&estado);
/* Diferencia ejemplo 6 */
}
else { while (read(fd,&dato,sizeof(int))>0)
{ for (j=0;j<100000;j++);
printf(Proceso hijo. Dato =%d\n,dato);
}
}
close(fd);
exit(0);
}
Sistemas Operativos (IS11) Tema 1

72

Llamadas al Sistema en UNIX.


Terminacin de un proceso: exit.
Sintaxis:
#include <stdlib.h>
void exit(estado);
int estado;

Indica al S.O. la terminacin del proceso. No es necesaria,


si aconsejable:
Cierra los descriptores de ficheros abiertos (Ver ejemplo 1).
Si el proceso padre ejecut una llamada wait se activa.

Comunicacin entre procesos: pipe (tubera):


UNIX proporciona un mecanismo bsico de comunicacin
entre procesos: tuberas.

Es un tipo especial de fichero.


Tiene asociados dos descriptores de ficheros.
Por uno los procesos pueden escribir en la tubera.
Por el otro pueden leer de la tubera.

Sistemas Operativos (IS11) Tema 1

73

Llamadas al Sistema en UNIX.


Sintaxis:

int pipe(descriptor);
int descritor[2];
descriptor[1]: descriptor para escribir datos en la tubera.
descriptor[0]: descriptor para leer datos de la tubera (en orden llegada)
Cuando se cierra descriptor[1] se introduce un EOF.

Ejemplo 8: Escribir y leer en una tubera


#include <stdio.h>
#include <unistd.h>
int main()
{ int dato, fd[2];
pipe (fd);
for (dato=0;dato<10;dato++) write(fd[1],&dato,sizeof(int));
close(fd[1]);
prinf(Datos escritos en la tubera\n);
printf(Se leen los datos\n);
while (read(fd[0],&dato,sizeof(int))>0) printf(%d\n,dato);
close(fd[0]);
exit(0);
}
Sistemas Operativos (IS11) Tema 1

74

Llamadas al Sistema en UNIX.


Ejemplo 9: Escribir y leer en tubera
#include <stdio.h>
#include <unistd.h>
int main()
{ int dato, fd[2];
pipe (fd);
for (dato=0;dato<10;dato++) write(fd[1],&dato,sizeof(int));
prinf(Datos escritos en la tubera\n);
printf(Se leen los datos\n);
while (read(fd[0],&dato,sizeof(int))>0) printf(%d\n,dato);
close(fd[1]);
close(fd[0]);
exit(0);
}

!! Mal, no acaba !! hay que cerrar fd[1] para que read no se bloquee
Sistemas Operativos (IS11) Tema 1

75

Llamadas al Sistema en UNIX.


Ejemplo10: #include <stdio.h> /*COMUNICACIN PADRE HIJO*/

int main(argc,argv[])
int argc; char *argv[];
{int tubera[2], dato, suma, estado;
pipe(tuberia);
if (fork()!=0)
{ /* proceso padre, escribe de 1 a dato */
close(tuberia[0]);
dato=atoi(argv[1]); /*transforma argv[1] en entero*/
for (i=1;i<=dato;i++) write(tuberia[1],&i,sizeof(int));
close(tuberia[1]); /* Que pasa si la quito? */
wait(&estado);
/* Que pasa si la quito ? */
printf(El padre finaliza despues que el hijo\n);
exit(0);
}
else
{ /* proceso hijo , suma de 1 a dato*/
close(tuberia[1]);
suma = 0;
while (read(tuberia[0],&dato,sizeof(int))>0) suma=suma+dato;
close(tuberia[0]); /* Que pasa si la quito ? */
prinf(Suma calculada en el proceso hijo%d\n,suma);
exit(0);
}

Sistemas Operativos (IS11) Tema 1

76

Llamadas al Sistema en UNIX.


Duplicacin de descriptores de fichero: dup.
Sintaxis:

#include <unistd.h>
int dup(desc_fich);
int desc_fich;

Duplica el descriptor de fichero que se le pasa como


parmetro.
Devuelve el nmero del nuevo descriptor duplicado
(tendremos dos descriptores apuntando al mismo sitio):
Utilizara el descriptor de fichero de nmero ms bajo para
la copia.

Sistemas Operativos (IS11) Tema 1

77

Llamadas al Sistema en UNIX.


Ejemplo 11: #include <stdio.h>
int main()
{int fichero, duplicado, i dato, salir;
fichero= creat(fprueba,0644);
for (i=0;i<10;i++) write(fichero,&i,sizeof(int));
close(fichero);
printf(Ya se ha creado el fichero\n);
fichero=open(fprueba,O_RDONLY);
printf(Abierto el fichero sobre descriptor: %d\n,fichero);
duplicado= dup(fichero);
printf(Duplicado sobre descriptor: %d\n,duplicado);
salir= FALSE;
while (!salir)
{salir= (read(fichero,&dato,sizeof(int))==0);
if (!salir)
{printf(dato leido mediante fichero = %d\n,dato);
salir= (read(duplicado,&dato,sizeof(dato))==0);
if (!salir) printf(dato leido mediante duplicado = %d\n,dato);
else printf(Final de fichero encontrado en duplicado\n);
}
else printf(Final de fichero encontrado en fichero\n);
}
close(fichero);
close(duplicado);
exit(0);
}
Sistemas Operativos (IS11) Tema 1

78

Llamadas al Sistema en UNIX.


Gestin de ficheros y directorios: remove, rename,
lseek, stat, mkdir, rmdir y chdir.
Borrar un fichero: remove.
Sintaxis:
#include <stdio.h>
int remove (Filename);
const char *Filename;

Borra el fichero llamado Filename


El fichero no se borrar si est abierto cuando se utiliza la
llamada remove.
Si el fichero tiene varios links (enlaces duros) la cuenta de
estos desciende en uno.
Devuelve:
cero en caso de que se haya podido borrar el fichero.
un valor no nulo en caso contrario.
Sistemas Operativos (IS11) Tema 1

79

Llamadas al Sistema en UNIX.


Cambio el nombre de un directorio o fichero: rename.
Sintaxis:
#include <stdio.h>

int rename (FromPath, ToPath);


const char * FromPath, ToPath;
FromPath identifica el fichero o directorio cuyo nombre se cambia.

ToPath identifica el nuevo path.


FromPath, ToPath deben ser ambos del mismo tipo (fich, o direc).
Si ToPath es fichero o directorio vaco se reemplaza por FromPath.
Si es directorio no vaco no cambia el nombre y da error.

Devuelve:
-1 en caso de error.
0 en caso contrario.

Errores:
Si no se tienen permisos de ejecucin en los directorios de los caminos
(paths), permisos de escritura en los directorios o ficheros oportunos, etc.
Si algn parmetro est siendo usado al mismo tiempo por el sistema.
Si ToPath especifica un directorio no vaco, FromPath es directorio y
ToPath no FromPath es fichero y ToPath no.
Sistemas Operativos (IS11) Tema 1

80

Llamadas al Sistema en UNIX.


Mover puntero de lectura o escritura de un fichero abierto : lseek.
Sintaxis:
#include <unistd.h>

off_t lseek ( FileDescriptor, Offset, Whence)


int FileDescriptor, Whence;
off_t Offset;
Posiciona el puntero de un fichero abierto cuyo descriptor sea
FileDescriptor.
FileDescriptor especifica el descriptor de un fichero abierto con la llamada
open.
Offset especifica el valor en bytes que se desplazar el puntero. Un valor
negativo mueve en direccin inversa. El valor de offset est limitado por
OFF_MAX.
Whence especifica cmo interpretar Offset para mover el puntero del
fichero especificado por FileDescriptor. Ser uno de los siguientes valores
que estn definidos en el fichero /usr/include/unistd.h:

Sistemas Operativos (IS11) Tema 1

81

Llamadas al Sistema en UNIX.


SEEK_SET ( 0) Mueve el puntero a la posicin indicada por
Offset.
SEEK_CUR ( 1) El Offset se usa como desplazamiento relativo
desde la posicin actual del puntero. La posicin final del puntero
ser (actual + Offset).
SEEK_END ( 2) El Offset se usa como desplazamiento relativo
desde el final del fichero. La posicin final del puntero ser (final de
fichero + Offset).

Devuelve:
Devuelve la localizacin final del puntero en bytes medida desde el
inicio del fichero.
Devuelve -1 en caso de error. .

Errores:
Si FileDescriptor no corresponde a un fichero abierto.
Si FileDescriptor corresponde a una tubera abierta.
Si el offset sobrepasa el lmite permitido definido en OFF_MAX.

En el fichero /usr/include/unistd.h estn definidos los macros, tipos y subrutinas.


Sistemas Operativos (IS11) Tema 1

82

Llamadas al Sistema en UNIX.


Obtiene informacin referente a un fichero : stat.
Sintaxis:
#include <sys/stat.h>

int stat ( Path, Buffer )


const char *Path;
struct stat *Buffer;
Obtiene informacin referente a un fichero del cual damos su path.
Path especifica el nombre del fichero.
Buffer es un puntero a la estructura stat en el que se devuelve la
informacin.
No son necesarios permisos de lectura, escritura o ejecucin para el
fichero.
En la ruta del Path todos los directorios deben tener permisos de
ejecucin.
Detallamos aqu slo los campos de la estructura stat ms importantes.

Sistemas Operativos (IS11) Tema 1

83

Llamadas al Sistema en UNIX.


Detallamos aqu slo los campos de la estructura stat ms importantes.
struct stat {
dev_t
st_dev;
/* Dispositivo de ubicacin del i_nodo */
ino_t
st_ino;
/* Nmero de i_nodo */
mode_t st_mode; /*Bits que indican tipo de fichero y permisos, en octal*/
nlink_t st_nlink;
/* Nmero de enlaces al fichero */
uid_t
st_uid;
/* UID del propietario */
gid_t
st_gid;
/* GID del propietario */
off_t
st_size;
/* Tamao del archivo en caracteres o bytes */
time_t st_atime;
/* Tiempo de ltimo acceso */
time_t st_mtime; /* Tiempo de ltima modificacin */
time_t st_ctime;
/* Tiempo de ltimo cambio en el i_nodo */
}

Sistemas Operativos (IS11) Tema 1

84

Llamadas al Sistema en UNIX.


Devuelve:
-1 en caso de error.
0 en caso contrario.

Errores:
Permiso denegado en alguno de los directorios del path.
Un componente del path no es un directorio.
No existe el fichero.

La
estructura
stat
/usr/include/sys/stat.h.

est

definida

en

el

fichero

Los valores de algunos campos de stat estn definidos en anubis


en el fichero /usr/include/sys/mode.h y para linux ver: man 2 stat
Los tipos de datos
/usr/include/sys/types.h.

estn

definidos

en

el

fichero

Sistemas Operativos (IS11) Tema 1

85

Llamadas al Sistema en UNIX.

El campo st_mode viene representado por un nmero en octal de 6 dgitos


Digto1) nmero octal que representa los permisos de otros sobre el fichero.
Digto2) nmero octal que representa los permisos de grupo sobre el fichero.
Digto3) nmero octal que representa permisos de usuario sobre el fichero.
Para averiguar los permisos se pueden utilizar las siguientes mscaras de bits
(los valores estn puestos en octal), que se encuentran definidas en los
diferentes ficheros que se incluyen al usar la llamada stat.

#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define

S_IRWXU
S_IRUSR
S_IWUSR
S_IXUSR
S_IRWXG
S_IRGRP
S_IWGRP
S_IXGRP
S_IRWXO
S_IROTH
S_IWOTH
S_IXOTH

0000700
0000400
0000200
0000100
0000070
0000040
0000020
0000010
0000007
0000004
0000002
0000001

/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*

read,write,execute perm: owner */


read permission: owner */
write permission: owner */
execute/search permission: owner */
read,write,execute perm: group */
read permission: group */
write permission: group */
execute/search permission: group */
read,write,execute perm: other */
read permission: other */
write permission: other */
execute/search permission: other */

Sistemas Operativos (IS11) Tema 1

86

Llamadas al Sistema en UNIX.


Digto 4) No lo usaremos.
Digto5 y 6) Contiene el tipo de fichero. Para averiguarlo se utilizan las
siguientes mscaras de bits (los valores estn puestos en octal), que se
encuentran definidas en los diferentes ficheros que se incluyen al usar la
llamada stat.

#define
#define
#define
#define
#define
#define

S_IFMT
S_IFREG
S_IFDIR
S_IFBLK
S_IFCHR
S_IFIFO

0170000
0100000
0040000
0060000
0020000
0010000

/* type of file */
/*
regular */
/*
directory */
/*
block special */
/*
character special */
/*
fifo */

Para conocer un campo concreto de la estructura stat se puede utilizar


mscaras junto con la operacin & (se trata de un AND bit a bit) o usar
macros. Ver

man 2 stat.

Al utilizar & es conveniente usar parntesis para distinguir con claridad la


prioridad de las operaciones que se utilicen.
Sistemas Operativos (IS11) Tema 1

87

Llamadas al Sistema en UNIX.


Ejemplo: Si queremos ver si un nombre que pasamos como primer
argumento al programa es un fichero regular, tendramos que poner al menos
las siguientes lneas de programa
{
struct stat campo;
.....
/*Sacar el contenido de la estructura*/
stat(argv[1], &campo);
/*Usar una mscara para ver si es fichero*/
if ( ( (0100000)&(campo.st_mode) ) = = (0100000) )

printf(%s es un fichero regular \n, argv[1] );


else

printf(%s no es un fichero regular \n, argv[1] );


}

Sistemas Operativos (IS11) Tema 1

88

Llamadas al Sistema en UNIX.


Ejemplo: La lnea if del ejemplo anterior puede realizarse utilizando el
nombre dado para la mscara 0100000 en el fichero /usr/include/sys/stat.h (o
consultar man 2 stat). Quedar entonces:
if ( ( (S_IFREG)&(campo.st_mode) ) = = (S_IFREG) )
printf(%s es un fichero regular \n, argv[1] );
else
printf(%s no es un fichero regular \n, argv[1] );

Sistemas Operativos (IS11) Tema 1

89

Llamadas al Sistema en UNIX.


Ejemplo: Finalmente, podemos utilizar una macro denominada
S_ISREG(m) definida en el fichero /usr/include/sys/stat.h (mode.h en
anubis). As dichas lneas quedaran: :
if ( S_ISREG ( campo.st_mode ) )
printf(%s es un fichero regular \n, argv[1] );
else
printf(%s no es un fichero regular \n, argv[1] );
Las macros definidas son:
S_ISFIFO(m)
tipo de fichero fifo
S_ISDIR(m)
tipo de fichero directorio
S_ISCHR(m)
tipo de fichero de caracteres especiales
S_ISBLK(m)
tipo de fichero de bloques especiales
S_ISREG(m)
tipo de fichero regular
Sistemas Operativos (IS11) Tema 1

90

Llamadas al Sistema en UNIX.


Crea un directorio: mkdir.
Sintaxis:
#include <stdio.h>

int mkdir (Path, Mode);


const char * Path; mode_t Mode;
Crea un nuevo directorio con los bits de permisos indicados en Mode.
Path especifica el nombre del nuevo directorio.
Mode especifica la mscara de lectura, escritura y ejecucin para
usuario, grupo y otros con la que se crear el nuevo directorio (en octal).

Devuelve:
-1 en caso de error.
0 en caso contrario.

Errores:

No se tienen los permisos adecuados para crear el directorio.


El nombre dado existe como fichero.
La longitud del Path es demasiado larga.
Algn componente del Path no es un directorio o no existe.

Sistemas Operativos (IS11) Tema 1

91

Llamadas al Sistema en UNIX.


Borra un directorio: rmdir.
Sintaxis:
#include <stdio.h>

int rmdir (Path);


const char * Path;
Borra el directorio especificado en Path. Para ello hay que tener
permiso de escritura en el directorio padre de Path.
Path especifica un nombre de directorio.

Devuelve:
-1 en caso de error.
0 en caso contrario.

Errores:

No se tiene permiso de escritura en el directorio padre de Path.


El directorio no est vaco.
La longitud de Path excede la permitida.
No existe el directorio.
Uno componente de Path no es directorio.
El directorio se refiere a un punto en el que hay montado un dispositivo.

Sistemas Operativos (IS11) Tema 1

92

Llamadas al Sistema en UNIX.


Cambiar el directorio de trabajo: chdir.
Sintaxis:
#include <stdio.h>
int chdir (Path);
const char * Path;
Cambia el directorio de trabajo actual por el directorio indicado en Path
Path especifica el nombre del directorio donde se desea cambiar

Devuelve:
-1 en caso de error.
0 en caso contrario.

Errores:
El acceso al nuevo directorio no est permitido (no se tienen permisos
adecuados)
Path no es un directorio.

Sistemas Operativos (IS11) Tema 1

93

Llamadas al Sistema en UNIX.


Ejercicio 12.-En una base de datos (fichero llamado base) tenemos el
formato que se describe a continuacin. Los registros (de 2 campos)
son de longitud fija, 64 bytes. El primer campo tiene formato de
nmero entero (4 bytes) y almacena un entero que da la longitud del
nombre acumulado en el segundo campo. El segundo campo
contiene el nombre asociado (caracteres) seguido por caracteres
basura hasta un total de 60 bytes. El formato sera el siguiente:
8
6
7

Mercedes
Carlos
Julieta

Realizar un programa en C que usando llamadas al sistema


lea, de manera adecuada, el fichero base que represente la base de
datos anterior e imprima en pantalla en diferentes lneas los nombres
que contiene.
Sistemas Operativos (IS11) Tema 1

94

Llamadas al Sistema en UNIX.


#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
main()
{ int fd, n, i, mueve, n_read, pos; dato, leidos;
char dato[60];
fd= open(base, 0); /*abrir base para leer*/
n= lseek(fd, 0, 0);
/*posicionar en primer dato*/
for (i=1;i<4;i++)
/* recorrer cada registros
{ n_read=read(fd,&pos,sizeof(int)); /*leer primer entero*/
n_read=read(fd, dato, pos);
/*leer nombre de tamao pos*/
dato[pos]= \0;
/*fin de nombre leido*/
printf(%s\n, dato);
/*imprimir nombre*/
mueve=64*i;
/*puntero al siguiente registro*/
n=lseek(fd, mueve,0);
}
close(fd);
/*cerrar fichero*/
}

Sistemas Operativos (IS11) Tema 1

95

Llamadas al Sistema en UNIX.


Ejercicio 13.-Realizar un programa en C que usando la llamada al
sistema stat, nos imprima en pantalla si el nombre que se pasa como
argumento es un fichero o es un directorio. En caso de ser fichero
debe tambin imprimir la siguiente informacin:
-tamao del mismo
-permisos que tenga habilitados
-tiempo de la ultima modificacin (usar ctime)
Ejemplo de ejecucin:
pepe es fichero
de tamao 512 bytes
permiso de lectura para propietario
permiso de escritura para propietario
permiso de ejecucin para el grupo
se modific en Tue Nov 9 18:26:38 2001
Sistemas Operativos (IS11) Tema 1

96

Llamadas al Sistema en UNIX.


#include <stdio.h>
#include <unistd.h>
#include <time.h>
main(argc, argv)
int argc; char * argv[];
{ struct stat campo;
stat(argv[1], &campo);
if (S_ISDIR(campo.st_mode))
printf(%s es un directorio\n, argv[1]);
else
if (S_ISREG(campo.st_mode))
{ printf(%s es un fichero\n, argv[1]);
printf(de tamao %d \n, campo.st_size);
/*PERMISOS PROPIETARIO*/

if (((S_IRUSR)&(campo.st_mode))= =(S_IRUSR))
printf(De lectura para el propietario\n);
if (((S_IWUSR)&(campo.st_mode))= =(S_IWUSR))
printf(De escritura para el propietario\n);
if (((S_IXUSR)&(campo.st_mode))= =(S_IXUSR))
printf(De ejecucin para el propietario\n);

/*0000400*/
/*0000200*/
/*0000100*/

Sistemas Operativos (IS11) Tema 1

97

Llamadas al Sistema en UNIX.


/*PERMISOS GRUPO*/

if (((S_IRGRP)&(campo.st_mode))= =(S_IRGRP))
printf(De lectura para el grupo\n);
if (((S_IWGRP)&(campo.st_mode))= =(S_IWGRP))
printf(De escritura para el grupo \n);
if (((S_IXGRP)&(campo.st_mode))= =(S_IXGRP))
printf(De ejecucin para el grupo \n);

/*0000040*/
/*0000020*/
/*0000010*/

/*PERMISOS OTROS*/

if (((S_IROTH)&(campo.st_mode))= =(S_IROTH))
printf(De lectura para otros\n);
if (((S_IWOTH)&(campo.st_mode))= =(S_IWOTH))
printf(De escritura para otros \n);
if (((S_IXOTH)&(campo.st_mode))= =(S_IXOTH))
printf(De ejecucin para otros \n);

/*0000004*/
/*0000002*/
/*0000001*/

printf(Se modifico en: %s \n, ctime(&campo.st_mtime));


}
}
Sistemas Operativos (IS11) Tema 1

98

También podría gustarte