Está en la página 1de 7

SSOO.

Llamadas al sistema
Prctica 1. Parmetros, compilacin y gestin de archivos.
Compilacin: gcc -o ejecutable fuente.c
Ejecucin: ./ejecutable parametros
Paso de parmetros:
main (int argc, char *argv[]) {
int i;
printf("Numero de argumentos: %d\n",argc);
for (i=0;i<argc;i++)
printf("Argumento %d: %s\n",i,argv[i]);
}

Llamadas del sistema de gestin de archivos:

#include
#include
#include
int open

<sys/types.h>
<sys/stat.h>
<fcntl.h>
(const char *path, int flag [, mode_t mode]);

Abre un fichero segn las opciones indicadas.


path es la trayectoria del fichero a abrir.
flag puede ser:
O_RDONLY para solo lectura.
O_CREAT se crea si no existe.
O_WRONLY para escritura.
O_EXCL junto a O_CREAT devuelve error si el fichero existe.
O_RDWR lectura y escritura.
O_TRUNC, si el fichero existe, trunca su longitud a cero bytes.
O_APPEND escritura para aadir.
mode indica los permisos (en octal). Es un nmero octal de 4 cifras que habitualmente comienza en 0.
Devuelve el descriptor de ficheros o -1, en cuyo caso errno contiene el error devuelto.
Ejemplo: fd =open("fich", O_WRONLY | O_TRUNC | O_CREAT, 0600);

int creat (const char *path, mode_t mode);

La llamada creat equivale a

int open (const char * path, O_WRONLY|O_TRUNC|O_CREAT, mode_t mode)


#include <unistd.h>
int read (int fd, char *buffer, unsigned nbyte) ;

Lee del fichero fd un total de nbyte bytes almacenndolos a partir de buffer. El total de bytes ledos es
devuelto por la funcin. Devuelve 1 en caso de error, en cuyo caso errno contiene el error devuelto.

int write (int fd, char *buffer, unsigned nbyte);

Escribe en el fichero fd un total de nbyte bytes almacenados a partir de buffer. El total de bytes escritos
realmente es devuelto por la funcin. Devuelve 1 en caso de error, en cuyo caso errno contiene el error
devuelto. La escritura se realiza en la posicin determinada en la apertura del fichero o por seek.
Ejemplo:
char *str = "En un lugar de la Mancha...";
int nbytes;
nbytes = write (fd, str, strlen (str));

int close (int fd);

Cierra el fichero fd. Devuelve -1 en caso de error.

#include <sys/types.h>
#include <unistd.h>
off_t lseek (int fd, off_t offset, int modo_desplaz) ;

Posiciona el puntero de lectura y escritura del fichero seleccionado en la posicin dada por offset y
modo_desplaz, segn la siguiente forma:
Si modo_desplaz vale SEEK_SET, el puntero avanza offset bytes con respecto al inicio del fichero.
Si modo_desplaz vale SEEK_CUR, el puntero avanza offset bytes con respecto a su posicin actual.
Si modo_desplaz vale SEEK_END, el puntero avanza offset bytes con respecto al final del fichero.

#include <errno.h>
int errno //Contiene el valor del error devuelto.

SSOO. Llamadas al sistema


Prctica 2. Gestin de permisos y enlaces a ficheros.
Llamadas del sistema de gestin de permisos:

#include <sys/types.h>
#include <sys/stat.h>
int chmod (char *path, mode_t mode);

Se utiliza para cambiar el modo del fichero especificado por path. El parmetro mode es un valor octal que
determina el modo. La funcin devuelve 0 en caso de xito o -1 en caso de error.
El tipo mode_t representa un valor de 4 cifras en octal que permite definir los permisos del fichero.

#include <unistd.h>
int access (char *path, int amode);

Indica si el fichero indicado en path es accesible por el proceso en ejecucin segn el modo indicado por
amode. Para indicar amode deben combinarse las constantes R_OK, W_OK o X_OK. Caso de que el acceso
sea posible, la llamada retorna 0. En caso contrario retorma -1.

#include <sys/types.h>
#include <sys/stat.h>
mode_t umask (mode_t cmask);

