Last active
August 19, 2022 13:10
-
-
Save mrbid/e1597fcc09e23cdc7157d0757d932ebd to your computer and use it in GitHub Desktop.
Mission critical file increment helper process. Variant 2.
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
/* | |
James William Fletcher (github.com/mrbid) | |
August 2021 | |
Mission critical file increments. Variant 2. | |
https://james-william-fletcher.medium.com/mission-critical-integer-increment-operations-from-php-c1c71fb42451 | |
This file is compiled to a program that any | |
service can externally execute to ensure | |
a file increment or decrement operation | |
never fails. | |
Assuming that there is no condition where the | |
operating system will terminate the process | |
and that your max process limit; | |
/proc/sys/kernel/pid_max is not exceeded. | |
Integers are processed as long long with a maximum | |
value of 9223372036854775807, and are saved in string | |
format as a maximum of 19 bytes long. | |
*/ | |
#include <sys/file.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#define CHMOD 0666 | |
#define MAX_BUFF 20 // +1 for the null terminator | |
int main(int argc, char *argv[]) | |
{ | |
// check all params supplied | |
if(argc < 3) | |
{ | |
printf("Incorrect arguments.\n"); | |
return 0; | |
} | |
// temporary buffer for file read | |
char tb[MAX_BUFF] = {0}; | |
// open file | |
int f = open(argv[1], O_CREAT | O_RDWR, CHMOD); | |
while(f < 0) | |
{ | |
f = open(argv[1], O_CREAT | O_RDWR, CHMOD); | |
sleep(1); | |
} | |
// lock file | |
while(flock(f, LOCK_EX) < 0) | |
sleep(1); | |
// get file size in bytes | |
off_t len = lseek(f, (size_t)0, SEEK_END); | |
while(len < 0) | |
{ | |
len = lseek(f, (size_t)0, SEEK_END); | |
sleep(1); | |
} | |
// check size of read fits into memory | |
// this should never fail but if it | |
// does we should exit the process or | |
// it would hang forever and eventually | |
// the system max process limit would | |
// be exceeded. | |
if(len >= MAX_BUFF) | |
{ | |
printf("len >= MAX_BUFF\n"); | |
close(f); | |
return 0; | |
} | |
// seek back to beginning of file | |
while(lseek(f, (size_t)0, SEEK_SET) < 0) | |
sleep(1); | |
// read file | |
while(read(f, &tb, len) != len) | |
sleep(1); | |
// convert to long long and increment | |
long long ll = atoll(tb); | |
ll += atoll(argv[2]); | |
// set temp buff to write data | |
sprintf(tb, "%lld", ll); | |
const int wlen = strlen(tb); | |
// trunc | |
while(ftruncate(f, 0) < 0) | |
sleep(1); | |
// seek | |
while(lseek(f, (size_t)0, SEEK_SET) < 0) | |
sleep(1); | |
// write | |
while(write(f, tb, wlen) != wlen) | |
sleep(1); | |
// unlock | |
flock(f, LOCK_UN); | |
//done | |
fsync(f); | |
close(f); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment