De nuevo me dirijo a vosotros con un problema de programación en linux. Esta vez en relación al bloqueo de descriptores de archivo.
Como he comentado en otra ocasión, estoy siguiendo el libro de Prentice Hall de Kurt Walt Programación en Linux y, aunque lentamente voy progresando, gracias al libro y a vuestra ayuda.
En esta ocasión se trata de ejecutar el programa desde dos ventanas distintas (./lockit /tmp/foo) y ver como permite a ambos el bloqueo de lectura (del primer byte) pero cuando en una de ellas pasas al bloqueo de escritura (El programa usa getchar() para detener la ejecución) debe decirte que el pid del programa que lo ejecuta en el otro terminal aún lo tiene bloqueado para lectura y no permitírlo. Bien, esto no me ha funcionado, incluso ejecutándolo en un único terminal la salida que obtengo al ejecutar el bloqueo de escritura es:
bloqueo de escritura ya establecido por -1075043608
cuando debería escribir lo que haya en el campo lock.l_pid, que según la página man de fcntl es lo que debe imprimir.
En fin, si podéis ayudarme os lo agradeceria. Más abajo el código.
Un saludo.
Código
/* * lockit.c - Establece el bloqueo en un archivo */ #include <unistd.h> #include <sys/file.h> #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> /* Establece un bloqueo de tipo en el descriptor fd */ void setlock(int fd, int type); int main ( int argc, char *argv[] ) { int fd; /* Abre el archivo */ fd = open(argv[1], O_RDWR | O_CREAT, 0666); if (fd < 0) { } /* Establece un bloqueo de lectura */ setlock(fd, F_RDLCK); /* Desbloqueo */ setlock(fd, F_UNLCK); close(fd); /* Establece un bloqueo de escritura */ setlock(fd, F_WRLCK); return EXIT_SUCCESS; } /* ---------- end of function main ---------- */ void setlock(int fd, int type) { struct flock lock; char msg[80]; /* Describe el bloqueo que queremos */ lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 1; /* bloquea un solo bit */ while (1) { lock.l_type = type; /* Bloqueo establecido y vuelta al que llama */ if ((fcntl(fd, F_SETLK, &lock)) == 0) return; /* Busca por qué no podemos establecer el bloqueo */ fcntl(fd, F_GETLK, &lock); if(lock.l_type != F_UNLCK) { switch(lock.l_type) { case(F_RDLCK): break; case(F_WRLCK): break; } } } }