Permite asignar una nueva mscara por defecto a utilizar conjuntamente con las llamadas open o creat. Por
defecto existe la mscara 022 que elimina los permisos de escritura y ejecucin a los usuarios del grupo y al
resto de usuarios del sistema en cualquier fichero creado por open o creat. Los permisos reales aplicados por
estas llamadas son el resultado de la AND entre el modo indicado en la misma y el complementario del
valor de esta variable mscara (mode & ~cmask). Para modificar el valor de la citada mscara se usa la
llamada umask, cuyo parmetro es el nuevo valor y la cual devuelve el antiguo valor.
Llamadas del sistema de gestin enlaces fsicos:

#include <unistd.h>
int link (const char *oldpath, const char *newpath);

Crea un nuevo enlace fsico al fichero existente oldpath. Si newpath existe, no ser sobrescrito. A partir de
ese momento, ambos nombres referenciarn de forma idntica al mismo fichero. Por tanto cualquier cambio
realizado en el fichero referenciado por el primer nombre ser aplicado al segundo. La funcin devuelve 0
en caso de xito y -1 en caso de error.

#include <unistd.h>
int symlink (const char *oldpath, const char *newpath);

Crea un enlace simblico a un fichero. El enlace simblico no es ms que un acceso directo o fichero de
texto que contiene una referencia a otro fichero. Si el fichero al que referencia fuese borrado, el enlace
simblico quedara colgante.

#include <unistd.h>
int unlink (const char *path);

Borra del sistema de archivos el nombre indicado en path. Si este nombre referencia a un enlace fsico, este
desaparece. Si adems es el ltimo enlace fsico, el fichero desaparece y todo el espacio que ocupaba queda
libre (En este caso, la operacin solo se realiza inmediatamente si el fichero no est siendo usado por ningn
proceso. En caso contrario, la operacin queda latente y se ejecuta cuando todos los procesos que usan el
fichero lo cierran). Si el enlace es simblico en lugar de fsico, simplemente se borra el enlace simblico.

SSOO. Llamadas al sistema


Prctica 3. Informacin sobre ficheros y conversin de tiempos.
Llamada al sistema stat

#include <sys/types.h>
#include <sys/stat.h>
int stat (char *path, struct stat *buf);

Recibe por parmetro una cadena que contiene el nombre de un fichero y devuelve por parmetro una
estructura de tipo stat con informacin asociada al mismo. La mayora de los campos de esta estructura
pueden ser tratados como valores enteros. Sin embargo, existen algunas funciones que permiten manejar de
forma ms cmoda la citada informacin. La llamada devuelve -1 en caso de error. La estructura stat se
define como sigue:
struct stat
mode_t
ino_t
dev_t
dev_t
nlink_t
uid_t
gid_t
off_t
time_t
time_t
time_t
unsigned
unsigned

{
st_mode;
/* proteccion */
st_ino;
/* numero de inodo */
st_dev;
/* ID del dispositivo que contiene el fichero */
st_rdev;
/* ID del dispositivo (solo definido para fich espec.) */
st_nlink; /* Nmero de enlaces fsicos */
st_uid;
/* ID del usuario propietario del fichero */
st_gid;
/* ID del grupo propietario del fichero */
st_size;
/* Tamao del fichero en bytes */
st_atime; /* Hora del ltimo acceso (Segundos desde 1970)*/
st_mtime; /* Hora de la ltima modificacin (Segundos desde 1970) */
st_ctime; /* Hora del ultimo cambio (Segundos desde 1970)*/
long st_blksize; /* Tamao de cada bloque del fichero */
long st_blocks;
/* Nmero de bloques de 512bytes del fichero */ };

Para determinar de una forma sencilla el tipo de fichero que estamos tratando pueden usarse las macros:

int S_ISLNK(mode_t st_mode)


//Es
int S_ISREG(mode_t st_mode)
//Es
int S_ISDIR(mode_t st_mode)
//Es
int S_ISCHR(mode_t st_mode)
//Es
int S_ISBLK(mode_t st_mode)
//Es
int S_ISFIFO(mode_t st_mode)
//Es
int S_ISSOCK(mode_t st_mode)
//Es
#include <time.h>
char *ctime(const time_t * st_time);

un enlace simblico?
un fichero regular?
un directorio?
un dispositivo de caracteres?
un dispositivo de bloques?
una tubera nombrada (fifo)?
un socket?

Transforma la informacin apuntada por st_time en una cadena de texto formateada con fecha y hora.

struct tm *gmtime(const time_t * st_time);

