// -*- C++ -*- // $Id$ // File: SO_Group.cpp #include "ace/OS_NS_string.h" #include "ace/OS_NS_unistd.h" #include "ace/Log_Msg.h" #include "ace/Process.h" #include "ace/Pipe.h" #include "Library.h" #include "SO_Group.h" ACE_RCSID(src, SO_Group, "$Id$") SO_Group::SO_Group () : undef_wrapper_ ("nothing"), undefs_(undef_wrapper_.imports()), libs_ (0), max_libs_ (128), num_libs_(0) { libs_ = new Library*[max_libs_]; } SO_Group::~SO_Group () { for (int i = 0; i < num_libs_; delete libs_[i++]); delete [] libs_; } void SO_Group::add_executable (const char * path) { ACE_Process proc; ACE_Process_Options opts; ACE_HANDLE pipe[2]; ACE_Pipe io(pipe); opts.set_handles (ACE_STDIN,pipe[1]); int result = opts.command_line ("ldd %s",path); // Prevent compiler warning about "unused variable" if ACE_ASSERT is // an empty macro. ACE_UNUSED_ARG (result); ACE_ASSERT (result == 0); proc.spawn (opts); if (ACE_OS::close(pipe[1]) == -1) ACE_DEBUG ((LM_DEBUG, "%p\n", "close")); opts.release_handles(); const int max_line_length = 1000; char line[max_line_length]; while (1) { ACE_OS::memset (line,0,max_line_length); int len = 0; int nread = 0; int bogus = 0; // skip initial whitespace while ((nread = ACE_OS::read(pipe[0],line,1)) == 1 && (*line == ' ' || *line == '\t')); if (nread != 1) break; // read the library name len = 1; while ((nread = ACE_OS::read(pipe[0],line + len,1)) == 1 && (line[len] != ' ')) if (! bogus && ++len == max_line_length) { bogus = 1; break; } if (nread != 1 || bogus) break; line[len] = 0; char * dot = ACE_OS::strchr (line,'.'); if (dot) *dot = 0; char * libname = line + 3; // skip over "lib" // check to see if this is a new library int found = 0; for (int i = 0; !found && i < num_libs_; i++) found = (libs_[i]->name() == libname); if (!found) { Library *nlib = new Library(libname); ACE_OS::memset (line,0,max_line_length); // skip over '=> ' if (ACE_OS::read(pipe[0],line,3) != 3) break; // get library path len = 0; while ((nread = ACE_OS::read(pipe[0],line + len,1)) == 1 && (line[len] != ' ')) if (! bogus && ++len == max_line_length) { bogus = 1; break; } if (nread != 1 || bogus) break; line[len] = 0; nlib->set_path (line); libs_[num_libs_++] = nlib; ACE_ASSERT (num_libs_ < max_libs_); // grow max libs? } // skip the rest of the line while ((nread = ACE_OS::read(pipe[0],line,1)) == 1 && *line != '\n'); if (nread != 1) break; } proc.wait (); ACE_OS::close (pipe[0]); undef_wrapper_.add_source(path,1); // now do the ldd, iterate over the results to add new libs, etc. } void SO_Group::analize () { for (int passcount = 0; undefs_.modified(); passcount++) { ACE_DEBUG ((LM_DEBUG,"pass %d, undef count = %d\n", passcount,undefs_.size())); for (int i = 0; i < num_libs_; libs_[i++]->resolve(undefs_)); } } void SO_Group::write_results() { for (int i = 0; i < num_libs_; libs_[i++]->write_export_list(1)); } void SO_Group::load_modules() { for (int i = 0; i < num_libs_; libs_[i++]->load_modules()); } void SO_Group::list_libs() { ACE_DEBUG ((LM_DEBUG,"Libs subject to analysis:\n")); for (int i = 0; i < num_libs_; i++) { if (libs_[i]->has_modules()) ACE_DEBUG ((LM_DEBUG," %s\n", libs_[i]->name().c_str())); } }