CREAT

int creat (nombre, permisos) /* crea un fichero */

char *nombre; /* nombre camino */

int permisos; /* bits de permisos */

Crea un fichero y lo abre en modo escritura, independiente del modo. Sus parámetros son el nombre del fichero y el permiso.

fd = CREAT("ac", 0751)

Crea un fichero de nombre ac y con permiso 0751.

Permiso está escrito en octal, cada dígito tiene tres bits que se relacionan con los modos rwx, lectura, escritura y ejecutar, un uno significa permiso, cero no permiso.

El tercer dígito (7) se refiere al propietario rwx todo.
El segundo dígito (5) a los usurarios del grupo r-x leer y ejecutar.
El primer dígito (1) al resto --x sólo ejecutar.

Si el fichero ya existe, el fichero se trunca a longitud cero, si el permiso es correcto.

Esta llamada nos devuelve el fd (descriptor del fichero) que se utiliza para posteriores referencias al fichero.

 

MKNOD

int mknod (nombre, modo, equipo) /* crea un fichero especial */

char *nombre; /* fichero a crearse */

int modo; /* modo del nuevo fichero */

int equipo; /* numero de equipo */

Crea un fichero especial, es solo llamable por el super usuario.

fd = mknod ("/dev/tty2", 020744, 0x0402);

Crea un fichero llamado /dev/tty2 (nombre usual para el terminal 2)
Modo en octal 020744, indica que es un fichero especial en modo carácter c..rwxr--r--
El tercer parámetro expresa en el byte más significativo 04 (mayor equipo) el tipo de equipo (disco, terminal impresora, etc) y en el byte menos significativo (menor equipo) el número dentro de su tipo, en este caso 02.

 

OPEN

Abre un fichero o crea un fichero, forma moderna de creat.

int open (fichero, modo) /* abre un fichero */

char *fichero; /* nombre paso */

int modo; /* lectura escritura o ambos */

Abre un fichero, declarando un identificador y el como.

O_RDONLY (0) -> lectura

O_WRONLY (1) -> escritura

O_RDWR (2) -> ambos

Devuelve el descriptor del fichero, (fd) para posteriormente utilizarlo en lecturas o escrituras; -1 en caso de error.

 

CLOSE

Cierra un fichero especificado por su descriptor.

int close (fd) /* cierra un fichero */

int fd; /* descriptor del fichero */

devuelve -1 en caso de error, y cero en caso de exito

 

READ

int read(fd, buffer, nbytes) /* lectura de un fichero */

int fd; /* descriptor del fichero */

char *buffer; /* dirección del buffer */

unsigned nbytes; /* numero de bytes a leer */

devuelve numero de bytes leídos, 0 un EOF, -1 error. 

 

WRITE

int write (fd, buffer, nbytes) /* escribe en un fichero */

int fd; /* descriptor de un fichero */

char *buffer; /* dirección del buffer */

unsigned nbytes; /* numero de bytes a escribir */

devuelve el numero de bytes escritos o -1 si hay errror.

Lectura, escritura secuencial, cada vez que se lee o escribe, el pointer asociado con el fichero es incrementado n bytes.

 

LSEEK

Mueve el pointer del fichero a una determinada posición, utilizado para acceso directa. Tiene tres parámetros.

long lseek(fd, offset, de_donde) /* mueve el pointer */

int fd; /* identificador del fichero */

long offset; /* desplazamiento dentro del fichero */

int de_donde; /* si la posición es relativa al principio 0, o al final del fichero 2, o actual 1*/

Lseek devuelve la posición absoluta del pointer después del cambio.

 

STAT

int stat(nombre, p) /* lee el estado de un fichero */

char *nombre; /* nombre camino */

struct stat *p; /* información del estado */

 

FSTAT

int fstat(fd, p) /* lee el estado de un fichero */

int fd; /* descriptor de un fichero */

struct stat *p /* información del estado */

Devuelve -1 si hay error, 0 si exito

Nos da información relativa a un fichero.

Modo, directorio, tipo de fichero, tamaño, última modificación, etc.

Estas llamadas difieren solo en la forma de especificar el fichero (nombre o identificador).

El segundo parámetro es un pointer a una estructura donde va a colocarse la información. La forma de esta estructura es:

