Working with System V IPC queues in Perl and PHP

· klm's blog


Original post is here: eklausmeier.goip.de

In continuation of Working with System V IPC queues a month ago this post will show how to access IPC queues with Perl and PHP. A typical scenario is that a web application wants an external application to process data coming from the web application. In that scenario a lot of messages/tasks from the web application can be queued up in an IPC queue for succesive processing by another program independent from the web application and possibly with more access rights.

For using System V queues in PHP you have to make sure that PHP has been compiled with POSIX support. With Red Hat you need php-process, in Ubuntu it is present by default.

[more_WP_Tag] The Perl code for reading data from an System V IPC queue is as below. Please take particular note for setting of $|.

 1$| = 1;         # "hot" pipes, i.e., flush output channel
 2use IPC::SysV qw(ftok IPC_PRIVATE IPC_RMID IPC_CREAT S_IRUSR S_IWUSR S_IRGRP S_IWGRP S_IROTH S_IWOTH MSG_NOERROR);
 3
 4my $key = ftok("/some/file/or/directory",65);    # 65="A"
 5my $id = msgget($key, IPC_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
 6die("msgget() failed") if (! defined $id);
 7
 8while (1) {
 9      die("msgrcv() failed") if ( msgrcv($id, $msg, 300, 0, MSG_NOERROR) == 0 );
10      # do something with the message in $msg
11}

Sending data to an IPC queue in PHP uses functions msg_get_queue(), for attaching to the queue, and msg_send() for actual writing to the queue. Function msg_get_queue() creates a queue with permissions 666, if not told otherwise. This is usually exactly what you want, because otherwise you cannot access the data in the queue. Usually the web-server runs with one user ID, and the processing of the queue data runs with another user ID.

1$key = ftok("/some/file/or/directory","A");
2$id = msg_get_queue($key);
3print "msg_send = " . msg_send($id,1,$msg . $destination,false,false) . "\n";

ftok() in PHP has a string as second argument, while Perl uses an integer. These values should match each other, otherwise Perl and PHP will not talk to the same queue.