OSDN Git Service

2007-08-10 Carlos O'Donell <carlos@codesourcery.com>
authorjjohnstn <jjohnstn>
Fri, 10 Aug 2007 19:36:46 +0000 (19:36 +0000)
committerjjohnstn <jjohnstn>
Fri, 10 Aug 2007 19:36:46 +0000 (19:36 +0000)
        2007-07-12  Daniel Jacobowitz  <dan@codesourcery.com>

        * arm/syscalls.c (_stat): Use _close

        * arm/syscalls.c (struct poslog): Rename to...
        (struct fdent): ... this.
        (FILE_HANDLE_OFFSET): Remove.
        (findslot): Return a struct fdent* if fd is valid, otherwise return NULL.
        (newslot): New function.
        (remap_handle): Remove.
        (initialise_monitor_handles): Use stdout as fallback for stderr.
        (wrap): Rename to...
        (checkerror): ...  this.
        (_swiread): Use checkerror() for the return of SWI calls.  Correct the use of r0.
        (_read): Use findslot().  Return EBADF on bad handle.
        (_swilseek): Call findslot().  Check for valid whence.  Check for negative offset when using
        SEEK_CUR, and check for overflow.  Use checkerror().  Check *_Flen calls for errors.
        (_swiwrite): Correct the use of r0.
        (_write): Call findslot().
        (_swiopen): Call findslot().  Check for valid flags.  Use checkerror().  Call newslot().
        Handle O_TRUNC, and O_WRONLY.  Return index into openfiles[] for fd.
        (_swiclose): Correct the use of r0.
        (_close): Handle stderr == stdout case.  Only reclaim handle if _swiclose succeeded.
        (_getpid): Use __attribute__((unused)).
        (_sbrk): Fix formatting.
        (_swistat): New function.
        (_stat): Call _swistat().
        (_fstat): Call _swistat().
        (_unlink): Correct the use of r0.
        (isatty): Call finslot().  Correct the use of r0.
        (_system): Call checkerror().  Correct the use of r0.
        (_rename): Correct the use of r0.

libgloss/ChangeLog
libgloss/arm/syscalls.c

index 3fce808..e1aa5c3 100644 (file)
@@ -1,8 +1,43 @@
-2007-07-13  Kevin Buettner  <kevinb@redhat.com>
-
-       * mep/fmax.ld, mep/gmap_default.ld, mep/min.ld, mep/simple.ld
-       (.gcc_except_table): Add pattern for .gcc_except_table.*.
-
+2007-08-10  Carlos O'Donell  <carlos@codesourcery.com>
+
+       2007-07-12  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * arm/syscalls.c (_stat): Use _close
+       
+       * arm/syscalls.c (struct poslog): Rename to...
+       (struct fdent): ... this.
+       (FILE_HANDLE_OFFSET): Remove.
+       (findslot): Return a struct fdent* if fd is valid, otherwise return NULL.  
+       (newslot): New function.  
+       (remap_handle): Remove.  
+       (initialise_monitor_handles): Use stdout as fallback for stderr.  
+       (wrap): Rename to...  
+       (checkerror): ...  this.  
+       (_swiread): Use checkerror() for the return of SWI calls.  Correct the use of r0.  
+       (_read): Use findslot().  Return EBADF on bad handle.  
+       (_swilseek): Call findslot().  Check for valid whence.  Check for negative offset when using 
+       SEEK_CUR, and check for overflow.  Use checkerror().  Check *_Flen calls for errors.  
+       (_swiwrite): Correct the use of r0.  
+       (_write): Call findslot().  
+       (_swiopen): Call findslot().  Check for valid flags.  Use checkerror().  Call newslot().  
+       Handle O_TRUNC, and O_WRONLY.  Return index into openfiles[] for fd.  
+       (_swiclose): Correct the use of r0.  
+       (_close): Handle stderr == stdout case.  Only reclaim handle if _swiclose succeeded.  
+       (_getpid): Use __attribute__((unused)).  
+       (_sbrk): Fix formatting.  
+       (_swistat): New function.  
+       (_stat): Call _swistat().  
+       (_fstat): Call _swistat().  
+       (_unlink): Correct the use of r0.  
+       (isatty): Call finslot().  Correct the use of r0.  
+       (_system): Call checkerror().  Correct the use of r0.  
+       (_rename): Correct the use of r0.  
+       
+2007-07-13  Kevin Buettner  <kevinb@redhat.com> 
+
+       * mep/fmax.ld, mep/gmap_default.ld, mep/min.ld, mep/simple.ld (.gcc_except_table): Add pattern 
+       for .gcc_except_table.*.  
+                                       
 2007-07-06  Jeff Johnston  <jjohnstn@redhat.com>
 
        * arm/syscalls.c (gettimeofday): Change to POSIX signature