Transforma la informacin contenida en la estructura apuntada por st_time en una estructura de tipo tm
definida como se muestra a continuacin (la llamada inversa es mktime):

struct tm {
int tm_sec;
/*Segundos*/
int tm_min;
/*Minutos*/
int tm_hour;
/*Horas*/
int tm_mday;
/*Da del mes*/
int tm_mon;
/*Mes: Enero=0 */
int tm_year;
/*Ao desde 1900. Ao 2006=106 */
int tm_wdaw;
/*Da de la semana: 0=Domingo, 1=lunes */
int tm_yday;
/*Das del ao*/
int tm_isdst;
/* >0 Horario Verano, 0=horario inv, <0 No definido */
}
time_t mktime(struct tm *ptr_time);

Transforma la informacin contenida en la estructura apuntada por ptr_time en una estructura de tipo
time_tm. La llamada no tiene en cuenta tm_wday ni tm_yday (los recalcula). En caso de error devuelve -1.
A continuacin se muestra un fragmento cdigo, a modo de ejemplo, que muestra el mes de ltimo acceso.
struct stat buf;
stat("ficherito.c",&buf);
printf("ltimo acceso en el mes %u \n",gmtime(&(buf.st_atime))->tm_mon);
printf("Es un directorio (Si/No): %s \n",S_ISDIR(buf.st_mode)!=0?"SI":"NO");

SSOO. Llamadas al sistema


Prctica 4. Gestin de directorios I: creacin, acceso y borrado.
Llamadas del sistema de gestin de directorios.

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int mkdir (const char *path, mode_t mode);

Crea un directorio con la trayectoria indicada por path y los permisos dados por mode y modificados por la
mscara umask. En caso de xito, la llamada devuelve 0. En caso de error, -1.

#include <unistd.h>
int rmdir (const char *path);

Borra el directorio especificado por path. La llamada devuelve 0 en caso de xito o -1 en caso de error.

int chdir (const char *path);

Cambia al directorio especificado por path. La llamada devuelve 0 en caso de xito o -1 en caso de error.

char *getcwd (char *buf, int size);

Devuelve en la cadena buf la ruta del directorio actual. La variable size indica el tamao de memoria
reservado para buf. Si la ruta fuese ms larga la funcin devolvera NULL. En caso contrario devuelve la
direccin de buf.

Prctica 5. Gestin de directorios II: acceso y recorrido de directorios.


Llamadas del sistema de gestin de directorios.

#include <sys/types.h>
#include <dirent.h>
DIR *opendir (const char *dirname);

Abre un flujo de directorio correspondiente al directorio indicado por la cadena dirname y devuelve un
puntero a dicho flujo. En caso de error, este puntero valdr NULL.

struct dirent *readdir (DIR *dirp);

Devuelve un puntero a una estructura dirent en la que se almacenar informacin sobre la siguiente entrada
del directorio abierto por opendir e indicado por el flujo dirp. Devuelve NULL en caso de error. Aunque la
estructura dirent tiene varios campos, la mayora de los programadores solo necesitan hacer uso de uno de
ellos: char d_name[NAME_MAX]. Es importante recordar que d_name contiene una cadena con un
nombre de fichero/directorio simplemente, sin la trayectoria. As, ser necesario cambiar al directorio de
trabajo o aadir la trayectoria a dicha cadena si esta desea ser procesada con llamadas similares a stat.

int closedir (DIR *dirp);

Cierra el flujo de directorio creado por la llamada opendir liberando el espacio de memoria reservado por
esta. Devuelve 0 si no se produce ningn error o 1 en caso contrario.

void rewinddir (DIR *dirp);

Reposiciona el flujo de directorio dado por opendir al primer directorio del mismo, independientemente de
las llamadas readdir que se hayan realizado. La llamada no devuelve ningn valor.
El siguiente fragmento de cdigo mostrara el contenido del directorio llamado como indica NombreFich:
...
char
* NombreFich;
struct stat
BufferStat;
DIR
* Directorio;
struct dirent * Entrada_dir;
...
if( stat( NombreFich, &BufferStat )!= 0 ) error("Error stat con %s", NombreFich);
if(!S_ISDIR(BufferStat.st_mode)) return;
if((Directorio=opendir(NombreFich))==NULL) error("Error opendir con %s", NombreFich);
while((Entrada_Dir=readdir(Directorio))!=NULL) {
printf("%s \n",Entrada_Dir->d_name);
}
closedir(Directorio);

