/* lseek.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes */

#include <io.h>
#include <errno.h>
#include <emx/io.h>
#include <emx/syscalls.h>

long _lseek (int handle, long offset, int origin)
{
  int *pflags, *pla;
  long n, cur;

  if ((pflags = _fd_flags (handle)) == NULL
      || (pla = _fd_lookahead (handle)) == NULL)
    {
      errno = EBADF;
      return -1;
    }
  if (origin == SEEK_CUR && (*pla >= 0 || (*pflags & F_EOF)))
    --offset;
  if (offset < 0)
    {
      /* DOS doesn't return an error for seek before beginning of file */
      if (origin == SEEK_SET)
        {
          errno = EINVAL;
          return -1;
        }
      cur = (long)__lseek (handle, 0L, SEEK_CUR);
      if (cur == -1L)
        return -1;
      n = (long)__lseek (handle, 0L, origin);
      if (n + offset < 0)
        {
          __lseek (handle, cur, SEEK_SET);
          errno = EINVAL;
          return -1;
        }
      offset += n; origin = SEEK_SET;
    }
  n = (long)__lseek (handle, offset, origin);
  if (n == -1L)
    return -1;
  else
    {
      *pflags &= ~F_EOF;        /* Clear Ctrl-Z flag */
      *pla = -1;                /* Clear lookahead */
      return n;
    }
}
