31 #include <boost/interprocess/sync/file_lock.hpp>
32 #include <boost/interprocess/sync/scoped_lock.hpp>
33 #include <boost/interprocess/sync/sharable_lock.hpp>
35 using boost::interprocess::file_lock;
36 using boost::interprocess::scoped_lock;
37 using boost::interprocess::sharable_lock;
47 void sigsegvHandler(
int sig );
48 ::sighandler_t lastSigsegvHandler = ::signal( SIGSEGV, sigsegvHandler );
51 void sigsegvHandler(
int sig )
54 ::signal( SIGSEGV, lastSigsegvHandler );
62 {
return getenv(
"ZYPP_LOCKFILE_ROOT") ? getenv(
"ZYPP_LOCKFILE_ROOT") :
"/"; }
66 namespace zypp_readonly_hack
69 static bool active = getenv(
"ZYPP_READONLY_HACK");
74 MIL <<
"ZYPP_READONLY promised." << endl;
115 MIL <<
"Cleanned lock file. (" << getpid() <<
")" << std::endl;
192 PathInfo status( procdir );
193 MIL <<
"Checking " << status << endl;
195 if ( ! status.isDir() )
197 DBG <<
"No such process." << endl;
201 static char buffer[513];
202 buffer[0] = buffer[512] = 0;
204 if ( std::ifstream( (procdir/
"cmdline").c_str() ).read( buffer, 512 ).gcount() > 0 )
211 DBG <<
"In zombie state." << endl;
221 MIL <<
"read: Lockfile " <<
_zyppLockFilePath <<
" has pid " << readpid <<
" (our pid: " << getpid() <<
") "<< std::endl;
222 return (pid_t)readpid;
243 if ( geteuid() != 0 )
268 WAR <<
_lockerPid <<
" is running and has a ZYpp lock. Sorry." << std::endl;
273 MIL <<
_lockerPid <<
" is dead. Taking the lock file." << std::endl;
279 INT <<
"Oops! We should not be here!" << std::endl;
287 static ZYppGlobalLock & globalLock()
289 static ZYppGlobalLock lock;
292 bool _haveZYpp =
false;
303 , _lockerPid( lockerPid_r )
304 , _lockerName( lockerName_r )
352 if ( geteuid() != 0 )
354 MIL <<
"Running as user. Skip creating " << globalLock().zyppLockFilePath() << std::endl;
358 MIL <<
"ZYPP_READONLY active." << endl;
360 else if ( globalLock().zyppLocked() )
363 const long LOCK_TIMEOUT = str::strtonum<long>( getenv(
"ZYPP_LOCK_TIMEOUT" ) );
364 if ( LOCK_TIMEOUT > 0 )
366 MIL <<
"Waiting whether pid " << globalLock().lockerPid() <<
" ends within $LOCK_TIMEOUT=" << LOCK_TIMEOUT <<
" sec." << endl;
368 Pathname procdir(
"/proc"/
str::numstring(globalLock().lockerPid()) );
369 for (
long i = 0; i < LOCK_TIMEOUT; i += delay )
371 if ( PathInfo( procdir ).isDir() )
375 MIL <<
"Retry after " << i <<
" sec." << endl;
376 failed = globalLock().zyppLocked();
380 MIL <<
"Waiting whether pid " << globalLock().lockerPid() <<
" ends within " << (LOCK_TIMEOUT-i) <<
" sec." << endl;
381 procdir = Pathname(
"/proc"/
str::numstring(globalLock().lockerPid()) );
385 MIL <<
"Finally got the lock!" << endl;
394 std::string t =
str::form(
_(
"System management is locked by the application with pid %d (%s).\n"
395 "Close this application before trying again."),
396 globalLock().lockerPid(),
397 globalLock().lockerName().c_str()
414 {
return _haveZYpp; }
423 return str <<
"ZYppFactory";
ScopedGuard accessLockFile()
Exception safe access to the lockfile.
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
bool haveZYpp() const
Whether the ZYpp instance is already created.
std::ostream & dumpBacktrace(std::ostream &stream_r)
Dump current stack trace to a stream.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
void IWantIt() ZYPP_DEPRECATED
virtual ~ZYppFactoryException()
Pathname ZYPP_LOCKFILE_ROOT()
Hack to circumvent the currently poor –root support.
ZYpp::Ptr getZYpp() const
shared_ptr< Impl > Impl_Ptr
static ZYppFactory instance()
Singleton ctor.
bool isProcessRunning(pid_t pid_r)
Pathname _zyppLockFilePath
std::ostream & operator<<(std::ostream &str, const Exception &obj)
shared_ptr< void > ScopedGuard
ZYppFactoryException(const std::string &msg_r, pid_t lockerPid_r, const std::string &lockerName_r)
ZYpp factory class (Singleton)
const Pathname & zyppLockFilePath() const
#define _(MSG)
Return translated text.
ZYppFactory()
Default ctor.
std::string numstring(char n, int w=0)
std::string form(const char *format,...)
Printf style construction of std::string.
void _closeLockFile()
Use accessLockFile.
Base class for Exception.
intrusive_ptr< ZYpp > Ptr
bool zyppLocked()
Try to aquire a lock.
const std::string & lockerName() const
void _openLockFile()
Use accessLockFile.
file_lock _zyppLockFileLock