index 1ab3830..0e0a5da 100644 (file)
@@ -27,6 +27,7 @@ int     _unlink               _PARAMS ((const char *));
 int     _link          _PARAMS ((void));
 int     _stat          _PARAMS ((const char *, struct stat *));
 int     _fstat                 _PARAMS ((int, struct stat *));
+int    _swistat        _PARAMS ((int fd, struct stat * st));
 caddr_t _sbrk          _PARAMS ((int));
 int     _getpid                _PARAMS ((int));
 int     _close         _PARAMS ((int));
@@ -42,11 +43,39 @@ int     _read               _PARAMS ((int, char *, int));
 int     _swiread       _PARAMS ((int, char *, int));
 void    initialise_monitor_handles _PARAMS ((void));
 
-static int     wrap            _PARAMS ((int));
+static int     checkerror      _PARAMS ((int));
 static int     error           _PARAMS ((int));
 static int     get_errno       _PARAMS ((void));
-static int     remap_handle    _PARAMS ((int));
-static int     findslot        _PARAMS ((int));
+
+/* Struct used to keep track of the file position, just so we
+   can implement fseek(fh,x,SEEK_CUR).  */
+struct fdent
+{
+  int handle;
+  int pos;
+};
+
+#define MAX_OPEN_FILES 20
+
+/* User file descriptors (fd) are integer indexes into 
+   the openfiles[] array. Error checking is done by using
+   findslot(). 
+
+   This openfiles array is manipulated directly by only 
+   these 5 functions:
+
+       findslot() - Translate entry.
+       newslot() - Find empty entry.
+       initilise_monitor_handles() - Initialize entries.
+       _swiopen() - Initialize entry.
+       _close() - Handle stdout == stderr case.
+
+   Every other function must use findslot().  */
+
+static struct fdent openfiles [MAX_OPEN_FILES];
+
+static struct fdent*   findslot        _PARAMS ((int));
+static int             newslot         _PARAMS ((void));
 
 /* Register name faking - works in collusion with the linker.  */
 register char * stack_ptr asm ("sp");
@@ -62,49 +91,44 @@ extern void   _EXFUN(__sinit,(struct _reent *));
     }                                          \
   while (0)
 
-/* Adjust our internal handles to stay away from std* handles.  */
-#define FILE_HANDLE_OFFSET (0x20)
-
 static int monitor_stdin;
 static int monitor_stdout;
 static int monitor_stderr;
 
-/* Struct used to keep track of the file position, just so we
-   can implement fseek(fh,x,SEEK_CUR).  */
-typedef struct
+/* Return a pointer to the structure associated with
+   the user file descriptor fd. */ 
+static struct fdent*
+findslot (int fd)
 {
-  int handle;
-  int pos;
-}
-poslog;
+  CHECK_INIT(_REENT);
 
-#define MAX_OPEN_FILES 20
-static poslog openfiles [MAX_OPEN_FILES];
+  /* User file descriptor is out of range. */
+  if ((unsigned int)fd >= MAX_OPEN_FILES)
+    return NULL;
 
-static int
-findslot (int fh)
-{
-  int i;
-  for (i = 0; i < MAX_OPEN_FILES; i ++)
-    if (openfiles[i].handle == fh)
-      break;
-  return i;
+  /* User file descriptor is open? */
+  if (openfiles[fd].handle == -1)
+    return NULL;
+
+  /* Valid. */
+  return &openfiles[fd];
 }
 