SSOO. Llamadas al sistema


Prctica 6. Las llamadas dup y dup2.
Llamadas del sistema de gestin de ficheros.

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

La llamada dup duplica el descriptor de fichero fd que ya ha sido asignado y que est ocupando una entrada
en la tabla de descriptores de fichero, recorriendo para ello la tabla de descriptores y marcando como
ocupada la primera entrada que encuentre libre. fd es un descriptor obtenido a travs de una llamada previa
a creat, open, dup, fcntl o pipe. La funcin devuelve la nueva entrada. Si falla en su ejecucin devolver -1.
A partir de ese momento ambos descriptores sern idnticos y sern afectados por los mismos cambios,
salvo por la bandera close_on_exec y la llamada close.

int dup2 (int oldfd, int newfd);

La llamada dup2 duplica al igual que dup un descriptor de fichero oldfd que ya ha sido asignado y que est
ocupando una entrada en la tabla de descriptores de fichero. Sin embargo, a diferencia de dup, la copia
sobrescribe un descriptor especificado por newfd, el cual puede o no estar siendo utilizado. A partir de ese
momento ambos descriptores sern idnticos y sern afectados por los mismos cambios, salvo por la
bandera close_on_exec y la llamada close. Es recomendable crear una copia de newfd mediante dup si
esta se va a utilizar con posterioridad.
Este tipo de llamadas suele utilizarse principalmente para redirecciones. Para ello se puede hacer uso de los
descriptores de fichero asociados a la entrada estndar, a la salida estndar y a la salida de errores estndar:
0: entrada normal (stdin).
1: salida normal (stdout).
2: salida de error (stderr).
Veamos un ejemplo de redireccin (haremos uso de la llamada execvp an no explicada):
/* dup2.c - Redireccin usando dup2 */
/* Este programa es llamado con 3 parmetros o ms:
primero = fichero salida
segundo = comando a ejecutar
tercero y sucesivos = parmetros del comando a ejecutar */
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main (int argc, char *argv[])
{
int desc_fich;
if (argc < 3) {
printf ("Formato: %s fichero comando [opciones].\n", args[0]);
exit (1);
}
desc_fich = creat (argv[1], 0777);
dup2 (desc_fich, 1); /* Redirige la salida normal al fichero */
close (desc_fich);
execvp (argv[2], &argv[2]); /* Ejecuta comando con parmetros */
exit (1);
}

A continuacin compilamos llamando dup2 al ejecutable y ejecutamos tecleando lo siguiente:


$./dup2 dup2.sal ls *.c

Tras la ejecucin se habr generado el fichero dup2.sal que contendr la informacin de salida de ls *.c.

SSOO. Llamadas al sistema


Prctica 7. Las llamadas exec, fork e identificadores de proceso y usuario.
Llamadas del sistema de gestin de procesos.

#include <unistd.h>
int execl (char *path, char *arg0,... char *argn, NULL);
int execv (char *path, char *argv[ ]);

int execlp (char *fichero, char *arg0,... char *argn, NULL);


int execvp (char *fichero, char *argv[ ]);

Las llamadas al sistema execl y execv (entre otras) permiten pasar el control del proceso que las llama a un
nuevo programa que se cargar en la misma zona de memoria. El programa que realiza la llamada de tipo
exec ser sustituido por el programa llamado y por tanto no podr retomar el control ms adelante. En
ambas llamadas, el parmetro path indica el fichero ejecutable (incluida su trayectoria) al que se pasar el
control. Por su parte, en execl existen una serie de argumentos adicionales, variables en nmero, que
determinan los parmetros a enviar al programa ejecutable dado por path. Estos parmetros son sustituidos
por un vector de cadenas en la llamada execv. En el caso de que se produzca un error, ambas llamadas
devolvern -1 y el programa que realiz la misma seguir ejecutndose.
Las llamadas execlp y execvp son similares a las anteriores, con la salvedad de que si no se indica una
trayectoria de bsqueda, el fichero se buscar en las rutas estndar donde se encuentran los ficheros
ejecutables.

#include <sys/types.h>
pid_t fork (void);

