msgrcv#
Receive a message from a System V IPC message queue.
msgrcv is the Perl binding for the msgrcv(2) syscall. It pulls one
message off the queue identified by ID, stores the message type and
payload into VAR, and returns a truthy value on success or false on
error. SIZE is the maximum number of payload bytes the caller is
willing to accept; TYPE selects which message to receive; FLAGS is
the bitmask passed to the kernel (IPC_NOWAIT, MSG_NOERROR, etc.).
The returned buffer is not just the message body — the first
sizeof(long) bytes are the message type the sender passed to
msgsnd, followed by the payload. Use unpack
with the l! a* template to split them apart.
Synopsis#
use IPC::SysV qw(IPC_NOWAIT MSG_NOERROR);
msgrcv $qid, my $buf, 1024, 0, 0 or die "msgrcv: $!";
msgrcv $qid, my $buf, 1024, 0, IPC_NOWAIT; # non-blocking
my ($type, $payload) = unpack "l! a*", $buf;
What you get back#
True on success, false on error with $! set. On success, VAR is
overwritten with the received frame: a native long (the message
type) immediately followed by up to SIZE bytes of payload. The
variable is marked tainted under -T.
VAR is grown or shrunk to fit the actual frame length — you do not
need to pre-size it. The content before the call is discarded.
To get the type and payload as separate values:
my ($type, $msg) = unpack "l! a*", $buf;
Arguments#
ID— the queue id previously returned bymsgget.VAR— a lvalue scalar that receives the raw frame. Its previous value is discarded on success.SIZE— the maximum payload size in bytes. If the next matching message is larger than this,msgrcvfails withE2BIGand the message stays on the queue — unlessMSG_NOERRORis set inFLAGS, in which case the message is truncated silently and the extra bytes are lost.TYPE— selects which message to receive:0— the first message on the queue, whatever its type.positive
N— the first message whose type is exactlyN.negative
-N— the first message of the lowest type that is<= abs(N), useful for priority queues.
FLAGS— bitmask ofIPC_NOWAIT(returnENOMSGimmediately instead of blocking when no matching message is available),MSG_NOERROR(truncate instead of failing on oversized messages), and the Linux-specificMSG_EXCEPT(with a positiveTYPE, receive the first message whose type is notTYPE).
The constants live in IPC::SysV; the bare names do not
become visible until you import them.
Global state it touches#
$!— set on error to the underlyingerrno(ENOMSG,E2BIG,EIDRM,EINVAL,EACCES,EFAULT,EINTR).Taint mode — the received
VARis marked tainted, since its contents came from another process.
Examples#
Blocking receive of any message, then split type and payload:
use IPC::SysV qw(IPC_CREAT S_IRUSR S_IWUSR);
my $qid = msgget(IPC_PRIVATE, S_IRUSR | S_IWUSR) // die "msgget: $!";
msgrcv $qid, my $buf, 4096, 0, 0 or die "msgrcv: $!";
my ($type, $payload) = unpack "l! a*", $buf;
print "got type=$type payload=$payload\n";
Receive only messages of type 42:
msgrcv $qid, my $buf, 4096, 42, 0 or die "msgrcv: $!";
Non-blocking poll — return immediately if the queue is empty:
use IPC::SysV qw(IPC_NOWAIT);
use Errno qw(ENOMSG);
if (msgrcv $qid, my $buf, 4096, 0, IPC_NOWAIT) {
my ($type, $msg) = unpack "l! a*", $buf;
handle($type, $msg);
} elsif ($! == ENOMSG) {
# queue was empty; try again later
} else {
die "msgrcv: $!";
}
Truncate oversized messages rather than failing:
use IPC::SysV qw(MSG_NOERROR);
msgrcv $qid, my $buf, 64, 0, MSG_NOERROR or die "msgrcv: $!";
# payload is at most 64 bytes, excess discarded without error
Priority-style receive — take the lowest-numbered message whose type
is <= 3:
msgrcv $qid, my $buf, 4096, -3, 0 or die "msgrcv: $!";
Edge cases#
VARmust be an lvalue. Passing a constant or a read-only scalar (for instance an element of@_that was passed by reference to a literal) raisesModification of a read-only value attempted.Frame layout is native
long, not four bytes. On 64-bit Linux the type occupies 8 bytes; on 32-bit systems it occupies 4. Thel!inunpack "l! a*"— the!— is mandatory; a plainlassumes 4 bytes and will corrupt payloads on 64-bit hosts.SIZEexcludes the type header forMSG_NOERRORpurposes. The kernel comparesSIZEagainst the payload length, not the frame length. Size the buffer for the largest payload you expect; the type header is written beyond it.Signal interruption. A blocking
msgrcvreturns false with$! == EINTRwhen a signal arrives before a message is available. Retry the call unless the signal is meant to abort the receive loop.Queue removed while blocked. If another process calls
msgctlwithIPC_RMIDwhile this process is asleep inmsgrcv, the call returns false with$! == EIDRM.Permissions. Receiving requires read permission on the queue.
EACCESmeans the queue exists but the current uid/gid doesn’t match the queue’s mode bits.TYPE = 0sees FIFO order. There is no “any” priority short of explicit negativeTYPE— messages of all types are pulled in send order.Kernel support. Linux kernels built without
CONFIG_SYSVIPC, and container runtimes that don’t expose the IPC namespace, fail everymsgrcvwithENOSYS. Check during startup if your deployment target is uncertain.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
msgsnd— the counterpart that puts messages on the queue; itspack "l! a*"template is the inverse of what youunpackheremsgget— obtain the queue idIDyou pass inmsgctl— inspect or delete the queue, including theIPC_RMIDthat causes a blockedmsgrcvto returnEIDRMunpack— split the returned frame into type and payload withl! a*IPC::SysV— source of theIPC_NOWAIT,MSG_NOERROR, and related flag constantsIPC::Msg— object-oriented wrapper that hides the pack/unpack dance behind arcvmethod