Chapter Contents

Previous

Next
fcntl

fcntl



Control Open File Descriptors

Portability: POSIX.1 conforming, UNIX compatible


SYNOPSIS
DESCRIPTION
RETURN VALUE
PORTABILITY
EXAMPLES
SEE ALSO


SYNOPSIS

#include <sys/types.h>
#include <fcntl.h>

int fcntl(int filedes, int action, argument);


DESCRIPTION

fcntl controls open USS file descriptors and sockets. filedes is the file descriptor. action is the action to be performed on the file or socket. For a nonintegrated socket, the only actions that can be specified are F_GETFL and F_SETFL . The third argument required by some actions is argument . The type of this argument depends on the action.

You can specify the following actions with fcntl :
F_DUPFD duplicates the file descriptor and returns the lowest available file descriptor greater than or equal to argument . This duplicate file descriptor refers to the same file as filedes .
F_DUPFD2 duplicates the file descriptor and returns a file descriptor specified by argument . The file descriptor specified by argument is closed and is then used as the new file descriptor. This duplicate file descriptor refers to the same file as filedes .
F_GETFD returns the file descriptor flags for filedes . This action has no effect if filedes is a non-integrated socket.
F_SETFD sets the file descriptor flags for filedes . New flag settings are specified by argument . This action has no effect if filedes is a nonintegrated socket.
F_GETFL returns the file-status flags and file access mode flags for filedes . If filedes is a nonintegrated socket, only the setting of O_NONBLOCK is significant.
F_SETFL Sets the flag status flags for filedes . New flag settings are specified by argument . fcntl does not change the file access mode. If filedes is a nonintegrated socket, only the O_NONBLOCK setting may be changed.
F_GETLK returns locking information for a file.
F_SETLK sets or clears a file segment lock.
F_SETLKW sets or clears a file segment lock. If a lock is blocked by other locks, fcntl waits until it can set or clear the lock.
F_CLOSFD closes a range of file descriptors. argument specifies the upper limit of the range. filedes is the lower limit. If argument is a -1, all file descriptors greater than or equal to fildes are closed.

The following flags and masks are defined in <fcntl.h> :
O_ACCMODE This mask defines the bits that comprise the file access mode. O_ACCMODE can be ANDed with the value stored by the F_GETFL action to isolate the file access mode.
FD_CLOEXEC If set to 1, requests that the file descriptor be closed if the process calls an exec function. If set to 0, the file descriptor remains open if the process calls exec .
O_APPEND If set to 1, every write operation begins at the end of the file.
FD_CLOFORK If set to 1, requests that, when a fork occurs, the file descriptor be closed for the child process. If set to 0, the file descriptor remains open for any child process.
O_NONBLOCK If set to 1, read and write operations return an error if I/O cannot be immediately performed. If set to 0, read and write operations wait until I/O can be performed. Note that the traditional BSD file status flag FNDELAY is defined in <fcntl.h> as a synonym for O_NONBLOCK .
O_RDONLY This file access mode value indicates the file is opened for input only.
O_RDWR This file access mode value indicates the file is opened for both input and output.
O_WRONLY This file access mode value indicates the file is opened for output only.


RETURN VALUE

fcntl returns the value specified by action . The fcntl function returns a -1 if it is not successful.


PORTABILITY

The F_CLOSFD action and the FD_CLOFORK flag are extensions defined by IBM to the POSIX.1 standard.


EXAMPLES

This example updates a counter stored in the first four bytes of an HFS file. It uses the record-locking feature of fcntl to ensure that two processes running the same program do not update the file simultaneously.

    /* This example requires cxompilation with the posix option. */
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

main() {
   int fd;
   long count;
   struct flock lock;
   int rc;

      /* If the file does not yet exist, create it, and treat the */
      /*  counter as 0.  If the file does exist, do not truncate  */
      /*  it, as we need the old data.                            */
   fd = open("/u/yvonne/counter", O_CREAT | O_RDWR,
             S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
   if (fd < 0) {
      perror("open error");
      exit(EXIT_FAILURE);
   }
   lock.l_type = F_WRLCK;
   lock.l_whence = SEEK_SET;
   lock.l_start = 0L;
   lock.l_len = sizeof(count);
   rc = fcntl(fd, F_SETLKW, &lock);            /* Lock bytes 0-3. */
   if (rc == -1) {
      perror("fcntl F_WRLCK error");
      exit(EXIT_FAILURE);
   }
   rc = read(fd, &count, sizeof(count));
   if (rc == -1) {
      perror("read");
      exit(EXIT_FAILURE);
   }
   if (rc < sizeof(count)) count = 0;

      /* If too few bytes read, assume count 0. */
   rc = lseek(fd, 0L, SEEK_SET);
   if (rc != 0) {
      perror("lseek error");
      exit(EXIT_FAILURE);
   }
   ++count;
   rc = write(fd, &count, sizeof(count));
   if (rc != sizeof(count)) {
      perror("write error");
      exit(EXIT_FAILURE);
   }

      /* The lock will be released when the file is closed,       */
      /*  but to be polite we will release it explicitly.         */
   lock.l_type = F_UNLCK;
   rc = fcntl(fd, F_SETLK, &lock);           /* Unlock bytes 0-3. */
   if (rc == -1) {
      perror("fcntl F_UNLCK error");
      exit(EXIT_FAILURE);
   }
   fclose(fd);
   exit(EXIT_SUCCESS);
}


SEE ALSO


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.