Mail Archives: djgpp-workers/2000/01/16/07:26:56
According to Eli Zaretskii:
> I was trying to understand what were you suggesting as the solution.
> Seems like I didn't understand it. Can you describe your solution
> in more details?
Here's my solution:
/*
* 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 <dpmi.h>
#include <errno.h>
#include <libc/dosio.h>
#define MAX_FILE_POINTER_POSITION ( ( 1LL << 32 ) - 2 )
static offset_t
ll_llseek(int handle, offset_t offset, int whence)
{
__dpmi_regs r;
r.h.ah = 0x42;
r.h.al = whence;
r.x.bx = handle;
r.x.cx = offset >> 16;
r.x.dx = offset & 0xffff;
__dpmi_int(0x21, &r);
if (r.x.flags & 1)
{
errno = __doserr_to_errno(r.x.ax);
return -1;
}
return( ( ( (unsigned)r.x.dx ) << 16) + r.x.ax );
}
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;
}
*/
offset_t position;
/* We convert SEEK_CUR and SEEK_END to SEEK_SET. */
if( whence == SEEK_CUR || whence == SEEK_END )
{
position = ll_llseek( handle, 0, whence );
if( position < 0 )
{
/* Seek failed. */
return( -1 );
}
whence = SEEK_SET;
offset = position + offset;
}
/* Obviously, this part must be after conversion to SEEK_SET. */
if( whence == SEEK_SET )
{
if( offset < 0 )
{
offset = 0;
}
else if( MAX_FILE_POINTER_POSITION < offset )
{
offset = MAX_FILE_POINTER_POSITION;
}
}
else
{
errno = EINVAL;
return( -1 );
}
return( ll_llseek( handle, offset, whence ) );
}
> > After running this, I'll have a file g:/ggg.grr that is 2^32-3 big!
> >
> > Substitute -3 with any big value in [2^31, 2^32-3] and you'll get a
> > big file (I've tried a couple different ones).
>
> Does this mean that FAT32 doesn't support negative seeks directly, even
> with SEEK_CUR?
I don't know and from my solution as you can see it doesn't matter as
long as seek(fd, SEEK_CUR/SEEK_END, 0) return valid values and
SEEK_SET works.
Right,
MartinS
- Raw text -