struct stat {

short st_dev; /* equipo donde el nodo esta */

unsigned short st_ino; /* numero del nodo */

unsigned short st_mode; /* palabra de modo */

short st_nlink; /* numero de enlaces */

short st_uid; /* identificador del usuario */

short st_gid; /* identificador del grupo */

short st_rdev; /* mayor/menor fichero especial */

short st_size; /* tamaño del fichero */

short st_atime; /* igual que st_mtime */

short st_mtime; /* fecha de la ultima modificación */

short st_ctime; /* hora de la última modificación del nodo-i */

};

Existen tres tiempos, para compatibilizar con UNIX.

 

DUP

int dup(fd) /* duplica el descriptor de un fichero */

int fd; /* descriptor de un fichero abierto */

Devuelve el nuevo descriptor del fichero o -1 si hay error

Se utiliza para manejar descriptores de ficheros.

Ejemplo: Consideremos la siguiente acción a un programa.

1) Cerrar la salida standar (descriptor de fichero = 1).

2) Utilizar otro fichero como salida standar.

3) Utiliza funciones de escritura para la salida standar (printf).

4) Recuperar la situación original.

Esto se puede realizar:

- cerrando con descriptor de fichero igual a uno

- abriendo un nuevo fichero que será la nueva salida standar

pero será imposible recuperar la situación más tarde.

La solución correcta es:

-Ejecutar fd = dup(1)

El cual origina un nuevo descriptor para la salida standar, la cual ahora tiene dos descriptores fd y 1.

-Cerrar la salida standar close(1), (se pierde el 1).

-Abrir un fichero (open) (se recupera para éste el 1).

Para recuperar la situación original.

- Cerrar con el descriptor igual a uno.

- Ejecutar n = dup(fd) para recuperar el descriptor 1 que apunta al mismo fichero que fd.

- Cerrar con fd y volvemos a la situación original.

Esto se entiende si las asignaciones de descriptores son secuenciales, se asigna el menor descriptor disponible.

El dup tiene una variante, que permite a un descriptor, que no ha sido asignado, referenciar a un fichero abierto.

dup2 (fd,fd2);

fd --> es el descriptor de un fichero abierto

fd2 --> el descriptor no asignado que va a referenciar al mismo fichero que fd.

Si fd referencia a la entrada standar (0) y fd2 es 4, después de la llamada la entrada standar se podrá referenciar como 0 y como 4.

 

PIPE

int pipe(pfd) /* crea un pipe */

int pfd[2]; /* descriptores de los ficheros */

La llamada Pipe, crea un pipe y devuelve dos enteros descriptores de fichero.

pfd[0] --> es el descriptor para leer

pfd[1] --> es el descriptor para escribir

devuelve -1 si hay error 0 si éxito.

La comunicación entre procesos en MINIX, utiliza pipes. Cuando ejecutamos el comando.

cat file1 file2 | sort

El Shell crea un pipe y hace que la salida standar del primer proceso (cat) se escriba en el pipe, y que la entrada standar del segundo proceso (sort) pueda leer de pipe.

ejemplo: procedimiento que crea dos procesos, con la salida del primero, escrita sobre un pipe, y leída por el segundo.

#defineSTD_INPUT 0 /*fd de la entrada estandar */

#define STD_OUTPUT 1 /* fd de la salida estandar */

pipeline(proceso1, proceso2)

char *proceso1, *proceso2; /* punteros a nombres de programa */

{

int fd[2];

pipe(&fd[0]); /* crea un pipe */

if (fork() != 0) { /* el padre ejecuta estas sentencias */

close(fd[0]); /* proceso uno no necesita leer de pipe */

close(STD_OUTPUT); /*prepara para una nueva salida estandar.*/

dup(fd[1]); /* coloca la salida estandar a fd[1] */

close(fd[1]); /* pipe no necesita ninguno más */

execl(proceso1, proceso1, 0);

} else {

/* el proceso hijo ejecuta estas sentencias */

close(fd[1]); /* proce. dos no necesita escribir en pipe */

close(STD_INPUT); /*prepara para una nueva entrada estandar.*/

dup(fd[0]); /* coloca la entrada estandar a fd[0] */

close(fd[0]); /* pipe no necesita ninguno más */

execl(proceso2, proceso2, 0);

}

}

