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; }