summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2014-08-05 23:01:15 +1000
committerChris Johns <chrisj@rtems.org>2014-08-05 23:01:15 +1000
commitf40cea54f3e7ef474552136b6f4b29cdb3b5c0f3 (patch)
tree961a51588821aa1ab1f712a314c7261324b3727c
parent13ee8dc9506807fd3fb253b52583611754cb719e (diff)
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.
-rw-r--r--rld-cc.cpp4
-rw-r--r--rld-process.cpp100
-rw-r--r--rld-process.h73
-rw-r--r--rtems-ld.cpp2
-rw-r--r--rtems-ra.cpp96
-rw-r--r--rtems-rapper.cpp2
-rw-r--r--rtems-syms.cpp2
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)
@@ -242,6 +256,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)
{
std::string prefix;
@@ -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 <chrisj@rtems.org>
+ * Copyright (c) 2011, Chris Johns <chrisj@rtems.org>
*
* 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.
@@ -82,11 +82,6 @@ namespace rld
};
/**
- * The temporary files.
- */
- static temporary_files temporaries;
-
- /**
* Handle the output files from the process.
*/
class tempfile
@@ -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