* [Xenomai-help] pipe fun
@ 2005-11-21 10:11 Ignacio García Pérez
2005-11-21 10:44 ` Dmitry Adamushko
0 siblings, 1 reply; 7+ messages in thread
From: Ignacio García Pérez @ 2005-11-21 10:11 UTC (permalink / raw)
To: xenomai
Hi,
This has to be something really simple but I'm hitting a wall. I have a
rt module that creates a pipe and periodically writes some data to it.
In the following program, the read fails with "No space left on device":
int main (void) {
int r, fd; u_char c;
fd = open("/proc/xenomai/registry/pipes/rt2event", O_RDWR);
if (fd < 0) {
fprintf(stderr, "ERROR opening pipe: %s\n", strerror(errno));
return -1;
}
for (;;) {
r = read(fd, &c, sizeof(c));
if (r == 0) { fprintf(stderr, "ERROR reading (returned 0)\n");
break; }
if (r < 0) { fprintf(stderr, "ERROR reading: %s\n",
strerror(errno)); break; }
fprintf(stderr, "%02hX ", c);
}
close(fd);
return 0;
}
However, the following program works fine!!!
int main (void) {
int r; u_char c;
FILE *f;
f = fopen("/proc/xenomai/registry/pipes/rt2event", "r+b");
if (f == NULL) {
fprintf(stderr, "ERROR opening pipe: %s\n", strerror(errno));
return -1;
}
for (;;) {
r = fread(&c, sizeof(c), 1, f);
if (r == 0) { fprintf(stderr, "ERROR reading (returned 0)\n");
break; }
if (r < 0) { fprintf(stderr, "ERROR reading: %s\n",
strerror(errno)); break; }
fprintf(stderr, "%02hX ", c);
}
fclose(f);
return 0;
}
Any clues?
By the way, I noticed a "cat /proc/xenomai/registry/pipes/rt2event |
xxd" won't work, perhaps due to the same reason?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Xenomai-help] pipe fun
2005-11-21 10:11 [Xenomai-help] pipe fun Ignacio García Pérez
@ 2005-11-21 10:44 ` Dmitry Adamushko
2005-11-21 11:24 ` Ignacio García Pérez
0 siblings, 1 reply; 7+ messages in thread
From: Dmitry Adamushko @ 2005-11-21 10:44 UTC (permalink / raw)
To: Ignacio García Pérez; +Cc: xenomai
[-- Attachment #1: Type: text/plain, Size: 3436 bytes --]
xenomai-help-bounces@domain.hid wrote on 21.11.2005 11:11:52:
>
> This has to be something really simple but I'm hitting a wall. I have a
> rt module that creates a pipe and periodically writes some data to it.
> In the following program, the read fails with "No space left on device":
The reason is as follows:
from rt_pipe_send() docs
* This service writes a complete message to be received from the
* associated special device. rt_pipe_send() always preserves message
* boundaries, which means that all data sent through a single call of
* this service will be gathered in a single read(2) operation from
* the special device.
Data is written as a size-bounded message so a reader must provide a
big-enough buffer for the message to be read as a whole. It's possible to
send data as a stream (rt_pipe_stream()) but not possible (well, should it
be so?) to read it as a stream (actually, it's possible but as a side
effect - that's why fread() works).
[code]
nucleus::pipe.c::xnpipe_read()
...
ret = (ssize_t)xnpipe_m_size(mh); /* Cannot be zero */
state->ionrd -= ret;
xnlock_put_irqrestore(&nklock,s);
if (ret <= count) <---- Is a provided buffer big enough to host
the whole message?
{
if (__copy_to_user(buf,xnpipe_m_data(mh),ret))
ret = -EFAULT;
}
else
/* Return buffer is too small - message is lost. */
ret = -ENOSPC; <---- That's the error you are getting.
...
[/code]
Why does fread() work? It just uses an additional buffering (by default)
and provides a big enough internal buffer for read(). So the whole message
is read into that buffer upon the first fread() call from your side and a
few subsequent fread() calls just return data from that internal buffer. So
it looks like data being read as a stream but that's only a consequence of
additional buffering being made by glibc::fread().
>
>
> int main (void) {
>
> int r, fd; u_char c;
>
> fd = open("/proc/xenomai/registry/pipes/rt2event", O_RDWR);
> if (fd < 0) {
> fprintf(stderr, "ERROR opening pipe: %s\n", strerror(errno));
> return -1;
> }
>
> for (;;) {
> r = read(fd, &c, sizeof(c));
> if (r == 0) { fprintf(stderr, "ERROR reading (returned 0)\n");
> break; }
> if (r < 0) { fprintf(stderr, "ERROR reading: %s\n",
> strerror(errno)); break; }
> fprintf(stderr, "%02hX ", c);
> }
>
> close(fd);
>
> return 0;
> }
>
>
> However, the following program works fine!!!
>
>
> int main (void) {
>
> int r; u_char c;
>
> FILE *f;
>
> f = fopen("/proc/xenomai/registry/pipes/rt2event", "r+b");
> if (f == NULL) {
> fprintf(stderr, "ERROR opening pipe: %s\n", strerror(errno));
> return -1;
> }
>
> for (;;) {
> r = fread(&c, sizeof(c), 1, f);
> if (r == 0) { fprintf(stderr, "ERROR reading (returned 0)\n");
> break; }
> if (r < 0) { fprintf(stderr, "ERROR reading: %s\n",
> strerror(errno)); break; }
> fprintf(stderr, "%02hX ", c);
> }
>
> fclose(f);
>
> return 0;
> }
>
>
>
> Any clues?
>
> By the way, I noticed a "cat /proc/xenomai/registry/pipes/rt2event |
> xxd" won't work, perhaps due to the same reason?
>
---
Best regards,
Dmitry
[-- Attachment #2: Type: text/html, Size: 5290 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Xenomai-help] pipe fun
2005-11-21 10:44 ` Dmitry Adamushko
@ 2005-11-21 11:24 ` Ignacio García Pérez
2005-11-21 12:11 ` Dmitry Adamushko
0 siblings, 1 reply; 7+ messages in thread
From: Ignacio García Pérez @ 2005-11-21 11:24 UTC (permalink / raw)
To: Dmitry Adamushko; +Cc: xenomai
Dmitry Adamushko wrote:
> /* Return buffer is too small - message is lost. */
> ret = -ENOSPC; <---- That's the error you are getting.
>
Maybe "No space left on device" is a bit misleading. Wouldn't ENOMEM fit
better? (or event EINVAL)
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Xenomai-help] pipe fun
2005-11-21 11:24 ` Ignacio García Pérez
@ 2005-11-21 12:11 ` Dmitry Adamushko
2005-11-21 12:36 ` Philippe Gerum
0 siblings, 1 reply; 7+ messages in thread
From: Dmitry Adamushko @ 2005-11-21 12:11 UTC (permalink / raw)
To: Ignacio García Pérez; +Cc: xenomai
[-- Attachment #1: Type: text/plain, Size: 862 bytes --]
Ignacio García Pérez <iggarpe@domain.hid> wrote on 21.11.2005 12:24:57:
> Dmitry Adamushko wrote:
>
> > /* Return buffer is too small - message is lost. */
> > ret = -ENOSPC; <---- That's the error you are getting.
> >
> Maybe "No space left on device" is a bit misleading. Wouldn't ENOMEM fit
> better? (or event EINVAL)
>
Actually, looking now at the linux sources, -ENOSPC is used for describing
the same reason (buffer is not big enough) in some places; although there
is, at least, one more value -ENOBUFS that's used for the same reason.
#define ENOSPC 28 /* No space left on device */
#define ENOBUFS 105 /* No buffer space available */
So it looks like both may be used in the same context but, I guess, a
definition of -ENOBUFS is less confusing.
---
Best regards,
Dmitry
[-- Attachment #2: Type: text/html, Size: 1232 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Xenomai-help] pipe fun
2005-11-21 12:11 ` Dmitry Adamushko
@ 2005-11-21 12:36 ` Philippe Gerum
2005-11-21 12:55 ` Dmitry Adamushko
0 siblings, 1 reply; 7+ messages in thread
From: Philippe Gerum @ 2005-11-21 12:36 UTC (permalink / raw)
To: Dmitry Adamushko; +Cc: xenomai
Dmitry Adamushko wrote:
> Ignacio García Pérez <iggarpe@domain.hid> wrote on 21.11.2005 12:24:57:
>
> > Dmitry Adamushko wrote:
> >
> > > /* Return buffer is too small - message is lost. */
> > > ret = -ENOSPC; <---- That's the error you are getting.
> > >
> > Maybe "No space left on device" is a bit misleading. Wouldn't ENOMEM fit
> > better? (or event EINVAL)
> >
>
> Actually, looking now at the linux sources, -ENOSPC is used for
> describing the same reason (buffer is not big enough) in some places;
> although there is, at least, one more value -ENOBUFS that's used for the
> same reason.
>
> #define ENOSPC 28 /* No space left on device */
> #define ENOBUFS 105 /* No buffer space available */
>
> So it looks like both may be used in the same context but, I guess, a
> definition of -ENOBUFS is less confusing.
>
>
Let's fix this.
> ---
> Best regards,
> Dmitry
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Xenomai-help mailing list
> Xenomai-help@domain.hid
> https://mail.gna.org/listinfo/xenomai-help
--
Philippe.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Xenomai-help] pipe fun
2005-11-21 12:36 ` Philippe Gerum
@ 2005-11-21 12:55 ` Dmitry Adamushko
2005-11-21 18:28 ` Philippe Gerum
0 siblings, 1 reply; 7+ messages in thread
From: Dmitry Adamushko @ 2005-11-21 12:55 UTC (permalink / raw)
To: Philippe Gerum; +Cc: xenomai
[-- Attachment #1.1: Type: text/plain, Size: 1623 bytes --]
Philippe Gerum <rpm@xenomai.org> wrote on 21.11.2005 13:36:41:
> Dmitry Adamushko wrote:
> > Ignacio García Pérez <iggarpe@domain.hid> wrote on 21.11.2005 12:24:57:
> >
> > > Dmitry Adamushko wrote:
> > >
> > > > /* Return buffer is too small - message is lost. */
> > > > ret = -ENOSPC; <---- That's the error you are getting.
> > > >
> > > Maybe "No space left on device" is a bit misleading. Wouldn't ENOMEM
fit
> > > better? (or event EINVAL)
> > >
> >
> > Actually, looking now at the linux sources, -ENOSPC is used for
> > describing the same reason (buffer is not big enough) in some places;
> > although there is, at least, one more value -ENOBUFS that's used for
the
> > same reason.
> >
> > #define ENOSPC 28 /* No space left on device */
> > #define ENOBUFS 105 /* No buffer space available */
> >
> > So it looks like both may be used in the same context but, I guess, a
> > definition of -ENOBUFS is less confusing.
> >
> >
>
> Let's fix this.
>
Enclosed.
One more thing about xnpipe_read() though.
...
}
else
/* Return buffer is too small - message is lost. */
ret = -ENOBUFS;
So the message is lost in such a case. We may easily avoid that by making a
proper check of the size when we are still in the locked section and
putting the message back into the queue (prependq() of course). I think
that would be more sane.
> --
>
> Philippe.
---
Best regards,
Dmitry
(See attached file: pipe-ENOBUFS.patch)(See attached file: ChangeLog.patch)
[-- Attachment #1.2: Type: text/html, Size: 2497 bytes --]
[-- Attachment #2: pipe-ENOBUFS.patch --]
[-- Type: application/octet-stream, Size: 321 bytes --]
--- pipe.c-old 2005-11-21 14:56:25.000000000 +0100
+++ pipe.c 2005-11-21 14:56:59.000000000 +0100
@@ -749,7 +749,7 @@
}
else
/* Return buffer is too small - message is lost. */
- ret = -ENOSPC;
+ ret = -ENOBUFS;
if (handler != NULL)
ret = handler(xnminor_from_state(state),mh,ret,cookie);
[-- Attachment #3: ChangeLog.patch --]
[-- Type: application/octet-stream, Size: 559 bytes --]
--- ChangeLog-old 2005-11-21 15:04:40.000000000 +0100
+++ ChangeLog 2005-11-21 15:04:27.000000000 +0100
@@ -1,4 +1,11 @@
+2005-11-21 Dmitry Adamushko <dmitry.adamushko@gmail.com>
+
+ * nucleus/pipe.c (xnpipe_send): Return -ENOBUFS instead of -ENOSPC
+ when a given buffer is not big enough for the entire message to be
+ written in. perror() gives a, hopefully, more-precise and less-confusing
+ description for the former one.
+
2005-11-18 Heikki Lindholm <holindho@cs.helsinki.fi>
* include/asm-powerpc/system.h, ksrc/arch/powerpc/switch_64.S: Add
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Xenomai-help] pipe fun
2005-11-21 12:55 ` Dmitry Adamushko
@ 2005-11-21 18:28 ` Philippe Gerum
0 siblings, 0 replies; 7+ messages in thread
From: Philippe Gerum @ 2005-11-21 18:28 UTC (permalink / raw)
To: Dmitry Adamushko; +Cc: xenomai
Dmitry Adamushko wrote:
> Philippe Gerum <rpm@xenomai.org> wrote on 21.11.2005 13:36:41:
>
> > Dmitry Adamushko wrote:
> > > Ignacio García Pérez <iggarpe@domain.hid> wrote on 21.11.2005 12:24:57:
> > >
> > > > Dmitry Adamushko wrote:
> > > >
> > > > > /* Return buffer is too small - message is lost. */
> > > > > ret = -ENOSPC; <---- That's the error you are getting.
> > > > >
> > > > Maybe "No space left on device" is a bit misleading. Wouldn't
> ENOMEM fit
> > > > better? (or event EINVAL)
> > > >
> > >
> > > Actually, looking now at the linux sources, -ENOSPC is used for
> > > describing the same reason (buffer is not big enough) in some places;
> > > although there is, at least, one more value -ENOBUFS that's used
> for the
> > > same reason.
> > >
> > > #define ENOSPC 28 /* No space left on device */
> > > #define ENOBUFS 105 /* No buffer space available */
> > >
> > > So it looks like both may be used in the same context but, I guess, a
> > > definition of -ENOBUFS is less confusing.
> > >
> > >
> >
> > Let's fix this.
> >
>
> Enclosed.
>
Applied, thanks.
> One more thing about xnpipe_read() though.
>
>
> ...
> }
> else
> /* Return buffer is too small - message is lost. */
> ret = -ENOBUFS;
>
> So the message is lost in such a case. We may easily avoid that by
> making a proper check of the size when we are still in the locked
> section and putting the message back into the queue (prependq() of
> course). I think that would be more sane.
>
Problem is that if nobody ends up reading the message because the
application always passes invalid args, internal heap memory may be
exhausted due to unread messages.
>
> > --
> >
> > Philippe.
>
> ---
> Best regards,
> Dmitry
>
> /(See attached file: pipe-ENOBUFS.patch)//(See attached file:
> ChangeLog.patch)/
>
--
Philippe.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2005-11-21 18:28 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-11-21 10:11 [Xenomai-help] pipe fun Ignacio García Pérez
2005-11-21 10:44 ` Dmitry Adamushko
2005-11-21 11:24 ` Ignacio García Pérez
2005-11-21 12:11 ` Dmitry Adamushko
2005-11-21 12:36 ` Philippe Gerum
2005-11-21 12:55 ` Dmitry Adamushko
2005-11-21 18:28 ` Philippe Gerum
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.