public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* Re: Cygwin's writev() non-standard behavior
@ 2014-04-23 15:48 qq qq
  2014-04-23 16:44 ` Corinna Vinschen
  2014-04-23 18:44 ` Christopher Faylor
  0 siblings, 2 replies; 9+ messages in thread
From: qq qq @ 2014-04-23 15:48 UTC (permalink / raw)
  To: cygwin

> I applied a patch to CVS.

Thanks.  Although I could not see it in ViewVC -- the page stops loading at the "configure" script.

Anyhow, I suppose that check_iovec still returns EINVAL for count==0 in any read functions:  simply returning
"tot"==0 means EOF in many (if not all) of them.

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Cygwin's writev() non-standard behavior
  2014-04-23 15:48 Cygwin's writev() non-standard behavior qq qq
@ 2014-04-23 16:44 ` Corinna Vinschen
  2014-04-23 18:44 ` Christopher Faylor
  1 sibling, 0 replies; 9+ messages in thread
From: Corinna Vinschen @ 2014-04-23 16:44 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 781 bytes --]

On Apr 23 17:48, qq qq wrote:
> > I applied a patch to CVS.
> 
> Thanks.  Although I could not see it in ViewVC -- the page stops loading at the "configure" script.
> 
> Anyhow, I suppose that check_iovec still returns EINVAL for count==0 in any read functions:  simply returning
> "tot"==0 means EOF in many (if not all) of them.

That's perfectly ok:

  If count is zero, read() may detect the errors described below.  In the
  absence of any errors, or if read() does not check for errors, a read()
  with a count of 0 returns zero and has no other effects.

This behaviour is also fine for readv.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Cygwin's writev() non-standard behavior
  2014-04-23 15:48 Cygwin's writev() non-standard behavior qq qq
  2014-04-23 16:44 ` Corinna Vinschen
@ 2014-04-23 18:44 ` Christopher Faylor
  1 sibling, 0 replies; 9+ messages in thread
From: Christopher Faylor @ 2014-04-23 18:44 UTC (permalink / raw)
  To: cygwin

On Wed, Apr 23, 2014 at 05:48:25PM +0200, qq qq wrote:
>>I applied a patch to CVS.
>Thanks.   Although I could not see it in ViewVC -- the page stops
>loading at the "configure" script.

Yeah.  It does seem screwed up.  One more reason to move to git as soon
as I'm over the flu.

cgf

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Cygwin's writev() non-standard behavior
  2014-04-23 14:53 qq qq
@ 2014-04-23 16:24 ` Eric Blake
  0 siblings, 0 replies; 9+ messages in thread
From: Eric Blake @ 2014-04-23 16:24 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 1146 bytes --]

On 04/23/2014 08:53 AM, qq qq wrote:

[your mailer should really be taught to use In-Reply-To correctly; it's
annoying that every message from you starts a new thread]

>> furthermore, cygwin should emulate Linux behavior, even if POSIX
>> doesn't define the behavior.
> 
> And which is why I compared Linux vs. Cygwin in my original post ?

If you'll note, I was trying to be careful in my reply - I'm not opposed
to a change in cygwin, and in fact welcome one to bring us into
consistency with Linux behavior; but at the same time, I'm also pointing
out that your program is not portable and therefore it may be worth
fixing the portability assumptions in your program instead of waiting on
cygwin to provide the specific undefined behavior that you want to use.

> int main()
> {
>   struct iovec vec;
>   int fd = open("test.out", O_WRONLY | O_CREAT, 0666);
>   memset(&vec, 0, sizeof(vec));
>   if (writev(fd, &vec, 0) < 0)

POSIX allows, but not requires, writev() to fail with EINVAL when iovcnt
is 0.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Cygwin's writev() non-standard behavior
  2014-04-23 14:06 qq qq
  2014-04-23 14:43 ` Eric Blake
@ 2014-04-23 15:29 ` Corinna Vinschen
  1 sibling, 0 replies; 9+ messages in thread
From: Corinna Vinschen @ 2014-04-23 15:29 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 1300 bytes --]

On Apr 23 16:06, qq qq wrote:
> writev() does not accept count 0 but it should
> 
> $ cat test.c
> #include <stdio.h>
> #include <errno.h>
> #include <stdlib.h>
> #include <string.h>
> #include <sys/uio.h>
> 
> int main()
> {
>   struct iovec vec;
> 
>   memset(&vec, 0, sizeof(vec));
>   if (writev(1, &vec, 0) < 0)
>     perror("writev");
>   return 0;
> }
> 
> Linux:
> $ gcc -Wall test.c
> $ ./a.out
> 
> Cygwin:
> $ gcc -Wall test.c
> $ ./a.exe
> writev: Invalid argument
> 
> This behavior is buggy per:
> 
>        EINVAL ... the vector count count is less than zero or greater than the permitted maximum ...

I applied a patch to CVS.  There's a central function (check_iovec)
checking the validity of the iovec input and this function returns
EINVAL if iovlen is <= 0, the total number of bytes otherwise.

However, check_iovec works fine with iovlen 0 and all the callers
(readv/writev/recvmsg/sendmsg) are handling a 0 return from this 
function, too, so a 0 return is nothing to worry about.

Please given the next snapshot from http://cygwin.com/snapshots/ a try.


Thanks,
Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Cygwin's writev() non-standard behavior
  2014-04-23 14:43 ` Eric Blake
