/* Slightly modified __seterrno.c from libnix 1.1a. */
/* (and _errno2ioerr added.) */
/* Public Domain. */

#include <errno.h>
#include <dos/dosasl.h>

#ifdef __PPC__
#include <ppcproto/dos.h>
#else
#include <proto/dos.h>
#endif

#include "globals.h"
#include "systemcalls.h"

/* Table to convert amigados error messages to unix ones */

static long _errortable[]=
{ 
  ERROR_NO_FREE_STORE		,ENOMEM,
  ERROR_TASK_TABLE_FULL		,EPROCLIM,
/*ERROR_BAD_TEMPLATE */
  ERROR_BAD_NUMBER   ,EINVAL,
/*ERROR_REQUIRED_ARG_MISSING
  ERROR_KEY_NEEDS_ARG*/
  ERROR_TOO_MANY_ARGS		,E2BIG,
/*ERROR_UNMATCHED_QUOTES*/
  ERROR_LINE_TOO_LONG		,E2BIG,
/*ERROR_FILE_NOT_OBJECT
  ERROR_INVALID_RESIDENT_LIBRARY
  ERROR_NO_DEFAULT_DIR*/
  ERROR_OBJECT_IN_USE		,ETXTBSY,
  ERROR_OBJECT_EXISTS		,EEXIST,
  ERROR_DIR_NOT_FOUND		,ENOENT,
  ERROR_OBJECT_NOT_FOUND	,ENOENT,
  ERROR_BAD_STREAM_NAME		,ENAMETOOLONG,
  ERROR_OBJECT_TOO_LARGE	,EFBIG,
  ERROR_ACTION_NOT_KNOWN	,ENODEV,
/*ERROR_INVALID_COMPONENT_NAME
  ERROR_INVALID_LOCK
  ERROR_OBJECT_WRONG_TYPE*/
  ERROR_DISK_NOT_VALIDATED	,EBUSY,
  ERROR_DISK_WRITE_PROTECTED	,EROFS,
/*ERROR_RENAME_ACROSS_DEVICES*/
  ERROR_DIRECTORY_NOT_EMPTY	,ENOTEMPTY,
  ERROR_TOO_MANY_LEVELS		,ELOOP /* ENAMETOOLONG */,
  ERROR_DEVICE_NOT_MOUNTED	,ENXIO,
  ERROR_SEEK_ERROR		,ESPIPE,
/*ERROR_COMMENT_TOO_BIG*/
  ERROR_DISK_FULL		,ENOSPC,
  ERROR_DELETE_PROTECTED	,EACCES,
  ERROR_WRITE_PROTECTED		,EACCES,
  ERROR_READ_PROTECTED		,EACCES,
  ERROR_NOT_A_DOS_DISK		,EFTYPE,
  ERROR_NO_DISK			,ENXIO,
/*ERROR_NO_MORE_ENTRIES
  ERROR_IS_SOFT_LINK
  ERROR_OBJECT_LINKED*/
  ERROR_BAD_HUNK		,ENOEXEC,
  ERROR_NOT_IMPLEMENTED   ,ENOSYS,
/*ERROR_RECORD_NOT_LOCKED
  ERROR_LOCK_COLLISION
  ERROR_LOCK_TIMEOUT
  ERROR_UNLOCK_ERROR
  ERROR_BUFFER_OVERFLOW
  ERROR_BREAK*/
  ERROR_NOT_EXECUTABLE		,EACCES,
  0
};
  
int __ioerr2errno (long int ioerr)
{ 
  long *ptr=_errortable;

  /* Work correctly if there was no error. */
  if (ioerr == 0)
    return (0);

  while (*ptr)
  {
    if (*ptr ++ == ioerr)
      return (*ptr);
    ptr ++;
  }
  return (EPERM);
}

long int __errno2ioerr (long int errnocode)
{
  long *ptr = _errortable;
  while (*ptr++)
  {
    if (errnocode == *ptr)
      return (*--ptr);
    ptr ++;
  }
  return (0);
}

void __seterrno (void)
{
  __syscall_handle sh;

  sh = __syscall_start ();
  __ioerr = IoErr ();
  errno = __ioerr2errno (__ioerr);
  __syscall_end (sh);
}
