Llamadas al Sistema C para Operaciones con Ficheros en Linux/Unix
Enviado por Programa Chuletas y clasificado en Informática y Telecomunicaciones
Escrito el en
español con un tamaño de 10,62 KB
Operaciones Fundamentales con Ficheros en C (Llamadas al Sistema)
int open(char *name, int flags, mode_t mode)
Abre un fichero especificado por name.
- Devuelve un descriptor de fichero (
fd) si tiene éxito, o -1 en caso de error. - flags: Determinan el modo de apertura:
O_WRONLY: Solo escritura.O_RDONLY: Solo lectura.O_RDWR: Lectura y escritura.O_APPEND: Añadir al final del fichero en cada escritura.O_CREAT: Crea el fichero si no existe (requiere el argumentomode).O_TRUNC: Trunca el fichero a tamaño 0 si existe y se abre para escritura.
- Si se crea el fichero (
O_CREAT),modeespecifica los permisos (afectados porumask). - Asigna el
fddevuelto a una entrada en la tabla de descriptores de fichero del proceso (BCP), incrementa el contador de referencias del fichero (nrefs) y el contador de aperturas (nopens).
int creat(char *name, mode_t mode)
Crea y abre un fichero exclusivamente en modo escritura (O_WRONLY | O_CREAT | O_TRUNC).
- Si el fichero no existe, lo crea vacío. El UID del fichero será el UID efectivo del proceso (
UIDef), el GID será el GID efectivo (GIDef), y los permisos seránmode & ~umask. - Si el fichero ya existe, lo trunca a tamaño 0 sin alterar sus permisos originales.
- Nota: La función
opencon las flags adecuadas es generalmente preferida sobrecreat.
int close(int fd)
Cierra un descriptor de fichero, rompiendo la asociación entre fd y el fichero correspondiente.
- Decrementa el contador de referencias (
nrefs) de la entrada de la tabla de ficheros abiertos asociada. - Si
nrefsllega a 0, se libera la entrada de la tabla y se decrementa el contador global de aperturas (nopens) del i-nodo. - Devuelve 0 si tiene éxito, o -1 en caso de error.
int dup(int fd)
Duplica un descriptor de fichero existente.
- Crea y devuelve un nuevo descriptor de fichero (
fd2) que comparte la misma entrada en la tabla de ficheros abiertos quefd. - Esto significa que
fdyfd2comparten el mismo fichero, el mismo puntero de lectura/escritura (PL/E) y el mismo modo de acceso. - Incrementa el contador de referencias (
nrefs) de la entrada compartida. - El nuevo descriptor
fd2será el menor número entero no negativo disponible en la tabla de descriptores del proceso. - Devuelve el nuevo descriptor si tiene éxito, o -1 en caso de error.
int dup2(int oldfd, int newfd)
Duplica un descriptor de fichero en un descriptor específico.
- Hace que
newfdse refiera a la misma entrada de la tabla de ficheros abiertos queoldfd. - Si
newfdya estaba abierto, se cierra implícitamente antes de la duplicación (de forma atómica). - Si
oldfdynewfdson iguales,dup2no hace nada y devuelvenewfd. - Equivalente conceptualmente a
close(newfd);seguido de una asignación similar adup(oldfd), pero garantizando quenewfdsea el descriptor resultante. - Devuelve
newfdsi tiene éxito, o -1 en caso de error. - Ejemplo:
dup2(fd, 1)redirige la salida estándar (descriptor 1) al fichero asociado confd.
ssize_t read(int fd, void *buf, size_t n_bytes)
Lee datos de un fichero.
- Intenta leer hasta
n_bytesdel fichero asociado afdy los almacena en el buffer apuntado porbuf. - Devuelve el número de bytes realmente leídos (puede ser menor que
n_bytessi se alcanza el final del fichero o si hay interrupciones). - Devuelve 0 si se alcanza el final del fichero (EOF).
- Devuelve -1 en caso de error.
- Incrementa la posición del puntero de lectura/escritura (PL/E) según el número de bytes leídos.
ssize_t write(int fd, void *buf, size_t nbytes)
Escribe datos en un fichero.
- Escribe hasta
nbytesdesde el buffer apuntado porbufen el fichero asociado afd. - Devuelve el número de bytes realmente escritos (puede ser menor que
nbytessi ocurre un error o interrupción). - Devuelve -1 en caso de error.
- Incrementa la posición del puntero de lectura/escritura (PL/E) según el número de bytes escritos.
- Puede aumentar el tamaño del fichero si la escritura se realiza más allá del final actual.
off_t lseek(int fd, off_t offset, int whence)
Modifica la posición del puntero de lectura/escritura (PL/E) del fichero asociado a fd.
- Devuelve la nueva posición del puntero (medida en bytes desde el inicio del fichero) si tiene éxito, o -1 en caso de error.
- El cálculo de la nueva posición depende de
whence:SEEK_SET: La nueva posición esoffsetbytes desde el inicio del fichero.SEEK_CUR: La nueva posición es la posición actual másoffsetbytes.SEEK_END: La nueva posición es el tamaño actual del fichero másoffsetbytes.
lseekpor sí solo no aumenta el tamaño del fichero. Sin embargo, si se posiciona el puntero más allá del final actual y luego se realiza una escritura, el espacio intermedio se rellena con bytes nulos (\0).- Ejemplos útiles:
- Obtener tamaño del fichero:
tam = lseek(fd, 0, SEEK_END); - Obtener posición actual:
pos_act = lseek(fd, 0, SEEK_CUR); - Volver al inicio:
lseek(fd, 0, SEEK_SET);
- Obtener tamaño del fichero:
int link(char *existing, char *new)
Crea un nuevo enlace físico (hard link) llamado new que apunta al mismo i-nodo que el fichero existing.
- Incrementa el contador de enlaces del i-nodo.
- Requiere permisos de escritura en el directorio donde se creará
new. newno debe existir previamente.existingynewson indistinguibles a nivel de fichero; comparten los mismos datos y metadatos (excepto el nombre y la ruta).- Devuelve 0 si tiene éxito, o -1 en caso de error.
int symlink(char *existing, char *new)
Crea un enlace simbólico (symbolic link o soft link) llamado new que apunta a la ruta existing.
newes un fichero especial que contiene la ruta deexisting.- Requiere permisos de escritura en el directorio donde se creará
new. newno debe existir previamente.- Cuando se accede a
new, el sistema operativo generalmente sigue la ruta almacenada para acceder aexisting. - Los permisos se comprueban tanto para el enlace simbólico como para el fichero/directorio apuntado (
existing) y todos los componentes de su ruta. - Si
existinges eliminado o renombrado, el enlacenewqueda "roto" o "abandonado" (dangling link). - Devuelve 0 si tiene éxito, o -1 en caso de error.
int unlink(char *pathname)
Elimina un nombre (enlace) del sistema de ficheros.
- Borra la entrada
pathnamedel directorio que la contiene. - Decrementa el contador de enlaces del i-nodo asociado a
pathname. - Requiere permisos de escritura en el directorio padre de
pathname. - Si el enlace eliminado era el último enlace físico al fichero y ningún proceso tiene el fichero abierto, el espacio ocupado por los datos del fichero y su i-nodo se marcan como libres (el fichero se borra efectivamente).
- Si era el último enlace físico pero algún proceso aún tiene el fichero abierto, el fichero permanecerá accesible para esos procesos y sus datos e i-nodo no se liberarán hasta que el último proceso cierre su descriptor de fichero asociado.
- Si
pathnameera un enlace simbólico, simplemente se elimina el propio enlace simbólico sin afectar al fichero o directorio al que apuntaba. - Devuelve 0 si tiene éxito, o -1 en caso de error.
int pipe(int fd[2])
Crea una tubería (pipe), un mecanismo de comunicación unidireccional entre procesos.
- Crea un par de descriptores de fichero conectados, que apuntan a un buffer interno gestionado por el kernel (asociado a un i-nodo de tipo tubería).
- Los descriptores se devuelven en el array
fd:fd[0]: Extremo de lectura de la tubería.fd[1]: Extremo de escritura de la tubería.
- Devuelve 0 si tiene éxito, o -1 en caso de error.
- Comportamiento de
readsobrefd[0]:- Si la tubería está vacía y hay algún proceso que tiene abierto
fd[1], la llamada areadse bloquea hasta que se escriban datos. - Si la tubería está vacía y todos los descriptores de escritura (
fd[1]) han sido cerrados,readdevuelve 0 (EOF).
- Si la tubería está vacía y hay algún proceso que tiene abierto
- Comportamiento de
writesobrefd[1]:- Si la tubería está llena (ha alcanzado su capacidad máxima) y hay algún proceso que tiene abierto
fd[0], la llamada awritese bloquea hasta que se lea espacio. - Si la tubería está llena o no, pero todos los descriptores de lectura (
fd[0]) han sido cerrados, el proceso escritor recibe la señalSIGPIPE(que por defecto termina el proceso).
- Si la tubería está llena (ha alcanzado su capacidad máxima) y hay algún proceso que tiene abierto
- Importante: Los procesos que usan la tubería (generalmente padre e hijo después de un
fork) deben cerrar los extremos de la tubería que no utilizan para evitar bloqueos indefinidos o condiciones de EOF incorrectas.