diff --git a/src/function.c b/src/function.c
index 00d09f3a..40b82e34 100644
--- a/src/function.c
+++ b/src/function.c
@@ -2327,6 +2327,10 @@ func_file (char *o, char **argv, const char *funcname UNUSED)
 
   if (fn[0] == '>')
     {
+      size_t len;
+      const char *end;
+      const char *start;
+      char *nm;
       FILE *fp;
       const char *mode = "w";
 
@@ -2337,14 +2341,21 @@ func_file (char *o, char **argv, const char *funcname UNUSED)
           mode = "a";
           ++fn;
         }
-      NEXT_TOKEN (fn);
 
-      if (fn[0] == '\0')
+      start = next_token (fn);
+
+      if (start[0] == '\0')
         O (fatal, *expanding_var, _("file: missing filename"));
 
-      ENULLLOOP (fp, fopen (fn, mode));
+      end = end_of_token (start);
+      len = end - start;
+      nm = alloca (len + 1);
+      memcpy (nm, start, len);
+      nm[len] = '\0';
+
+      ENULLLOOP (fp, fopen (nm, mode));
       if (fp == NULL)
-        OSS (fatal, reading_file, _("open: %s: %s"), fn, strerror (errno));
+        OSS (fatal, reading_file, _("open: %s: %s"), nm, strerror (errno));
 
       /* We've changed the contents of a directory, possibly.
          Another option would be to look up the directory we changed and reset
@@ -2357,30 +2368,44 @@ func_file (char *o, char **argv, const char *funcname UNUSED)
           int nl = l == 0 || argv[1][l-1] != '\n';
 
           if (fputs (argv[1], fp) == EOF || (nl && fputc ('\n', fp) == EOF))
-            OSS (fatal, reading_file, _("write: %s: %s"), fn, strerror (errno));
+            OSS (fatal, reading_file, _("write: %s: %s"), nm, strerror (errno));
         }
       if (fclose (fp))
-        OSS (fatal, reading_file, _("close: %s: %s"), fn, strerror (errno));
+        OSS (fatal, reading_file, _("close: %s: %s"), nm, strerror (errno));
     }
   else if (fn[0] == '<')
     {
       size_t n = 0;
+      size_t len;
+      const char *end;
+      const char *start;
+      char *nm;
       FILE *fp;
 
-      ++fn;
-      NEXT_TOKEN (fn);
-      if (fn[0] == '\0')
+      start = next_token (fn + 1);
+
+      if (start[0] == '\0')
         O (fatal, *expanding_var, _("file: missing filename"));
 
       if (argv[1])
         O (fatal, *expanding_var, _("file: too many arguments"));
 
-      ENULLLOOP (fp, fopen (fn, "r"));
+      end = end_of_token (start);
+      len = end - start;
+      nm = alloca (len + 1);
+      memcpy (nm, start, len);
+      nm[len] = '\0';
+
+      ENULLLOOP (fp, fopen (nm, "r"));
       if (fp == NULL)
         {
           if (errno == ENOENT)
-            return o;
-          OSS (fatal, reading_file, _("open: %s: %s"), fn, strerror (errno));
+            {
+              DB (DB_VERBOSE, (_("file: Failed to open '%s': %s\n"),
+                               nm, strerror (errno)));
+              return o;
+            }
+          OSS (fatal, reading_file, _("open: %s: %s"), nm, strerror (errno));
         }
 
       while (1)
@@ -2394,12 +2419,12 @@ func_file (char *o, char **argv, const char *funcname UNUSED)
             }
           if (ferror (fp))
             if (errno != EINTR)
-              OSS (fatal, reading_file, _("read: %s: %s"), fn, strerror (errno));
+              OSS (fatal, reading_file, _("read: %s: %s"), nm, strerror (errno));
           if (feof (fp))
             break;
         }
       if (fclose (fp))
-        OSS (fatal, reading_file, _("close: %s: %s"), fn, strerror (errno));
+        OSS (fatal, reading_file, _("close: %s: %s"), nm, strerror (errno));
 
       /* Remove trailing newline.  */
       if (n && o[-1] == '\n')
diff --git a/tests/scripts/functions/file b/tests/scripts/functions/file
index 50948a04..48318b08 100644
--- a/tests/scripts/functions/file
+++ b/tests/scripts/functions/file
@@ -23,7 +23,7 @@ define A
 a
 b
 endef
-$(file     >>     file.out,$(A))
+$(file     >>     file.out    ,$(A))
 x:;@cat file.out
 !,
               '', "a\nb");
@@ -219,4 +219,14 @@ run_make_test('$(file <)', '',
 run_make_test('$(file foo)', '',
               "#MAKEFILE#:1: *** file: invalid file operation: foo.  Stop.\n", 512);
 
+# SV 17448: check whitespace
+create_file('out1', "1\n");
+
+run_make_test(q!
+all:;$(info $(file <  out1  ))
+!,
+              '', "1\n#MAKE#: 'all' is up to date.");
+
+unlink('out1');
+
 1;
diff --git a/tests/test_driver.pl b/tests/test_driver.pl
index e7e57763..38ec4587 100644
--- a/tests/test_driver.pl
+++ b/tests/test_driver.pl
@@ -434,7 +434,7 @@ sub get_osname
   # See if the filesystem supports long file names with multiple
   # dots.  DOS doesn't.
   $short_filenames = 0;
-  (open (TOUCHFD, "> fancy.file.name") and close (TOUCHFD))
+  (open (TOUCHFD, '>', 'fancy.file.name') and close (TOUCHFD))
       or $short_filenames = 1;
   unlink ("fancy.file.name") or $short_filenames = 1;
 
@@ -1287,7 +1287,7 @@ sub remove_directory_tree_inner
 #
 #  foreach my $file (@filenames) {
 #    utime ($now, $now, $file)
-#          or (open (TOUCHFD, ">> $file") and close (TOUCHFD))
+#          or (open (TOUCHFD, '>>', $file) and close (TOUCHFD))
 #               or &error ("Couldn't touch $file: $!\n", 1);
 #  }
 #  return 1;
@@ -1334,7 +1334,7 @@ sub create_file
 {
   my ($filename, @lines) = @_;
 
-  open (CF, "> $filename") or &error ("Couldn't open $filename: $!\n", 1);
+  open (CF, '>', $filename) or &error ("Couldn't open '$filename': $!\n", 1);
   foreach $line (@lines) {
     print CF $line;
   }