-/* Function to convert std(in|out|err) handles to internal versions.  */
+/* Return the next lowest numbered free file 
+   structure, or -1 if we can't find one. */ 
 static int
-remap_handle (int fh)
+newslot (void)
 {
-  CHECK_INIT(_REENT);
+  int i;
+
+  for (i = 0; i < MAX_OPEN_FILES; i++)
+    if (openfiles[i].handle == -1)
+      break;
 
-  if (fh == STDIN_FILENO)
-    return monitor_stdin;
-  if (fh == STDOUT_FILENO)
-    return monitor_stdout;
-  if (fh == STDERR_FILENO)
-    return monitor_stderr;
+  if (i == MAX_OPEN_FILES)
+    return -1;
 
-  return fh - FILE_HANDLE_OFFSET;
+  return i;
 }
 
 void
@@ -165,6 +189,10 @@ initialise_monitor_handles (void)
   monitor_stderr = fh;
 #endif
 
+  /* If we failed to open stderr, redirect to stdout. */
+  if (monitor_stderr == -1)
+    monitor_stderr = monitor_stdout;
+
   for (i = 0; i < MAX_OPEN_FILES; i ++)
     openfiles[i].handle = -1;
 
@@ -188,6 +216,7 @@ get_errno (void)
 #endif
 }
 
+/* Set errno and return result. */
 static int
 error (int result)
 {
@@ -195,21 +224,24 @@ error (int result)
   return result;
 }
 
+/* Check the return and set errno appropriately. */
 static int
-wrap (int result)
+checkerror (int result)
 {
   if (result == -1)
     return error (-1);
   return result;
 }
 
-/* Returns # chars not! written.  */
+/* fh, is a valid internal file handle.
+   ptr, is a null terminated string.
+   len, is the length in bytes to read. 
+   Returns the number of bytes *not* written. */
 int
