seguridad - qué tipos de archivos no puedo adjuntar a un correo electronico
¿Cómo bloqueo archivos usando fopen()? (6)
Me pregunto si hay alguna forma de bloquear y desbloquear un archivo en Linux cuando abro un archivo usando fopen
(no open
).
Basado en la pregunta de desbordamiento de pila C fopen vs open , se prefiere fopen
sobre open
.
¿Cómo puedo implementar mi propio bloqueo de archivos (si es posible) creando y eliminando archivos de bloqueo?
En Linux, si necesita un descriptor de archivo (por ejemplo, para pasar a una primitiva de bloqueo de archivos), puede usar fileno(FILE*)
para recuperarlo. Después de recuperar el descriptor de archivo, puede usarlo como si hubiera sido devuelto por open
.
Por ejemplo, en lugar de
int fd = open("myfile.txt", flags);
int result = flock(fd, LOCK_SH);
igualmente podría hacer esto:
FILE* f = fopen("myfile.txt", "r");
int result = flock(fileno(f)), LOCK_SH);
Tenga en cuenta que fileno
se define en el estándar POSIX, pero no en los estándares C o C ++.
En cuanto a su segunda pregunta, la página del manual de Linux open()
tiene esto que decir:
La solución para realizar el bloqueo de archivos atómicos usando un archivo de bloqueo es crear un archivo único en el mismo sistema de archivos (por ejemplo, incorporando nombre de host y pid), use el link(2) para crear un enlace al archivo de bloqueo. Si link () devuelve 0, el bloqueo es exitoso. De lo contrario, use stat(2) en el archivo único para verificar si su recuento de enlaces ha aumentado a 2, en cuyo caso el bloqueo también es exitoso.
Estoy totalmente en desacuerdo con la afirmación de que se fopen
en lugar de open
. Es imposible usar fopen
forma segura al escribir un archivo en un directorio que otros usuarios puedan escribir debido a las vulnerabilidades del enlace simbólico / condiciones de carrera, ya que no hay O_EXCL
opción O_EXCL
. Si necesita usar stdio en sistemas POSIX, es mejor usar open
y fdopen
lugar de llamar a fopen
directamente.
Ahora, en cuanto a bloquearlo depende de lo que quieras hacer. POSIX no tiene un bloqueo obligatorio como Windows, pero si solo quiere asegurarse de que está trabajando con un nuevo archivo y no está obstruyendo un archivo existente o siguiendo un enlace simbólico, utilice las opciones O_EXCL
y O_NOFOLLOW
, según corresponda. Si desea realizar un bloqueo cooperativo más allá de la apertura inicial, use los bloqueos fcntl
.
Hay otra forma con la función open () , pero no estoy seguro acerca de este llamado archivo bloqueado. Estoy usando permisos de archivo para abrir un archivo.
El código está aquí:
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#define FILE_NAME "hello.txt"
int main()
{
int fd;
fd = open(FILE_NAME, O_CREAT, S_IRWXU);
// Error checking
if(fd == -1){
perror("[error]/n");
}
else{
printf("[file is opened]/n");
}
return 0;
}
Utilicé una bandera para permisos (tercer argumento). Esta bandera otorga permisos de lectura, escritura y ejecución al usuario.
$ls -alh
total 24K
drwxrwxr-x 2 arien arien 4.0K Dec 28 20:56 .
drwxrwxr-x 18 arien arien 4.0K Dec 27 22:20 ..
-rwxrwxr-x 1 arien arien 8.5K Dec 28 20:56 fopen
-rw-rw-r-- 1 arien arien 290 Dec 28 20:56 fopen.c
-rwx------ 1 arien arien 0 Dec 28 20:55 hello.txt
Un pequeño consejo: si está utilizando Ubuntu o Debian, puede ver la descripción de las funciones con las páginas man de man [function_name]
open () .
Los archivos se pueden bloquear utilizando flock()
. Su sintaxis es
#include <sys/file.h>
#define LOCK_SH 1 /* shared lock */
#define LOCK_EX 2 /* exclusive lock */
#define LOCK_NB 4 /* don''t block when locking */
#define LOCK_UN 8 /* unlock */
int flock(int fd, int operation);
El primer archivo se abre usando fopen()
o open()
. Entonces este archivo abierto se bloquea usando flock()
como se indica a continuación
int fd = open("test.txt","r");
int lock = flock(fd, LOCK_SH); // Lock the file . . .
// . . . .
// Locked file in use
// . . . .
int release = flock(fd, LOCK_UN); // Unlock the file . . .
Si desea implementar su propio bloqueo simplemente, sugiero la respuesta de Rob de usar el rebaño. Si desea implementarlo de una manera compleja, como por ejemplo para una alta disponibilidad, puede intentar algo como usar un hilo para tocar un archivo en un intervalo regular. Todos los demás programas que deseen bloquear el archivo también deben revisar el archivo para ver si su tiempo de actualización se ha actualizado en otro intervalo fijo, pero más amplio (la parte más grande es importante). Es probable que esto sea una exageración para la mayoría de las aplicaciones, pero maneja cosas como choques, congelamientos, etc. mucho mejor que el rebaño.
Tenga en cuenta que en el siguiente código, fopen
fallará (y devolverá NULL) si el archivo de bloqueo /var/lock/my.lock
no existe.
FILE* f = fopen("/var/lock/my.lock", "r");
int result = flock(fileno(f)), LOCK_SH);
Use fopen
con w+
si necesita que se cree el archivo de bloqueo si no existe.
FILE* f = fopen("/var/lock/my.lock", "w+");
int result = flock(fileno(f)), LOCK_SH);