Go to the previous, next section.

Setting the File Position of a Descriptor

Just as you can set the file position of a stream with fseek, you can set the file position of a descriptor with lseek. This specifies the position in the file for the next read or write operation. See section File Positioning, for more information on the file position and what it means.

To read the current file position value from a descriptor, use lseek (desc, 0, SEEK_CUR).

Function: off_t lseek (int filedes, off_t offset, int whence)

The lseek function is used to change the file position of the file with descriptor filedes.

The whence argument specifies how the offset should be interpreted in the same way as for the fseek function, and can be one of the symbolic constants SEEK_SET, SEEK_CUR, or SEEK_END.

SEEK_SET
Specifies that whence is a count of characters from the beginning of the file.

SEEK_CUR
Specifies that whence is a count of characters from the current file position. This count may be positive or negative.

SEEK_END
Specifies that whence is a count of characters from the end of the file. A negative count specifies a position within the current extent of the file; a positive count specifies a position past the current end. If you set the position past the current end, and actually write data, you will extend the file with zeros up to that position.

The return value from lseek is normally the resulting file position, measured in bytes from the beginning of the file. You can use this feature together with SEEK_CUR to read the current file position.

You can set the file position past the current end of the file. This does not by itself make the file longer; lseek never changes the file. But subsequent output at that position will extend the file's size.

If the file position cannot be changed, or the operation is in some way invalid, lseek returns a value of -1. The following errno error conditions are defined for this function:

EBADF
The filedes is not a valid file descriptor.

EINVAL
The whence argument value is not valid, or the resulting file offset is not valid.

ESPIPE
The filedes corresponds to a pipe or FIFO, which cannot be positioned. (There may be other kinds of files that cannot be positioned either, but the behavior is not specified in those cases.)

The lseek function is the underlying primitive for the fseek, ftell and rewind functions, which operate on streams instead of file descriptors.

You can have multiple descriptors for the same file if you open the file more than once, or if you duplicate a descriptor with dup. Descriptors that come from separate calls to open have independent file positions; using lseek on one descriptor has no effect on the other. For example,

{
  int d1, d2;
  char buf[4];
  d1 = open ("foo", O_RDONLY);
  d2 = open ("foo", O_RDONLY);
  lseek (d1, 1024, SEEK_SET);
  read (d2, buf, 4);
}

will read the first four characters of the file `foo'. (The error-checking code necessary for a real program has been omitted here for brevity.)

By contrast, descriptors made by duplication share a common file position with the original descriptor that was duplicated. Anything which alters the file position of one of the duplicates, including reading or writing data, affects all of them alike. Thus, for example,

{
  int d1, d2, d3;
  char buf1[4], buf2[4];
  d1 = open ("foo", O_RDONLY);
  d2 = dup (d1);
  d3 = dup (d2);
  lseek (d3, 1024, SEEK_SET);
  read (d1, buf1, 4);
  read (d2, buf2, 4);
}

will read four characters starting with the 1024'th character of `foo', and then four more characters starting with the 1028'th character.

Data Type: off_t

This is an arithmetic data type used to represent file sizes. In the GNU system, this is equivalent to fpos_t or long int.

These three aliases for the `SEEK_...' constants exist for the sake of compatibility with older BSD systems. They are defined in two different header files: `fcntl.h' and `sys/file.h'.

L_SET
An alias for SEEK_SET.

L_INCR
An alias for SEEK_CUR.

L_XTND
An alias for SEEK_END.

Go to the previous, next section.