Skip to content

Instantly share code, notes, and snippets.

@rsht
Created June 24, 2016 14:37
Show Gist options
  • Save rsht/6d4be2ee4b8abf5fced3b1ec8258ef95 to your computer and use it in GitHub Desktop.
Save rsht/6d4be2ee4b8abf5fced3b1ec8258ef95 to your computer and use it in GitHub Desktop.
example of C program that writes data to itself. Works under Linux only.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <unistd.h>
#include <fcntl.h>
typedef int var_t;
var_t getSavedVar(const char * exec_filename);
void saveNewVar(const var_t newVar, const char * exec_filename);
int main(int argc, char * argv[]) {
const var_t savedVar = getSavedVar(argv[0]);
printf("saved var = %d\n", savedVar);
var_t newVar = 0;
if ( argc > 1 ) {
newVar = atoi(argv[1]);
}
if ( newVar > 0 ) {
printf("new var value = %d\n", newVar);
saveNewVar(newVar, argv[0]);
}
}
var_t getSavedVar(const char * exec_filename) {
FILE * fd_this_exec = fopen(exec_filename, "r");
fseek(fd_this_exec, -(sizeof(var_t)), SEEK_END);
var_t savedVar = -1;
size_t read_res = fread((void *)&savedVar, sizeof(var_t), 1, fd_this_exec);
assert(read_res == 1);
return savedVar;
}
#define TEMP_STRING_LEN 3
const char g_temp_file_prefix_str[TEMP_STRING_LEN] = "_cp";
int copy_file(const char *source, const char * dest);
void saveNewVar(const var_t newVar, const char * exec_filename) {
char tmp_filename[strlen(exec_filename)+TEMP_STRING_LEN];
strncpy(tmp_filename, exec_filename, strlen(exec_filename));
strncat(tmp_filename, g_temp_file_prefix_str, TEMP_STRING_LEN);
int cp_res = copy_file(exec_filename, tmp_filename);
assert(cp_res == 0);
FILE * tmp_file = fopen(tmp_filename, "a");
if ( tmp_file > 0 ) {
fwrite((void *)&newVar, sizeof(newVar), 1, tmp_file);
fclose(tmp_file);
} else {
perror("fopen()");
return;
}
int remove_res = remove(exec_filename);
if ( remove_res != 0 ) {
perror("remove()");
return;
}
int rename_res = rename(tmp_filename, exec_filename);
if ( rename_res != 0 ) {
perror("rename()");
return;
}
}
int copy_file(const char *source, const char * dest) {
int fd_source = open(source, O_RDONLY);
int fd_dest = open(dest, O_CREAT|O_WRONLY, S_IRWXU);
if ( fd_source < 0 || fd_dest < 0 ) return -1;
char buf[8192];
while(1) {
ssize_t read_res = read(fd_source, &buf[0], sizeof(buf));
if ( read_res < 0 ) {
perror("read()");
return -1;
} else if ( read_res == 0 ) {
break;
}
ssize_t write_res = write(fd_dest, &buf[0], read_res);
if ( write_res == -1 ) {
perror("write()");
return -1;
}
}
close(fd_source);
close(fd_dest);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment