From f40cea54f3e7ef474552136b6f4b29cdb3b5c0f3 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Tue, 5 Aug 2014 23:01:15 +1000 Subject: Fix temporary file handling and add tempfile write support. Move the static objects into the rld-process file and change the clean up to a call. Add support to write to tempfiles. --- rld-cc.cpp | 4 +-- rld-process.cpp | 100 ++++++++++++++++++++++++++++++++++++++++++++----------- rld-process.h | 73 +++++++++++++++++++++++++--------------- rtems-ld.cpp | 2 +- rtems-ra.cpp | 96 ++++++++++++++++++++++++++-------------------------- rtems-rapper.cpp | 2 +- rtems-syms.cpp | 2 +- 7 files changed, 180 insertions(+), 99 deletions(-) diff --git a/rld-cc.cpp b/rld-cc.cpp index ed48d1c..38d3093 100644 --- a/rld-cc.cpp +++ b/rld-cc.cpp @@ -99,7 +99,7 @@ namespace rld while (true) { std::string line; - out.getline (line); + out.read_line (line); if (line.size () == 0) break; if (match_and_trim ("install: ", line, install_path)) @@ -143,7 +143,7 @@ namespace rld if (rld::verbose () >= RLD_VERBOSE_DETAILS) out.output ("cc", std::cout, true); out.open (); - out.get (path); + out.read (path); out.close (); if (rld::verbose () >= RLD_VERBOSE_DETAILS) std::cout << "cc::libpath: " << name << " -> " << path << std::endl; diff --git a/rld-process.cpp b/rld-process.cpp index 5a20366..2032404 100644 --- a/rld-process.cpp +++ b/rld-process.cpp @@ -59,6 +59,16 @@ namespace rld { namespace process { + /** + * Keep the temporary files if true. Used to help debug a system. + */ + bool keep_temporary_files = false; + + /** + * The temporary files. + */ + temporary_files temporaries; + temporary_files::temporary_files () { } @@ -69,12 +79,12 @@ namespace rld } const std::string - temporary_files::get () + temporary_files::get (const std::string& suffix) { - char* temp = ::make_temp_file ("rldXXXXXX"); + char* temp = ::make_temp_file (suffix.c_str ()); if (!temp) - throw rld::error ("bad temp name", "pex"); + throw rld::error ("bad temp name", "temp-file"); std::string name = temp; @@ -86,19 +96,22 @@ namespace rld void temporary_files::unlink (const std::string& name) { - struct stat sb; - if ((::stat (name.c_str (), &sb) >= 0) && S_ISREG (sb.st_mode)) + if (!keep_temporary_files) { - int r; + struct stat sb; + if ((::stat (name.c_str (), &sb) >= 0) && S_ISREG (sb.st_mode)) + { + int r; #if _WIN32 - r = ::remove(name.c_str ()); + r = ::remove(name.c_str ()); #else - r = ::unlink (name.c_str ()); + r = ::unlink (name.c_str ()); #endif - if (r < 0) - { - std::cerr << "error: unlinking temp file: " << name << std::endl; - ::exit (100); + if (r < 0) + { + std::cerr << "error: unlinking temp file: " << name << std::endl; + ::exit (100); + } } } } @@ -130,11 +143,12 @@ namespace rld } } - tempfile::tempfile () - : fd (-1), + tempfile::tempfile (const std::string& suffix) + : suffix (suffix), + fd (-1), level (0) { - _name = temporaries.get (); + _name = temporaries.get (suffix); } tempfile::~tempfile () @@ -144,12 +158,12 @@ namespace rld } void - tempfile::open () + tempfile::open (bool writable) { if ((fd < 0) && rld::files::check_file (_name)) { level = 0; - fd = ::open (_name.c_str (), O_RDONLY); + fd = ::open (_name.c_str (), writable ? O_RDWR : O_RDONLY); if (fd < 0) throw rld::error (::strerror (errno), "tempfile open:" + _name); } @@ -186,7 +200,7 @@ namespace rld } void - tempfile::get (std::string& all) + tempfile::read (std::string& all) { all.clear (); if (fd != -1) @@ -208,7 +222,7 @@ namespace rld } void - tempfile::getline (std::string& line) + tempfile::read_line (std::string& line) { line.clear (); if (fd != -1) @@ -241,6 +255,40 @@ namespace rld } } + void + tempfile::write (const std::string& s) + { + const char* p = s.c_str (); + size_t l = s.length (); + while (l) + { + int written = ::write (fd, p, l); + if (written < 0) + throw rld::error (::strerror (errno), "tempfile write:" + _name); + if (written == 0) + break; + l -= written; + } + } + + void + tempfile::write_line (const std::string& s) + { + write (s); + write (RLD_LINE_SEPARATOR); + } + + void + tempfile::write_lines (const rld::strings& ss) + { + for (rld::strings::const_iterator ssi = ss.begin (); + ssi != ss.end (); + ++ssi) + { + write_line (*ssi); + } + } + void tempfile::output (std::ostream& out) { @@ -260,7 +308,7 @@ namespace rld open (); while (true) { - getline (line); + read_line (line); ++lc; if (line.empty ()) break; @@ -274,6 +322,18 @@ namespace rld } } + void + set_keep_temporary_files () + { + keep_temporary_files = true; + } + + void + temporaries_clean_up () + { + temporaries.clean_up (); + } + status execute (const std::string& pname, const std::string& command, diff --git a/rld-process.h b/rld-process.h index 4f5be11..c50bb08 100644 --- a/rld-process.h +++ b/rld-process.h @@ -1,10 +1,10 @@ /* - * Copyright (c) 2011, Chris Johns + * Copyright (c) 2011, Chris Johns * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR @@ -44,7 +44,7 @@ namespace rld * Container of temporary file names. */ typedef std::list < std::string > tempfile_container; - + /** * Construct the temporary files. */ @@ -58,7 +58,7 @@ namespace rld /** * Get a new temporary file name. */ - const std::string get (); + const std::string get (const std::string& suffix = ".rldxx"); /** * Remove the temporary file. @@ -81,11 +81,6 @@ namespace rld }; - /** - * The temporary files. - */ - static temporary_files temporaries; - /** * Handle the output files from the process. */ @@ -96,7 +91,7 @@ namespace rld /** * Get a temporary file name. */ - tempfile (); + tempfile (const std::string& suffix = ".rldxx"); /** * Clean up the temporary file. @@ -104,9 +99,9 @@ namespace rld ~tempfile (); /** - * Open the temporary file. + * Open the temporary file. It can optionally be written too. */ - void open (); + void open (bool writable = false); /** * Close the temporary file. @@ -124,20 +119,35 @@ namespace rld size_t size (); /** - * Get all the file. + * Read all the file. + */ + void read (std::string& all); + + /** + * Read a line at a time. + */ + void read_line (std::string& line); + + /** + * Write the string to the file. */ - void get (std::string& all); + void write (const std::string& s); /** - * Get time. + * Write the string as a line to the file. */ - void getline (std::string& line); + void write_line (const std::string& s); + + /** + * Write the strings to the file using a suitable line separator. + */ + void write_lines (const rld::strings& ss); /** * Output the file. */ - void output (const std::string& prefix, - std::ostream& out, + void output (const std::string& prefix, + std::ostream& out, bool line_numbers = false); /** @@ -147,12 +157,23 @@ namespace rld private: - std::string _name; //< The name of the file. - int fd; //< The file descriptor - char buf[256]; //< The read buffer. - int level; //< The level of data in the buffer. + std::string _name; //< The name of the file. + const std::string suffix; //< The temp file's suffix. + int fd; //< The file descriptor + char buf[256]; //< The read buffer. + int level; //< The level of data in the buffer. }; - + + /** + * Keep the temporary files. + */ + void set_keep_temporary_files (); + + /** + * Clean up the temporaryes. + */ + void temporaries_clean_up (); + /** * The arguments containter has a single argument per element. */ @@ -169,7 +190,7 @@ namespace rld signal, //< The process terminated due to receipt of a signal. stopped //< The process has not terminated, but has stopped and can be restarted. }; - + types type; //< Type of status. int code; //< The status code returned. }; @@ -178,7 +199,7 @@ namespace rld * Execute a process and capture stdout and stderr. The first element is * the program name to run. Return an error code. */ - status execute (const std::string& pname, + status execute (const std::string& pname, const arg_container& args, const std::string& outname, const std::string& errname); @@ -187,7 +208,7 @@ namespace rld * Execute a process and capture stdout and stderr given a command line * string. Return an error code. */ - status execute (const std::string& pname, + status execute (const std::string& pname, const std::string& command, const std::string& outname, const std::string& errname); diff --git a/rtems-ld.cpp b/rtems-ld.cpp index a7453cb..944afc3 100644 --- a/rtems-ld.cpp +++ b/rtems-ld.cpp @@ -132,7 +132,7 @@ fatal_signal (int signum) { signal (signum, SIG_DFL); - rld::process::temporaries.clean_up (); + rld::process::temporaries_clean_up (); /* * Get the same signal again, this time not handled, so its normal effect diff --git a/rtems-ra.cpp b/rtems-ra.cpp index 07d2f00..0900ccc 100644 --- a/rtems-ra.cpp +++ b/rtems-ra.cpp @@ -117,7 +117,7 @@ fatal_signal (int signum) { signal (signum, SIG_DFL); - rld::process::temporaries.clean_up (); + rld::process::temporaries_clean_up (); /* * Get the same signal again, this time not handled, so its normal effect @@ -315,7 +315,7 @@ main (int argc, char* argv[]) * Get the command line libraries. */ rld::files::find_libraries (libraries, libpaths, libs); - + /* * Are we to load standard libraries ? */ @@ -330,28 +330,28 @@ main (int argc, char* argv[]) rld::files::paths library; rld::symbols::table symbols; rld::files::cache* cache = new rld::files::cache (); - + library.clear (); library.push_back (*p); - + /* * Open the cache. */ cache->open (); - + /* * Load the library to the cache. */ cache->add_libraries (library); - + cache->load_symbols (symbols); - + try { - + rld::files::objects& objs = cache->get_objects (); rld::files::paths raobjects; - + int pos = -1; std::string rap_name; for (rld::files::objects::iterator obi = objs.begin (); @@ -359,49 +359,49 @@ main (int argc, char* argv[]) ++obi) { rld::files::object* obj = (*obi).second; - + dependents.clear (); - + rap_name = obj->name ().oname (); - + pos = obj->name ().oname ().rfind ('.', rap_name.length ()); if (pos != -1) { rap_name.erase (pos, rap_name.length ()); } - + rap_name += ".rap"; - + dependents.push_back (obj); - + raobjects.push_back (rap_name); - + /* Todo: include absolute name for rap_name */ - + rld::outputter::application (rap_name, entry, exit, dependents, *cache, symbols, true); } - + dependents.clear (); for (rld::files::paths::iterator ni = raobjects.begin (); ni != raobjects.end (); ++ni) { rld::files::object* obj = new rld::files::object (*ni); dependents.push_back (obj); } - + bool ra_rap = true; bool ra_exist = false; rld::files::cache cachera; std::string raname = *p; - + pos = -1; pos = raname.rfind ('/', raname.length ()); if (pos != -1) { raname.erase (0, pos); } - + pos = -1; pos = raname.rfind ('.', raname.length ()); if (pos != -1) @@ -409,14 +409,14 @@ main (int argc, char* argv[]) raname.erase (pos, raname.length ()); } raname += ".ra"; - + raname = output_path + raname; - + rld::outputter::archivera (raname, dependents, cachera, ra_exist, ra_rap); std::cout << "Generated: " << raname << std::endl; - - + + for (rld::files::object_list::iterator oi = dependents.begin (); oi != dependents.end (); ++oi) @@ -430,7 +430,7 @@ main (int argc, char* argv[]) cache->archives_end (); throw; } - + cache->archives_end (); delete cache; } @@ -438,32 +438,32 @@ main (int argc, char* argv[]) else { /* - * Add, replace, delete files from the ra file. + * Add, replace, delete files from the ra file. */ for (rld::files::paths::iterator pl = libs.begin (); pl != libs.end (); ++pl) { rld::files::paths library; rld::files::cache* cache = new rld::files::cache (); - + library.clear (); library.push_back (*pl); - + /* * Open the cache. */ cache->open (); - + /* * Load the library to the cache. */ cache->add_libraries (library); - + rld::files::objects& objs = cache->get_objects (); rld::files::paths raobjects; - + std::string rap_name; bool rap_delete = false; - + dependents.clear (); /* * Delete rap files in ra file. @@ -473,10 +473,10 @@ main (int argc, char* argv[]) ++obi) { rld::files::object* obj = (*obi).second; - + rap_name = obj->name ().oname (); rap_delete = false; - + for (rld::files::paths::iterator pa = raps_delete.begin (); pa != raps_delete.end (); ++pa) @@ -487,11 +487,11 @@ main (int argc, char* argv[]) break; } } - + if (!rap_delete) dependents.push_back (obj); } - + /* * Add rap files into ra file, add supports replace. */ @@ -502,7 +502,7 @@ main (int argc, char* argv[]) ++pa) { rap_exist = false; - + for (rld::files::object_list::iterator oi = dependents.begin (); oi != dependents.end (); ++oi) @@ -515,11 +515,11 @@ main (int argc, char* argv[]) break; } } - + if (!rap_exist) rap_objects.push_back (*pa); } - + for (rld::files::paths::iterator pa = rap_objects.begin (); pa != rap_objects.end (); ++pa) @@ -532,22 +532,22 @@ main (int argc, char* argv[]) } else dependents.push_back (obj); } - + /* * Replace rap files in ra file */ bool rap_replace = false; rld::files::cache cachera; - + rap_objects.clear (); cachera.open (); - + for (rld::files::paths::iterator pa = raps_replace.begin (); pa != raps_replace.end (); ++pa) { rap_replace = false; - + for (rld::files::object_list::iterator oi = dependents.begin (); oi != dependents.end (); ) @@ -561,11 +561,11 @@ main (int argc, char* argv[]) } ++oi; } - + if (rap_replace) rap_objects.push_back (*pa); } - + for (rld::files::paths::iterator pa = rap_objects.begin (); pa != rap_objects.end (); ++pa) @@ -578,11 +578,11 @@ main (int argc, char* argv[]) } else dependents.push_back (obj); } - + rld::outputter::archivera (*pl, dependents, cachera, true, true); std::cout << "End" << std::endl; - + cache->archives_end (); delete cache; } diff --git a/rtems-rapper.cpp b/rtems-rapper.cpp index 7610963..2e3d2cf 100644 --- a/rtems-rapper.cpp +++ b/rtems-rapper.cpp @@ -1111,7 +1111,7 @@ fatal_signal (int signum) { signal (signum, SIG_DFL); - rld::process::temporaries.clean_up (); + rld::process::temporaries_clean_up (); /* * Get the same signal again, this time not handled, so its normal effect diff --git a/rtems-syms.cpp b/rtems-syms.cpp index baa152c..437884c 100644 --- a/rtems-syms.cpp +++ b/rtems-syms.cpp @@ -92,7 +92,7 @@ fatal_signal (int signum) { signal (signum, SIG_DFL); - rld::process::temporaries.clean_up (); + rld::process::temporaries_clean_up (); /* * Get the same signal again, this time not handled, so its normal effect -- cgit v1.2.3