13 #include <unordered_set>
26 #undef ZYPP_BASE_LOGGER_LOGGROUP
27 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::misc"
46 typedef std::pair<std::string,std::unordered_set<std::string>> CacheEntry;
52 inline void addDataIf( std::vector<CheckAccessDeleted::ProcInfo> & data_r,
const CacheEntry & cache_r )
54 const auto & filelist( cache_r.second );
56 if ( filelist.empty() )
60 data_r.push_back( CheckAccessDeleted::ProcInfo() );
61 CheckAccessDeleted::ProcInfo & pinfo( data_r.back() );
62 pinfo.files.insert( pinfo.files.begin(), filelist.begin(), filelist.end() );
64 const std::string & pline( cache_r.first );
65 for_( ch, pline.begin(), pline.end() )
73 pinfo.ppid = &*(ch+1);
76 pinfo.puid = &*(ch+1);
79 pinfo.login = &*(ch+1);
82 pinfo.command = &*(ch+1);
85 if ( *ch ==
'\n' )
break;
86 do { ++ch; }
while ( *ch !=
'\0' );
89 if ( pinfo.command.size() == 15 )
93 if ( ! command.empty() )
94 pinfo.command = command.basename();
105 inline void addCacheIf( CacheEntry & cache_r,
const std::string & line_r,
bool verbose_r )
111 for_( ch, line_r.c_str(), ch+line_r.size() )
116 if ( *(ch+1) !=
'0' )
129 if ( *ch ==
'\n' )
break;
130 do { ++ch; }
while ( *ch !=
'\0' );
133 if ( !t || !f || !n )
136 if ( !( ( *t ==
'R' && *(t+1) ==
'E' && *(t+2) ==
'G' && *(t+3) ==
'\0' )
137 || ( *t ==
'D' && *(t+1) ==
'E' && *(t+2) ==
'L' && *(t+3) ==
'\0' ) ) )
140 if ( !( ( *f ==
'm' && *(f+1) ==
'e' && *(f+2) ==
'm' && *(f+3) ==
'\0' )
141 || ( *f ==
't' && *(f+1) ==
'x' && *(f+2) ==
't' && *(f+3) ==
'\0' )
142 || ( *f ==
'D' && *(f+1) ==
'E' && *(f+2) ==
'L' && *(f+3) ==
'\0' )
143 || ( *f ==
'l' && *(f+1) ==
't' && *(f+2) ==
'x' && *(f+3) ==
'\0' ) ) )
155 if ( *f ==
'm' || *f ==
'D' )
157 static const char * black[] = {
169 cache_r.second.insert( n );
179 static const char* argv[] =
181 "lsof",
"-n",
"-FpcuLRftkn0", NULL
186 std::map<pid_t,CacheEntry> cachemap;
191 if ( line[0] ==
'p' )
194 cachemap[cachepid].first.swap( line );
198 addCacheIf( cachemap[cachepid], line, verbose_r );
202 int ret = prog.
close();
214 std::vector<ProcInfo> data;
215 for (
const auto & cached : cachemap )
217 addDataIf( data, cached.second );
226 p.
command = command_r.basename();
248 return std::string();
252 static const Pathname initD(
"/etc/init.d" );
255 if ( pi.isFile() && pi.isX() )
259 std::string alt(
command+
"d" );
260 PathInfo pi( initD/alt );
261 if ( pi.isFile() && pi.isX() )
264 if ( *
command.rbegin() ==
'd' )
267 alt.erase( alt.size()-1 );
268 PathInfo pi( initD/alt );
270 if ( pi.isFile() && pi.isX() )
273 return std::string();
283 return dumpRange( str <<
"CheckAccessDeleted ",
295 if ( obj.
pid.empty() )
296 return str <<
"<NoProc>";
Data about one running process accessing deleted files.
bool contains(const C_Str &str_r, const C_Str &val_r)
Locate substring case sensitive.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
int readlink(const Pathname &symlink_r, Pathname &target_r)
Like 'readlink'.
std::vector< ProcInfo > _data
const std::string & execError() const
Some detail telling why the execution failed, if it failed.
std::string service() const
Guess if command was started by an /etc/init.d/ script.
std::string command
process command name
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
std::ostream & operator<<(std::ostream &str, const CheckAccessDeleted &obj)
void remember(const Exception &old_r)
Store an other Exception as history.
size_type check(bool verbose_r=false)
Check for running processes which access deleted executables or libraries.
std::string pid
process ID
std::ostream & dumpRange(std::ostream &str, _Iterator begin, _Iterator end, const std::string &intro="{", const std::string &pfx="\n ", const std::string &sep="\n ", const std::string &sfx="\n", const std::string &extro="}")
Print range defined by iterators (multiline style).
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
std::string puid
process user ID
#define _(MSG)
Return translated text.
std::string receiveLine()
Read one line from the input stream.
_It strtonum(const C_Str &str)
Parsing numbers from string.
std::ostream & dumpRangeLine(std::ostream &str, _Iterator begin, _Iterator end)
Print range defined by iterators (single line style).
std::string numstring(char n, int w=0)
int close()
Wait for the progamm to complete.
#define arrayBegin(A)
Simple C-array iterator.
std::string form(const char *format,...)
Printf style construction of std::string.
Base class for Exception.
Check for running processes which access deleted executables or libraries.
const_iterator end() const
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
const_iterator begin() const
std::string login
process login name
static std::string findService(const char *command_r)
Guess if command was started by an /etc/init.d/ script.
std::vector< std::string > files
list of deleted executables or libraries accessed
std::string ppid
parent process ID