Martin-Éric Racine, le Wed 27 Dec 2006 12:06:34 +0200, a écrit : > ke, 2006-12-27 kello 11:03 +0100, Samuel Thibault kirjoitti: > > Martin-Éric Racine, le Wed 27 Dec 2006 11:45:43 +0200, a écrit : > > > _llseek(3, 0, 0, SEEK_SET) = -1 EFAULT (Bad address) > > > write(4, "llseek: Bad address\n", 20llseek: Bad address > > > > This looks like the problem: > > fdisk shouldn't be providing a NULL address here. > > I wonder why it does.
Herm, because atari-fdisk directly calls Linux' _llseek() without taking care about the size of arguments, without taking care of 64bits architectures, etc. while GNU libc has been providing a sane way for doing 64bits lseek() for a long time. Here is a patch for using that instead. Samuel
diff -ur atari-fdisk-0.7.1/disk.c atari-fdisk-0.7.1-mine/disk.c --- atari-fdisk-0.7.1/disk.c 2006-10-23 20:35:51.000000000 +0200 +++ atari-fdisk-0.7.1-mine/disk.c 2006-12-27 22:56:24.000000000 +0100 @@ -60,13 +60,12 @@ "$Id: disk.c,v 1.10 1997/08/22 12:35:38 rnhodek Exp $"; #endif /* lint */ +#define _FILE_OFFSET_BITS 64 + #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -#ifdef __linux__ -#include <sys/syscall.h> -#endif #include <fcntl.h> #include <errno.h> @@ -81,43 +80,13 @@ /* * sseek: seek to specified sector - return 0 on failure * - * For >4GB disks lseek needs a > 32bit arg, and we have to use llseek. + * For >4GB disks lseek needs a > 32bit arg. * On the other hand, a 32 bit sector number is OK until 2TB. - * The routines _llseek and sseek below are the only ones that - * know about the loff_t type. + * + * Thanks to _FILE_OFFSET_BITS, we can have GNU libc use an 64bit off_t even on + * 32bit platforms. */ -#ifdef SYS__llseek - -#define _llseek(fd, hi, lo, res, wh) syscall(SYS__llseek, fd, hi, lo, res, wh) - -/* seek to a sector */ -int sseek( unsigned int fd, unsigned long s ) -{ - loff_t in, out; - - in = (loff_t)s * SECTOR_SIZE; - out = 1; - - if (_llseek (fd, in>>32, in & 0xffffffff, &out, SEEK_SET) != 0) { - perror( "llseek" ); - fprintf( stderr, "seek error - cannot seek to sector %lu\n", s ); - return 0; - } - - if (in != out) { - fprintf( stderr, "seek error: wanted 0x%08x%08x, got 0x%08x%08x\n", - (uint)(in>>32), (uint)(in & 0xffffffff), - (uint)(out>>32), (uint)(out & 0xffffffff) ); - return 0; - } - return 1; -} - -#else - -/* Sorry, kernel doesn't know _llseek call :-((( */ - int sseek( unsigned int fd, unsigned long s ) { off_t in, out; @@ -136,8 +105,6 @@ return 1; } -#endif - /* read one sector */ void sread( char *buffer, unsigned long secno ) {