Skip to content

Instantly share code, notes, and snippets.

@chris-marsh
Created January 26, 2017 22:55
Show Gist options
  • Save chris-marsh/74d31ce02b550f7e75e11db474b01cd4 to your computer and use it in GitHub Desktop.
Save chris-marsh/74d31ce02b550f7e75e11db474b01cd4 to your computer and use it in GitHub Desktop.
Only open a unique instance of an application.
include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/file.h>
#include <sys/wait.h>
#define TRUE 1
#define FALSE 0
#define PID_FILENAME "/tmp/test_pid.lock"
typedef struct Instance {
int unique;
char pid[10];
int pid_file;
} Instance;
int send_sig(int pid, int sig)
{
char exec_str[128];
sprintf(exec_str, "kill -%d %d >/dev/null 2>&1", sig, pid);
int result = WEXITSTATUS(system(exec_str));
if (result == 0)
return 0;
else
return -1;
}
static void signal_handler(int signal_id)
{
if (signal_id == SIGTERM)
exit(0);
}
int instance_lock(Instance *this) {
this->unique = FALSE;
this->pid_file = open(PID_FILENAME, O_CREAT | O_RDWR, 0666);
if (this->pid_file != -1){
if (flock(this->pid_file, LOCK_EX | LOCK_NB)) {
if (EWOULDBLOCK == errno) {
/* Already running, get the PID */
read(this->pid_file, this->pid, 10);
} else {
/* Deal with an error */
}
} else {
/* Get lock */
if (this->pid_file) {
sprintf(this->pid, "%d", getpid());
write(this->pid_file, this->pid, strlen(this->pid));
this->unique = TRUE;
}
}
}
return this->unique;
}
int instance_is_unique(Instance *this) {
return this->unique;
}
void instance_signal(Instance *this, int signal_code)
{
send_sig(atoi(this->pid), signal_code);
}
void instance_kill(Instance *this)
{
instance_signal(this, SIGTERM);
}
void instance_free(Instance *this)
{
if (this->pid_file)
close(this->pid_file);
unlink(PID_FILENAME);
}
int main(void)
{
Instance instance;
instance_lock(&instance);
if (instance.unique != TRUE) {
puts("Another instance is running");
instance_kill(&instance);
} else {
puts("We are the only instance");
while(1) {
sleep(5);
puts("Waiting");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment