v3.1.0a Added primaryUser()

Closes #95
This commit is contained in:
Itay Grudev 2020-03-03 01:22:54 +00:00 committed by Itay Grudev
parent 666fd4d8e8
commit 81cc2719be
8 changed files with 77 additions and 28 deletions

14
.gitignore vendored
View File

@ -6,9 +6,11 @@
/examples/basic/basic /examples/basic/basic
/examples/calculator/calculator /examples/calculator/calculator
/examples/sending_arguments/sending_arguments /examples/sending_arguments/sending_arguments
CMakeLists.txt.user /**/CMakeLists.txt.user
CMakeCache.txt /**/CMakeCache.txt
CMakeCache/* /**/CMakeCache/*
CMakeFiles/* /**/CMakeFiles/*
Makefile /**/Makefile
cmake_install.cmake /**/cmake_install.cmake
/**/*_autogen/
libSingleApplication.a

View File

@ -1,6 +1,11 @@
Changelog Changelog
========= =========
__3.1.0a__
----------
* Added primaryUser() method that returns the user the primary instance is running as.
__3.0.19__ __3.0.19__
---------- ----------

View File

@ -206,6 +206,14 @@ qint64 SingleApplication::primaryPid()
Returns the process ID (PID) of the primary instance. Returns the process ID (PID) of the primary instance.
---
```cpp
QString SingleApplication::primaryUser()
```
Returns the username the primary instance is running as.
### Signals ### Signals
```cpp ```cpp

View File

