msgctl#
Perform a control operation on a System V IPC message queue.
msgctl is a direct wrapper around the C msgctl(2) system call. It
inspects, modifies, or removes the message queue identified by ID.
The operation selected by CMD determines how ARG is used — either
as an input descriptor, an output buffer, or ignored entirely. The
symbolic constants needed for CMD (IPC_STAT, IPC_SET, IPC_RMID,
and on Linux IPC_INFO, MSG_STAT, MSG_INFO) live in
IPC::SysV, which you have to pull in before the
names resolve.
Synopsis#
use IPC::SysV;
msgctl $id, IPC_STAT, $buf # read queue info into $buf
msgctl $id, IPC_SET, $buf # write queue info from $buf
msgctl $id, IPC_RMID, 0 # destroy the queue
What you get back#
Return value follows the same convention as ioctl:
The string
"0 but true"when the underlying call returned0. This is the zero-valued success case — it tests true in boolean context and compares equal to0in numeric context, so one check handles both success and failure.The raw non-zero integer return otherwise (for example the index returned by Linux-specific
MSG_STAT).
The "0 but true" convention exists precisely so that
msgctl(...) or die does the right thing even when the syscall
legitimately returns zero:
msgctl $id, IPC_RMID, 0
or die "msgctl IPC_RMID failed: $!";
How ARG is used#
ARG plays three different roles depending on CMD. The kernel only
touches the memory in the directions the command requires:
IPC_STAT—ARGmust be a writable scalar. The kernel fills it with the packedmsqid_dsstructure describing the queue (permissions, owner, last-send/last-receive times, queue byte limits, counts). Unpack withIPC::SysVhelpers rather than hand-rolling the layout;msqid_dsvaries across kernels and libc versions.IPC_SET—ARGmust contain a packedmsqid_dsproduced by a priorIPC_STATon the same (or compatible) queue. Only a few fields are honoured:msg_perm.uid,msg_perm.gid,msg_perm.mode(low 9 bits), andmsg_qbytes. The rest is ignored.IPC_RMID—ARGis unused. Pass0. The queue is marked for destruction; any blockedmsgsnd/msgrcvon it fails withEIDRM.
On Linux only, MSG_STAT and MSG_INFO also accept a writable
scalar for ARG and return extra data; these are non-portable and
should be gated behind a runtime check.
Global state it touches#
$!— set on failure with the system errno (EPERM,EACCES,EINVAL,EIDRM,EFAULTare the common values).No other special variables are touched.
Examples#
Read the queue header and inspect the current byte limit:
use IPC::SysV qw(IPC_STAT);
my $buf = "";
msgctl($id, IPC_STAT, $buf)
or die "msgctl IPC_STAT failed: $!";
# Layout is platform-dependent; use IPC::SysV helpers to decode.
Shrink the queue’s byte budget. Round-trip through IPC_STAT so the
immutable fields keep their current kernel values:
use IPC::SysV qw(IPC_STAT IPC_SET);
my $buf = "";
msgctl($id, IPC_STAT, $buf) or die "stat: $!";
# ... modify msg_qbytes inside $buf via IPC::SysV ...
msgctl($id, IPC_SET, $buf) or die "set: $!";
Destroy a queue when done. ARG is ignored, but it still has to be
passed — 0 is the conventional placeholder:
use IPC::SysV qw(IPC_RMID);
msgctl($qid, IPC_RMID, 0)
or warn "could not remove queue $qid: $!";
Idiomatic success test that works for the "0 but true" case:
my $rc = msgctl($id, IPC_RMID, 0);
die "msgctl failed: $!" unless defined $rc; # undef = error
# $rc is now either "0 but true" or a positive integer
Edge cases#
IPC::SysVnot loaded: bare constant names likeIPC_STATbecome barewords and, underuse strict, a compile-time error. Alwaysuse IPC::SysVfirst.Scalar passed to
IPC_STATis not writable: croaks withModification of a read-only value attempted. Use a plainmy $buf = ""— not a constant, not a string literal.Length mismatch on
IPC_SET: ifARGis shorter than the kernel’smsqid_ds, the call fails withEFAULT. Always start from anIPC_STATbuffer rather than packing one from scratch.Removed queue (
EIDRM): onceIPC_RMIDhas been issued, any further operation on the same ID fails with$!set toEIDRM, notEINVAL. Scripts that poll a queue must treatEIDRMas “queue is gone, stop.”Permission errors:
IPC_SETandIPC_RMIDrequire effective UID match orCAP_SYS_ADMIN. Kernel returnsEPERM, notEACCES, for ownership failures.Return-value trap:
if (msgctl(...) == 0)is wrong — on success the value is the string"0 but true", which stringifies as non-empty but compares numerically equal to0. Test withdefinedfor the error case, or rely onor die.Platform availability: System V IPC is not universal. On systems where the kernel omits it,
msgctlraises the runtime exceptionmsgctl not implemented.
Differences from upstream#
Fully compatible with upstream Perl 5.42 on Linux. System V IPC is
the only supported IPC surface; pperl targets Linux, so the
portability caveats that upstream perlport lists for non-Linux
platforms do not apply.
See also#
msgget— obtain the queue ID thatmsgctloperates onmsgsnd— send a message to the queuemsgrcv— receive a message from the queuesemctl— the semaphore-set analogue, same return convention and sameIPC_STAT/IPC_SET/IPC_RMIDpatternshmctl— the shared-memory-segment analogueIPC::SysV— the constants (IPC_STAT,IPC_SET,IPC_RMID) and themsqid_dspack/unpack helpers this call requires