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 )
 {

Reply via email to