@ -11,6 +11,9 @@ int main(int argc, char *argv[])
// If this is a secondary instance // If this is a secondary instance
if( app.isSecondary() ) { if( app.isSecondary() ) {
app.sendMessage( app.arguments().join(' ').toUtf8() ); app.sendMessage( app.arguments().join(' ').toUtf8() );
qDebug() << "App already running.";
qDebug() << "Primary instance PID: " << app.primaryPid();
qDebug() << "Primary instance user: " << app.primaryUser();
return 0; return 0;
} else { } else {
QObject::connect( QObject::connect(

View File

@ -172,6 +172,12 @@ qint64 SingleApplication::primaryPid()
return d->primaryPid(); return d->primaryPid();
} }
QString SingleApplication::primaryUser()
{
Q_D(SingleApplication);
return d->primaryUser();
}
bool SingleApplication::sendMessage( QByteArray message, int timeout ) bool SingleApplication::sendMessage( QByteArray message, int timeout )
{ {
Q_D(SingleApplication); Q_D(SingleApplication);

View File

@ -112,6 +112,12 @@ public:
*/ */
qint64 primaryPid(); qint64 primaryPid();
/**
* @brief Returns the username of the user running the primary instance
* @returns {QString}
*/
QString primaryUser();
/** /**
* @brief Sends a message to the primary instance. Returns true on success. * @brief Sends a message to the primary instance. Returns true on success.
* @param {int} timeout - Timeout for connecting * @param {int} timeout - Timeout for connecting

View File

@ -76,6 +76,7 @@ SingleApplicationPrivate::~SingleApplicationPrivate()
delete server; delete server;
inst->primary = false; inst->primary = false;
inst->primaryPid = -1; inst->primaryPid = -1;
inst->primaryUser[0] = '\0';
inst->checksum = blockChecksum(); inst->checksum = blockChecksum();
} }
memory->unlock(); memory->unlock();
@ -83,6 +84,27 @@ SingleApplicationPrivate::~SingleApplicationPrivate()
delete memory; delete memory;
} }
QByteArray SingleApplicationPrivate::getUsername(){
#ifdef Q_OS_WIN
wchar_t username[UNLEN + 1];
// Specifies size of the buffer on input
DWORD usernameLength = UNLEN + 1;
if( GetUserNameW( username, &usernameLength ) )
return QString::fromWCharArray( username ).toUtf8();
return qgetenv( "USERNAME" );
#endif
#ifdef Q_OS_UNIX
QByteArray username;
uid_t uid = geteuid();
struct passwd *pw = getpwuid( uid );
if( pw )
username = pw->pw_name;
if( username.isEmpty() )
username = qgetenv( "USER" );
return username;
#endif
}
void SingleApplicationPrivate::genBlockServerName() void SingleApplicationPrivate::genBlockServerName()
{ {
QCryptographicHash appData( QCryptographicHash::Sha256 ); QCryptographicHash appData( QCryptographicHash::Sha256 );
@ -105,28 +127,7 @@ void SingleApplicationPrivate::genBlockServerName()
// User level block requires a user specific data in the hash // User level block requires a user specific data in the hash
if( options & SingleApplication::Mode::User ) { if( options & SingleApplication::Mode::User ) {
#ifdef Q_OS_WIN appData.addData( getUsername() );
wchar_t username [ UNLEN + 1 ];
// Specifies size of the buffer on input
DWORD usernameLength = UNLEN + 1;
if( GetUserNameW( username, &usernameLength ) ) {
appData.addData( QString::fromWCharArray(username).toUtf8() );
} else {
appData.addData( qgetenv("USERNAME") );
}
#endif
#ifdef Q_OS_UNIX
QByteArray username;
uid_t uid = geteuid();
struct passwd *pw = getpwuid(uid);
if( pw ) {
username = pw->pw_name;
}
if( username.isEmpty() ) {
username = qgetenv("USER");
}
appData.addData(username);
#endif
} }
// Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with // Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with
@ -140,6 +141,7 @@ void SingleApplicationPrivate::initializeMemoryBlock()
inst->primary = false; inst->primary = false;
inst->secondary = 0; inst->secondary = 0;
inst->primaryPid = -1; inst->primaryPid = -1;
inst->primaryUser[0] = '\0';
inst->checksum = blockChecksum(); inst->checksum = blockChecksum();
} }
@ -173,6 +175,8 @@ void SingleApplicationPrivate::startPrimary()
inst->primary = true; inst->primary = true;
inst->primaryPid = q->applicationPid(); inst->primaryPid = q->applicationPid();
strncpy( inst->primaryUser, getUsername().data(), 127 );
inst->primaryUser[127] = '\0';
inst->checksum = blockChecksum(); inst->checksum = blockChecksum();
instanceNumber = 0; instanceNumber = 0;
@ -257,6 +261,18 @@ qint64 SingleApplicationPrivate::primaryPid()
return pid; return pid;
} }
QString SingleApplicationPrivate::primaryUser()
{
QByteArray username;
memory->lock();
InstancesInfo* inst = static_cast<InstancesInfo*>( memory->data() );
username = inst->primaryUser;
memory->unlock();
return QString::fromUtf8( username );
}
/** /**
* @brief Executed when a connection has been made to the LocalServer * @brief Executed when a connection has been made to the LocalServer
*/ */

View File

@ -42,6 +42,7 @@ struct InstancesInfo {
quint32 secondary; quint32 secondary;
qint64 primaryPid; qint64 primaryPid;
quint16 checksum; quint16 checksum;
char primaryUser[128];
}; };
struct ConnectionInfo { struct ConnectionInfo {
@ -71,6 +72,7 @@ public:
SingleApplicationPrivate( SingleApplication *q_ptr ); SingleApplicationPrivate( SingleApplication *q_ptr );
~SingleApplicationPrivate(); ~SingleApplicationPrivate();
QByteArray getUsername();
void genBlockServerName(); void genBlockServerName();
void initializeMemoryBlock(); void initializeMemoryBlock();
void startPrimary(); void startPrimary();
@ -78,6 +80,7 @@ public:
void connectToPrimary(int msecs, ConnectionType connectionType ); void connectToPrimary(int msecs, ConnectionType connectionType );
quint16 blockChecksum(); quint16 blockChecksum();
qint64 primaryPid(); qint64 primaryPid();
QString primaryUser();
void readInitMessageHeader(QLocalSocket *socket); void readInitMessageHeader(QLocalSocket *socket);
void readInitMessageBody(QLocalSocket *socket); void readInitMessageBody(QLocalSocket *socket);