2

I have written this code to make a posix message queue. But I am receiving an error "Function not implemented".

Q1. Is it a platform related issue ? [Am using Ubuntu 10.10] I read somewhere that I need to rebuild my kernel to enable message queues !?

Q2. I also read something about starting the mqueue server before actually using message queues ?

Can someone please explain..

#include <mqueue.h>     /* message queue stuff */
#include <iostream>
#include <unistd.h>     /* for getopt() */
#include <errno.h>      /* errno and perror */
#include <fcntl.h>      /* O_flags */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using namespace std;

int main(int argc, char **argv)
{

mqd_t msgQueueDescriptor;
mq_attr attr;

char Msg[]="msg";

attr.mq_maxmsg = 10;
attr.mq_msgsize = sizeof(Msg);
attr.mq_flags = 0;

msgQueueDescriptor = mq_open("/myQueue", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH , attr );
cout << msgQueueDescriptor << " " << errno << " " << strerror(errno);
mq_close(msgQueueDescriptor);

return 0;
}
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
Amit Tomar
  • 4,800
  • 6
  • 50
  • 83
  • According to `mq_overview(7)`, POSIX messages queues are enabled by default when building the kernel, but the Ubuntu packagers might have turned them off. – Fred Foo Jan 16 '12 at 11:35
  • @larsmans How can I confirm that? Will that be a part of release notes of Ubuntu? And how can I turn it back on in case its really turned off? – Amit Tomar Jan 16 '12 at 11:40
  • I would find ubuntu really weird if they really turned them off. On fedora 15, your example compiles and links successfully. – BЈовић Jan 16 '12 at 11:42
  • You might want to download a kernel source package via Synaptic and check its configuration; the error you got is surely `ENOSYS`, meaning no system call. Turning MQs on would involve recompiling the kernel, I think. I'd be very surprised if MQs are not supported in the default kernel, though. – Fred Foo Jan 16 '12 at 11:47
  • 1
    This compiles, links and runs on Ubuntu 10.04.3. To verify your kernel is configured with the needed flag. look at `/boot/config*`. – n. m. could be an AI Jan 16 '12 at 11:52
  • @n.m. `CONFIG_POSIX_MQUEUE=y` `CONFIG_POSIX_MQUEUE_SYSCTL=y` is what I can see in this file related to mqueues. But it seems they are enabled? – Amit Tomar Jan 16 '12 at 11:57
  • I'm sure you just made a mistake in your code in your question, but in the call to `mq_open` you should give the attribute argument as a pointer (i.e. `&attr` in your code snippet). – Some programmer dude Jan 16 '12 at 12:12
  • @VJovic well yes, some distros just are weird like that. – jørgensen Jan 16 '12 at 16:00
  • @JoachimPileborg: Good point. The compiler will not catch it, because the function is prototyped with `...` in place of the fourth parameter. – n. m. could be an AI Jan 16 '12 at 17:33
  • @JoachimPileborg Thanks for pointing that out, although I was having the same problem when I used `NULL`. – Amit Tomar Jan 17 '12 at 04:34

1 Answers1

2

I think I have realized what the problem was, or rather a mistake from side.

This is what I read from here -

[ In reference to mq_open( ) ]

Returns: A valid message queue descriptor if the queue is successfully created, or -1 (errno is set).

So, I should be checking the value for errno only when an error actually occurs!. But in the above code I am just printing the value irrespective of an error occured or not, and thus it is printing the error message corresponding to some garbage value stored in errno.

So my code should be something like this -

if ((msgQueueDescriptor = mq_open("/myQueue", O_RDWR|O_CREAT, 0664 ,NULL ) == -1))
{
    cout << msgQueueDescriptor << " " << errno << " " << strerror(errno);
}
else
{
   cout << "All is well" ;
} 

Did I just made a fool outa myself :p

PS: As far as message queues being enabled on Ubuntu 10.10 is concerned, I checked the flags as mentioned by "n.m.", they are very much enabled, and I am able to use the message queues now. Thanks all of you - larsmans, VJovic, n.m., Joachim Pileborg, jørgensen.

About my second question

Q2. I also read something about starting the mqueue server before actually using message queues ?

I think that is a requirement specifically on QNX.

Community
  • 1
  • 1
Amit Tomar
  • 4,800
  • 6
  • 50
  • 83
  • 1
    It is important to remember that no library function sets `errno` to zero (at least, not in the standard C library), and that you should only inspect `errno` if the last function that might set it actually indicated that it failed. Counter-example: on Solaris, many of the stdio calls check whether the output is a tty, and leave `errno == ENOTTY` when it isn't, even though the call succeeded perfectly. So, yes, you made a small fool of yourself, but you learned from it, so it is a valuable experience. – Jonathan Leffler Jan 17 '12 at 06:01
  • As for Q2: if there's nothing in the manual pages about starting `mqueue server` (and I've never seen any mention of it), then there's no need to do so - regardless of what QNX thinks about the situation. – Jonathan Leffler Jan 17 '12 at 06:02
  • 1
    Checking `errno` should only be done if a function fails (unless specified otherwise). Actually, reading the official POSIX specification on `errno` [here](http://pubs.opengroup.org/onlinepubs/009695399/functions/errno.html), it says _No function in this volume of IEEE Std 1003.1-2001 shall set errno to 0. The setting of errno after a successful call to a function is unspecified unless the description of that function specifies that errno shall not be modified._ – Some programmer dude Jan 17 '12 at 06:47
  • Verdict: Not a fool. Helpful learner, yes :) Cheers – sehe Aug 12 '21 at 10:53