pwritev() doesn't work anymore on i386

Bug #1309818 reported by Gianluca Borello
16
This bug affects 3 people
Affects Status Importance Assigned to Milestone
eglibc (Ubuntu)
Confirmed
Undecided
Unassigned

Bug Description

I just upgraded to Trusty, and the following programs fails on x86:

#include <stdio.h>
#include <stdint.h>
#include <sys/uio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
 char *str0 = "hello ";
 char *str1 = "world\n";
 struct iovec iov[2];
 ssize_t nwritten;
 int fd = open("test.txt", O_CREAT | O_WRONLY);

 iov[0].iov_base = str0;
 iov[0].iov_len = strlen(str0);
 iov[1].iov_base = str1;
 iov[1].iov_len = strlen(str1);

 nwritten = pwritev(fd, iov, 2, 0);
 if(nwritten < 0)
  perror("pwritev");

 return 0;
}

Compiled without any flags, I see:

$ ./test
pwritev: File too large

And, from strace, I can see the offset parameter is handled wrongly by (presumably) libc:

...
pwritev(3, [{"hello ", 6}, {"world\n", 6}], 2, 577730142772658176) = -1 EFBIG (File too large)
...

If I compile with -D_FILE_OFFSET_BITS=64, everything is right, but is not a solution for my problem as I can't use that flag in my program.

I reported this here because it doesn't seem to happen on Debian sid, but let me know if I have to report it upstream.

$ lsb_release -rd
Description: Ubuntu 14.04 LTS
Release: 14.04

$ apt-cache policy libc6
libc6:
  Installed: 2.19-0ubuntu6
  Candidate: 2.19-0ubuntu6

Revision history for this message
Gianluca Borello (g.borello) wrote :

Any update on this?

Revision history for this message
Michael Ferguson (mpfergu) wrote :

I'm also encountering this bug with updated Ubuntu 14.04 but only on 32-bit installations.

I have another program to reproduce it, included below. This program
makes it to printing out OK on the 64-bit version.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/uio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>

int main() {
  struct iovec vec[1];
  char* buf;
  size_t buflen = 4096;
  char* data = "aaaaaaaaaaaaaaaaaaaa";
  int datalen = strlen(data);
  int fd;
  ssize_t got;

  buf = malloc(buflen);
  assert(buf);
  vec[0].iov_base = buf;
  vec[0].iov_len = buflen;

  // open file
  fd = open("tmp.data", O_RDWR | O_CREAT, S_IRWXU);
  assert(fd>=0);

  // copy data to buf
  memset(buf, 0, buflen);
  memcpy(buf, data, datalen);
  vec[0].iov_base = buf;
  vec[0].iov_len = datalen;
  // write data
  got = pwritev(fd, vec, 1, 0);
  //got = pwrite(fd, buf, datalen, 0);
  if( got == - 1 ) perror("in write");
  assert(got == datalen);

  // clear buf
  memset(buf, 0, buflen);
  // read data
  vec[0].iov_base = buf;
  vec[0].iov_len = buflen;
  got = preadv(fd, vec, 1, 0);
  //got = pread(fd, buf, buflen, 0);
  if( got == - 1 ) perror("in read");
  assert(got == datalen);
  // check data
  assert(0 == memcmp(data, buf, datalen));

  close(fd);
  unlink("tmp.data");

  printf("OK\n");

  return 0;
}

Revision history for this message
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in eglibc (Ubuntu):
status: New → Confirmed
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.