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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.