mirror of
https://github.com/ckb-next/ckb-next.git
synced 2026-10-10 12:27:21 -04:00
(ckb) Added --close option to quit ckb instead of opening it
(ckb) Added --version option to print current version (ckb) Fixed "ckb is already running" after the program had crashed New shared memory format allows storing the PID as well as a more robust command format. This will be put to more use later.
This commit is contained in:
+4
-2
@@ -63,7 +63,6 @@ if [[ ! -d $BINDIR ]]; then
|
||||
echo "There is nothing to do."
|
||||
finish 0
|
||||
fi
|
||||
|
||||
# Offer to install ckb at a standard location
|
||||
shopt -s nocasematch
|
||||
read -rp "Install ckb system-wide [Y/n]? " doinstall
|
||||
@@ -191,8 +190,11 @@ sleep 1
|
||||
echo ""
|
||||
read -rp "Start ckb now [Y/n]? " dolaunch
|
||||
[[ $dolaunch =~ no? ]] && exit 0
|
||||
sleep 0.5
|
||||
APP=$PREFIX/ckb
|
||||
[[ "$OSTYPE" == "darwin"* ]] && APP=$APP.app/Contents/MacOS/ckb
|
||||
# Ask ckb to close if there's an instance already running
|
||||
$APP --close >/dev/null 2>&1
|
||||
sleep 0.5
|
||||
# Launch
|
||||
nohup $APP >/dev/null 2>&1 &
|
||||
exit 0
|
||||
|
||||
+76
-10
@@ -3,6 +3,9 @@
|
||||
#include <QDateTime>
|
||||
#include <QSharedMemory>
|
||||
#include <cstring>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
QSharedMemory appShare("ckb");
|
||||
|
||||
@@ -12,17 +15,64 @@ QSharedMemory appShare("ckb");
|
||||
extern "C" void disableAppNap();
|
||||
#endif
|
||||
|
||||
bool isRunning(bool showWindow){
|
||||
if(!appShare.create(16)){
|
||||
if(!appShare.attach() || !appShare.lock())
|
||||
return false;
|
||||
if(showWindow){
|
||||
void* data = appShare.data();
|
||||
snprintf((char*)data, 16, "Open");
|
||||
// Shared memory sizes
|
||||
#define SHMEM_SIZE 128 * 1024
|
||||
#define SHMEM_SIZE_V015 16
|
||||
|
||||
// Scan shared memory for an active PID
|
||||
static bool pidActive(const QStringList& lines){
|
||||
foreach(const QString& line, lines){
|
||||
if(line.startsWith("PID ")){
|
||||
bool ok;
|
||||
pid_t pid;
|
||||
// Valid PID found?
|
||||
if((pid = line.split(" ")[1].toLong(&ok)) > 0 && ok){
|
||||
// kill -0 does nothing to the application, but checks if it's running
|
||||
return (kill(pid, 0) == 0 || errno != ESRCH);
|
||||
}
|
||||
}
|
||||
appShare.unlock();
|
||||
return true;
|
||||
}
|
||||
// If the PID wasn't listed in the shmem, assume it is running
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if the application is running. Optionally write something to its shared memory.
|
||||
static bool isRunning(const char* command){
|
||||
// Try to create shared memory (if successful, application was not already running)
|
||||
if(!appShare.create(SHMEM_SIZE) || !appShare.lock()){
|
||||
// Lock existing shared memory
|
||||
if(!appShare.attach() || !appShare.lock())
|
||||
return true;
|
||||
bool running = false;
|
||||
if(appShare.size() == SHMEM_SIZE_V015){
|
||||
// Old shmem - no PID listed so assume the process is running, and print the command directly to the buffer
|
||||
if(command){
|
||||
void* data = appShare.data();
|
||||
snprintf((char*)data, SHMEM_SIZE_V015, "%s", command);
|
||||
}
|
||||
running = true;
|
||||
} else {
|
||||
// New shmem. Scan the contents of the shared memory for a PID
|
||||
QStringList lines = QString((const char*)appShare.constData()).split("\n");
|
||||
if(pidActive(lines)){
|
||||
running = true;
|
||||
// Append the command
|
||||
if(command){
|
||||
lines.append(QString("Option ") + command);
|
||||
QByteArray newMem = lines.join("\n").left(SHMEM_SIZE).toLatin1();
|
||||
// Copy the NUL byte as well as the string
|
||||
memcpy(appShare.data(), newMem.constData(), newMem.length() + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(running){
|
||||
appShare.unlock();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Not already running. Initialize the shared memory with our PID
|
||||
snprintf((char*)appShare.data(), appShare.size(), "PID %ld", (long)getpid());
|
||||
appShare.unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -40,8 +90,24 @@ int main(int argc, char *argv[]){
|
||||
qApp->setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#endif
|
||||
|
||||
// If launched with --version, print version info and then quit
|
||||
if(qApp->arguments().contains("--version")){
|
||||
printf("ckb %s\n", CKB_VERSION_STR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Kill existing app when launched with --close
|
||||
if(qApp->arguments().contains("--close")){
|
||||
if(isRunning("Close"))
|
||||
printf("Asking existing instance to close.\n");
|
||||
else
|
||||
printf("ckb is not running.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Launch in background if requested
|
||||
bool background = qApp->arguments().contains("--background");
|
||||
if(isRunning(!background)){
|
||||
if(isRunning(background ? 0 : "Open")){
|
||||
printf("ckb is already running. Exiting.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
+21
-5
@@ -6,6 +6,7 @@
|
||||
#include <QShortcut>
|
||||
#include <QMessageBox>
|
||||
#include <QMenuBar>
|
||||
#include <unistd.h>
|
||||
|
||||
extern QSharedMemory appShare;
|
||||
|
||||
@@ -204,14 +205,29 @@ void MainWindow::closeEvent(QCloseEvent *event){
|
||||
}
|
||||
|
||||
void MainWindow::timerTick(){
|
||||
// Check if another instance requested this in the foreground
|
||||
// Check shared memory for changes
|
||||
if(appShare.lock()){
|
||||
void* data = appShare.data();
|
||||
if((QString)QByteArray((const char*)data) == "Open")
|
||||
showWindow();
|
||||
// Remove the request
|
||||
*(char*)data = 0;
|
||||
QStringList commands = QString((const char*)data).split("\n");
|
||||
// Restore PID, remove all other data
|
||||
snprintf((char*)appShare.data(), appShare.size(), "PID %ld", (long)getpid());
|
||||
appShare.unlock();
|
||||
// Parse commands
|
||||
foreach(const QString& line, commands){
|
||||
// Old ckb option line - bring application to foreground
|
||||
if(line == "Open")
|
||||
showWindow();
|
||||
if(line.startsWith("Option ")){
|
||||
// New ckb option line
|
||||
QString option = line.split(" ")[1];
|
||||
if(option == "Open")
|
||||
// Bring to foreground
|
||||
showWindow();
|
||||
else if(option == "Close")
|
||||
// Quit application
|
||||
qApp->quit();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check for firmware updates (when appropriate)
|
||||
if(!CkbSettings::get("Program/DisableAutoFWCheck").toBool())
|
||||
|
||||
Reference in New Issue
Block a user