Skip to content

Commit

Permalink
Merge pull request #96 from itay-grudev/primary_user
Browse files Browse the repository at this point in the history
v3.1.0a Added primaryUser()
  • Loading branch information
itay-grudev committed Mar 3, 2020
2 parents 666fd4d + 81cc271 commit 4abe20a
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 28 deletions.
14 changes: 8 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
/examples/basic/basic
/examples/calculator/calculator
/examples/sending_arguments/sending_arguments
CMakeLists.txt.user
CMakeCache.txt
CMakeCache/*
CMakeFiles/*
Makefile
cmake_install.cmake
/**/CMakeLists.txt.user
/**/CMakeCache.txt
/**/CMakeCache/*
/**/CMakeFiles/*
/**/Makefile
/**/cmake_install.cmake
/**/*_autogen/
libSingleApplication.a
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Changelog
=========

__3.1.0a__
----------

* Added primaryUser() method that returns the user the primary instance is running as.

__3.0.19__
----------

Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,14 @@ qint64 SingleApplication::primaryPid()

Returns the process ID (PID) of the primary instance.

---

```cpp
QString SingleApplication::primaryUser()
```

Returns the username the primary instance is running as.

### Signals

```cpp
Expand Down
3 changes: 3 additions & 0 deletions examples/sending_arguments/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ int main(int argc, char *argv[])
// If this is a secondary instance
if( app.isSecondary() ) {
app.sendMessage( app.arguments().join(' ').toUtf8() );
qDebug() << "App already running.";
qDebug() << "Primary instance PID: " << app.primaryPid();
qDebug() << "Primary instance user: " << app.primaryUser();
return 0;
} else {
QObject::connect(
Expand Down
6 changes: 6 additions & 0 deletions singleapplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,12 @@ qint64 SingleApplication::primaryPid()
return d->primaryPid();
}

QString SingleApplication::primaryUser()
{
Q_D(SingleApplication);
return d->primaryUser();
}

bool SingleApplication::sendMessage( QByteArray message, int timeout )
{
Q_D(SingleApplication);
Expand Down
6 changes: 6 additions & 0 deletions singleapplication.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ class SingleApplication : public QAPPLICATION_CLASS
*/
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.
* @param {int} timeout - Timeout for connecting
Expand Down
60 changes: 38 additions & 22 deletions singleapplication_p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,35 @@ SingleApplicationPrivate::~SingleApplicationPrivate()
delete server;
inst->primary = false;
inst->primaryPid = -1;
inst->primaryUser[0] = '\0';
inst->checksum = blockChecksum();
}
memory->unlock();

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()
{
QCryptographicHash appData( QCryptographicHash::Sha256 );
Expand All @@ -105,28 +127,7 @@ void SingleApplicationPrivate::genBlockServerName()

// User level block requires a user specific data in the hash
if( options & SingleApplication::Mode::User ) {
#ifdef Q_OS_WIN
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
appData.addData( getUsername() );
}

// Replace the backslash in RFC 2045 Base64 [a-zA-Z0-9+/=] to comply with
Expand All @@ -140,6 +141,7 @@ void SingleApplicationPrivate::initializeMemoryBlock()
inst->primary = false;
inst->secondary = 0;
inst->primaryPid = -1;
inst->primaryUser[0] = '\0';
inst->checksum = blockChecksum();
}

Expand Down Expand Up @@ -173,6 +175,8 @@ void SingleApplicationPrivate::startPrimary()

inst->primary = true;
inst->primaryPid = q->applicationPid();
strncpy( inst->primaryUser, getUsername().data(), 127 );
inst->primaryUser[127] = '\0';
inst->checksum = blockChecksum();

instanceNumber = 0;
Expand Down Expand Up @@ -257,6 +261,18 @@ qint64 SingleApplicationPrivate::primaryPid()
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
*/
Expand Down
3 changes: 3 additions & 0 deletions singleapplication_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ struct InstancesInfo {
quint32 secondary;
qint64 primaryPid;
quint16 checksum;
char primaryUser[128];
};

struct ConnectionInfo {
Expand Down Expand Up @@ -71,13 +72,15 @@ Q_OBJECT
SingleApplicationPrivate( SingleApplication *q_ptr );
~SingleApplicationPrivate();

QByteArray getUsername();
void genBlockServerName();
void initializeMemoryBlock();
void startPrimary();
void startSecondary();
void connectToPrimary(int msecs, ConnectionType connectionType );
quint16 blockChecksum();
qint64 primaryPid();
QString primaryUser();
void readInitMessageHeader(QLocalSocket *socket);
void readInitMessageBody(QLocalSocket *socket);

Expand Down

0 comments on commit 4abe20a

Please sign in to comment.