perl pack string

Discussion in 'Perl Misc' started by unxl3arn3r, Mar 24, 2008.

  1. unxl3arn3r

    unxl3arn3r Guest

    Gurus
    I seem to be unable to pack a string padded with nulls and containing
    the length of the string prepended to it. This is my code snippet,
    where am i going wrong ?

    $message1 = pack("l! a*",1, "This is a test,This program is free
    software,you can redistribute it terms as Perl network, This is why I
    said to talk");
    msgsnd($queue,$message1,0);

    In my msgrcv i only want to recieve upto 100 characters. If i send a
    string greater than 100 my script receiving the message fails.

    Thanks
    Perl Monger
     
    unxl3arn3r, Mar 24, 2008
    #1
    1. Advertising

  2. unxl3arn3r

    Guest

    unxl3arn3r <> wrote:
    > Gurus
    > I seem to be unable to pack a string padded with nulls and containing
    > the length of the string prepended to it. This is my code snippet,
    > where am i going wrong ?
    >
    > $message1 = pack("l! a*",1, "This is a test,This program is free
    > software,you can redistribute it terms as Perl network, This is why I
    > said to talk");


    l! packs the "1", and a* packs the message. No where in there does the
    length of the message enter into it.

    I see that that is copied from the perldoc -f msgsnd. I can only
    assume that that documentation is hosed.

    Perhaps it should be this, instead?

    pack("l! l!/a*",1,"foo")

    Here l! packs the message type (1), l!/ packs the length of the message,
    and a* packs the message itself.

    > msgsnd($queue,$message1,0);


    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
     
    , Mar 24, 2008
    #2
    1. Advertising

  3. unxl3arn3r wrote:
    > Gurus
    > I seem to be unable to pack a string padded with nulls and containing
    > the length of the string prepended to it. This is my code snippet,
    > where am i going wrong ?
    >
    > $message1 = pack("l! a*",1, "This is a test,This program is free
    > software,you can redistribute it terms as Perl network, This is why I
    > said to talk");
    > msgsnd($queue,$message1,0);
    >
    > In my msgrcv i only want to recieve upto 100 characters. If i send a
    > string greater than 100 my script receiving the message fails.


    $ perl -le'
    use Data::Dumper;
    $Data::Dumper::Useqq = 1;

    my $x = pack q[l!/Z*], "This is a test,This program is free software,you
    can redistribute it terms as Perl network, This is why I said to talk";

    print Dumper $x;
    '
    $VAR1 = "w\0\0\0This is a test,This program is free software,you can
    redistribute it terms as Perl network, This is why I said to talk\0";


    And then to unpack:

    $ perl -le'
    use Data::Dumper;
    $Data::Dumper::Useqq = 1;

    my $x = unpack q[l!/Z*], "w\0\0\0This is a test,This program is free
    software,you can redistribute it terms as Perl network, This is why I
    said to talk\0";

    print Dumper $x;
    '
    $VAR1 = "This is a test,This program is free software,you can
    redistribute it terms as Perl network, This is why I said to talk";


    If you want to limit the size of the string to 100 characters:

    perldoc -f substr



    John
    --
    Perl isn't a toolbox, but a small machine shop where you
    can special-order certain sorts of tools at low cost and
    in short order. -- Larry Wall
     
    John W. Krahn, Mar 24, 2008
    #3
  4. unxl3arn3r

    unxl3arn3r Guest

    On Mar 24, 4:57 pm, wrote:
    > unxl3arn3r <> wrote:
    > > Gurus
    > > I seem to be unable to pack a string padded with nulls and containing
    > > the length of the string prepended to it. This is my code snippet,
    > > where am i going wrong ?

    >
    > > $message1 = pack("l! a*",1, "This is a test,This program is free
    > > software,you can redistribute it terms as Perl network, This is why I
    > > said to talk");

    >
    > l! packs the "1", and a* packs the message. No where in there does the
    > length of the message enter into it.
    >
    > I see that that is copied from the perldoc -f msgsnd. I can only
    > assume that that documentation is hosed.
    >
    > Perhaps it should be this, instead?
    >
    > pack("l! l!/a*",1,"foo")
    >
    > Here l! packs the message type (1), l!/ packs the length of the message,
    > and a* packs the message itself.
    >
    > > msgsnd($queue,$message1,0);

    >
    > Xho
    >
    > --
    > --------------------http://NewsReader.Com/--------------------
    > The costs of publication of this article were defrayed in part by the
    > payment of page charges. This article must therefore be hereby marked
    > advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    > this fact.


    why do I need to have the second variable in pack ? All I need to do
    is pack my outgoing string and prepad its length in front of it. Since
    I am doing a* doesn't it already mean its a string of characters, then
    why do i need to define the $type = 1 ?
     
    unxl3arn3r, Mar 25, 2008
    #4
  5. unxl3arn3r

    Guest

    unxl3arn3r <> wrote:
    > On Mar 24, 4:57 pm, wrote:
    > > unxl3arn3r <> wrote:
    > > > Gurus
    > > > I seem to be unable to pack a string padded with nulls and
    > > > containing the length of the string prepended to it. This is my code
    > > > snippet, where am i going wrong ?

    > >
    > > > $message1 = pack("l! a*",1, "This is a test,This program is free
    > > > software,you can redistribute it terms as Perl network, This is why I
    > > > said to talk");

    > >
    > > l! packs the "1", and a* packs the message. No where in there does the
    > > length of the message enter into it.
    > >
    > > I see that that is copied from the perldoc -f msgsnd. I can only
    > > assume that that documentation is hosed.
    > >
    > > Perhaps it should be this, instead?
    > >
    > > pack("l! l!/a*",1,"foo")
    > >
    > > Here l! packs the message type (1), l!/ packs the length of the
    > > message, and a* packs the message itself.
    > >
    > > > msgsnd($queue,$message1,0);

    > >


    (please don't quote sigs when you reply. Sig snipped)

    > why do I need to have the second variable in pack ?


    I don't understand your question. None of the packs I've seen in this
    thread are given two variables. They are given three constants--a constant
    format string, an constant integer, and a constant message string.


    > All I need to do
    > is pack my outgoing string and prepad its length in front of it.


    But the code you posted prepended it with the native signed long
    representation of 1. 1 is not the length of that message.

    > Since
    > I am doing a* doesn't it already mean its a string of characters, then
    > why do i need to define the $type = 1 ?


    If you believe that part of the documentation of "msgsnd", you have to do
    that because that is what the interface requires that you do. If you don't
    believe that part of the documentation, then I don't know what to tell you.
    Perl has some dark corners. If you don't want to put up with them, then
    don't use those parts of Perl. Anyway, your problem seems to be with sysV
    messages, not with "pack" itself.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
     
    , Mar 25, 2008
    #5
  6. unxl3arn3r

    Ben Morrow Guest

    Quoth :
    > unxl3arn3r <> wrote:
    > > On Mar 24, 4:57 pm, wrote:
    > > > unxl3arn3r <> wrote:
    > > > > Gurus
    > > > > I seem to be unable to pack a string padded with nulls and
    > > > > containing the length of the string prepended to it. This is my code
    > > > > snippet, where am i going wrong ?
    > > >
    > > > > $message1 = pack("l! a*",1, "This is a test,This program is free
    > > > > software,you can redistribute it terms as Perl network, This is why I
    > > > > said to talk");
    > > >
    > > > l! packs the "1", and a* packs the message. No where in there does the
    > > > length of the message enter into it.
    > > >
    > > > I see that that is copied from the perldoc -f msgsnd. I can only
    > > > assume that that documentation is hosed.
    > > >
    > > > Perhaps it should be this, instead?
    > > >
    > > > pack("l! l!/a*",1,"foo")
    > > >
    > > > Here l! packs the message type (1), l!/ packs the length of the
    > > > message, and a* packs the message itself.
    > > >
    > > > > msgsnd($queue,$message1,0);

    >
    > > why do I need to have the second variable in pack ?

    >
    > I don't understand your question. None of the packs I've seen in this
    > thread are given two variables. They are given three constants--a constant
    > format string, an constant integer, and a constant message string.
    >
    > > All I need to do
    > > is pack my outgoing string and prepad its length in front of it.

    >
    > But the code you posted prepended it with the native signed long
    > representation of 1. 1 is not the length of that message.


    The msgsnd docs are lying. The second argument of msgsnd should be the
    message, with a native long message type on the beginning; that is, the
    pack template 'l! a*' is correct, assuming your system doesn't pad after
    longs in structures. No length is required anywhere: msgsnd(2) takes a
    length argument, but perl can work this out from the length of the
    passed-in string.

    To the OP: why on earth aren't you using IPC::Msg? (Whose docs also lie,
    by the way: there is no need for a pack in the argument to ->snd.)

    Ben
     
    Ben Morrow, Mar 25, 2008
    #6
  7. unxl3arn3r

    unxl3arn3r Guest

    On Mar 25, 12:51 pm, Ben Morrow <> wrote:
    > Quoth :
    >
    >
    >
    > > unxl3arn3r <> wrote:
    > > > On Mar 24, 4:57 pm, wrote:
    > > > > unxl3arn3r <> wrote:
    > > > > > Gurus
    > > > > > I seem to be unable to pack a string padded with nulls and
    > > > > > containing the length of the string prepended to it. This is my code
    > > > > > snippet, where am i going wrong ?

    >
    > > > > > $message1 = pack("l! a*",1, "This is a test,This program is free
    > > > > > software,you can redistribute it terms as Perl network, This is why I
    > > > > > said to talk");

    >
    > > > > l! packs the "1", and a* packs the message. No where in there does the
    > > > > length of the message enter into it.

    >
    > > > > I see that that is copied from the perldoc -f msgsnd. I can only
    > > > > assume that that documentation is hosed.

    >
    > > > > Perhaps it should be this, instead?

    >
    > > > > pack("l! l!/a*",1,"foo")

    >
    > > > > Here l! packs the message type (1), l!/ packs the length of the
    > > > > message, and a* packs the message itself.

    >
    > > > > > msgsnd($queue,$message1,0);

    >
    > > > why do I need to have the second variable in pack ?

    >
    > > I don't understand your question. None of the packs I've seen in this
    > > thread are given two variables. They are given three constants--a constant
    > > format string, an constant integer, and a constant message string.

    >
    > > > All I need to do
    > > > is pack my outgoing string and prepad its length in front of it.

    >
    > > But the code you posted prepended it with the native signed long
    > > representation of 1. 1 is not the length of that message.

    >
    > The msgsnd docs are lying. The second argument of msgsnd should be the
    > message, with a native long message type on the beginning; that is, the
    > pack template 'l! a*' is correct, assuming your system doesn't pad after
    > longs in structures. No length is required anywhere: msgsnd(2) takes a
    > length argument, but perl can work this out from the length of the
    > passed-in string.
    >
    > To the OP: why on earth aren't you using IPC::Msg? (Whose docs also lie,
    > by the way: there is no need for a pack in the argument to ->snd.)
    >
    > Ben

    This msgrcv function is getting to me..... Now that I got the length
    in front of the string, I see the actual length. But if i send a
    message greater than the size of SIZE value, the queue goes in a tizzy
    and keeps trying to read the message again and over again. Whats the
    point of having this length, If it can't do its job right.
     
    unxl3arn3r, Mar 25, 2008
    #7
  8. unxl3arn3r

    unxl3arn3r Guest

    On Mar 25, 12:51 pm, Ben Morrow <> wrote:
    > Quoth :
    >
    >
    >
    > > unxl3arn3r <> wrote:
    > > > On Mar 24, 4:57 pm, wrote:
    > > > > unxl3arn3r <> wrote:
    > > > > > Gurus
    > > > > > I seem to be unable to pack a string padded with nulls and
    > > > > > containing the length of the string prepended to it. This is my code
    > > > > > snippet, where am i going wrong ?

    >
    > > > > > $message1 = pack("l! a*",1, "This is a test,This program is free
    > > > > > software,you can redistribute it terms as Perl network, This is why I
    > > > > > said to talk");

    >
    > > > > l! packs the "1", and a* packs the message. No where in there does the
    > > > > length of the message enter into it.

    >
    > > > > I see that that is copied from the perldoc -f msgsnd. I can only
    > > > > assume that that documentation is hosed.

    >
    > > > > Perhaps it should be this, instead?

    >
    > > > > pack("l! l!/a*",1,"foo")

    >
    > > > > Here l! packs the message type (1), l!/ packs the length of the
    > > > > message, and a* packs the message itself.

    >
    > > > > > msgsnd($queue,$message1,0);

    >
    > > > why do I need to have the second variable in pack ?

    >
    > > I don't understand your question. None of the packs I've seen in this
    > > thread are given two variables. They are given three constants--a constant
    > > format string, an constant integer, and a constant message string.

    >
    > > > All I need to do
    > > > is pack my outgoing string and prepad its length in front of it.

    >
    > > But the code you posted prepended it with the native signed long
    > > representation of 1. 1 is not the length of that message.

    >
    > The msgsnd docs are lying. The second argument of msgsnd should be the
    > message, with a native long message type on the beginning; that is, the
    > pack template 'l! a*' is correct, assuming your system doesn't pad after
    > longs in structures. No length is required anywhere: msgsnd(2) takes a
    > length argument, but perl can work this out from the length of the
    > passed-in string.
    >
    > To the OP: why on earth aren't you using IPC::Msg? (Whose docs also lie,
    > by the way: there is no need for a pack in the argument to ->snd.)
    >
    > Ben


    I forgot to put the code snippet in,
    #!/usr/bin/perl
    use strict;
    use IPC::Msg;
    use IPC::SysV;

    #$outgoing=$ARGV[0];
    my $key = 999;
    my $queue = msgget($key,0) or die $!;
    my $type = 1234;

    #$queue = new IPC::Msg($key,0);
    my $string = "This is a very long string The msgsnd docs are lying.
    The second a
    rgument of msgsnd should be the message, with a native long";
    my $value = length ($string);
    my $message1 = pack("l! a*",$value,$string);
    print "one=$message1 \n";
    msgsnd($queue,$message1,1);
    print $! ;


    receive
    #!/usr/bin/perl

    use IPC::SysV qw(IPC_RMID IPC_PRIVATE S_IRWXU IPC_CREAT
    IPC_NOWAIT );
    use IPC::Msg;

    my $key = 999;
    my $i = 0;
    my $queue = msgget($key,&IPC_CREAT | 0777) or die $!;
    my ($string, $i,$buffer,$type);

    for ($i;$i < 15; $i++) {

    if ( msgrcv($queue,$buffer,150,0,0) ) {

    ($type,$string)=unpack("l! a*",$buffer);
    print $buffer .$string . "\n" . $type;
    print "------------------------------\n";
    } else {

    print "Failed to read properly $! \n";
    print "Length to be read = length($buffer) \n";
    }
    }
    print "Now Removing\n";
    msgctl($queue,IPC_RMID,0);
     
    unxl3arn3r, Mar 25, 2008
    #8
  9. unxl3arn3r

    Guest

    unxl3arn3r <> wrote:
    > On Mar 25, 12:51 pm, Ben Morrow <> wrote:
    > >
    > > The msgsnd docs are lying. The second argument of msgsnd should be the
    > > message, with a native long message type on the beginning; that is, the
    > > pack template 'l! a*' is correct, assuming your system doesn't pad
    > > after longs in structures. No length is required anywhere: msgsnd(2)
    > > takes a length argument, but perl can work this out from the length of
    > > the passed-in string.
    > >
    > > To the OP: why on earth aren't you using IPC::Msg? (Whose docs also
    > > lie, by the way: there is no need for a pack in the argument to ->snd.)
    > >
    > > Ben

    ....
    >
    > my $value = length ($string);
    > my $message1 = pack("l! a*",$value,$string);


    As Ben just explained, you should be packing the message type,
    not the message length. So the original code was correct, despite
    the documentation mis-describing it.


    >
    > if ( msgrcv($queue,$buffer,150,0,0) ) {
    >
    > This msgrcv function is getting to me..... Now that I got the length
    > in front of the string, I see the actual length.


    Where is it that you are you seeing the actual length?

    > But if i send a
    > message greater than the size of SIZE value, the queue goes in a tizzy
    > and keeps trying to read the message again and over again.


    It fails because that is what the system call msgrcv is documented to do
    when the message is too big and when (msgflg & MSG_NOERROR) is 0. It "goes
    into a tizzy" because that is what you coded it to do by wrapping a bizarre
    loop around it. If you want it to truncate the message rather than
    fail, then pass MSG_NOERROR rather than 0 as the flag to msgrcv.


    > Whats the
    > point of having this length, If it can't do its job right.


    It does its jobs right. You just don't understand what its job is.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
     
    , Mar 25, 2008
    #9
  10. unxl3arn3r

    unxl3arn3r Guest

    On Mar 25, 4:58 pm, wrote:
    > unxl3arn3r <> wrote:
    > > On Mar 25, 12:51 pm, Ben Morrow <> wrote:

    >
    > > > The msgsnd docs are lying. The second argument of msgsnd should be the
    > > > message, with a native long message type on the beginning; that is, the
    > > > pack template 'l! a*' is correct, assuming your system doesn't pad
    > > > after longs in structures. No length is required anywhere: msgsnd(2)
    > > > takes a length argument, but perl can work this out from the length of
    > > > the passed-in string.

    >
    > > > To the OP: why on earth aren't you using IPC::Msg? (Whose docs also
    > > > lie, by the way: there is no need for a pack in the argument to ->snd.)

    >
    > > > Ben

    > ...
    >
    > > my $value = length ($string);
    > > my $message1 = pack("l! a*",$value,$string);

    >
    > As Ben just explained, you should be packing the message type,
    > not the message length. So the original code was correct, despite
    > the documentation mis-describing it.
    >
    >
    >
    > > if ( msgrcv($queue,$buffer,150,0,0) ) {

    >
    > > This msgrcv function is getting to me..... Now that I got the length
    > > in front of the string, I see the actual length.

    >
    > Where is it that you are you seeing the actual length?
    >
    > > But if i send a
    > > message greater than the size of SIZE value, the queue goes in a tizzy
    > > and keeps trying to read the message again and over again.

    >
    > It fails because that is what the system call msgrcv is documented to do
    > when the message is too big and when (msgflg & MSG_NOERROR) is 0. It "goes
    > into a tizzy" because that is what you coded it to do by wrapping a bizarre
    > loop around it. If you want it to truncate the message rather than
    > fail, then pass MSG_NOERROR rather than 0 as the flag to msgrcv.
    >
    > > Whats the
    > > point of having this length, If it can't do its job right.

    >
    > It does its jobs right. You just don't understand what its job is.
    >
    > Xho
    >
    > --
    > --------------------http://NewsReader.Com/--------------------
    > The costs of publication of this article were defrayed in part by the
    > payment of page charges. This article must therefore be hereby marked
    > advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    > this fact.


    Things would be easy to understand if there was a explanation of the
    what flags were meant to do what. Even docs are crap, so I can't be
    expected to master the perl msgrcv function without taking any help. I
    misunderstood pack and Ben both. Going back to read it again.
     
    unxl3arn3r, Mar 25, 2008
    #10
  11. unxl3arn3r

    Guest

    unxl3arn3r <> wrote:
    >
    > Things would be easy to understand if there was a explanation of the
    > what flags were meant to do what. Even docs are crap, so I can't be
    > expected to master the perl msgrcv function without taking any help. I
    > misunderstood pack and Ben both. Going back to read it again.


    Perl's msgrcv is just fairly shallow wrapper around the system call of the
    same name. To understand the flags, you should read the system's
    documentation ("man msgrcv"). But mastering it seems to be something of
    dubious value, to me. If you need to make your Perl script talk to your C
    programs that use this type of message passing, then you should already
    know all about this stuff from the C perspective, which will make it much
    easier to understand if from Perl as well. And if you are just talking
    Perl to Perl, I certainly would pick a different (more Perlish) method to
    do so.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
     
    , Mar 25, 2008
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Stacy Mader
    Replies:
    4
    Views:
    821
    Ekkehard Morgenstern
    Nov 22, 2003
  2. Oren Tirosh
    Replies:
    1
    Views:
    2,203
    Troy Melhase
    Jun 28, 2003
  3. Tim Jones
    Replies:
    0
    Views:
    381
    Tim Jones
    Jan 31, 2004
  4. Tulan W. Hu

    pack and unpack question for perl 5.8.0

    Tulan W. Hu, Jul 28, 2003, in forum: Perl Misc
    Replies:
    0
    Views:
    107
    Tulan W. Hu
    Jul 28, 2003
  5. Alexander Farber

    pack 'C3U*' not same as pack 'C3(xC)*'

    Alexander Farber, Jun 23, 2005, in forum: Perl Misc
    Replies:
    2
    Views:
    137
    Ilmari Karonen
    Jun 23, 2005
Loading...

Share This Page