@ 2014-04-23 14:53   ` Eliot Moss
  0 siblings, 0 replies; 9+ messages in thread
From: Eliot Moss @ 2014-04-23 14:53 UTC (permalink / raw)
  To: cygwin

Using the link Eric Blake provided, I extract this from the POSIX
specification for writev:

"The iovcnt argument is valid if greater than 0 ..."

So, while the man page is a little off, the response seems
to be correct.  You cold argue, and I might agree, that
POSIX should have allowed a 0 and said writev should just
return 0 in that case, but they didn't ...

Regards -- Eliot Moss

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Cygwin's writev() non-standard behavior
@ 2014-04-23 14:53 qq qq
  2014-04-23 16:24 ` Eric Blake
  0 siblings, 1 reply; 9+ messages in thread
From: qq qq @ 2014-04-23 14:53 UTC (permalink / raw)
  To: cygwin

> furthermore, cygwin should emulate Linux behavior, even if POSIX
> doesn't define the behavior.

And which is why I compared Linux vs. Cygwin in my original post ?

> so your argument is flawed - you have triggered undefined behavior.

Same difference:
$ cat test.c
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/uio.h>

int main()
{
  struct iovec vec;
  int fd = open("test.out", O_WRONLY | O_CREAT, 0666);
  memset(&vec, 0, sizeof(vec));
  if (writev(fd, &vec, 0) < 0)
    perror("writev");
  return 0;
}

Linux:
$ gcc -Wall test.c
$ ./a.out

Cygwin:
$ gcc -Wall test.c
$ ./a.exe
writev: Invalid argument

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Cygwin's writev() non-standard behavior
  2014-04-23 14:06 qq qq
@ 2014-04-23 14:43 ` Eric Blake
  2014-04-23 14:53   ` Eliot Moss
  2014-04-23 15:29 ` Corinna Vinschen
  1 sibling, 1 reply; 9+ messages in thread
From: Eric Blake @ 2014-04-23 14:43 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 1115 bytes --]

On 04/23/2014 08:06 AM, qq qq wrote:
> writev() does not accept count 0 but it should

POSIX says:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/writev.html

If fildes refers to a regular file and all of the iov_len members in the
array pointed to by iov are 0, writev() shall return 0 and have no other
effect. For other file types, the behavior is unspecified.

> 
> $ cat test.c
> #include <stdio.h>
> #include <errno.h>
> #include <stdlib.h>
> #include <string.h>
> #include <sys/uio.h>
> 
> int main()
> {
>   struct iovec vec;
> 
>   memset(&vec, 0, sizeof(vec));
>   if (writev(1, &vec, 0) < 0)

But in your case, fd 1 is a terminal...

> Cygwin:
> $ gcc -Wall test.c
> $ ./a.exe
> writev: Invalid argument

so your argument is flawed - you have triggered undefined behavior.
That said, if you can reproduce it with ./a.exe > file, you have proven
a bug; furthermore, cygwin should emulate Linux behavior, even if POSIX
doesn't define the behavior.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Cygwin's writev() non-standard behavior
@ 2014-04-23 14:06 qq qq
  2014-04-23 14:43 ` Eric Blake
  2014-04-23 15:29 ` Corinna Vinschen
  0 siblings, 2 replies; 9+ messages in thread
From: qq qq @ 2014-04-23 14:06 UTC (permalink / raw)
  To: cygwin

writev() does not accept count 0 but it should

$ cat test.c
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/uio.h>

int main()
{
  struct iovec vec;

  memset(&vec, 0, sizeof(vec));
  if (writev(1, &vec, 0) < 0)
    perror("writev");
  return 0;
}

Linux:
$ gcc -Wall test.c
$ ./a.out

Cygwin:
$ gcc -Wall test.c
$ ./a.exe
writev: Invalid argument

This behavior is buggy per:

       EINVAL ... the vector count count is less than zero or greater than the permitted maximum ...

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2014-04-23 18:44 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-23 15:48 Cygwin's writev() non-standard behavior qq qq
2014-04-23 16:44 ` Corinna Vinschen
2014-04-23 18:44 ` Christopher Faylor
  -- strict thread matches above, loose matches on Subject: below --
2014-04-23 14:53 qq qq
2014-04-23 16:24 ` Eric Blake
2014-04-23 14:06 qq qq
2014-04-23 14:43 ` Eric Blake
2014-04-23 14:53   ` Eliot Moss
2014-04-23 15:29 ` Corinna Vinschen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).