Skip to content

Instantly share code, notes, and snippets.

@mrbid
Last active August 19, 2022 13:10
Show Gist options
  • Save mrbid/e1597fcc09e23cdc7157d0757d932ebd to your computer and use it in GitHub Desktop.
Save mrbid/e1597fcc09e23cdc7157d0757d932ebd to your computer and use it in GitHub Desktop.
Mission critical file increment helper process. Variant 2.
/*
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