Let us learn manipulating file descriptor using fcntl system call in Linux. fcntl system call works on open file descriptors and manipulates it based on the command supplied in the fcntl(int fd, int cmd, ../*arg*/).

Syntax of fcntl() system call

#include <unistd.h>
#include <fcntl.h>

int fcntl(int fd, int cmd, ... /* arg */ );
  • fcntl requires a valid file descriptor
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

int main ()
{
  int flags;
  if ((flags = fcntl (-1, F_SETFL, 0)) < 0)
    {
      printf ("fcntl: ");
    }
  printf ("\n %d\n", flags);
}

ubuntu@seco-desk-ubuntu:~$ gcc main.c

ubuntu@seco-desk-ubuntu:~$ ./a.out

fcntl: : Bad file descriptor -1 The return value is -1 , it means fcntl() fails , becuase the first argument -1 to the fcntl() system call is not a valid file descriptor.

What is the use of fcntl system call in c?

  • To duplicate an existing descriptor (cmd = F_DUPFD)
#include <stdlib.h>
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

int main ()
{
  /* create a temp file in /tmp */
  int fd;
  char name[] = "/tmp/FooXXXXXX";
  fd = mkstemp(name);
  printf("The new file name is %s\n",name);
 
  int duplicate_fd;

  // duplicate fd with duplicate_fd
  duplicate_fd = fcntl(fd, F_DUPFD,0);

  // work on duplicate fd
  write(duplicate_fd, "hello" , 5);

   /* close fd */
   close(fd);
}
  • get/set file descriptor flags (cmd = F_GETFD or F_SETFD),
  • get/set asynchronous I/O ownership (cmd = F_GETOWN or F_SETOWN),
  • get/set record locks (cmd = F_GETLK, F_SETLK, or F_SETLKW).

Ref:

https://linux.die.net/man/2/fcntl



Related Contents to follow