Escritura en un PIPE

Los datos se escriben en orden de llegada.

Si el pipe se llena (tamaño finito # 4kB), el proceso que escribe se bloquea hasta que datos son extraídos del pipe.

Lectura en un PIPE

Los datos se leen en el orden de llegada FIFO

Una vez un dato es leído, es sacado del pipe y no puede ser leído de nuevo.

Si el pipe esta vacio el proceso que lee se bloquea hasta que se introducen datos en el pipe.

Close sobre un PIPE

Libera el descriptor del pipe y puede ser asignado

Si se cierra el descriptor para escritura close(pfd[1]); actúa como un end-of-file (final de fichero) para el lector.

 

IOCTL

int ioctl(fd, comando, tbuf) /* control de un fichero especial como un terminal */

int fd; /* descriptor del fichero */
int comando; /* comando */
struct termio *tbuf; /* información del terminal */
Devuelve -1 si hay error, 0 si exito.

Tiene su aplicación mas común en terminales, se utiliza para:

- Cambiar el carácter de borrado.

- Cambiar el modo del terminal.

modo "cooked" (en POSIX modo canónico)

Para leer espera por una línea completa.

backspace --> trabaja normalmente

break --> trabaja normalmente

CRTL S --> Para la salida en el terminal

CTRL Q --> Reanuda la salida en el terminal

CTRL D --> fin de fichero

DEL --> señal de interrupción

CRTL \ --> señal quit para producir un volcado.

 

modo "raw" (en POSIX modo no canónico)

Todos las funciones anteriores son desabilitadas.

Los caracteres pasan directamente al programa, sin ningún proceso.

Para leer no espera por una línea completa.

 

modo "Cbreak" (en POSIX modo canónico variando ciertos parámetros)

inhibidos: backspace, break, CTRL D

permitidos: CTRL S, CTRL Q, DEL CTRL\

Puede leer líneas parciales.

La forma de esta llamada es:

ioctl (fd, operación, &sgttyb);

fd --> especifica un fichero

operación --> específica una operación

&sgttyb --> dirección a una estructura de flags

Las operaciones soportadas por MINIX son:

TIOCSETP --> asigna los valores de la estructura a los parámetros del terminal.

TIOCGETP --> Llena la estructura con los valores actuales del terminal.

La estructura está definida en el fichero sgtty.h

/* Estructura de datos para IOCTL llamadas TIOCGETP/TIOCSETP */

struct sgttyb {

char sg_ispeed; /* velocidad de entrada (no se usa) */

char sg_ospeed; /* velocidad de salida (no se usa) */

char sg_erase; /* carácter de borrado */

char sg_kill; /* carácter de matar */

int sg_flags; /* flags de modo */

};

/* Campos de sg_flags */

#define XTABS 0006000 /* a uno causa la expansión de tab */

#define RAW 0000040 /* a uno permite el modo raw */

#define CRMOD 0000020 /* a uno LF transforma en LF + CR */

#define ECHO 0000010 /* a uno permite el eco */

#define CBREAK 0000002 /* a uno permite el modo Cbreak */

#define COOKED 0000000 /* ni CBREAK ni RAW */

#define TIOCGETP (( 't'<<8 ) | 8 )

#define TIOCSETP (( 't'<<8 ) | 9 )

Los bits en sg_flags pueden ponerse estando en los modos "raw" o "cbreak".

XTABS debe colocarse a cero cuando utilizamos terminales que realizan la tabulación por hardware.

XTABS puesto a uno, hace que LF se transforme en LF + CR.

ECHO puesto a uno, produce el eco de los caracteres hacia el terminal. (cero, para palabras claves).

IOCTL puede utilizarse con otra estructura de datos, (tchars) para cambiar:

- el carácter de interrupción

- el carácter quit

- el carácter de parada

- el carácter de reanudar

- el carácter de fin de fichero

 

ACCESS(name,amode) - verifica los accesos de un programa a un fichero. Un programa puede ejecutarse con el UID de otro, como el caso de comandos del sistema.

 

RENAME(viejo, nuevo) - cambia el nombre viejo de un fichero por nuevo. 

 

FCNTL(fd, cmd, ...) - bloqueo, candados, de partes de un fichero y otras operaciones.