The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

POSIX::1003::FdIO - POSIX handling file descriptors

SYNOPSIS

  use POSIX::1003::FdIO;

  $fd = openfd($fn, O_RDWR);
  defined $fd or die $!;   # $fd==0 is valid value! (STDIN)

  $fd = openfd($fn, O_WRONLY|O_TRUNC);
  $fd = openfd($fn, O_CREAT|O_WRONLY, 0640);

  my $buf;
  $bytes_read    = readfd($fd, $buf, BUFSIZ);
  $bytes_written = writefd($fd, $buf, 5);

  $off_t = seekfd($fd, 0, SEEK_SET);  # rewind!
  $fd2   = dupfd($fd);

  closefd($fd) or die $!;

  my ($r, $w) = pipefd();
  writefd($w, "hello", 5);
  readfd($r, $buf, 5);
  closefd($r) && closefd($w) or die $!;

  my $fh = fdopen($fd, 'w') or die $!;

DESCRIPTION

Most people believe that the sys* commands in Perl Core are not capable of doing unbuffered IO. For those people, we have this module. But there is more in file-descriptor space, missing from Core.

The question whether sysread() or readfd() is meassurable faster cannot be answered.

The fcntl() command has its separate module POSIX::1003::Fcntl. Locking functions are locate there as well, because they are often implemented via fcntl.

FUNCTIONS

Overview

Perl defaults to use file-handles, avoiding file descriptors. For that reason, the fread of POSIX is the read of Perl; that's confusing. But the POSIX standard is confused as well: some function names which start with an f are actually for file-descriptors, other for file-handles!

The POSIX module, distributed with Perl, makes you write CORE::read() and POSIX::read() explicitly. However, POSIX::read() is the same as CORE::sysread()!

To avoid conflicts with function names in Perl core, and the confusion that the POSIX created, all exported function names provided by this module contain 'fd' in their name.

    POSIX    Perl-Core POSIX.pm  POSIX::1003::FdIO
 FH fseek     seek
 FD lseek     sysseek   lseek    seekfd
 FH fopen     open
 FD open      sysopen            openfd   # sysopen is clumpsy
 FD fdopen    open               fdopen   # IO::Handle->new_from_fd
 FH fclose    close
 FD close     close     close    closefd
 FH fread     read
 FD read      sysread   read     readfd
 FH fwrite    print
 FD write     syswrite  write    writefd
 FH           pipe,open                   # buffered unless $|=0
 FD pipe                pipe     pipefd
 FH stat      stat
 FD fstat               fstat    statfd
 FN lstat     lstat
 FH ftell     tell
 FD                              tellfd   # tell on fd not in POSIX
 FH rewind              rewind
 FD                              rewindfd # rewind on fd not in POSIX
 FD creat               creat    creatfd
 FD dup                          dupfd
 FD fcntl     fcntl              (many)   # see ::Fcntl
 FD flock     flock              flockfd  # see ::Fcntl
 FD lockf                        lockf    # see ::Fcntl
 FN truncate  truncate
 FD ftruncate                    truncfd

Works on: FH=file handle, FD=file descriptor, FN=file name

Standard POSIX

closefd($fd)

Always check the return code: undef on error, cause in $!. closefd $fd or die $!;

There is no sysclose() in core, because sysopen() does unbuffered IO via its perl-style file-handle: when you open with CORE::sysopen(), you must close with CORE::close().

creatfd($filename, $mode)

Implemented via openfd(), which is true by definition of POSIX.

dup2fd($fd, $newfd)

Copy file-descriptor $fd to an explicit $newfd number. When already in use, the file at $newfd will be closed first. Returns undef on failure.

dupfd($fd)

Copy the file-descriptor $fd into the lowest-numbered unused descriptor. The new fd is returned, undef on failure.

fdopen($fd, $mode)

Converts a $fd into an (buffered) FH. You probably want to set binmode after this. $mode can be Perl-like '<', '>', '>>', or POSIX standard 'r', 'w', 'a'. POSIX modes 'r+', 'w+', and 'a+' can probably not be supported.

openfd($filename, $flags, $mode)

Returned is an integer file descriptor (FD). Returns undef on failure (and '0' is a valid FD!)

$flags are composed from the O_* constants defined by this module (import tag :mode) The $mode field combines S_I* constants defined by POSIX::1003::FS (import tag :stat).

pipefd()

Returns the reader and writer file descriptors. See also POSIX::1003::Fcntl::setfd_pipe_size()

example:

  my ($r, $w) = pipefd;
  writefd($w, "hello", 5 );
  readfd($r, $buf, 5 );
readfd( $fd, SCALAR, [$length] )

Read the maximum of $length bytes from $fd into the SCALAR. Returned is the actual number of bytes read. The value -1 tells you there is an error, reported in $!

Be warned that a returned value smaller than $length does not mean that the $fd has nothing more to offer: the end is reached only when 0 (zero) is returned. Therefore, this reading is quite inconvenient. You may want to use POSIX::Util subroutine readfd_all

seekfd($fd, $offset, $whence)

The $whence is a SEEK_* constant.

statfd($fd)

Request file administration information about an open file. It returns the same list of values as stat on filenames.

truncfd( $fd, [$length] )

[0.96] Shorten the file to the $length (defaults to 0). The file offset (your pointer in the file) is not changed, so you may need to seekfd() as well. Behavior is undefined when $length is larger than the file size.

The POSIX name for this function is ftruncate.

writefd( $fd, $bytes, [$length] )

Attempt to write the first $length bytes of STRING to $fd. Returned is the number of bytes actually written. You have an error only when -1 is returned.

Additional

Zillions of Perl programs reimplement these functions. Let's simplify code.

rewindfd($fd)

Seek to the beginning of the file.

tellfd($fd)

Reports the location in the file. This call does not exist (not in POSIX, nor on other UNIXes), however is a logical counterpart of the tell() on filenames.

CONSTANTS

The following constants are exported, shown here with the values discovered during installation of this module.

  BUFSIZ         8192
  EOF            -1
  MAX_INPUT      255
  O_ACCMODE      3
  O_APPEND       1024
  O_ASYNC        8192
  O_CLOEXEC      524288
  O_CREAT        64
  O_DIRECT       16384
  O_DIRECTORY    65536
  O_DSYNC        4096
  O_EXCL         128
  O_FSYNC        1052672
  O_LARGEFILE    0
  O_NDELAY       2048
  O_NOATIME      262144
  O_NOCTTY       256
  O_NOFOLLOW     131072
  O_NONBLOCK     2048
  O_RDONLY       0
  O_RDWR         2
  O_RSYNC        1052672
  O_SYNC         1052672
  O_TRUNC        512
  O_WRONLY       1
  PIPE_BUF       4096
  SEEK_CUR       1
  SEEK_DATA      3
  SEEK_END       2
  SEEK_HOLE      4
  SEEK_SET       0
  SSIZE_MAX      9223372036854775807
  STDERR_FILENO  2
  STDIN_FILENO   0
  STDOUT_FILENO  1

You can limit the import to the SEEK_* constants by explicitly using the :seek import tag. Use the :mode for all O_* constants, to be used with openfd().

SEE ALSO

This module is part of POSIX-1003 distribution version 0.99_01, built on January 31, 2015. Website: http://perl.overmeer.net. The code is based on POSIX, which is released with Perl itself. See also POSIX::Util for additional functionality.

COPYRIGHTS

Copyrights 2011-2015 on the perl code and the related documentation by [Mark Overmeer]. For other contributors see ChangeLog.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html