La llamada a fork hace que se cree un nuevo proceso idntico al proceso que realiza la llamada. En el
proceso que realiza la llamada (proceso padre), fork devolver el identificador del proceso creado (proceso
hijo). Sin embargo, en el nuevo proceso creado el mismo cdigo devolver 0. De esta forma, a partir de este
punto habr dos procesos idnticos en ejecucin independientes. En el caso de que se produzca un error en
la llamada, fork devolver -1 en el proceso padre y el hijo no ser creado.

#include <unistd.h>
pid_t getpid (void);
pid_t getppid (void);

La llamada getpid devuelve el identificador de proceso actual (Este valor es invariable durante la vida del
proceso). Generalmente esto se usa cuando se quiere generar un fichero temporal con un nombre nico. La
llamada getppid devuelve el identificador del proceso padre del proceso actual (Este valor puede variar
durante la vida del proceso. Si el proceso padre muere, este valor se transforma en 1). Estas funciones nunca
devuelven un error.

#include <unistd.h>
#include <sys/types.h>
uid_t getuid (void)

Devuelve el identificador real del usuario del proceso desde el que se realiza la llamada. Este usuario es
quien ejecut el programa, que puede o no coincidir con el propietario del fichero donde se almacena el
ejecutable. La funcin nunca devuelve un error.

SSOO. Llamadas al sistema


Prctica 8. Envo de seales y temporizadores.
Llamadas del sistema de gestin de procesos.

#include <stdlib.h>
void exit (int status);

Esta llamada termina la ejecucin de un proceso retornando el control al sistema y devolviendo a este el
valor indicado por status, el cual puede ser consultado mediante la variable de entorno ?.
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait (int *status);

Detiene el proceso actual hasta que un proceso hijo del mismo finalice (porque llame a la funcin exit o bien
porque reciba una seal del exterior, por ejemplo, mediante la llamada kill) Si previamente a la llamada ya
hubiera finalizado algn proceso hijo, la llamada retornara inmediatamente. La llamada devuelve un
puntero en la variable status que puede valer NULL o bien otra cosa. En este segundo caso, las siguientes
macros, haciendo uso de la variable status, determinan la causa de finalizacin del proceso hijo:
int
int
int
int

WIFEXITED (int * status)


WIXTSTATUS (int * status)
WIFSIGNALED (int * status)
WTERMSIG (int * status)

//
//
//
//

verdadero si el proceso termin con exit.


8 bits menores que exit le pasa al proceso padre.
verdadero si termina debido a alguna seal (signal).
nmero de la seal (signal) que par del proceso.

La llamada devuelve bien el identificador del proceso hijo que se detuvo, bien -1 en caso de error o bien 0
en caso de que no existiese hijo disponible.
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);

Enva el nmero de seal especificado por la variable sig al proceso indicado por pid. Cuando un proceso
recibe una seal, ejecuta un manejador de la misma (en el caso de que no se haya definido ninguno mediante
la llamada signal, se ejecuta el manejador por defecto, que generalmente concluye matando el proceso). Los
identificadores de proceso son siempre positivos. Si la variable pid tomase un valor 0 o negativo, la seal se
enviar a un grupo de procesos (ver manual para estudiar distintos casos).
#include <signal.h>
void (*signal (int seal, void (*manejador)()))();

La llamada signal asocia una funcin del tipo void nombre_funcion() a la recepcin de una determinada
seal. De esta forma, a partir de la llamada signal, cada vez que el proceso reciba una seal determinada, se
ejecutar la funcin especificada por manejador. Existen dos funciones predefinidas muy importantes que
pueden ser utilizadas como manejadores: SIG_DFL que realiza la accin por defecto asociada a la seal, y
SIG_IGN que lo que hace es ignorar la seal recibida. A continuacin se muestra un ejemplo de creacin y
uso de un determinado manejador de seal:
void manejador (); /* Capturar la seal nmero 1 */
int main () {
int cont=1;
signal (1, manejador); /* Asocia el manejador a la recepcin de la seal 1 */
while (cont<10) {
printf ("Ejecutando programa");
cont++;
sleep(1);
}
exit(0);
}
void manejador() {
printf ("Se ha recibido la seal 1. Se restaurar el manejador por defecto");
signal (1, SIG_DFL);
}
#include <unistd.h>
unsigned int sleep(unsigned int segundos);

Detiene el proceso un determinado nmero de segundos indicado por la variable segundos.

También podría gustarte