Re: [PATCH v2] Support regular file type in _swistat for ARM
Joe Ramsay <[email protected]>
| Newsgroups | gmane.comp.lib.newlib |
|---|---|
| Message-ID | <[email protected]> |
Apologies, full patch is attached here. On 18/08/2020, 14:00, "Corinna Vinschen" <[email protected]> wrote: On Aug 18 09:49, Joe Ramsay wrote: > Hi all, > > Just pinging this patch (original at > https://sourceware.org/pipermail/newlib/2020/017719.html), as it looks > to have fallen through the cracks somewhat. I’ve attached the patch Was still waiting for a review from Richard who reviewd v1, see https://sourceware.org/pipermail/newlib/2020/017727.html > file directly, as I think it may have been corrupted in my original Please attach a git patch, not a naked diff. Thanks, Corinna
0001-Support-regular-file-type-in-_swistat.patch
(application/octet-stream, 5 KB)
From 967c45d40709f873f84860f43700f1d2d25c0551 Mon Sep 17 00:00:00 2001 From: Joe Ramsay <[email protected]> Date: Tue, 18 Aug 2020 13:04:24 +0000 Subject: [PATCH] Support regular file type in _swistat Previously, the implementation of _swistat() for ARM assumed all files to be of type character device. This change adds support for stat-ing regular files --- libgloss/arm/syscalls.c | 44 +++++++++++++++++++----------- newlib/libc/sys/arm/syscalls.c | 61 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 82 insertions(+), 23 deletions(-) diff --git a/libgloss/arm/syscalls.c b/libgloss/arm/syscalls.c index fc394f94bda37dfb2dfc2d12a5dd923391b9e025..652301cef67489d4b85bd009c14713df29d77d5e 100644 --- a/libgloss/arm/syscalls.c +++ b/libgloss/arm/syscalls.c @@ -59,6 +59,7 @@ struct fdent }; #define MAX_OPEN_FILES 20 +#define DEFAULT_BLOCK_SIZE 1024 /* User file descriptors (fd) are integer indexes into the openfiles[] array. Error checking is done by using @@ -728,33 +729,46 @@ _sbrk (ptrdiff_t incr) int _swistat (int fd, struct stat * st) { - struct fdent *pfd; - int res; - - pfd = findslot (fd); + struct fdent *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; + int isCharDevice; #ifdef ARM_RDI_MONITOR - res = checkerror (do_AngelSWI (AngelSWI_Reason_FLen, &pfd->handle)); + isCharDevice = checkerror (do_AngelSWI (AngelSWI_Reason_IsTTY, &pfd->handle)); #else asm ("mov r0, %2; swi %a1; mov %0, r0" - : "=r" (res) + : "=r" (isCharDevice) + : "i" (SWI_IsTTY), "r" (pfd->handle) + : "r0"); + checkerror(isCharDevice); +#endif + + int flen; +#ifdef ARM_RDI_MONITOR + flen = checkerror (do_AngelSWI (AngelSWI_Reason_FLen, &pfd->handle)); +#else + asm ("mov r0, %2; swi %a1; mov %0, r0" + : "=r" (flen) : "i" (SWI_Flen), "r" (pfd->handle) : "r0"); - checkerror (res); + checkerror(flen); #endif - if (res == -1) - return -1; - /* Return the file size. */ - st->st_size = res; + + st->st_size = flen; + st->st_blksize = DEFAULT_BLOCK_SIZE; + + if (isCharDevice) + st->st_mode |= S_IFCHR; + else + { + st->st_mode |= S_IFREG; + st->st_blocks = (flen + DEFAULT_BLOCK_SIZE - 1) / DEFAULT_BLOCK_SIZE; + } + return 0; } diff --git a/newlib/libc/sys/arm/syscalls.c b/newlib/libc/sys/arm/syscalls.c index 1f722298024885d04691a1af1ff509318b36b7a6..5156f1ac81663fffa9b8286133f43181d6f16852 100644 --- a/newlib/libc/sys/arm/syscalls.c +++ b/newlib/libc/sys/arm/syscalls.c @@ -28,6 +28,7 @@ int _unlink (const char *); int _link (const char *, const char *); int _stat (const char *, struct stat *); int _fstat (int, struct stat *); +int _swistat (int fd, struct stat * st); void * _sbrk (ptrdiff_t); pid_t _getpid (void); int _kill (int, int); @@ -84,6 +85,8 @@ poslog; #define MAX_OPEN_FILES 20 static poslog openfiles [MAX_OPEN_FILES]; +#define DEFAULT_BLOCK_SIZE 1024 + static int findslot (int fh) { @@ -543,33 +546,75 @@ _sbrk (ptrdiff_t incr) return (void *) prev_heap_end; } +int +_swistat (int fd, struct stat * st) +{ + struct fdent *pfd = findslot (fd); + if (pfd == NULL) + { + errno = EBADF; + return -1; + } + + int isCharDevice; +#ifdef ARM_RDI_MONITOR + isCharDevice = checkerror (do_AngelSWI (AngelSWI_Reason_IsTTY, &pfd->handle)); +#else + asm ("mov r0, %2; swi %a1; mov %0, r0" + : "=r" (isCharDevice) + : "i" (SWI_IsTTY), "r" (pfd->handle) + : "r0"); + checkerror(isCharDevice); +#endif + + int flen; +#ifdef ARM_RDI_MONITOR + flen = checkerror (do_AngelSWI (AngelSWI_Reason_FLen, &pfd->handle)); +#else + asm ("mov r0, %2; swi %a1; mov %0, r0" + : "=r" (flen) + : "i" (SWI_Flen), "r" (pfd->handle) + : "r0"); + checkerror(flen); +#endif + + st->st_size = flen; + st->st_blksize = DEFAULT_BLOCK_SIZE; + + if (isCharDevice) + st->st_mode |= S_IFCHR; + else + { + st->st_mode |= S_IFREG; + st->st_blocks = (flen + DEFAULT_BLOCK_SIZE - 1) / DEFAULT_BLOCK_SIZE; + } + + return 0; +} + extern void memset (struct stat *, int, unsigned int); int __attribute__((weak)) _fstat (int file, struct stat * st) { memset (st, 0, sizeof (* st)); - st->st_mode = S_IFCHR; - st->st_blksize = 1024; - return 0; - file = file; + return _swistat (file, st); } int __attribute__((weak)) _stat (const char *fname, struct stat *st) { int file; - + memset (st, 0, sizeof (* st)); /* 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; + res = _swistat (file, st); _swiclose (file); /* Not interested in the error. */ - return 0; + return res; } int __attribute__((weak)) -- 2.7.4