Fix archive GNU extension and make image read/write follow POSIX.

Fix the finding of a file name in the GNU extension for long names
in GNU archives so the correct location is referenced.

Made the image read and write routines keep reading if not all the
requested data is read or written due to possible signals.
This commit is contained in:
Chris Johns 2012-11-21 10:40:01 +11:00
parent fd8a2c559f
commit fe19d0684a
2 changed files with 52 additions and 29 deletions

View File

@ -402,21 +402,41 @@ namespace rld
} }
ssize_t ssize_t
image::read (uint8_t* buffer, size_t size) image::read (void* buffer_, size_t size)
{ {
ssize_t rsize = ::read (fd (), buffer, size); uint8_t* buffer = static_cast <uint8_t*> (buffer_);
size_t have_read = 0;
size_t to_read = size;
while (have_read < size)
{
ssize_t rsize = ::read (fd (), buffer, to_read);
if (rsize < 0) if (rsize < 0)
throw rld::error (strerror (errno), "read:" + name ().path ()); throw rld::error (strerror (errno), "read:" + name ().path ());
return rsize; if (rsize == 0)
break;
have_read += rsize;
to_read -= rsize;
buffer += rsize;
}
return have_read;
} }
ssize_t ssize_t
image::write (const void* buffer, size_t size) image::write (const void* buffer_, size_t size)
{ {
ssize_t wsize = ::write (fd (), buffer, size); const uint8_t* buffer = static_cast <const uint8_t*> (buffer_);
size_t have_written = 0;
size_t to_write = size;
while (have_written < size)
{
ssize_t wsize = ::write (fd (), buffer, to_write);
if (wsize < 0) if (wsize < 0)
throw rld::error (strerror (errno), "write:" + name ().path ()); throw rld::error (strerror (errno), "write:" + name ().path ());
return wsize; have_written += wsize;
to_write -= wsize;
buffer += wsize;
}
return have_written;
} }
void void
@ -487,6 +507,10 @@ namespace rld
{ {
#define COPY_FILE_BUFFER_SIZE (8 * 1024) #define COPY_FILE_BUFFER_SIZE (8 * 1024)
uint8_t* buffer = 0; uint8_t* buffer = 0;
if (size == 0)
size = in.name ().size ();
try try
{ {
buffer = new uint8_t[COPY_FILE_BUFFER_SIZE]; buffer = new uint8_t[COPY_FILE_BUFFER_SIZE];
@ -792,6 +816,10 @@ namespace rld
void void
archive::create (object_list& objects) archive::create (object_list& objects)
{ {
if (rld::verbose () >= RLD_VERBOSE_INFO)
std::cout << "archive::create: " << name ().full ()
<< ", objects: " << objects.size () << std::endl;
open (true); open (true);
try try
@ -838,7 +866,7 @@ namespace rld
if (oname.length () > rld_archive_fname_size) if (oname.length () > rld_archive_fname_size)
{ {
size_t pos = extended_file_names.find_first_of (oname + '\n'); size_t pos = extended_file_names.find (oname + '\n');
if (pos == std::string::npos) if (pos == std::string::npos)
throw rld_error_at ("extended file name not found"); throw rld_error_at ("extended file name not found");
std::ostringstream oss; std::ostringstream oss;
@ -848,7 +876,7 @@ namespace rld
write_header (oname, 0, 0, 0, 0666, obj.name ().size ()); write_header (oname, 0, 0, 0, 0666, obj.name ().size ());
obj.seek (0); obj.seek (0);
copy_file (obj, *this, obj.name ().size ()); copy_file (obj, *this);
} }
catch (...) catch (...)
{ {
@ -1052,20 +1080,6 @@ namespace rld
return archive_; return archive_;
} }
#if 0
int
object::sections () const
{
return ehdr.e_shnum;
}
int
object::section_strings () const
{
return ehdr.e_shstrndx;
}
#endif
rld::symbols::table& rld::symbols::table&
object::unresolved_symbols () object::unresolved_symbols ()
{ {

View File

@ -240,7 +240,7 @@ namespace rld
const std::string& oname () const; const std::string& oname () const;
/** /**
* The object's offset in the archive. * The object's offset in the archive or on disk.
*/ */
off_t offset () const; off_t offset () const;
@ -253,7 +253,7 @@ namespace rld
std::string aname_; //< The archive name. std::string aname_; //< The archive name.
std::string oname_; //< The object name. std::string oname_; //< The object name.
off_t offset_; //< The object's offset in the archive. off_t offset_; //< The object's offset in the archive.
size_t size_; //< The object's size in teh archive. size_t size_; //< The object's size in the archive or on disk.
}; };
/** /**
@ -308,7 +308,7 @@ namespace rld
/** /**
* Read a block from the file. * Read a block from the file.
*/ */
virtual ssize_t read (uint8_t* buffer, size_t size); virtual ssize_t read (void* buffer, size_t size);
/** /**
* Write a block from the file. * Write a block from the file.
@ -779,6 +779,15 @@ namespace rld
bool opened; //< The cache is open. bool opened; //< The cache is open.
}; };
/**
* Copy the in file to the out file.
*
* @param in The input file.
* @param out The output file.
* @param size The amount to copy. If 0 the whole on in is copied.
*/
void copy_file (image& in, image& out, size_t size = 0);
/** /**
* Find the libraries given the list of libraries as bare name which * Find the libraries given the list of libraries as bare name which
* have 'lib' and '.a' added. * have 'lib' and '.a' added.