This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: fix 12099 -- quick review?


Thanks Frank for the review, here is the C++ iostreams version.

Rayson


diff --git a/tapsets.cxx b/tapsets.cxx
index a8970bc..86b1552 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -30,6 +30,7 @@
 #include <cstdlib>
 #include <algorithm>
 #include <deque>
+#include <fstream>
 #include <iostream>
 #include <map>
 #include <set>
@@ -56,6 +57,7 @@ extern "C" {
 #include <math.h>
 #include <regex.h>
 #include <unistd.h>
+#include <limits.h>

 #define __STDC_FORMAT_MACROS
 #include <inttypes.h>
@@ -5823,6 +5825,78 @@ dwarf_builder::build(systemtap_session & sess,
         }

       user_path = find_executable (module_name); // canonicalize it
+
+
+      // if the executable starts with "#!", we look for the
interpreter of the script
+      {
+         ifstream script_file (user_path.c_str());
+
+         if (script_file.good())
+         {
+           char buffer[PATH_MAX + 1 + 2]; // max path len + \n + #!
+
+           script_file.getline(buffer, sizeof(buffer));
+
+           if (buffer[0] != '\0')
+           {
+             size_t plen = strlen (buffer);
+
+             if (plen > sizeof ("#!") && memcmp (buffer, "#!", sizeof
("#!")-1) == 0)
+             {
+                // remove white spaces at the end of the string
+                plen--;
+
+                while (buffer[plen] == '\n' || buffer[plen] == ' ' ||
buffer[plen] == '\t')
+                {
+                  buffer[plen] = '\0';
+                  plen--;
+                }
+
+                // move pass #! and white spaces at the beginning of the string
+                char *path = buffer+2;
+
+                while (*path == ' ' || *path == '\t')
+                  path++;
+
+                user_path = find_executable (string (path));
+
+                struct stat st;
+
+                if (access (user_path.c_str(), X_OK) == 0
+                  && stat (user_path.c_str(), &st) == 0
+                  && S_ISREG (st.st_mode)) // see find_executable()
+                {
+
+                  if (sess.verbose > 1)
+                    clog << "Expanded process(\"" << module_name << "\") to "
+                         << "process(\"" << user_path << "\")" << endl;
+
+                  assert (location->components.size() > 0);
+                  assert (location->components[0]->functor == TOK_PROCESS);
+                  assert (location->components[0]->arg);
+                  literal_string* lit =
dynamic_cast<literal_string*>(location->components[0]->arg);
+                  assert (lit);
+
+                  // synthesize a new probe_point, with the expanded string
+                  probe_point *pp = new probe_point (*location);
+                  probe_point::component* ppc = new
probe_point::component (TOK_PROCESS,
+
      new literal_string (user_path.c_str()));
+                  ppc->tok = location->components[0]->tok; //
overwrite [0] slot, pattern matched above
+                  pp->components[0] = ppc;
+
+                  probe* new_probe = new probe (*base, pp);
+
+                  derive_probes (sess, new_probe, finished_results);
+
+                  script_file.close();
+                  return;
+                }
+             }
+           }
+           script_file.close();
+         }
+      }
+
       if (get_param (parameters, TOK_LIBRARY, library_name))
 	{
 	  module_name = find_executable (library_name, "LD_LIBRARY_PATH");


On Thu, Nov 25, 2010 at 5:43 PM, Frank Ch. Eigler <fche@redhat.com> wrote:
> Rayson Ho <raysonlogin@gmail.com> writes:
>
>> I am going to check the code in if no one has complains about the fix.
>
>> + ? ? ? ? FILE *fp = fopen (user_path.c_str(), "r");
>> + ? ? ? ? if (fp != NULL)
>> + ? ? ? ? {
>> + ? ? ? ? ? char buffer[PATH_MAX + 1 + 2]; // max path len + \n + #!
>> + ? ? ? ? ? if (fgets (buffer, PATH_MAX + 1 + 2, fp))
>> + ? ? ? ? ? ? size_t plen = strlen (buffer);
>> + ? ? ? ? ? ? if (plen > sizeof ("#!") && memcmp (buffer, "#!", sizeof
>> ("#!")-1) == 0)
>> + ? ? ? ? ? ? {
>> [...]
>
> I bet it would be simpler if the code used c++ iostreams rather than
> C stdio in order to parse first line of the shell script.
>
> - FChE
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]