Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,13 @@ extern "C" {
#include <stdint.h>
#include <electrostatic/electronetsoft/util/utilities.h>

struct read_op_processor {
struct op_processor {
void (*op_preprocessor)(file_mem *, void *);
void (*op_postprocessor)(file_mem *, void *);
void (*on_bytes_processed)(file_mem *, ssize_t, void *); /* Executed on each successful read operation. */
void (*on_eof_reached)(file_mem *); /* Executed when EOF is reached. Could be used to chain calls to memory deallocators. */
void (*on_last_char_sampled)(file_mem *, void *caller);
void (*on_error_encountered)(file_mem *, int, void *caller);
};

struct write_op_processor {
void (*on_bytes_processed)(file_mem *, ssize_t, void *); /* Executed on each successful read operation. */
void (*on_eob_reached)(file_mem *);
void (*on_last_char_sampled)(file_mem *, void *caller);
void (*on_error_encountered)(file_mem *, int, void *caller);
void (*on_last_byte_sampled)(file_mem *, void *); // uses count
void (*on_trailing_char_sampled)(file_mem *, void *); // uses predicate check
void (*on_error_encountered)(file_mem *, int, void *);
};

struct update_op_processor {
Expand Down Expand Up @@ -95,7 +90,7 @@ struct pipe_serializer {
* @param _processor a pointer to the file read operations processor; that links the API to the user application.
* @param __processor a pointer to the file attrs update processors.
*/
status_code read_into_mem(file_mem *, read_op_processor *, update_op_processor *);
status_code read_into_mem(file_mem *, op_processor *, update_op_processor *);

status_code update_file_attrs(file_mem *, update_op_processor *);

Expand All @@ -107,7 +102,7 @@ status_code update_file_attrs(file_mem *, update_op_processor *);
* @param mem a pointer to the file memory model struct.
* @param processor a pointer to the file operations processor; that links the API to the user application.
*/
status_code write_from_mem(file_mem *, write_op_processor *, update_op_processor *);
status_code write_from_mem(file_mem *, op_processor *, update_op_processor *);

status_code init_serializer(pipe_serializer *, serializer_op_processor *, update_op_processor *);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,23 @@ extern "C" {
#include <sys/stat.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <electrostatic/electronetsoft/util/filesystem/file_operations.h>

static inline int get_path_from_fd(int fd, char *buf, ssize_t len) {
if (fd < 0 || NULL == buf) {
return -1;
}

pid_t pid = getpid();

char path[255];
memset(path, '\0', sizeof (path));
sprintf(path, "/proc/%d/fd/%d", pid, fd);

return readlink(path, buf, len) > 0;
}

static inline int is_existential(const char *file) {
if (file == NULL) {
Expand All @@ -19,7 +36,23 @@ static inline int is_existential(const char *file) {
return stat(file, &statbuf) == 0;
}

static inline int is_fd_existential(int fd) {
if (fd < 0) {
return -1;
}
char path[255];
memset(path, '\0', sizeof (path));
int __status = get_path_from_fd(fd, path, sizeof (path));
if (!__status) {
return -1;
}
return is_existential(path);
}

static inline int is_fexistential(int fd) {
if (fd < 0) {
return -1;
}
struct stat statbuf;
return fstat(fd, &statbuf) == 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ typedef struct routine_data (routine_data);
typedef struct dll_function_table (dll_function_table);
typedef struct routine_callbacks (routine_callbacks);

typedef struct write_op_processor (write_op_processor);
typedef struct read_op_processor (read_op_processor);
typedef struct op_processor (op_processor);
typedef struct update_op_processor (update_op_processor);

typedef struct serializer_op_processor (serializer_op_processor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
#include <electrostatic/electronetsoft/util/filesystem/file_verify.h>

status_code read_into_mem(file_mem *mem,
read_op_processor *_processor,
op_processor *_processor,
update_op_processor *__processor) {
// pre-processing automata -- Input validation
if (rvalue(mem) == NULL) {
return EUNDEFINEDBUFFER;
}

if (NULL != __processor && NULL != __processor->update_model_preprocessor) {
__processor->update_model_preprocessor(mem, &read_into_mem);
if (NULL != _processor && NULL != _processor->op_preprocessor) {
_processor->op_preprocessor(mem, &read_into_mem);
}

// pre-processing automata -- Calculating the file size, current position,
Expand All @@ -23,11 +23,6 @@ status_code read_into_mem(file_mem *mem,
}
}

// postprocessing automata -- Invoke the update file postprocessor
if (NULL != __processor && NULL != __processor->update_model_postprocessor) {
__processor->update_model_postprocessor(mem, &read_into_mem);
}

if (NULL == mem->buffer) {
return EUNDEFINEDBUFFER;
}
Expand All @@ -37,6 +32,13 @@ status_code read_into_mem(file_mem *mem,
ssize_t read_bytes = 0;
ssize_t total_bytes = 0;
while (1) {
// sanity check the file
if (!is_fd_existential(mem->fd)) {
if (NULL != _processor && NULL != _processor->on_error_encountered) {
_processor->on_error_encountered(mem, errno, &read_into_mem);
}
return errno;
}
read_bytes = read(mem->fd, (mem->buffer + total_bytes), /* Advance linearly over the File Mem model buffer
* with the read bytes */
(mem->n_bytes - 1) - total_bytes); /* Retro-advance on the number of available bytes
Expand All @@ -55,14 +57,14 @@ status_code read_into_mem(file_mem *mem,
} else if (0 == read_bytes) {
// EOF terminate!
mem->buffer[total_bytes] = mem->trailing; /* add a null-terminating character */
if (NULL != _processor && NULL != _processor->on_eof_reached) {
_processor->on_eof_reached(mem);
if (NULL != _processor && NULL != _processor->on_trailing_char_sampled) {
_processor->on_trailing_char_sampled(mem, &read_into_mem);
}
// post-processing sub-state (HACK!)
if (mem->__continue_after_eof) {
continue;
}
return PASS;
break;
} else if (read_bytes > 0) {
// execute on_read
if (NULL != _processor && NULL != _processor->on_bytes_processed) {
Expand All @@ -73,14 +75,18 @@ status_code read_into_mem(file_mem *mem,
// even though the EOF is not reached, yet.
if ((mem->n_bytes - 1) == total_bytes) {
mem->buffer[total_bytes] = mem->trailing; /* add a null-terminating character */
if (NULL != _processor && NULL != _processor->on_last_char_sampled) {
_processor->on_last_char_sampled(mem, &read_into_mem);
if (NULL != _processor && NULL != _processor->on_last_byte_sampled) {
_processor->on_last_byte_sampled(mem, &read_into_mem);
}
}
} else {
return UNEXPECTED_ERROR;
}
}

return ASSERTION_FAILURE;
if (NULL != _processor && NULL != _processor->op_postprocessor) {
_processor->op_postprocessor(mem, &read_into_mem);
}

return PASS;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ status_code update_file_attrs(file_mem *mem,
return EUNDEFINEDBUFFER;
}

if (!mem->__auto_update_attrs) {
return PASS;
}

if (NULL != _processor && NULL != _processor->update_model_preprocessor) {
_processor->update_model_preprocessor(mem, &read_into_mem);
}

if (mem->fd < 0 || !is_fexistential(mem->fd)) {
return EUNDEFINEDBUFFER;
}
Expand Down Expand Up @@ -50,5 +58,10 @@ status_code update_file_attrs(file_mem *mem,
}
}

// postprocessing automata -- Invoke the update file postprocessor
if (NULL != _processor && NULL != _processor->update_model_postprocessor) {
_processor->update_model_postprocessor(mem, &read_into_mem);
}

return PASS;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
#include <electrostatic/electronetsoft/util/filesystem/file_verify.h>

status_code write_from_mem(file_mem *mem,
write_op_processor *_processor,
op_processor *_processor,
update_op_processor *__processor) {
// pre-processing automata -- Input validation
if (rvalue(mem) == NULL) {
return EUNDEFINEDBUFFER;
}

if (NULL != __processor && NULL != __processor->update_model_preprocessor) {
__processor->update_model_preprocessor(mem, &write_from_mem);
if (NULL != _processor && NULL != _processor->op_preprocessor) {
_processor->op_preprocessor(mem, &write_from_mem);
}

if (mem->fd < 0 || !is_fexistential(mem->fd)) {
Expand All @@ -31,9 +31,16 @@ status_code write_from_mem(file_mem *mem,
ssize_t written_bytes = 0;
ssize_t total_bytes = 0;
while (1) {
if (!is_fd_existential(mem->fd)) {
if (NULL != _processor && NULL != _processor->on_error_encountered) {
_processor->on_error_encountered(mem, errno, &read_into_mem);
}
return errno;
}

if (*(mem->buffer + total_bytes) == mem->trailing) {
if (NULL != _processor && NULL != _processor->on_eob_reached) {
_processor->on_eob_reached(mem);
if (NULL != _processor && NULL != _processor->on_trailing_char_sampled) {
_processor->on_trailing_char_sampled(mem, &write_from_mem);
}
break;
}
Expand All @@ -58,8 +65,8 @@ status_code write_from_mem(file_mem *mem,
} else if (total_bytes == (mem->n_bytes - 1)) {
// All bytes are written? -> terminate
// Equivalent to EOF.
if (NULL != _processor && NULL != _processor->on_eob_reached) {
_processor->on_eob_reached(mem);
if (NULL != _processor && NULL != _processor->on_last_byte_sampled) {
_processor->on_last_byte_sampled(mem, &write_from_mem);
}
break;
} else {
Expand All @@ -73,9 +80,10 @@ status_code write_from_mem(file_mem *mem,
return ___status;
}

// postprocessing automata -- Invoke the update file postprocessor
if (NULL != __processor && NULL != __processor->update_model_postprocessor) {
__processor->update_model_postprocessor(mem, &write_from_mem);
// to avoid premature closure of files; use the postprocessor at the end of the
// write routine
if (NULL != _processor && NULL != _processor->op_postprocessor) {
_processor->op_postprocessor(mem, &write_from_mem);
}

return PASS;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,12 @@ static inline void on_bytes_processed(file_mem *mem,
if (caller != &read_into_mem) {
return;
}
fprintf(stdout, "Read bytes = %s\n", mem->buffer);
}

static inline void on_eof_reached(file_mem *mem) {
static inline void on_eof_reached(file_mem *mem, void *caller) {
if (caller != &read_into_mem) {
return;
}
// support for stdin
if (mem->fd == STDIN_FILENO && mem->n_bytes < 20) {
mem->n_bytes += mem->n_bytes;
Expand All @@ -61,6 +63,13 @@ static inline void on_eof_reached(file_mem *mem) {
}
fprintf(stdout, "Read Bytes after EOF: %s\n", mem->buffer);
fprintf(stdout, "EOF Reached!\n");
}

static inline void op_postprocessor(file_mem *mem, void *caller) {
if (&read_into_mem != caller) {
return;
}

// deallocates memory here!
if (NULL != mem->buffer) {
free(mem->buffer);
Expand All @@ -87,9 +96,10 @@ int main() {
.__continue_after_eof = 0
};

read_op_processor _processor = {
op_processor _processor = {
.on_bytes_processed = &on_bytes_processed,
.on_eof_reached = &on_eof_reached
.on_trailing_char_sampled = &on_eof_reached,
.op_postprocessor = &op_postprocessor
};

update_op_processor __processor = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
#include <stdlib.h>
#include <fcntl.h>

static inline void update_model_preprocessor(file_mem *mem,
void *caller) {
static inline void op_preprocessor(file_mem *mem, void *caller) {
if (caller != &write_from_mem) {
return;
}
Expand Down Expand Up @@ -43,12 +42,14 @@ static inline void on_bytes_processed(file_mem *mem, ssize_t bytes,
fprintf(stdout, "%s", mem->buffer);
}

static inline void on_eob_reached(file_mem *mem) {
static inline void on_eob_reached(file_mem *mem, void *caller) {
if (caller != &write_from_mem) {
return;
}
fprintf(stdout, "EOB Reached!\n");
}

static inline void update_model_postprocessor(file_mem *mem,
void *caller) {
static inline void op_postprocessor(file_mem *mem, void *caller) {
if (caller != &write_from_mem) {
return;
}
Expand All @@ -69,17 +70,14 @@ int main() {
.__auto_update_attrs = 1,
};

write_op_processor _processor = {
op_processor _processor = {
.on_bytes_processed = &on_bytes_processed,
.on_eob_reached = &on_eob_reached,
};

update_op_processor __processor = {
.update_model_preprocessor = &update_model_preprocessor,
.update_model_postprocessor = &update_model_postprocessor,
.on_trailing_char_sampled = &on_eob_reached,
.op_preprocessor = &op_preprocessor,
.op_postprocessor = &op_postprocessor
};

status_code __status = write_from_mem(&_file_mem, &_processor, &__processor);
status_code __status = write_from_mem(&_file_mem, &_processor, NULL);

if (PASS != __status) {
fprintf(stderr, "Error Encountered: %s\n", strerror(__status));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include <electrostatic/electronetsoft/util/filesystem/file_verify.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>

int main() {
char path[128];
int __return = get_path_from_fd(STDOUT_FILENO, path, sizeof (path));
if (!__return) {
fprintf(stderr, "%s\n", strerror(errno));
exit(errno);
}
fprintf(stdout, "The path of fd=%d is %s\n", STDOUT_FILENO, path);

return 0;
}
Loading