libgloss/arm fstat [PATCH]
Shaun Jackman
sjackman@gmail.com
Mon Dec 5 20:50:00 GMT 2005
This patch uses the ARM IsTTY syscall to implement fstat(2). It passes
a struct stat *buf as the second argument to the IsTTY syscall, as in
fstat(2). An ARM kernel that does not implement the fstat syscall, but
only IsTTY, will ignore the second argument. In this case libgloss
uses the result of IsTTY to set st_mode to either S_IFCHR or S_IFREG.
If the kernel returns stat information in buf, libgloss uses that
instead.
This patch is diffed against my local tree, which includes my patch
from earlier today. If it helps, I can provide a patch against the CVS
head instead.
With my recent patches it is becoming very possible to build busybox
with an arm-elf toolchain! This is very exciting.
Cheers,
Shaun
2005-12-02 Shaun Jackman <sjackman@gmail.com>
* libcfunc.c (isatty): Call fstat.
* syscalls.c (_isatty): Make static.
(_fstat): Call _isatty.
(_stat): Call _fstat.
================================================================================
--- libcfunc.c fc962aa09a8d41d13f9001eadcfd211bd9f0a3e9
+++ libcfunc.c d1294e45755479831373f00862f4c4df2aee971d
@@ -96,11 +96,16 @@
return _ioctl(fildes, request, arg);
}
-int _isatty(int fildes);
int __attribute__((weak))
isatty(int fildes)
{
- return _isatty(fildes);
+ struct stat buf;
+
+ if (fstat (fildes, &buf) < 0)
+ return 0;
+ if (S_ISCHR (buf.st_mode))
+ return 1;
+ return 0;
}
int __attribute__((weak))
================================================================================
--- syscalls.c 6b407a44f7f7c3466954602e92217ee6235972e9
+++ syscalls.c 03f9a0025f53f2303f263e708c7f6c656b00dc77
@@ -19,7 +19,6 @@
/* Forward prototypes. */
int _system _PARAMS ((const char *));
int _rename _PARAMS ((const char *, const char *));
-int _isatty _PARAMS ((int));
clock_t _times _PARAMS ((struct tms *));
int _gettimeofday _PARAMS ((struct timeval *, struct timezone *));
int _unlink _PARAMS ((const char *));
@@ -522,31 +521,48 @@
return (caddr_t) prev_heap_end;
}
+static int _isatty (int fildes, struct stat *buf)
+{
+#ifdef ARM_RDI_MONITOR
+ int block[2] = { fildes, (int)buf };
+ return do_AngelSWI (AngelSWI_Reason_IsTTY, block);
+#else
+ int result;
+ asm ("mov r0, %2; mov r1, %3; swi %a1; mov %0, r0"
+ : "=r"(result)
+ : "i"(SWI_IsTTY), "r"(fildes), "r"(buf)
+ : "r0", "r1");
+ return result;
+#endif
+}
+
int __attribute__((weak))
-_fstat (int file, struct stat * st)
+_fstat (int fildes, struct stat *buf)
{
- memset (st, 0, sizeof (* st));
- st->st_mode = S_IFCHR;
- st->st_blksize = 1024;
+ int status;
+ memset (buf, 0, sizeof (* buf));
+ status = _isatty(fildes, buf);
+ if (status == -1) return error(-1);
+ if (buf->st_mode == 0) {
+ buf->st_mode = status ? S_IFCHR : S_IFREG;
+ buf->st_blksize = 1024;
+ }
return 0;
- file = file;
}
int __attribute__((weak))
_stat (const char *fname, struct stat *st)
{
- int file;
+ int file, status;
/* 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));
- st->st_mode = S_IFREG | S_IREAD;
- st->st_blksize = 1024;
+ status = _fstat(file, st);
_swiclose (file); /* Not interested in the error. */
- return 0;
+ return status;
}
int __attribute__((weak))
@@ -630,17 +646,6 @@
};
-int
-_isatty (int fd)
-{
-#ifdef ARM_RDI_MONITOR
- return do_AngelSWI (AngelSWI_Reason_IsTTY, &fd);
-#else
- (void)fd;
- asm ("swi %a0" :: "i" (SWI_IsTTY));
-#endif
-}
-
int __attribute__((weak))
_execve(const char *path, char *const argv[], char *const envp[])
{
More information about the Newlib
mailing list