-_swiread (int file,
+_swiread (int fh,
          char * ptr,
          int len)
 {
-  int fh = remap_handle (file);
 #ifdef ARM_RDI_MONITOR
   int block[3];
   
@@ -217,104 +249,152 @@ _swiread (int file,
   block[1] = (int) ptr;
   block[2] = len;
   
-  return do_AngelSWI (AngelSWI_Reason_Read, block);
+  return checkerror (do_AngelSWI (AngelSWI_Reason_Read, block));
 #else
-  asm ("mov r0, %1; mov r1, %2;mov r2, %3; swi %a0"
-       : /* No outputs */
-       : "i"(SWI_Read), "r"(fh), "r"(ptr), "r"(len)
-       : "r0","r1","r2");
+  register r0 asm("r0");
+  register r1 asm("r1");
+  register r2 asm("r2");
+  r0 = fh;
+  r1 = (int)ptr;
+  r2 = len;
+  asm ("swi %a4"
+       : "=r" (r0)
+       : "0"(r0), "r"(r1), "r"(r2), "i"(SWI_Read));
+  return checkerror (r0);
 #endif
 }
 
+/* fd, is a valid user file handle. 
+   Translates the return of _swiread into
+   bytes read. */
 int
-_read (int file,
+_read (int fd,
        char * ptr,
        int len)
 {
-  int slot = findslot (remap_handle (file));
-  int x = _swiread (file, ptr, len);
+  int res;
+  struct fdent *pfd;
 
-  if (x < 0)
-    return error (-1);
+  pfd = findslot (fd);
+  if (pfd == NULL)
+    {
+      errno = EBADF;
+      return -1;
+    }
 
-  if (slot != MAX_OPEN_FILES)
-    openfiles [slot].pos += len - x;
+  res = _swiread (pfd->handle, ptr, len);
 
-  /* x == len is not an error, at least if we want feof() to work.  */
-  return len - x;
+  if (res == -1)
+    return res;
+
+  pfd->pos += len - res;
+
+  /* res == len is not an error, 
+     at least if we want feof() to work.  */
+  return len - res;
 }
 
+/* fd, is a user file descriptor. */
 int
-_swilseek (int file,
-          int ptr,
-          int dir)
+_swilseek (int fd,
+       int ptr,
+       int dir)
 {
   int res;
-  int fh = remap_handle (file);
-  int slot = findslot (fh);
-#ifdef ARM_RDI_MONITOR
-  int block[2];
-#endif
+  struct fdent *pfd;
+
+  /* Valid file descriptor? */
+  pfd = findslot (fd);
+  if (pfd == NULL)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
+  /* Valid whence? */
+  if ((dir != SEEK_CUR)
+      && (dir != SEEK_SET)
+      && (dir != SEEK_END))
+    {
+      errno = EINVAL;
+      return -1;
+    }
 
+  /* Convert SEEK_CUR to SEEK_SET */
   if (dir == SEEK_CUR)
     {
-      if (slot == MAX_OPEN_FILES)
-       return -1;
-      ptr = openfiles[slot].pos + ptr;
+      ptr = pfd->pos + ptr;
+      /* The resulting file offset would be negative. */
+      if (ptr < 0)
+        {
+          errno = EINVAL;
+          if ((pfd->pos > 0) && (ptr > 0))
+            errno = EOVERFLOW;
+          return -1;
+        }
       dir = SEEK_SET;
     }
-  
 #ifdef ARM_RDI_MONITOR
+  int block[2];
   if (dir == SEEK_END)
     {
-      block[0] = fh;
-      ptr += do_AngelSWI (AngelSWI_Reason_FLen, block);
+      block[0] = pfd->handle;
+      res = checkerror (do_AngelSWI (AngelSWI_Reason_FLen, block));
+      if (res == -1)
+        return -1;
+      ptr += res;
     }
   
   /* This code only does absolute seeks.  */
-  block[0] = remap_handle (file);
+  block[0] = pfd->handle;
   block[1] = ptr;
-  res = do_AngelSWI (AngelSWI_Reason_Seek, block);
+  res = checkerror (do_AngelSWI (AngelSWI_Reason_Seek, block));
 #else
   if (dir == SEEK_END)
     {
       asm ("mov r0, %2; swi %a1; mov %0, r0"
           : "=r" (res)
-          : "i" (SWI_Flen), "r" (fh)
+          : "i" (SWI_Flen), "r" (pfd->handle)
           : "r0");
+      checkerror (res);
+      if (res == -1)
+        return -1;
       ptr += res;
     }
 
   /* This code only does absolute seeks.  */
   asm ("mov r0, %2; mov r1, %3; swi %a1; mov %0, r0"
        : "=r" (res)
-       : "i" (SWI_Seek), "r" (fh), "r" (ptr)
+       : "i" (SWI_Seek), "r" (pfd->handle), "r" (ptr)
        : "r0", "r1");
+  checkerror (res);
 #endif
-
-  if (slot != MAX_OPEN_FILES && res == 0)
-    openfiles[slot].pos = ptr;
-
-  /* This is expected to return the position in the file.  */
-  return res == 0 ? ptr : -1;
+  /* At this point ptr is the current file position. */
+  if (res >= 0)
+    {
+      pfd->pos = ptr;
+      return ptr;
+    }
+  else
+    return -1;
 }
 
-int
-_lseek (int file,
+_lseek (int fd,
        int ptr,
        int dir)
 {
-  return wrap (_swilseek (file, ptr, dir));
+  return _swilseek (fd, ptr, dir);
 }
 
-/* Returns #chars not! written.  */
+/* fh, is a valid internal file handle.
+   Returns the number of bytes *not* written. */
 int
 _swiwrite (
-          int    file,
+          int    fh,
           char * ptr,
           int    len)
 {
-  int fh = remap_handle (file);
 #ifdef ARM_RDI_MONITOR
   int block[3];
   
@@ -322,64 +402,103 @@ _swiwrite (
   block[1] = (int) ptr;
   block[2] = len;
   
-  return do_AngelSWI (AngelSWI_Reason_Write, block);
+  return checkerror (do_AngelSWI (AngelSWI_Reason_Write, block));
 #else
-  asm ("mov r0, %1; mov r1, %2;mov r2, %3; swi %a0"
-       : /* No outputs */
-       : "i"(SWI_Write), "r"(fh), "r"(ptr), "r"(len)
-       : "r0","r1","r2");
+  register r0 asm("r0");
+  register r1 asm("r1");
+  register r2 asm("r2");
+  r0 = fh;
+  r1 = (int)ptr;
+  r2 = len;
+  asm ("swi %a4"
+       : "=r" (r0)
+       : "0"(r0), "r"(r1), "r"(r2), "i"(SWI_Write));
+  return checkerror (r0);
 #endif
 }
 
+/* fd, is a user file descriptor. */
 int
-_write (int    file,
+_write (int    fd,
        char * ptr,
        int    len)
 {
-  int slot = findslot (remap_handle (file));
-  int x = _swiwrite (file, ptr,len);
+  int res;
+  struct fdent *pfd;
 
-  if (x == -1 || x == len)
-    return error (-1);
-  
-  if (slot != MAX_OPEN_FILES)
-    openfiles[slot].pos += len - x;
+  pfd = findslot (fd);
+  if (pfd == NULL)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
+  res = _swiwrite (pfd->handle, ptr,len);
+
+  /* Clearly an error. */
+  if (res < 0)
+    return -1;
+
+  pfd->pos += len - res;
+
+  /* We wrote 0 bytes? 
+     Retrieve errno just in case. */
+  if ((len - res) == 0)
+    return error (0);
   
-  return len - x;
+  return (len - res);
 }
 
 int
-_swiopen (const char * path,
-         int          flags)
+_swiopen (const char * path, int flags)
 {
   int aflags = 0, fh;
 #ifdef ARM_RDI_MONITOR
   int block[3];
 #endif
   
-  int i = findslot (-1);
+  int fd = newslot ();
+
+  if (fd == -1)
+    {
+      errno = EMFILE;
+      return -1;
+    }
   
-  if (i == MAX_OPEN_FILES)
-    return -1;
+  /* It is an error to open a file that already exists. */
+  if ((flags & O_CREAT) 
+      && (flags & O_EXCL))
+    {
+      struct stat st;
+      int res;
+      res = _stat (path, &st);
+      if (res != -1)
+        {
+         errno = EEXIST;
+         return -1;
+        }
+    }
 
-  /* The flags are Unix-style, so we need to convert them.  */
+  /* The flags are Unix-style, so we need to convert them. */ 
 #ifdef O_BINARY
   if (flags & O_BINARY)
     aflags |= 1;
 #endif
+  
+  /* In O_RDONLY we expect aflags == 0. */
 
-  if (flags & O_RDWR)
+  if (flags & O_RDWR) 
     aflags |= 2;
 
-  if (flags & O_CREAT)
-    aflags |= 4;
-
-  if (flags & O_TRUNC)
+  if ((flags & O_CREAT)
+      || (flags & O_TRUNC)
+      || (flags & O_WRONLY))
     aflags |= 4;
 
   if (flags & O_APPEND)
     {
-      aflags &= ~4;     /* Can't ask for w AND a; means just 'a'.  */
+      /* Can't ask for w AND a; means just 'a'.  */
+      aflags &= ~4;
       aflags |= 8;
     }
   
@@ -397,58 +516,83 @@ _swiopen (const char * path,
        : "r0","r1");
 #endif
   
+  /* Return a user file descriptor or an error. */
   if (fh >= 0)
     {
-      openfiles[i].handle = fh;
-      openfiles[i].pos = 0;
+      openfiles[fd].handle = fh;
+      openfiles[fd].pos = 0;
+      return fd;
     }
-
-  return fh >= 0 ? fh + FILE_HANDLE_OFFSET : error (fh);
+  else
+    return error (fh);
 }
 
 int
-_open (const char * path,
-       int          flags,
-       ...)
+_open (const char * path, int flags, ...)
 {
-  return wrap (_swiopen (path, flags));
+  return _swiopen (path, flags);
 }
 
+/* fh, is a valid internal file handle. */
 int
-_swiclose (int file)
+_swiclose (int fh)
 {
-  int myhan = remap_handle (file);
-  int slot = findslot (myhan);
-  
-  if (slot != MAX_OPEN_FILES)
-    openfiles[slot].handle = -1;
-
 #ifdef ARM_RDI_MONITOR
-  return do_AngelSWI (AngelSWI_Reason_Close, & myhan);
+  return checkerror (do_AngelSWI (AngelSWI_Reason_Close, &fh));
 #else
-  asm ("mov r0, %1; swi %a0" :: "i" (SWI_Close),"r"(myhan):"r0");
+  register r0 asm("r0");
+  r0 = fh;
+  asm ("swi %a2" 
+       : "=r"(r0) 
+       : "0"(r0), "i" (SWI_Close));
+  return checkerror (r0);
 #endif
 }
 
+/* fd, is a user file descriptor. */
 int
-_close (int file)
+_close (int fd)
 {
-  return wrap (_swiclose (file));
+  int res;
+  struct fdent *pfd;
+
+  pfd = findslot (fd);
+  if (pfd == NULL)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
+  /* Handle stderr == stdout. */
+  if ((fd == 1 || fd == 2)
+      && (openfiles[1].handle == openfiles[2].handle))
+    {
+      pfd->handle = -1;
+      return 0;
+    }
+
+  /* Attempt to close the handle. */
+  res = _swiclose (pfd->handle);
+
+  /* Reclaim handle? */
+  if (res == 0)
+    pfd->handle = -1;
+
+  return res;
 }
 
 int __attribute__((weak))
-_getpid (int n)
+_getpid (int n __attribute__ ((unused)))
 {
   return 1;
-  n = n;
 }
 
 caddr_t
 _sbrk (int incr)
 {
-  extern char   end asm ("end");       /* Defined by the linker.  */
+  extern char end asm ("end"); /* Defined by the linker.  */
   static char * heap_end;
-  char *        prev_heap_end;
+  char * prev_heap_end;
 
   if (heap_end == NULL)
     heap_end = & end;
@@ -476,31 +620,60 @@ _sbrk (int incr)
   return (caddr_t) prev_heap_end;
 }
 
-int __attribute__((weak))
-_fstat (int file, struct stat * st)
+int 
+_swistat (int fd, struct stat * st)
 {
-  memset (st, 0, sizeof (* st));
-  st->st_mode = S_IFCHR;
+  struct fdent *pfd;
+  int res;
+
+  pfd = findslot (fd);
+  if (pfd == NULL)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
+  /* Always assume a character device,
+     with 1024 byte blocks. */
+  st->st_mode |= S_IFCHR;
   st->st_blksize = 1024;
+#ifdef ARM_RDI_MONITOR
+  res = checkerror (do_AngelSWI (AngelSWI_Reason_FLen, &pfd->handle));
+#else
+  asm ("mov r0, %2; swi %a1; mov %0, r0"
+       : "=r" (res)
+       : "i" (SWI_Flen), "r" (pfd->handle)
+       : "r0");
+  checkerror (res);
+#endif
+  if (res == -1)
+    return -1;
+  /* Return the file size. */
+  st->st_size = res;
   return 0;
-  file = file;
 }
 
 int __attribute__((weak))
-_stat (const char *fname, struct stat *st)
+_fstat (int fd, struct stat * st)
 {
-  int file;
-
-  /* The best we can do is try to open the file readonly.  If it exists,
-     then we can guess a few things about it.  */
-  if ((file = _open (fname, O_RDONLY)) < 0)
-    return -1;
+  memset (st, 0, sizeof (* st));
+  return _swistat (fd, st);
+}
 
+int __attribute__((weak))
+_stat (const char *fname, struct stat *st)
+{
+  int fd, res;
   memset (st, 0, sizeof (* st));
-  st->st_mode = S_IFREG | S_IREAD;
-  st->st_blksize = 1024;
-  _swiclose (file); /* Not interested in the error.  */
-  return 0;
+  /* The best we can do is try to open the file readonly.  
+     If it exists, then we can guess a few things about it. */
+  if ((fd = _open (fname, O_RDONLY)) == -1)
+    return -1;
+  st->st_mode |= S_IFREG | S_IREAD;
+  res = _swistat (fd, st);
+  /* Not interested in the error. */
+  _close (fd); 
+  return res;
 }
 
 int __attribute__((weak))
@@ -513,15 +686,23 @@ _link (void)
 int
 _unlink (const char *path)
 {
+  int res;
 #ifdef ARM_RDI_MONITOR
   int block[2];
   block[0] = (int)path;
   block[1] = strlen(path);
-  return wrap (do_AngelSWI (AngelSWI_Reason_Remove, block)) ? -1 : 0;
+  res = do_AngelSWI (AngelSWI_Reason_Remove, block);
 #else
-  (void)path;
-  asm ("swi %a0" :: "i" (SWI_Remove));
+  register r0 asm("r0");
+  r0 = (int)path;
+  asm ("swi %a2" 
+       : "=r"(r0)
+       : "0"(r0), "i" (SWI_Remove));
+  res = r0;
 #endif
+  if (res == -1) 
+    return error (res);
+  return 0;
 }
 
 int
@@ -588,14 +769,24 @@ _times (struct tms * tp)
 int
 _isatty (int fd)
 {
-  int fh = remap_handle (fd);
+  struct fdent *pfd;
+
+  pfd = findslot (fd);
+  if (pfd == NULL)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
 #ifdef ARM_RDI_MONITOR
-  return wrap (do_AngelSWI (AngelSWI_Reason_IsTTY, &fh));
+  return checkerror (do_AngelSWI (AngelSWI_Reason_IsTTY, &pfd->handle));
 #else
-  asm ("mov r0, %1; swi %a0"
-       : /* No outputs */
-       : "i" (SWI_IsTTY), "r"(fh)
-       : "r0");
+  register r0 asm("r0");
+  r0 = pfd->handle;
+  asm ("swi %a2"
+       : "=r" (r0)
+       : "0"(r0), "i" (SWI_IsTTY));
+  return checkerror (r0);
 #endif
 }
 
@@ -613,7 +804,7 @@ _system (const char *s)
     return 1;  /* maybe there is a shell available? we can hope. :-P */
   block[0] = (int)s;
   block[1] = strlen (s);
-  e = wrap (do_AngelSWI (AngelSWI_Reason_System, block));
+  e = checkerror (do_AngelSWI (AngelSWI_Reason_System, block));
   if ((e >= 0) && (e < 256))
     {
       /* We have to convert e, an exit status to the encoded status of
@@ -626,8 +817,12 @@ _system (const char *s)
     }
   return e;
 #else
-  (void)s;
-  asm ("swi %a0" :: "i" (SWI_CLI));
+  register r0 asm("r0");
+  r0 = (int)s;
+  asm ("swi %a2" 
+       : "=r" (r0)
+       : "0"(r0), "i" (SWI_CLI));
+  return checkerror (r0);
 #endif
 }
 
@@ -640,9 +835,15 @@ _rename (const char * oldpath, const char * newpath)
   block[1] = strlen(oldpath);
   block[2] = (int)newpath;
   block[3] = strlen(newpath);
-  return wrap (do_AngelSWI (AngelSWI_Reason_Rename, block)) ? -1 : 0;
+  return checkerror (do_AngelSWI (AngelSWI_Reason_Rename, block)) ? -1 : 0;
 #else
-  (void)oldpath; (void)newpath;
-  asm ("swi %a0" :: "i" (SWI_Rename));
+  register r0 asm("r0");
+  register r1 asm("r1");
+  r0 = (int)oldpath;
+  r1 = (int)newpath;
+  asm ("swi %a3" 
+       : "=r" (r0)
+       : "0" (r0), "r" (r1), "i" (SWI_Rename));
+  return checkerror (r0);
 #endif
 }