delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2000/01/16/07:26:56

From: Martin Str|mberg <ams AT ludd DOT luth DOT se>
Message-Id: <200001161132.MAA17402@father.ludd.luth.se>
Subject: Re: _lleek
To: eliz AT is DOT elta DOT co DOT il (Eli Zaretskii)
Date: Sun, 16 Jan 100 12:32:53 +0100 (MET)
Cc: djgpp-workers AT delorie DOT com (DJGPP-WORKERS)
In-Reply-To: <Pine.SUN.3.91.1000116131542.12891A-100000@is> from Eli Zaretskii at "Jan 16, 0 01:18:31 pm"
X-Mailer: ELM [version 2.4ME+ PL15 (25)]
MIME-Version: 1.0
Reply-To: djgpp-workers AT delorie DOT com
Errors-To: dj-admin AT delorie DOT com
X-Mailing-List: djgpp-workers AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

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 -


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