SysV IPC

msgget#

Create or look up a System V IPC message queue and return its id.

msgget is the entry point to the System V message-queue family: every later msgsnd, msgrcv, or msgctl call needs an id, and this is where that id comes from. KEY names the queue across the whole system (a key_t integer, typically built with IPC::SysV::ftok or the special value IPC_PRIVATE). FLAGS is the bitwise-or of permission bits (low nine, same layout as file modes) and optional IPC_CREAT / IPC_EXCL flags. The call is a direct wrapper around the msgget(2) syscall.

Synopsis#

use IPC::SysV qw(IPC_CREAT IPC_EXCL IPC_PRIVATE S_IRUSR S_IWUSR);

my $id = msgget($key, IPC_CREAT | 0600);
my $id = msgget(IPC_PRIVATE, 0600);
my $id = msgget($key, IPC_CREAT | IPC_EXCL | 0600);

What you get back#

A non-negative integer message-queue id on success, or undef on failure (with $! set to the errno value from the underlying syscall). The id is an opaque handle — do not do arithmetic on it, just pass it back to the other msg* built-ins.

my $id = msgget($key, IPC_CREAT | 0600)
    // die "msgget($key) failed: $!";

Global state it touches#

  • $! — set on failure to the errno from msgget(2) (commonly EACCES, EEXIST, ENOENT, ENOSPC, ENOMEM).

No other special variables are involved. The queue itself lives in the kernel, not in the Perl process, and persists across exec and after the creating process exits — it must be removed explicitly with msgctl and IPC_RMID.

Examples#

Create a private queue that no other process can name — the usual choice when the queue is shared only with children of this process:

use IPC::SysV qw(IPC_PRIVATE);
my $id = msgget(IPC_PRIVATE, 0600) // die "msgget: $!";

Create or attach to a named queue using a key_t derived from a file path. ftok turns a path plus a single-character project id into a stable key so unrelated processes can agree on a queue:

use IPC::SysV qw(ftok IPC_CREAT);
my $key = ftok("/var/run/myapp", 'M');
my $id  = msgget($key, IPC_CREAT | 0600) // die "msgget: $!";

Create exclusively — fail if the queue already exists. This is how you detect that a previous instance of your program is still around:

use IPC::SysV qw(IPC_CREAT IPC_EXCL);
my $id = msgget($key, IPC_CREAT | IPC_EXCL | 0600);
if (!defined $id) {
    die "queue already exists" if $!{EEXIST};
    die "msgget: $!";
}

Attach to an existing queue without creating one — omit IPC_CREAT. Returns undef with $! set to ENOENT if no such queue exists:

my $id = msgget($key, 0) // die "no queue for key $key: $!";

Remove the queue when done. msgget itself has no teardown counterpart; removal goes through msgctl:

use IPC::SysV qw(IPC_RMID);
msgctl($id, IPC_RMID, 0) or warn "msgctl IPC_RMID: $!";

Edge cases#

  • KEY must be an integer, typically a key_t. Passing a string triggers the usual numeric-conversion rules and will almost certainly name the wrong queue. Build keys with IPC::SysV::ftok or use IPC_PRIVATE.

  • IPC_PRIVATE always creates a new queue, regardless of whether IPC_CREAT is set. The key is not reusable — you cannot msgget the same queue later from an unrelated process using IPC_PRIVATE.

  • Permission bits apply at every call, not just creation. Attaching to an existing queue without IPC_CREAT still checks the permission bits against the queue’s owner/group and the current process’s effective uid/gid. Mismatched bits give EACCES.

  • IPC_EXCL without IPC_CREAT is meaningless — the kernel ignores it. If you want exclusive creation, always pair them.

  • System-wide limits. Creation can fail with ENOSPC when the kernel’s MSGMNI limit is hit, or ENOMEM under memory pressure. These are not bugs in your program; they are operational conditions.

  • Queue lifetime outlives processes. A queue created here persists until explicitly removed with msgctl and IPC_RMID, or until the system reboots. Forgotten queues leak kernel resources that ipcs and ipcrm are used to find and clean up.

  • Not all systems have SysV message queues. On platforms that omit them, the built-in croaks with msgget not implemented on this architecture. The portability warning in upstream POD applies.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • msgsnd — send a message to the queue returned by msgget

  • msgrcv — receive a message from that queue

  • msgctl — query, set options on, or remove the queue; teardown after msgget goes through here

  • semget — same API shape for System V semaphores when you need synchronization rather than data transfer

  • shmget — same API shape for System V shared memory when you need direct memory sharing rather than message passing

  • IPC::SysV — provides ftok and the IPC_* / S_* constants msgget expects in FLAGS