Created
June 24, 2016 14:37
-
-
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.
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 <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