www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1999/02/06/12:30:59

From: Martin Str|mberg <ams AT ludd DOT luth DOT se>
Message-Id: <199902061729.SAA23636@father.ludd.luth.se>
Subject: FAT32 step 3
To: djgpp-workers AT delorie DOT com (DJGPP-WORKERS)
Date: Sat, 6 Feb 1999 18:29:03 +0100 (MET)
X-Mailer: ELM [version 2.4ME+ PL15 (25)]
MIME-Version: 1.0
Reply-To: djgpp-workers AT delorie DOT com

Here's the last step of FAT32 support (unless somebody thinks something
should be added). This adds _llseek().

Again if somebody knows how to get the correct offset on files bigger
than 2^31, alternatively can detect whether the file pointer is past
the beginning of the file, let me know.

If nobody finds anything major wrong with this, I'll later (a week) post
all three steps in one big patch.


Genesis, Trespass,

							MartinS

diff -ru include.org/sys/djtypes.h include/sys/djtypes.h
--- include.org/sys/djtypes.h	Wed Sep  9 16:56:26 1998
+++ include/sys/djtypes.h	Fri Feb  5 23:42:46 1999
@@ -6,6 +6,7 @@
 #define __DJ_clock_t	typedef int clock_t;
 #define __DJ_gid_t	typedef int gid_t;
 #define __DJ_off_t	typedef int off_t;
+#define __DJ_offset_t	typedef long long offset_t;
 #define __DJ_pid_t	typedef int pid_t;
 #define __DJ_size_t	typedef long unsigned int size_t;
 #define __DJ_ssize_t	typedef int ssize_t;
diff -ru include.org/sys/types.h include/sys/types.h
--- include.org/sys/types.h	Sat Feb 22 13:06:06 1997
+++ include/sys/types.h	Fri Feb  5 23:42:52 1999
@@ -24,6 +24,9 @@
 __DJ_off_t
 #undef __DJ_off_t
 #define __DJ_off_t
+__DJ_offset_t
+#undef __DJ_offset_t
+#define __DJ_offset_t
 __DJ_pid_t
 #undef __DJ_pid_t
 #define __DJ_pid_t
diff -ru include.org/unistd.h include/unistd.h
--- include.org/unistd.h	Mon Jun 29 00:02:48 1998
+++ include/unistd.h	Fri Feb  5 23:44:40 1999
@@ -72,6 +72,7 @@
 
 void		__exit(int _status) __attribute__((noreturn));
 void		_exit(int _status) __attribute__((noreturn));
+offset_t       	_llseek(int _fildes, offset_t _offset, int _whence);
 int		access(const char *_path, int _amode);
 unsigned int	alarm(unsigned int _seconds);
 int		chdir(const char *_path);
