Foro de elhacker.net

Sistemas Operativos => GNU/Linux => Mensaje iniciado por: joe2011 en 29 Septiembre 2013, 23:29 pm



Título: Bloqueos en Linux con fcntl.
Publicado por: joe2011 en 29 Septiembre 2013, 23:29 pm
Buenas noches de nuevo, compañeros del foro

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
  1. /*
  2.  * lockit.c - Establece el bloqueo en un archivo
  3.  */
  4. #include <unistd.h>
  5. #include <sys/file.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10.  
  11. /* Establece un bloqueo de tipo en el descriptor fd */
  12. void setlock(int fd, int type);
  13.  
  14. int main ( int argc, char *argv[] )
  15. {
  16. int fd;
  17. /* Abre el archivo */
  18. fd = open(argv[1], O_RDWR | O_CREAT, 0666);
  19. if (fd < 0) {
  20. perror("open");
  21. exit(EXIT_FAILURE);
  22. }
  23.  
  24. /* Establece un bloqueo de lectura */
  25. setlock(fd, F_RDLCK);
  26. printf("PID %d bloqueado para lectura %s\n", getpid(), argv[1]);
  27.  
  28. /* Desbloqueo */
  29. setlock(fd, F_UNLCK);
  30. printf("PID %d unlocked %s\n", getpid(), argv[1]);
  31. close(fd);
  32.  
  33. /* Establece un bloqueo de escritura */
  34. setlock(fd, F_WRLCK);
  35. printf("PID %d bloqueado para escritura %s\n", getpid(), argv[1]);
  36.  
  37.  
  38. return EXIT_SUCCESS;
  39. } /* ----------  end of function main  ---------- */
  40.  
  41. void setlock(int fd, int type)
  42. {
  43. struct flock lock;
  44. char msg[80];
  45.  
  46. /* Describe el bloqueo que queremos */
  47. lock.l_whence = SEEK_SET;
  48. lock.l_start = 0;
  49. lock.l_len = 1; /* bloquea un solo bit */
  50.  
  51. while (1) {
  52. lock.l_type = type;
  53. /* Bloqueo establecido y vuelta al que llama */
  54. if ((fcntl(fd, F_SETLK, &lock)) == 0)
  55. return;
  56.  
  57. /* Busca por qué no podemos establecer el bloqueo */
  58. fcntl(fd, F_GETLK, &lock);
  59. if(lock.l_type != F_UNLCK) {
  60. switch(lock.l_type) {
  61. case(F_RDLCK):
  62. sprintf(msg, "bloqueo de lectura ya establecido por %d\n", lock.l_pid);
  63. break;
  64. case(F_WRLCK):
  65. sprintf(msg, "bloqueo de escritura ya establecido por %d\n", lock.l_pid);
  66. break;
  67. }
  68. }
  69. puts(msg);
  70. }
  71. }
  72.  


Título: Re: Bloqueos en Linux con fcntl.
Publicado por: joe2011 en 30 Septiembre 2013, 23:33 pm
¡Vaya error más tonto! Disculpen las molestias.

He cerrado el descriptor en el módulo Desbloqueo, y ha de cerrarse en el bloque que establece el bloqueo de escritura, posteriormente a un getchar ()

Es decir, borrar la línea 33, e incluir en las líneas 38 y 39

Código
  1. close(fd);