LTP GCOV extension - code coverage report
Current view: directory - src - util.cxx
Test: stap.info
Date: 2008-03-12 Instrumented lines: 87
Code covered: 69.0 % Executed lines: 60

       1                 : // Copyright (C) Andrew Tridgell 2002 (original file)
       2                 : // Copyright (C) 2006 Red Hat Inc. (systemtap changes)
       3                 : //
       4                 : // This program is free software; you can redistribute it and/or
       5                 : // modify it under the terms of the GNU General Public License as
       6                 : // published by the Free Software Foundation; either version 2 of the
       7                 : // License, or (at your option) any later version.
       8                 : //
       9                 : // This program is distributed in the hope that it will be useful, but
      10                 : // WITHOUT ANY WARRANTY; without even the implied warranty of
      11                 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU
      12                 : // General Public License for more details.
      13                 : //
      14                 : // You should have received a copy of the GNU General Public License
      15                 : // along with this program; if not, write to the Free Software
      16                 : // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
      17                 : 
      18                 : #include "util.h"
      19                 : #include <stdexcept>
      20                 : #include <cerrno>
      21                 : 
      22                 : extern "C" {
      23                 : #include <sys/types.h>
      24                 : #include <sys/stat.h>
      25                 : #include <pwd.h>
      26                 : #include <unistd.h>
      27                 : #include <stdlib.h>
      28                 : #include <fcntl.h>
      29                 : }
      30                 : 
      31                 : using namespace std;
      32                 : 
      33                 : 
      34                 : // Return current users home directory or die.
      35                 : const char *
      36               0 : get_home_directory(void)
      37                 : {
      38               0 :   const char *p = getenv("HOME");
      39               0 :   if (p)
      40               0 :     return p;
      41                 : 
      42               0 :   struct passwd *pwd = getpwuid(getuid());
      43               0 :   if (pwd)
      44               0 :     return pwd->pw_dir;
      45                 : 
      46               0 :   throw runtime_error("Unable to determine home directory");
      47                 :   return NULL;
      48                 : }
      49                 : 
      50                 : 
      51                 : // Copy a file.  The copy is done via a temporary file and atomic
      52                 : // rename.
      53                 : int
      54             669 : copy_file(const char *src, const char *dest)
      55                 : {
      56                 :   int fd1, fd2;
      57                 :   char buf[10240];
      58                 :   int n;
      59             669 :   string tmp;
      60                 :   char *tmp_name;
      61                 :   mode_t mask;
      62                 : 
      63                 :   // Open the src file.
      64             669 :   fd1 = open(src, O_RDONLY);
      65             669 :   if (fd1 == -1)
      66               0 :     return -1;
      67                 : 
      68                 :   // Open the temporary output file.
      69             669 :   tmp = dest + string(".XXXXXX");
      70            1338 :   tmp_name = (char *)tmp.c_str();
      71             669 :   fd2 = mkstemp(tmp_name);
      72             669 :   if (fd2 == -1)
      73                 :     {
      74               0 :       close(fd1);
      75               0 :       return -1;
      76                 :     }
      77                 : 
      78                 :   // Copy the src file to the temporary output file.
      79           44876 :   while ((n = read(fd1, buf, sizeof(buf))) > 0)
      80                 :     {
      81           43538 :       if (write(fd2, buf, n) != n)
      82                 :         {
      83               0 :           close(fd2);
      84               0 :           close(fd1);
      85               0 :           unlink(tmp_name);
      86               0 :           return -1;
      87                 :         }
      88                 :     }
      89             669 :   close(fd1);
      90                 : 
      91                 :   // Set the permissions on the temporary output file.
      92             669 :   mask = umask(0);
      93             669 :   fchmod(fd2, 0666 & ~mask);
      94             669 :   umask(mask);
      95                 : 
      96                 :   // Close the temporary output file.  The close can fail on NFS if
      97                 :   // out of space.
      98             669 :   if (close(fd2) == -1)
      99                 :     {
     100               0 :       unlink(tmp_name);
     101               0 :       return -1;
     102                 :     }
     103                 : 
     104                 :   // Rename the temporary output file to the destination file.
     105             669 :   unlink(dest);
     106             669 :   if (rename(tmp_name, dest) == -1)
     107                 :     {
     108               0 :       unlink(tmp_name);
     109               0 :       return -1;
     110                 :     }
     111                 : 
     112             669 :   return 0;
     113                 : }
     114                 : 
     115                 : 
     116                 : // Make sure a directory exists.
     117                 : int
     118            2533 : create_dir(const char *dir)
     119                 : {
     120                 :   struct stat st;
     121            2533 :   if (stat(dir, &st) == 0)
     122                 :     {
     123            2350 :       if (S_ISDIR(st.st_mode))
     124            2348 :         return 0;
     125               2 :       errno = ENOTDIR;
     126               2 :       return 1;
     127                 :     }
     128                 : 
     129             183 :   if (mkdir(dir, 0777) != 0 && errno != EEXIST)
     130               0 :     return 1;
     131                 : 
     132             183 :   return 0;
     133                 : }
     134                 : 
     135                 : 
     136                 : void
     137                 : tokenize(const string& str, vector<string>& tokens,
     138             347 :          const string& delimiters = " ")
     139                 : {
     140                 :   // Skip delimiters at beginning.
     141             347 :   string::size_type lastPos = str.find_first_not_of(delimiters, 0);
     142                 :   // Find first "non-delimiter".
     143             347 :   string::size_type pos     = str.find_first_of(delimiters, lastPos);
     144                 : 
     145            2082 :   while (pos != string::npos || lastPos != string::npos)
     146                 :     {
     147                 :       // Found a token, add it to the vector.
     148            1388 :       tokens.push_back(str.substr(lastPos, pos - lastPos));
     149                 :       // Skip delimiters.  Note the "not_of"
     150            1388 :       lastPos = str.find_first_not_of(delimiters, pos);
     151                 :       // Find next "non-delimiter"
     152            1388 :       pos = str.find_first_of(delimiters, lastPos);
     153                 :     }
     154             347 : }
     155                 : 
     156                 : 
     157                 : //  Find an executable by name in $PATH.
     158                 : bool
     159             347 : find_executable(const char *name, string& retpath)
     160                 : {
     161                 :   const char *p;
     162             347 :   string path;
     163             347 :   vector<string> dirs;
     164                 :   struct stat st1, st2;
     165                 : 
     166             347 :   if (*name == '/')
     167                 :     {
     168               0 :       retpath = name;
     169               0 :       return true;
     170                 :     }
     171                 : 
     172             347 :   p = getenv("PATH");
     173             347 :   if (!p)
     174               0 :     return false;
     175             347 :   path = p;
     176                 :         
     177                 :   // Split PATH up.
     178             347 :   tokenize(path, dirs, string(":"));
     179                 : 
     180                 :   // Search the path looking for the first executable of the right name.
     181             694 :   for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); i++)
     182                 :     {
     183            1041 :       string fname = *i + "/" + name;
     184            1041 :       const char *f = fname.c_str();
     185                 : 
     186                 :       // Look for a normal executable file.
     187            1041 :       if (access(f, X_OK) == 0
     188                 :           && lstat(f, &st1) == 0
     189                 :           && stat(f, &st2) == 0
     190                 :           && S_ISREG(st2.st_mode))
     191                 :         {
     192                 :           // Found it!
     193             347 :           retpath = fname;
     194             347 :           return true;
     195                 :         }
     196                 :     }
     197                 : 
     198               0 :   return false;
     199                 : }
     200                 : 
     201              68 : const string cmdstr_quoted(const string& cmd)
     202                 : {
     203                 :         // original cmd : substr1
     204                 :         //           or : substr1'substr2
     205                 :         //           or : substr1'substr2'substr3......
     206                 :         // after quoted :
     207                 :         // every substr(even it's empty) is quoted by ''
     208                 :         // every single-quote(') is quoted by ""
     209                 :         // examples: substr1 --> 'substr1'
     210                 :         //           substr1'substr2 --> 'substr1'"'"'substr2'
     211                 : 
     212              68 :         string quoted_cmd;
     213              68 :         string quote("'");
     214             136 :         string replace("'\"'\"'");
     215              68 :         string::size_type pos = 0;
     216                 : 
     217              68 :         quoted_cmd += quote;
     218              68 :         for (string::size_type quote_pos = cmd.find(quote, pos); 
     219                 :                         quote_pos != string::npos; 
     220                 :                         quote_pos = cmd.find(quote, pos)) {
     221               0 :                 quoted_cmd += cmd.substr(pos, quote_pos - pos);
     222               0 :                 quoted_cmd += replace;
     223               0 :                 pos = quote_pos + 1;
     224                 :         }
     225              68 :         quoted_cmd += cmd.substr(pos, cmd.length() - pos);
     226              68 :         quoted_cmd += quote;
     227                 : 
     228              68 :         return quoted_cmd;
     229            2188 : }
     230            1094 : 

Generated by: LTP GCOV extension version 1.5