This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
[PATCH] Fixes for libgloss/arm/syscalls.c.
- From: Carlos O'Donell <carlos at codesourcery dot com>
- To: newlib at sources dot redhat dot com
- Cc: Daniel Jacobowitz <dan at codesourcery dot com>
- Date: Thu, 12 Jul 2007 13:49:19 -0400
- Subject: [PATCH] Fixes for libgloss/arm/syscalls.c.
The following patch increases the quality-of-implementation for
libgloss/arm/syscalls.c
1. A rewrite of the file handling cache to support POSIX's requirement
that a lowest possible file handle be returned from open().
In this implementation user file descriptors are represented as indicies
into the openfiles array. This makes the open file lookup O(1) as
opposed to the previous O(n) search.
The function findslot() takes as input a user file descriptor and
returns a pointer to the file descriptor structure. If the user file
descriptor was invalid or not open, findslot() returns NULL. The
caller is responsible for setting errno appropriatly. We centralize fd
checking in findslot().
The open() function uses newslot() to find the lowest numbered unused
file descriptor structure. We cannot use findslot() in open() because
findslot() does error checking.
The function remap_handle() is removed since the values of 0, 1, and 2
for stdin, stdout, and stderr are handled by findslot().
All functions that manipulate fd's must call one of findslot() or
newslot().
We call checkerror() or error() on the return of *all* SWI calls, this
ensures that errno is always set correctly.
The following testcase passes with this patch.
----------
cat >> test.c <<EOF
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
int main()
{
int fd;
int fd2;
fd = open("test.c", O_RDONLY);
assert(fd >= 3);
fd2 = open("test.c", O_RDONLY);
assert(fd2 > fd);
close(fd);
fd2 = open("test.c", O_RDONLY);
assert(fd == fd2);
close(STDIN_FILENO);
close(STDOUT_FILENO);
fd = open("test.c", O_RDONLY);
assert(fd == 0);
close(fd);
fprintf(stderr, "OK\n");
return 0;
}
EOF
2. Incorrect use of inline assembly, with the assumption that gcc's
epilogue won't modify r0.
Inline assembly code of the form:
---
asm ("mov r0, %1; swi %a0" :: "i" (SWI_Close),"r"(myhan):"r0");
---
has been corrected to:
---
register r0 asm("r0");
r0 = fh;
asm ("swi %a2"
: "=r"(r0)
: "0"(r0), "i" (SWI_Close));
return r0;
---
Firstly, this code doesn't return anything. Secondly it assumes that the
epilogue generated by GCC will not clobber r0. Lastly GCC may decide to
save and restore "r0" around the asm block, thereby destroying the
return of the software interrupt. This has been fixed.
3. Robust support of stderr, with redirection to stdout in the case that
the semi-hosting interface does not support ":tt" in append mode.
During the initialization of the monitor handles we detect a failure to
open stderr, and map it to stdout.
/* If we failed to open stderr, redirect to stdout. */
if (monitor_stderr == -1)
monitor_stderr = monitor_stdout;
To avoid a double close of stdout, we add the following logic to
close():
/* Handle stderr == stdout. */
if ((fd == 1 || fd == 2)
&& (openfiles[1].handle == openfiles[2].handle))
{
openfiles[fd].handle = -1;
return;
}
Thus we only close one of the two handles, but track the close for both.
4. Improve _stat and _fstat.
The _stat and _fstat functions now call _swistat to get imformation
about the file, including file length.
Tested on arm-none-eabi without regressions.
Comments?
If everything looks ok, please apply.
Cheers,
Carlos.
--
Carlos O'Donell
CodeSourcery
carlos@codesourcery.com
(650) 331-3385 x716
2007-07-12 Daniel Jacobowitz <dan@codesourcery.com>
* arm/syscalls.c (_stat): Use _close
2007-07-12 Carlos O'Donell <carlos@codesourcery.com>
* libgloss/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.
Index: libgloss/arm/syscalls.c
===================================================================
RCS file: /cvs/src/src/libgloss/arm/syscalls.c,v
retrieving revision 1.15
diff -u -p -r1.15 syscalls.c
--- libgloss/arm/syscalls.c 6 Jul 2007 17:00:12 -0000 1.15
+++ libgloss/arm/syscalls.c 12 Jul 2007 17:33:39 -0000
@@ -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 *, in
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 _re
} \
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 cha
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
}