Block with fcntl

Good evening, friends

I'm learning with a book: Programming Linux by Kurt Wall (Prentice Hall)

The code below could run in two windows (./lockit /tmp/foo in both for example). There is not problem with the read block (first byte) but when one, apply the write block while in the other is with the read block yet, the error message is:

block write already by -1075043608

and appear every time you press a key (instead of show the pid of the proccess)

But, even you running the program in a window only, happens the same.

I don't get to understand it.

Can you help to correct the code?

Thanks.

/*
 * 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) {
   perror("open");
   exit(EXIT_FAILURE);
  }
  /* Establece un bloqueo de lectura */
  setlock(fd, F_RDLCK);
  printf("PID %d bloqueado para lectura %s\n", getpid(), argv[1]);
  getchar();
  /* Desbloqueo */
  setlock(fd, F_UNLCK);
  printf("PID %d unlocked %s\n", getpid(), argv[1]);
  getchar();
  close(fd);
  /* Establece un bloqueo de escritura */
  setlock(fd, F_WRLCK);
  printf("PID %d bloqueado para escritura %s\n", getpid(), argv[1]);
 
  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):
      sprintf(msg, "bloqueo de lectura ya establecido por %d\n", lock.l_pid);
      break;
     case(F_WRLCK):
      sprintf(msg, "bloqueo de escritura ya establecido por %d\n", lock.l_pid);
      break;
    }
   }
   puts(msg);
   getchar();
  }
}

---------- Post updated at 11:42 PM ---------- Previous update was at 08:18 PM ----------

Sorry, i had an error.

Deleting line --> close(fd); into /* Desbloqueo */

Adding getchar(); close(fd) after printf("PID %d bloqueado para escritura %s\n", getpid(), argv[1]);

Sorry again.

1 Like

Thanks for letting us know the fix.

I am closing this thread.