diff -ruN src.org.3/libc/compat/unistd/_llseek.c src/libc/compat/unistd/_llseek.c
--- src.org.3/libc/compat/unistd/_llseek.c	Thu Jan  1 00:00:00 1970
+++ src/libc/compat/unistd/_llseek.c	Sat Feb  6 14:24:28 1999
@@ -0,0 +1,128 @@
+/*
+ * File _llseek.c.
+ *
+ * Copyright (C) 1999 Martin Str”mberg <ams AT ludd DOT luth DOT se>.
+ *
+ * This software may be used freely so long as this copyright notice is
+ * left intact. There is no warranty on this software.
+ *
+ */
+
+#include <libc/stubs.h>
+#include <unistd.h>
+#include <limits.h>
+
+#if 0
+/* This #if 0ed code is an atempt to make _llseek() return correct
+   values when the file pointer is further than MAX_INT from the
+   beginning of the file. Unsuccessful so far. If you know the
+   solution let me know, thank you.
+   */
+
+#define SEEK_STEP (1<<30)
+
+static void
+do__llseek_from_0(int handle, offset_t offset)
+{
+
+  lseek(handle, 0, SEEK_SET);
+  while( offset )
+  {
+    if( INT_MAX < offset )
+    {
+      lseek(handle, INT_MAX, SEEK_CUR);
+      offset -= INT_MAX;
+    }
+    else
+    {
+      lseek(handle, offset, SEEK_CUR);
+      offset = 0;
+    }
+  }
+
+}
+
+
+static offset_t
+get_offset(int handle)
+{
+  long long real_offset;
+  off_t lseek_offset;
+  
+  real_offset = lseek(handle, 0, SEEK_CUR);
+
+  lseek(handle, -real_offset, SEEK_CUR);
+  /* Now we are on an 1<<31 (2^31) boundary. */
+
+  /* Try stepping backwards. */
+  lseek_offset = lseek(handle, -SEEK_STEP, SEEK_CUR);
+  while( lseek_offset )
+  {
+    /* We did move over zero, so this must be another chunk of 2^31 bytes. 
+     Move to the 1<<31 boundary. */
+    lseek(handle, -lseek_offset, SEEK_CUR);
+
+    /* Increase the real offset. */
+    real_offset += SEEK_STEP + lseek_offset;
+
+    /* Another step backwards... */
+    lseek_offset = lseek(handle, -SEEK_STEP, SEEK_CUR);
+  }
+
+  /* Reset file pointer to where we started. */
+  do__llseek_from_0(handle, real_offset);
+
+  return( real_offset );
+
+}
+#endif
+      
+
+offset_t
+_llseek(int handle, offset_t offset, int whence)
+{
+  /* Should it have an FS extension? 
+  __FSEXT_Function *func = __FSEXT_get_function(handle);
+  if (func)
+  {
+    int rv;
+    if (func(__FSEXT_llseek, &rv, &handle))
+      return rv;
+  }
+  */
+
+  int sign;
+  off_t lseek_offset = lseek(handle, 0, whence);  /* If we are seeking
+						     from beginning or
+						     end this sets the
+						     pointer there. */
+
+#if 0
+  tmp_offset = get_offset(handle);
+#endif
+
+  if( 0LL <= offset )
+  {
+    sign = 1;
+  }
+  else
+  {
+    sign = -1;
+  }
+  while( offset )
+  {
+    if( INT_MAX < sign*offset )
+    {
+      lseek(handle, sign*INT_MAX, SEEK_CUR);
+      offset -= sign*INT_MAX;
+    }
+    else
+    {
+      lseek_offset = lseek(handle, offset, SEEK_CUR);
+      offset = 0;
+    }
+  }
+
+  return( lseek_offset );
+
+}
diff -ruN src.org.3/libc/compat/unistd/_llseek.txh src/libc/compat/unistd/_llseek.txh
--- src.org.3/libc/compat/unistd/_llseek.txh	Thu Jan  1 00:00:00 1970
+++ src/libc/compat/unistd/_llseek.txh	Fri Feb  5 23:41:06 1999
@@ -0,0 +1,55 @@
+@node _llseek, io
+@subheading Syntax
+
+@example
+#include <unistd.h>
+
+offset_t _llseek(int fd, offset_t offset, int whence);
+@end example
+
+@subheading Description
+
+This function moves the file pointer for @var{fd} according to
+@var{whence}:
+
+@table @code
+
+@item SEEK_SET
+
+The file pointer is moved to the offset specified.
+
+@item SEEK_CUR
+
+The file pointer is moved relative to its current position.
+
+@item SEEK_END
+
+The file pointer is moved to a position @var{offset} bytes from the end
+of the file.  The offset is usually nonpositive in this case. 
+
+@end table
+
+@var{offset} is of type long long, thus enabling you to seek with
+offsets as large as ~2^63.
+
+@subheading Return Value
+
+The new offset is returned. Note that due to limitations in the
+underlying DOS implementation only return values in the range 
+[0, MAX_INT] should be relied upon.
+
+@subheading Portability
+
+@portability !ansi, !posix
+
+@subheading Example
+
+@example
+long long ret;
+
+ret = _llseek(fd, (1<<32), SEEK_SET); /* Now ret equals 0 (unfortunately). */
+ret = _llseek(fd, -1, SEEK_CUR); /* Now ret equals 2^32-1 (good!). */
+ret = _llseek(fd, 0, SEEK_SET); /* Now ret equals 0 (good!). */
+ret = _llseek(fd, -1, SEEK_CUR); /* Now ret equals 2^32-1 (bad). */
+@end example
+
diff -ruN src.org.3/libc/compat/unistd/makefile src/libc/compat/unistd/makefile
--- src.org.3/libc/compat/unistd/makefile	Sun Jun 28 21:53:24 1998
+++ src/libc/compat/unistd/makefile	Sat Feb  6 00:16:44 1999
@@ -2,6 +2,7 @@
 # Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details
 TOP=../..
 
+SRC += _llseek.c
 SRC += basename.c
 SRC += dirname.c
 SRC += fsync.c

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019