@@ -3,22 +3,35 @@ import std;
33
44namespace mcpp ::build::schedule::transaction {
55
6- bool replace_record (const fs::path& path,std::string_view bytes) {
6+ bool replace_record (const fs::path& path,std::string_view bytes,std::string* diagnostic ) {
77 // No process may observe a partial record. This protects process loss,
88 // not power loss; do not change the OS library's durable write_atomic.
99 static const auto who=os::process::self ();
1010 static std::atomic<unsigned long long > sequence{0 };
11- if (!who||!who->id ||!who->started_ns )return false ;
11+ auto fail=[&](std::string_view stage) {
12+ if (diagnostic)*diagnostic=stage;
13+ return false ;
14+ };
15+ if (!who||!who->id ||!who->started_ns )return fail (" identify writer" );
1216 const auto temporary=path.parent_path ()/named (std::format (" .mcpp-record-{}-{}-{}" ,
1317 who->id ,who->started_ns ,sequence++));
1418 std::ofstream output (temporary,std::ios::binary|std::ios::out|std::ios::noreplace);
15- if (!output)return false ; // Never remove a name this invocation did not create.
19+ if (!output)return fail ( " open temporary " ) ; // Never remove a name this invocation did not create.
1620 output.write (bytes.data (),static_cast <std::streamsize>(bytes.size ()));
1721 output.flush ();
1822 const bool written=bool (output);
1923 output.close ();
2024 const bool closed=bool (output);
21- if (written&&closed&&os::fs::rename (temporary,path,true ))return true ;
25+ if (written&&closed) {
26+ auto renamed=os::fs::rename (temporary,path,true );
27+ if (renamed)return true ;
28+ if (diagnostic)*diagnostic=std::format (" rename temporary (condition {}, native {})" ,
29+ static_cast <int >(renamed.error ().code ),renamed.error ().native );
30+ } else if (!written) {
31+ fail (" write/flush temporary" );
32+ } else {
33+ fail (" close temporary" );
34+ }
2235 std::error_code ec;fs::remove (temporary,ec);return false ;
2336}
2437bool publish (const fs::path& path,std::string_view tag,const Fields& fields) {
0 commit comments