SysV IPC

shmwrite#

Copy bytes into a System V shared memory segment.

shmwrite attaches to the shared memory segment identified by ID, copies up to SIZE bytes from STRING starting at byte offset POS inside the segment, and detaches. If STRING is longer than SIZE, only the first SIZE bytes are written; if it is shorter, the remainder of the SIZE-byte window is zero-filled with NUL bytes. The segment ID is the value returned by an earlier shmget call (or obtained from another process via some out-of-band channel).

Synopsis#

shmwrite ID, STRING, POS, SIZE

What you get back#

True on success, false on error, with $! set to the reason (typically EINVAL, EACCES, or EIDRM). Unlike most I/O built-ins the return value is a plain boolean — there is no byte-count variant, because the count is always exactly SIZE when the call succeeds.

shmwrite($id, $payload, 0, 4096)
    or die "shmwrite($id) failed: $!";

Global state it touches#

  • $! is set on failure to the underlying shmat / memcpy / shmdt errno.

  • No other special variables are read or written. Unlike shmread, shmwrite does not taint anything — it is the source of bytes, not a sink.

Examples#

Publish a fixed-size record at the start of a segment:

use IPC::SysV qw(IPC_PRIVATE S_IRUSR S_IWUSR);
my $id = shmget(IPC_PRIVATE, 4096, S_IRUSR | S_IWUSR)
    or die "shmget: $!";
shmwrite($id, "hello, world", 0, 4096)
    or die "shmwrite: $!";

A STRING shorter than SIZE is NUL-padded to fill the window — useful for clearing stale trailing bytes from a previous writer:

shmwrite($id, "short", 0, 64);   # 5 bytes of "short", then 59 NULs

A STRING longer than SIZE is truncated; the tail is silently discarded, so size your window to the largest record you ever intend to publish:

shmwrite($id, "x" x 10_000, 0, 128);   # only the first 128 x's land

Writing to a non-zero offset lets multiple fixed-size records share one segment. Pair it with a matching shmread on the reader side:

my $slot = 3;
my $len  = 64;
shmwrite($id, $record, $slot * $len, $len)
    or die "shmwrite slot $slot: $!";

Check the return value — a segment that has been marked for deletion with IPC_RMID continues to accept writes from processes already attached, but fails for new shmwrite calls with EIDRM:

unless (shmwrite($id, $msg, 0, $SIZE)) {
    warn "segment $id gone: $!";
    # reacquire via shmget() and retry
}

Edge cases#

  • Kernel must be built with SysV IPC. On systems without SysV shared memory shmwrite croaks with shmwrite not implemented. This is a compile-time property of the kernel / libc, not a runtime condition you can probe for.

  • SIZE of 0 is accepted by the kernel and writes nothing; shmwrite returns true. Use it only when you genuinely mean “no-op”, not as an error signal.

  • POS + SIZE must fit inside the segment. Overrunning the segment boundary fails with EINVAL and leaves the segment untouched — the copy is not partial.

  • Binary payloads are fine. STRING is treated as a byte string; embedded NULs are written literally. If the string carries the UTF-8 flag, the raw internal bytes are what hits the segment — use pack or Encode::encode first if you need a specific encoding on the wire.

  • No locking. The kernel guarantees that each shmwrite call is atomic with respect to shmat / shmdt, but two concurrent writers can still interleave byte ranges within the segment. Coordinate with semop or a user-space lock if multiple processes write the same region.

  • Permissions come from the segment’s mode at shmget time. Attaching read-only and calling shmwrite fails with EACCES.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • shmread — inverse operation; copy bytes out of a segment into a Perl scalar

  • shmget — obtain the ID that shmwrite writes into

  • shmctl — inspect segment attributes, change permissions, or mark a segment for deletion

  • semop — the usual companion primitive for serialising access to a shared segment

  • pack — build the fixed-layout byte string you hand to shmwrite when the segment holds structured records

  • IPC::SysV — constants (IPC_PRIVATE, S_IRUSR, IPC_RMID) used to construct the arguments to shmget and shmctl