Hi,

yesterday i downloaded and installed the newest maemo sdk and scratchbox 4.1 from maemo.org to port a database library (hamsterdb).

after some pondering, i found out that pwrite() usually succeeds, but only writes zeroes to the file. When replacing pwrite() with seek()/write(), everything works.

To reproduce, i wrote a small test program which allocates 3 pages (each of size 16kb), fills them and then writes them with pwrite(). But hexdump shows that only the first page is written, all other pages are zeroes.

I have attached my test program - it compiles with "gcc -g iotest.c", and creates an iotest.bin file with the broken pages. On my host system (Ubuntu 8 x64) it works.

Regards
Christoph

PS: i tried to search bugzilla, but the web interface seems to be broken (mysql returns SQL errors when querying the database).

PPS: in my configure script i will disable pread/pwrite if the target is arm-*-linux-gnu. If someone has a better test for broken pread/pwrite implementations, or a better test for scratchbox environments, please tell me.

/**
 * Copyright (C) 2005-2008 Christoph Rupp ([EMAIL PROTECTED]).
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or 
 * (at your option) any later version.
 *
 * See files COPYING.* for License information.
 *
 */

#define _GNU_SOURCE   1 /* for O_LARGEFILE */
#define __USE_XOPEN2K 1 /* for ftruncate() */
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>

typedef unsigned long long ham_offset_t;
typedef unsigned ham_size_t;

static void
my_enable_largefile(int fd)
{
    /*
     * not available on cygwin...
     */
    int oflag=fcntl(fd, F_GETFL, 0);
    fcntl(fd, F_SETFL, oflag|O_LARGEFILE);
}

static void
my_lock_exclusive(int fd, int lock)
{
    int r, flags;

    if (lock)
        flags=LOCK_EX|LOCK_NB;
    else
        flags=LOCK_UN;

    r=flock(fd, flags);
    assert(r==0);
}

void
os_pread(int fd, ham_offset_t addr, void *buffer, ham_size_t bufferlen)
{
    int r;
    ham_size_t total=0;

    while (total<bufferlen) {
        r=pread(fd, buffer+total, bufferlen-total, addr+total);
	assert(r>=0);
        if (r==0)
            break;
        total+=r;
    }

    assert(total==bufferlen);
}

void
os_seek(int fd, ham_offset_t offset, int whence)
{
    int r=lseek(fd, offset, whence);
    assert(r!=-1);
}

void
os_pwrite(int fd, ham_offset_t addr, const void *buffer, ham_size_t bufferlen)
{
    ssize_t s;
    ham_size_t total=0;

    while (total<bufferlen) {
        s=pwrite(fd, buffer, bufferlen, addr);
        assert(s>=0);
        if (s==0)
            break;
        total+=s;
    }

    assert(total==bufferlen);
}

void
os_truncate(int fd, ham_offset_t newsize)
{
    int r=ftruncate(fd, newsize);
    assert(r==0);
}

void
os_create(const char *filename, unsigned mode, int *fd)
{
    int osflags=O_CREAT|O_RDWR|O_TRUNC;

    *fd=open(filename, osflags, mode);
    assert(*fd>0);

    my_enable_largefile(*fd);
    my_lock_exclusive(*fd, 1);
}

void
os_close(int fd)
{
    my_lock_exclusive(fd, 0);
    close(fd);
}

void
os_tell(int fd, ham_offset_t *offset)
{
    *offset=lseek(fd, 0, SEEK_CUR);
    assert(*offset!=-1);
}

void
os_get_filesize(int fd, ham_offset_t *size)
{
    os_seek(fd, 0, SEEK_END);
    os_tell(fd, size);
}

int main()
{
	const char *fname="iotest.bin";
	char page[1024*16];
	int fd;
	ham_offset_t address;
	int i;

	os_create(fname, 0644, &fd);

	for (i=0; i<3; i++) {
		printf("%u: line %d\n", i, __LINE__);
    		os_get_filesize(fd, &address);
		printf("next page: %llu\n", address);
		printf("%u: line %d\n", i, __LINE__);
    		os_truncate(fd, address+sizeof(page));
		printf("%u: line %d\n", i, __LINE__);
		os_pread(fd, address, page, sizeof(page));
		printf("%u: line %d\n", i, __LINE__);
		memset(page, 'a'+i, sizeof(page));
		printf("%u: line %d\n", i, __LINE__);
		os_pwrite(fd, address, page, sizeof(page));
	}
	os_close(fd);
	return (0);
}
_______________________________________________
Scratchbox-users mailing list
[email protected]
http://lists.scratchbox.org/cgi-bin/mailman/listinfo/scratchbox-users

Reply via email to