From: Martin Str|mberg 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 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit 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 . + * + * This software may be used freely so long as this copyright notice is + * left intact. There is no warranty on this software. + * + */ + +#include +#include +#include + +#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 + +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