Closed p5pRT closed 20 years ago
Hello\,
I get different results with the IPC msgrcv function on Alpha and Intel (Linux and FreeBSD) platforms. It involves the "type" argument of msgrcv\, which I suspect may not be 64-bit clean (??) on the Alpha platform. Here's a test program\, followed by results on the two platforms I have tested:
-------cut here---------------
#!/usr/bin/perl -w use strict; use strict; use IPC::SysV qw(S_IRWXU S_IRWXG S_IRWXO IPC_CREAT IPC_NOWAIT IPC_RMID);
my $q; my $buf = "";
sub BEGIN { my $key = 0xA5A5A5; my $perms = S_IRWXU | S_IRWXG | S_IRWXO | IPC_CREAT; $q = msgget($key\,$perms) or die $!; }
sub END { msgctl($q\,IPC_RMID\,0) or die $!; }
# send 3 messages msgsnd($q\,pack("L a*"\,1\,"msg 1")\,0) or die $!; msgsnd($q\,pack("L a*"\,2\,"msg 2")\,0) or die $!; msgsnd($q\,pack("L a*"\,3\,"msg 3")\,0) or die $!;
# receive any message print "receiving any message:\n"; msgrcv($q\,$buf\,1024\,0\,IPC_NOWAIT) or die $!; my ($t1\,$m1) = unpack("L a*"\,$buf); print $m1\," type = "\,$t1\,"\n";
# receive a message of type 2 print "receiving type 2 message:\n"; msgrcv($q\,$buf\,1024\,2\,IPC_NOWAIT) or die $!; my ($t2\,$m2) = unpack("L a*"\,$buf); print $m2\," type = "\,$t2\,"\n";
# receive a message with type \<= 3 print "receiving type \<= 3 message:\n"; msgrcv($q\,$buf\,1024\,-3\,IPC_NOWAIT) or die $!; my ($t3\,$m3) = unpack("L a*"\,$buf); print $m3\," type = "\,$t3\,"\n";
-------- cut here ---------------
results on linux-alpha:
[djt@garauda perl]$ ./test.pl receiving any message: msg 1 type = 1 receiving type 2 message: No message of desired type at ./test.pl line 32.
results on freebsd-intel:
[djt@elk djt]$ ./test.pl receiving any message: msg 1 type = 1 receiving type 2 message: msg 2 type = 2 receiving type \<= 3 message: msg 3 type = 3
this could of course be a kernel problem\, rather than a perl problem\, so I will investigate further.
Regards\,
David Thorpe djt@state51.co.uk
Instead of "L a*" you should use "l! a*". The System V IPC uses native integer sizes\, which is what the "!" stands for. Also "l!" instead of "L!"\, because the msg_type is signed (well\, at least I've never seen unsigned being used).
For intel platforms there is no width difference between the pack formats "l" and "l!" (no Itanium yet)\, but in alphas there is (the "l" is forced to be 32 bits\, while the native long "l!" is 64 bits).
This is documented in the Perl 5.6.0 manuals\, for example at the perlfunc/msgsnd entry.
On Thu\, Jun 29\, 2000 at 06:11:28PM +0100\, David Thorpe wrote:
On Thu\, 29 Jun 2000\, Jarkko Hietaniemi wrote:
Instead of "L a*" you should use "l! a*". The System V IPC uses native integer sizes\, which is what the "!" stands for. Also "l!" instead of "L!"\, because the msg_type is signed (well\, at least I've never seen unsigned being used).
For intel platforms there is no width difference between the pack formats "l" and "l!" (no Itanium yet)\, but in alphas there is (the "l" is forced to be 32 bits\, while the native long "l!" is 64 bits).
This is documented in the Perl 5.6.0 manuals\, for example at the perlfunc/msgsnd entry.
Thanks ever so much Jarkko\, sorry that I didn't quite understand. I used pack("q a*"\,...) which worked fine on perl 5.005
Yes\, for alpha the pack format "q" (a quad\, 64 bits\, which in alpha happens to be also the native long) is the only way to get the type right in pre-5.6. But for 5.6 and onwards "l!" works for every platform (well\, for every platform that uses "long" for its msg_type in its struct msg...)
David Thorpe wrote:
On 29 Jun 2000 richard@perl.org wrote:
Your e-mail has been received by the Perl Bug Squashing Team.
With regard to this being a perl problem and not a kernel problem\, I have written the same program I enclosed with the bug report in C (which I have included as an attachment to this email) and it seems to work OK\, so any help or guidance with using msgrcv on perl would be very useful.
Regards\,
David Thorpe djt@state51.co.uk ----------+ a member of the state51 conspiracy ---+ 8-10 rhoda street http://motion.state51.co.uk/ london e2 7ef --+ it's about new music --+ tel +44.20.7729.4343 fax +44.20.7729.8494
------------------------------------------------------------------------------ Name: msgtest.c msgtest.c Type: Plain Text (TEXT/PLAIN) Encoding: 7BIT Description: msgtest.c
#include \<stdio.h> #include \<string.h> #include \<errno.h> #include \<sys/stat.h> #include \<sys/types.h> #include \<sys/ipc.h> #include \<sys/msg.h>
#define MSG_SIZE 1024
struct CMsg { long m_type; char m_text[MSG_SIZE]; };
int main(void) { const key_t key = 0xA5A5A5; const int perms = S_IRWXU | S_IRWXG | S_IRWXO | IPC_CREAT; int q = msgget(key\,perms); if(q == 0) { printf("%s"\,strerror(errno)); return 0; }
// send three messages CMsg* m1 = new CMsg; CMsg* m2 = new CMsg; CMsg* m3 = new CMsg;
m1->m_type = 1; strcpy(m1->m_text\,"msg-1");
m2->m_type = 2; strcpy(m2->m_text\,"msg-2");
m3->m_type = 3; strcpy(m3->m_text\,"msg-3");
if(msgsnd(q\,m1\,MSG_SIZE\,0) == -1) { printf("%s"\,strerror(errno)); return 0; }
if(msgsnd(q\,m2\,MSG_SIZE\,0) == -1) { printf("%s"\,strerror(errno)); return 0; }
if(msgsnd(q\,m3\,MSG_SIZE\,0) == -1) { printf("%s"\,strerror(errno)); return 0; }
// get first message CMsg r1; if(msgrcv(q\,&r1\,MSG_SIZE\,0\,IPC_NOWAIT) == -1) { printf("%s"\,strerror(errno)); return 0; } printf("received %ld %s\n"\,r1.m_type\,r1.m_text);
CMsg r2; if(msgrcv(q\,&r2\,MSG_SIZE\,2\,IPC_NOWAIT) == -1) { printf("%s"\,strerror(errno)); return 0; } printf("received %ld %s\n"\,r2.m_type\,r2.m_text);
CMsg r3; if(msgrcv(q\,&r3\,MSG_SIZE\,-2\,IPC_NOWAIT) == -1) { printf("%s"\,strerror(errno)); return 0; } printf("received %ld %s\n"\,r3.m_type\,r3.m_text);
msgctl(q\,IPC_RMID\,0); return 0; }
Migrated from rt.perl.org#3445 (status was 'resolved')
Searchable as RT3445$