skvadrik / re2c

Lexer generator for C, C++, Go and Rust.
https://re2c.org
Other
1.07k stars 169 forks source link

re2c: error: cannot rename or write temporary file #417

Closed satmandu closed 1 year ago

satmandu commented 1 year ago

The host is a ChromeOS/x86_64 Chromebrew environment inside a docker container.

When building ninja 1.11.1 I get this errror with re2c 3.0 with both lexer.in.cc and depfile_parser.in.cc. Touching the output file first solves the issue.

[26/66] Generating lexer.cc
samu: job failed: cd /usr/local/tmp/crew/ninja.20220929165525.dir/ninja-1.11.1/builddir && /usr/local/bin/re2c -b -i --no-generation-date --no-version -o /usr/local/tmp/crew/ninja.202
20929165525.dir/ninja-1.11.1/builddir/lexer.cc /usr/local/tmp/crew/ninja.20220929165525.dir/ninja-1.11.1/src/lexer.in.cc
re2c: error: cannot rename or write temporary file /usr/local/tmp/crew/ninja.20220929165525.dir/ninja-1.11.1/builddir/lexer.cc to output file /usr/local/tmp/crew/ninja.20220929165525.dir/ninja-1.11.1/builddir/lexer.cc
samu: subcommand failed

(I don't have this issue on armv7l or i686.)

skvadrik commented 1 year ago

The error comes from here. Interestingly, source and destination filenames are the same: /usr/local/tmp/crew/ninja.20220929165525.dir/ninja-1.11.1/builddir/lexer.cc, which means that tempname and fname are the same. tempname is initially set to fname and modified in temp_file(). This probably means that strftime fails. Why? Not sure (the buffer should be the right size including terminating null).

Can you try the following patch:

diff --git a/src/util/file_utils.cc b/src/util/file_utils.cc
index 35a43e12..41be7696 100644
--- a/src/util/file_utils.cc
+++ b/src/util/file_utils.cc
@@ -62,8 +62,10 @@ namespace re2c {
 FILE* temp_file(std::string& fname) {
     // append "random enough" suffix to filename
     const time_t t = time(nullptr);
-    char buffer[20];
-    strftime(buffer, sizeof(buffer), ".tmp.%Y%m%d%H%M%S", localtime(&t));
+    char buffer[20]; // 20 = 5(".tmp.") + 4(%Y) + 2(%m) + 2(%d) + 2(%H) + 2(%M) + 2(%S) + 1(null)
+    if (strftime(buffer, sizeof(buffer), ".tmp.%Y%m%d%H%M%S", localtime(&t)) == 0) {
+        return nullptr;
+    }
     fname += buffer;

     // open file for writing, unless it exists already

(In re2c/src/util.)

satmandu commented 1 year ago

The issue was with mold 1.5.0. the issue goes away when built with 1.5.1.

I don't think this is a re2c issue at all!

skvadrik commented 1 year ago

Oh! Good. I'll add the comment and the error handling anyway, it's useful. :)

Closing then.