/* set the message queue attributes */
struct mq_attr attr;
attr.mq_maxmsg = max_msgs;
attr.mq_msgsize = max_msgsize;
attr.mq_flags = O_NONBLOCK;
errno = 0;
mqd_t msgQ = mq_open(
mqname, /* message queue name */
O_RDWR | O_NONBLOCK | O_CREAT | O_EXCL, /* oflag */
S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH |
S_IWOTH | S_IXOTH, /* mode */
&attr); /* attributes */
The request handler attempts to open that (existing) messaege queue
with:
mqd_t msgQ = mq_open(
mqname, /* message queue name */
O_RDWR | O_NONBLOCK); /* mode */
The attempt to open the existing message queue fails with errno=13 -
permission denied.
The opening of the existing message queue works fine if attempted from
a process that has the same owner as the process that created the
message queue - in this case the app process. Any help will be
appreciated. Thx.
Making a message queue executable makes preciously little sense. Also,
do yourself a favor and ignore this set of inpronouncible acronyms in
favor of using octal numbers, like everyone else does. The values are
actually standardized as
0400 owner read
0200 owner write
0100 owner execute
with 'group' and 'other' permission encoded just like that, but using
00x0 for group permissions and 000x for other permissions. This reduces
the ASCII character flatworm to a simple 0777 (0666 in order to omit
the execute permission).
> The request handler attempts to open that (existing) messaege queue
> with:
>
> mqd_t msgQ = mq_open(
> mqname, /* message queue name */
> O_RDWR | O_NONBLOCK); /* mode */
>
> The attempt to open the existing message queue fails with errno=13 -
> permission denied.
Only the first two arguments to mq_open have standardized
semantics. At least on Linux, the third argument is interpreted like
all other access permission arguments, meaning, a set of effective
permission bits is calculated by masking the bits which are currently
set in the umask of the executing process. Assuming that x is your
input value, the value which gets applied is actually
x & ~umask
and umask will usually by 022 or 002, cause the group write and other
write bits to be disabled.
Thx for your response Rainer. Do you have any suggestion on how to
transfer data between an app process and the request handler process
of Apache? I tried to create a message queue in Apache main init
process, and open it within an app process. That works. The problem is
that the request handler process (a child process of Apache main
process) cannot open the message queue, so the request handler is
still unable to communicate with an app process.
Gogol
[...]
>> > errno = 0;
>> > mqd_t msgQ = mq_open(
>> > mqname, /* message queue name */
>> > O_RDWR | O_NONBLOCK | O_CREAT | O_EXCL, /* oflag */
>> > S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH |
>> > S_IWOTH | S_IXOTH, /* mode */
>> > &attr); /* attributes */
[...]
>> > The request handler attempts to open that (existing) messaege queue
>> > with:
>>
>> > mqd_t msgQ = mq_open(
>> > mqname, /* message queue name */
>> > O_RDWR | O_NONBLOCK); /* mode */
>>
>> > The attempt to open the existing message queue fails with errno=13 -
>> > permission denied.
[...]
>> Assuming that x is your> input value, the value which gets applied
>> is actually
>>
>> x & ~umask
>>
>> and umask will usually by 022 or 002, cause the group write and other
>> write bits to be disabled.
[...]
> I tried to create a message queue in Apache main init process, and
> open it within an app process. That works. The problem is that the
> request handler process (a child process of Apache main process)
> cannot open the message queue,
As I already wrote: Most likely, your problem is that the 'other
write' permission bit you gave in the mq_open call used to create the
message queue got disabled because the umask setting of the apache
process requested this to be done. Provided this was actually the case
(apache inherits the umask from the shell it was started from), you
could change the umask before creating the message queue, eg, by doing
something like this:
mode_t omask;
omask = umask(0); /* use permissions as specified */
mq_t = mq_open(...);
umask(omask);
It doesn't seem to make any difference. This is what I have in the
message queue creation:
mode_t omask = umask(0666);
printf("1st call to umask returned %o\n", omask);
printf("2nd call to umask returned %o\n", umask(0666));
mdq_t mq = mq_open("/mqname", O_RDWR | O_NONBLOCK | O_CREAT |
O_EXCL, 0666, &attr);
umask(omask);
if (mq < 0)
{
printf("mq_open() failed, errno=%d\n", errno);
return 0;
}
printf("mq_open successful\n");
The execution of this code shows:
1st call to unmask returned 22
2nd call to unmask return 777
mq_open() successful
In the Apache request handler I simply try (while the process that
created the queue is still running and the queue is not closed):
mqd_t mq = mq_open("/mqname", O_RDWR | O_NONBLOCK);
It fails with errno-13 - permission denied.
Phew...
Thx,
Need to make a correction to my previous response:
1st call to unmask returned 22
2nd call to unmask returned 666
mq_open() successful
[...]
>> eg, by doing something like this:
>>
>> mode_t omask;
>>
>> omask = umask(0); /* use permissions as specified */
>> mq_t = mq_open(...);
>> umask(omask);
>
> It doesn't seem to make any difference. This is what I have in the
> message queue creation:
>
> mode_t omask = umask(0666);
Rest assured that it does: You are now creating the message queue with
all read and write permission bits disabled.
>> write' permission bit you gave in the mq_open call used to create the
>> message queue got disabled because the umask setting of the apache
>> process requested this to be done. Provided this was actually the case
>> (apache inherits the umask from the shell it was started from), you
>> could change the umask before creating the message queue, eg, by doing
>> something like this:
>>
>> =A0 =A0 =A0 =A0 mode_t omask;
>>
>> =A0 =A0 =A0 =A0 omask =3D umask(0); =A0 =A0 =A0 /* use permissions as spe=
>cified */
>> =A0 =A0 =A0 =A0 mq_t =3D mq_open(...);
>> =A0 =A0 =A0 =A0 umask(omask);
>
>It doesn't seem to make any difference. This is what I have in the
>message queue creation:
>
> mode_t omask =3D umask(0666);
So, when Rainer suggested "umask(0)", why did use umask(0666)?
You are masking off write permission for everyone.
scott
This is the description of umask function:
-----------------------------------------------------------------------------------------------------
Synopsis
#include <sys/types.h>
#include <sys/stat.h>
mode_t umask(mode_t mask);
Description
umask() sets the calling process's file mode creation mask (umask) to
mask & 0777.
----------------------------------------------------------------------------------------------------------
So, if I call umask(0), then the mode creation mask is: 0 & 0777,
which is 0. I.e. all bits are reset. Anyways, against my logic, I
tried with umask(0) and got the same result in the request handler
when tried to open the message queue: errno=13 - permission denied.
If you guys see something wrong in what I am doing, please let me
know. I am really in a deep hole with my project.
Thx.
Your are right Rainer, the umask(0) does the trick. When I tried the
first time umask(0) I had the queue undeleted. Now I do the cleaning
and it works fine. Thx a bunch.
[...]
> This is the description of umask function:
> -----------------------------------------------------------------------------------------------------
> Synopsis
> #include <sys/types.h>
> #include <sys/stat.h>
>
> mode_t umask(mode_t mask);
> Description
> umask() sets the calling process's file mode creation mask (umask) to
> mask & 0777.
> ----------------------------------------------------------------------------------------------------------
>
> So, if I call umask(0), then the mode creation mask is: 0 & 0777,
> which is 0. I.e. all bits are reset.
It is often helpful to read a text completely before believing to know
what it was meant to say. Specifically, the text you partially quoted
continues with
(i.e., only the file permission bits of mask are used)
which means that if you use, say, 04022 as argument (04000 is the
set-user-id bit), the resulting umask will be 022. Somewhat later in
the same text, you could find this sentence:
Specifically, permissions in the umask are turned off from the
mode argument to open(2) and mkdir(2).
which is what I wrote in my reply to your original post.