www.delorie.com/djgpp/doc/libc/libc_309.html   search  
libc.a reference

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

fcntl

Syntax

 
#include <fcntl.h>

int fcntl (int fd, int cmd, ...);

Description

This function performs the operation specified by cmd on the file open on handle fd. The following operations are defined by the header fcntl.h:

F_DUPFD
Returns a file handle that duplicates fd like dup does (see section dup), except that fcntl also makes sure the returned handle is the lowest available handle greater than or equal to the integer value of the third argument.

F_GETFD
Get the FD_CLOEXEC close-on-exec (a.k.a. no-inherit) status of fd. If the returned value has its least-significant bit set, the file will not be inherited by programs invoked by this process; otherwise, the file will remain open in the child processes.

Note that only the first 20 handles can be passed to child processes by DOS/Windows; handles beyond that cannot be inherited. In addition, the stub loader of the child DJGPP program will forcibly close handles 19 and 18 (since otherwise it will be unable to read the COFF executable information and enter protected mode). Therefore, the current implementation always returns FD_CLOEXEC for handles 18 and above.

For handles less than 18, the call will try to determine the status of the O_NOINHERIT flag for that file and will return either FD_CLOEXEC if the flag is set, or 0 if the flag is not set. If the status of the O_NOINHERIT flag cannot be determined, the call will return -1, setting errno to ENOSYS.

The no-inherit bit can be set when the file is opened by using the O_NOINHERIT in the open flags; see open.

F_SETFD
Set or unset the close-on-exec flag for the handle fd using the LSB of the integer value supplied as the third argument. Since only the first 20 handles are passed to child programs, and since the stub loader of the child DJGPP program will forcibly close handles 19 and 18 (since otherwise it will be unable to read the COFF executable information and enter protected mode), the flag can only be set or unset on the first 18 handles. Attempts to set the flag for handles 18 or above will always return 0, and attempts to unset the flag for handles 18 or above will always return -1, setting errno to ENOSYS.

For handles less than 18, the call will try to set or unset the O_NOINHERIT flag for that file and will return 0 if the flag is changed. If the O_NOINHERIT flag cannot be changed, the call will return -1, setting errno to ENOSYS.

F_GETFL
Get the open mode and status flags associated with the handle fd. The flags are those supported by open and creat functions, like O_RDONLY, O_APPEND, etc.

On Windows NT this cannot report the open mode correctly --- O_RDONLY is always returned.

F_SETFL
Set the open mode and status flags associated with the handle fd. This fails in all but one case, and sets errno to ENOSYS, since DOS and Windows don't allow changing the descriptor flags after the file is open.

The one allowed case is for O_NONBLOCK, since DJGPP doesn't support it anyway. That is, calls using F_SETFL will fail for all flag values except O_NONBLOCK.

 
#include <fcntl.h>

ret = fcntl(fd, F_SETFL, O_BINARY); /* This will fail, returning -1  */
                                    /* and setting errno to ENOSYS.  */

ret = fcntl(fd, F_SETFL, O_NONBLOCK); /* This will succeed          */
                                      /* returning 0.               */

F_GETLK
Return the lock structure that prevents obtaining the lock pointed to by the third argument, or set the l_type field of the lock structure to F_UNLCK if there is no obstruction. Currently, only the setting of the l_type field is provided. This call will not return values in the struct flock parameter identifying what lock parameters prevent getting the requested lock, since there is no way to obtain this information from DOS/Windows. If the lock cannot be obtained, -1 is returned and errno is set to the reason (which will be one of EINVAL, EBADF, EACCES or ENOLCK).

Locking of directories is not supported.

F_SETLK
Set or clear a file segment lock according to the structure pointed to by the third argument. The lock is set when l_type is F_RDLCK (shared lock request) or F_WRLCK (exclusive lock request), and the lock is cleared when l_type is F_UNLCK. If the lock is already held, then this call returns -1 and sets errno to EACCES.

The F_RDLCK value for requesting a read lock is always treated as if it were F_WRLCK for a write lock.

This is because DOS/Win9x only supports one kind of lock, and it is the exclusive kind.

Locking of directories is not supported.

F_SETLKW
Same as F_SETLK, but if the lock is blocked, the call will wait (using __dpmi_yield, see see section __dpmi_yield) until it is unblocked and the lock can be applied. This call will never exit if the program making the call is the program which already owns the lock.

Locking of directories is not supported.

F_GETLK64
F_SETLK64
F_SETLKW64
Each of these does exactly the same function as the non-"64" version, but the third argument must be of type struct flock64, which allows the l_start and l_len members to be long long int values. The current code will only use these long long int values modulo 2^32, which allows file locking positions up to 4 gigabytes minus 1. True 64-bit file locking is not supported.

The struct flock64 members l_start and l_len are declared to be of type offset_t, which is in turn typedef'ed to be a long long.

Locking of directories is not supported.

This function can be hooked by the Filesystem extensions, see File System Extensions. If you don't want this, and you are calling fcntl with the F_DUPFD command, you should use dup2 instead, see dup2.

Return Value

If an invalid or unsupported value is passed in cmd, or fd is an invalid file handle, the function returns -1 and sets errno to the appropriate value. Unsupported values of cmd cause ENOSYS to be stored in errno. If cmd is F_DUPFD, the function returns the new descriptor or -1 in case of a failure.

Lock requests which specify the open file's current EOF position as the value of l_start and zero as the l_len value will fail, returning -1 with errno set to EACCES.

Portability

ANSI/ISO C No
POSIX 1003.2-1992; 1003.1-2001 (see note 1)

Notes:

  1. Contrary to Posix requirement, the handle returned by F_DUPFD shares the FD_CLOEXEC flag with fd (unless they are on different sides of the 20-handle mark), since DOS/Windows only maintain a single set of bits for all the handles associated with the same call to open.

Example

 
 /* Save the handle in a way that it won't be passed
    to child processes.  */
  int saved_fd = fcntl(fd, F_DUPFD, 20);

 /* Set an advisory lock for the whole file.  */
  struct flock flock;
  int retval, fd;

  flock.l_type = F_RDLCK;
  flock.l_whence = SEEK_SET;
  flock.l_start = flock.l_len = 0;
  errno = 0;
  retval = fcntl(fd, F_SETLK, &flock);

 /* Get the status of the lock we just obtained
    (should return -1 with errno == EACCES).  */
  errno = 0;
  retval = fcntl(fd, F_GETLK, &flock);

 /* Release the lock.  */
  errno = 0;
  flock.l_type = F_UNLCK;
  retval = fcntl(fd, F_SETLK, &flock);

 /* Get the status of the lock we just released
    (should return 0).  */
  errno = 0;
  flock.l_type = F_RDLCK;
  retval = fcntl(fd, F_GETLK, &flock);

 /* Try to set the O_BINARY flag on the open file
    (should return -1 with errno == ENOSYS).  */
  errno = 0;
  retval = fcntl(fd, F_SETFL, O_BINARY);

 /* Set the O_NONBLOCK flag on the open file
    (should return 0).  */
  errno = 0;
  retval = fcntl(fd, F_SETFL, O_NONBLOCK);

 /* Get the flags on the open file
    (always returns 0).  */
  errno = 0;
  retval = fcntl(fd, F_GETFL);


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

  webmaster   donations   bookstore     delorie software   privacy  
  Copyright 2004   by DJ Delorie     Updated Apr 2004