Created
January 18, 2013 22:16
-
-
Save prasmussen/4569123 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <fcntl.h> | |
#define CMD_OFFSET 2 | |
#define MAX_CMD_LENGTH 2048 | |
int strlen_total(char **str, int length) { | |
int i, total = 0; | |
for (i = 0; i < length; i++) { | |
total += strlen(str[i]); | |
} | |
return total; | |
} | |
void join(char *res, char **str, int length, char *sep) { | |
int i; | |
for (i = 0; i < length; i++) { | |
if (i > 0) { | |
strcat(res, sep); | |
} | |
strcat(res, str[i]); | |
} | |
} | |
int main(int argc, char **argv) { | |
if (argc <= CMD_OFFSET) { | |
fprintf(stderr, "%s ensures that only one instance of an application is running by creating an exclusive lockfile.\n\n", argv[0]); | |
fprintf(stderr, "Usage: %s <lockfile> <command> [arg ...]\n", argv[0]); | |
return 1; | |
} | |
// Grab name of lock file | |
char *lock_fname = argv[1]; | |
// Grab a pointer to where the command starts - and the length | |
char **cmd = argv + CMD_OFFSET; | |
int length = argc - CMD_OFFSET; | |
// Calculate total length of the command, assuming there is a space after each argument (and \0 after the last argument) | |
int length_total = strlen_total(cmd, length) + length; | |
// Make sure that our buffer is large enough to hold the command | |
if (length_total > MAX_CMD_LENGTH) { | |
fprintf(stderr, "ERROR: Max command length is %d bytes, given command is %d bytes\n", MAX_CMD_LENGTH, length_total); | |
return 1; | |
} | |
// Build command string - separated by spaces | |
char cmd_str[MAX_CMD_LENGTH] = ""; | |
join(cmd_str, cmd, length, " "); | |
// Try to create lockfile in exclusive mode (this is an atomic operation) | |
int lock_fd = open(lock_fname, O_CREAT|O_RDONLY|O_EXCL, 0600); | |
if (lock_fd == -1) { | |
fprintf(stderr, "ERROR: Failed to create exclusive lockfile: %s\n", lock_fname); | |
return 1; | |
} | |
// Execute command | |
int status = system(cmd_str); | |
if (status == -1) { | |
fprintf(stderr, "ERROR: Failed to execute command: '%s'\n", cmd_str); | |
} | |
// Delete lockfile | |
remove(lock_fname); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment