okay, here's an alternative patch that only does the temporary file
dance for regular files...


[PATCH] Implement `file -`.

Previously we'd just always bogusly report "empty".
---
 tests/file.test   |  6 ++++++
 toys/posix/file.c | 34 +++++++++++++++++++++++++++-------
 2 files changed, 33 insertions(+), 7 deletions(-)


On Thu, May 3, 2018 at 8:12 PM, enh <e...@google.com> wrote:
> the FSF file(1) is inconsistent too, in a way that suggests it's being
> clever:
>
> ~$ file /dev/zero
> /dev/zero: character special (1/5)
> ~$ file - < /dev/zero
> /dev/stdin: data
> ~$
>
>
>
> On Thu, May 3, 2018, 18:36 Rob Landley <r...@landley.net> wrote:
>>
>> On 05/03/2018 06:40 PM, enh wrote:
>> > +    // If we're working on stdin, copy to a temporary file and then use
>> > +    // an fd for that file. That way the rest of the code doesn't have
>> > to
>> > +    // worry about non-seekable/non-mmap'able input.
>>
>> Hmmm, in the old code:
>>
>> $ ./file ../filesystems.tar.gz
>> ../filesystems.tar.gz: gzip compressed data
>> $ ./file - < ../filesystems.tar.gz
>> -: gzip compressed data
>> $ file /dev/zero
>> /dev/zero: character special
>> $ file - < /dev/zero
>> /dev/stdin: data
>>
>> That's inconsistent about /dev/zero, not sure why.
>>
>> But if we copy /dev/zero to a temp file we'll fill the hard drive...
>>
>> Rob
From 8de4ecfc1e1764a4f48ae4c6d65ee5f81dc5300e Mon Sep 17 00:00:00 2001
From: Elliott Hughes <e...@google.com>
Date: Thu, 3 May 2018 16:39:21 -0700
Subject: [PATCH] Implement `file -`.

Previously we'd just always bogusly report "empty".
---
 tests/file.test   |  6 ++++++
 toys/posix/file.c | 34 +++++++++++++++++++++++++++-------
 2 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/tests/file.test b/tests/file.test
index 4c7f001..9380556 100644
--- a/tests/file.test
+++ b/tests/file.test
@@ -22,4 +22,10 @@ testing "symlink" "file symlink" "symlink: symbolic link\n" "" ""
 testing "symlink -h" "file -h symlink" "symlink: symbolic link\n" "" ""
 testing "symlink -L" "file -L symlink" "symlink: Java class file, version 49.0\n" "" ""
 
+testing "- pipe" "cat java.class | file -" "-: Java class file, version 49.0\n" "" ""
+testing "- redirect" "file - <java.class" "-: Java class file, version 49.0\n" "" ""
+
+testing "/dev/zero" "file /dev/zero" "/dev/zero: character special\n" "" ""
+testing "- </dev/zero" "file - </dev/zero" "-: data\n" "" ""
+
 rm empty bash.script bash.script2 env.python.script ascii java.class
diff --git a/toys/posix/file.c b/toys/posix/file.c
index 2eeb058..4489eb3 100644
--- a/toys/posix/file.c
+++ b/toys/posix/file.c
@@ -356,17 +356,37 @@ void file_main(void)
   for (arg = toys.optargs; *arg; arg++) {
     char *name = *arg, *what = "cannot open";
     struct stat sb;
-    int fd = !strcmp(name, "-");
+    int fd = -1;
 
     xprintf("%s: %*s", name, (int)(TT.max_name_len - strlen(name)), "");
 
-    if (fd || !((toys.optflags & FLAG_L) ? stat : lstat)(name, &sb)) {
-      if (fd || S_ISREG(sb.st_mode)) {
+    // If we're working on stdin, copy to a temporary file and then use
+    // an fd for that file. That way the rest of the code doesn't have to
+    // worry about non-seekable/non-mmap'able input.
+    if (!strcmp(name, "-")) {
+      if (!fstat(0, &sb) && S_ISREG(sb.st_mode)) {
+        FILE* tmp = tmpfile();
+        ssize_t i;
+
+        if (!tmp) perror_exit("tmpfile failed");
+        fd = fileno(tmp);
+        while ((i = xread(0, toybuf, sizeof(toybuf)))) xwrite(fd, toybuf, i);
+        xlseek(fd, 0, SEEK_SET);
+      } else fd = 0;
+      fstat(fd, &sb);
+      do_regular_file(fd, name, &sb);
+      continue;
+    }
+
+    if (!((toys.optflags & FLAG_L) ? stat : lstat)(name, &sb)) {
+      if (S_ISREG(sb.st_mode)) {
         if (!sb.st_size) what = "empty";
-        else if ((fd = openro(name, O_RDONLY)) != -1) {
-          do_regular_file(fd, name, &sb);
-          if (fd) close(fd);
-          continue;
+        else {
+          if ((fd = openro(name, O_RDONLY)) != -1) {
+            do_regular_file(fd, name, &sb);
+            close(fd);
+            continue;
+          }
         }
       } else if (S_ISFIFO(sb.st_mode)) what = "fifo";
       else if (S_ISBLK(sb.st_mode)) what = "block special";
-- 
2.17.0.441.gb46fe60e1d-goog

_______________________________________________
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to