syswrite#
Write bytes to a filehandle with the raw write(2) system call,
bypassing Perl’s buffered I/O.
syswrite hands LENGTH bytes from SCALAR directly to the kernel
via write(2), skipping the PerlIO buffering that print,
printf, and write go through. The kernel may
accept fewer bytes than requested — syswrite returns whatever it
actually wrote, and well-written code always checks. If LENGTH is
omitted, the whole SCALAR is written. An optional OFFSET starts
the write at a position other than the beginning of the string.
Synopsis#
syswrite FILEHANDLE, SCALAR, LENGTH, OFFSET
syswrite FILEHANDLE, SCALAR, LENGTH
syswrite FILEHANDLE, SCALAR
What you get back#
The number of bytes actually written, or undef on error (with
$! set). The returned count can be less than LENGTH.
This is normal on pipes, sockets, and non-blocking handles; it is not
an error. Code that needs every byte delivered must loop:
my $off = 0;
my $len = length $buf;
while ($off < $len) {
my $n = syswrite $fh, $buf, $len - $off, $off;
defined $n or die "write failed: $!";
$off += $n;
}
A return of 0 is legal and means “no bytes written this call, try
again” — not end-of-stream. undef is the only error signal.
Global state it touches#
No interaction with
$,,$\, or$|.syswritedoes not format, does not append record separators, and does not honour the autoflush flag because there is no buffer to flush — bytes go straight to the kernel.No interaction with the selected filehandle from
select.FILEHANDLEis mandatory; there is no default.
Examples#
Write a string verbatim to STDOUT, no separators added:
syswrite STDOUT, "hello\n"; # 6 bytes written
Write a fixed-size record and check for a short write:
my $rec = pack "A8 N", $name, $id; # 12 bytes
my $n = syswrite $fh, $rec;
defined $n or die "syswrite: $!";
$n == length $rec or die "short write: $n of ${\length $rec}";
Write from the middle of a buffer with OFFSET. Useful inside a
drain loop where $off tracks how much has been accepted so far:
my $buf = "ABCDEFGHIJ";
syswrite $fh, $buf, 4, 3; # writes "DEFG"
Negative OFFSET counts from the end:
my $buf = "ABCDEFGHIJ";
syswrite $fh, $buf, 3, -4; # writes "GHI"
Write to a non-blocking socket and handle EAGAIN:
use Errno qw(EAGAIN EWOULDBLOCK);
my $n = syswrite $sock, $buf;
if (!defined $n) {
if ($! == EAGAIN || $! == EWOULDBLOCK) {
# kernel buffer full — try again after select()
} else {
die "syswrite: $!";
}
}
Edge cases#
Do not mix with buffered I/O on the same handle.
syswritebypassesPerlIO, butprint,printf,write,seek,tell, andeofall go through the:perlioand:crlfbuffering layers. Interleaving them on one handle corrupts the output order. Pick one mode per handle. If you must mix, useread/sysreadsymmetry rules and be deliberate.Short writes are normal. Pipes, sockets, terminals, and non-blocking handles routinely accept fewer bytes than offered. The drain-loop idiom above is the correct pattern for any handle where short writes matter.
Return value
0means the kernel accepted zero bytes this call. It is not end-of-stream and not an error; retry.Length larger than available data: if
LENGTHexceedslength(SCALAR) - OFFSET, only the available bytes are written and that count is returned.Empty SCALAR: if
SCALARhas length zero,OFFSETmust be0. Any other value raises an exception.:utf8and:encoding(...)layers raise an exception.syswriteoperates on bytes, not characters, and refuses any handle carrying a UTF-8 encoding layer.:encoding(...)implicitly adds:utf8, so it is equally forbidden. Usebinmodeto remove the layer, or write throughprintinstead.Characters above U+00FF on a byte-mode handle also raise an exception — there is no way to serialise a codepoint greater than
0xFFas a single byte. Encode the string explicitly before callingsyswrite:use Encode qw(encode); syswrite $fh, encode("UTF-8", $text);
Broken pipe / closed socket raises
SIGPIPE. The default action terminates the process. Install$SIG{PIPE} = 'IGNORE'(or a handler) to turn it into a normalsyswriteerror with$!set toEPIPE.Closed filehandle returns
undefwith$!set to"Bad file descriptor"; underuse warningsasyswrite() on closed filehandlewarning is emitted.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
sysread— the read counterpart; same buffer-bypassing semantics and same short-read caveatsysopen— open a handle at theopen(2)level sosyswritecan talk to it without anyPerlIOtranslation layers in the waysysseek— reposition the handle usinglseek(2), paired withsyswritefor random-access I/O on raw handlesprint— the buffered counterpart you almost always want instead; honours$,,$\, and$|binmode— remove a:utf8or:encoding(...)layer from a handle sosyswritecan be used on it$!— inspect after aundefreturn to distinguishEAGAINfrom a real failure