Alex 'AdUser' Z
8 years ago
24 changed files with 561 additions and 325 deletions
@ -0,0 +1,2 @@
|
||||
[source:files] |
||||
load = libf2b_source_files.so |
@ -1,58 +0,0 @@
|
||||
/* Copyright 2016 Alex 'AdUser' Z (ad_user@runbox.com)
|
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 as |
||||
* published by the Free Software Foundation. |
||||
*/ |
||||
#include <glob.h> |
||||
|
||||
#include "common.h" |
||||
#include "logfile.h" |
||||
#include "filelist.h" |
||||
#include "log.h" |
||||
|
||||
f2b_logfile_t * |
||||
f2b_filelist_append(f2b_logfile_t *list, f2b_logfile_t *file) { |
||||
assert(file != NULL); |
||||
|
||||
if (list != NULL) |
||||
return file->next = list; |
||||
return file; |
||||
} |
||||
|
||||
f2b_logfile_t * |
||||
f2b_filelist_from_glob(const char *pattern) { |
||||
f2b_logfile_t *file = NULL; |
||||
f2b_logfile_t *files = NULL; |
||||
glob_t globbuf; |
||||
|
||||
assert(pattern != NULL); |
||||
|
||||
if (glob(pattern, GLOB_MARK | GLOB_NOESCAPE, NULL, &globbuf) != 0) |
||||
return NULL; |
||||
|
||||
for (size_t i = 0; i < globbuf.gl_pathc; i++) { |
||||
if ((file = calloc(1, sizeof(f2b_logfile_t))) == NULL) |
||||
continue; |
||||
if (f2b_logfile_open(file, globbuf.gl_pathv[i]) == false) { |
||||
f2b_log_msg(log_error, "can't open file: %s: %s", globbuf.gl_pathv[i], strerror(errno)); |
||||
free(file); |
||||
continue; |
||||
} |
||||
files = f2b_filelist_append(files, file); |
||||
} |
||||
|
||||
globfree(&globbuf); |
||||
return files; |
||||
} |
||||
|
||||
void |
||||
f2b_filelist_destroy(f2b_logfile_t *list) { |
||||
f2b_logfile_t *next = NULL; |
||||
|
||||
for (; list != NULL; list = next) { |
||||
next = list->next; |
||||
f2b_logfile_close(list); |
||||
free(list); |
||||
} |
||||
} |
@ -1,19 +0,0 @@
|
||||
/* Copyright 2016 Alex 'AdUser' Z (ad_user@runbox.com)
|
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 as |
||||
* published by the Free Software Foundation. |
||||
*/ |
||||
#ifndef F2B_FILELIST_H_ |
||||
#define F2B_FILELIST_H_ |
||||
|
||||
f2b_logfile_t * |
||||
f2b_filelist_from_glob(const char *pattern); |
||||
|
||||
f2b_logfile_t * |
||||
f2b_filelist_append(f2b_logfile_t *list, f2b_logfile_t *file); |
||||
|
||||
void |
||||
f2b_filelist_destroy(f2b_logfile_t *list); |
||||
|
||||
#endif /* F2B_FILELIST_H_ */ |
@ -1,84 +0,0 @@
|
||||
/* Copyright 2016 Alex 'AdUser' Z (ad_user@runbox.com)
|
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 as |
||||
* published by the Free Software Foundation. |
||||
*/ |
||||
#include "common.h" |
||||
#include "logfile.h" |
||||
|
||||
bool |
||||
f2b_logfile_open(f2b_logfile_t *file, const char *path) { |
||||
struct stat st; |
||||
char buf[PATH_MAX] = ""; |
||||
|
||||
assert(file != NULL); |
||||
assert(path != NULL || file->path[0] != '\0'); |
||||
|
||||
strlcpy(buf, path ? path : file->path, sizeof(buf)); |
||||
|
||||
memset(file, 0x0, sizeof(f2b_logfile_t)); |
||||
|
||||
if (stat(buf, &st) != 0) |
||||
return false; |
||||
|
||||
if (!(S_ISREG(st.st_mode) || S_ISFIFO(st.st_mode))) |
||||
return false; |
||||
|
||||
if ((file->fd = fopen(buf, "r")) == NULL) |
||||
return false; |
||||
|
||||
if (S_ISREG(st.st_mode) && fseek(file->fd, 0, SEEK_END) < 0) |
||||
return false; |
||||
|
||||
memcpy(&file->st, &st, sizeof(st)); |
||||
strlcpy(file->path, buf, sizeof(file->path)); |
||||
file->opened = true; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
void |
||||
f2b_logfile_close(f2b_logfile_t *file) { |
||||
assert(file != NULL); |
||||
|
||||
if (file->fd) |
||||
fclose(file->fd); |
||||
|
||||
file->opened = false; |
||||
file->fd = NULL; |
||||
} |
||||
|
||||
bool |
||||
f2b_logfile_rotated(const f2b_logfile_t *file) { |
||||
struct stat st; |
||||
|
||||
assert(file != NULL); |
||||
|
||||
if (!file->opened) |
||||
return true; |
||||
|
||||
if (stat(file->path, &st) != 0) |
||||
return true; |
||||
|
||||
if (file->st.st_dev != st.st_dev || |
||||
file->st.st_ino != st.st_ino || |
||||
file->st.st_size > st.st_size) |
||||
return true; |
||||
|
||||
return false; |
||||
} |
||||
|
||||
bool |
||||
f2b_logfile_getline(const f2b_logfile_t *file, char *buf, size_t bufsize) { |
||||
assert(file != NULL); |
||||
assert(buf != NULL); |
||||
|
||||
if (feof(file->fd)) |
||||
clearerr(file->fd); |
||||
/* fread()+EOF set is implementation defined */ |
||||
if (fgets(buf, bufsize, file->fd) != NULL) |
||||
return true; |
||||
|
||||
return false; |
||||
} |
@ -1,23 +0,0 @@
|
||||
/* Copyright 2016 Alex 'AdUser' Z (ad_user@runbox.com)
|
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 as |
||||
* published by the Free Software Foundation. |
||||
*/ |
||||
#ifndef F2B_LOGFILE_H_ |
||||
#define F2B_LOGFILE_H_ |
||||
|
||||
typedef struct f2b_logfile_t { |
||||
struct f2b_logfile_t *next; |
||||
bool opened; |
||||
char path[PATH_MAX]; |
||||
FILE *fd; |
||||
struct stat st; |
||||
} f2b_logfile_t; |
||||
|
||||
bool f2b_logfile_open(f2b_logfile_t *file, const char *path); |
||||
void f2b_logfile_close(f2b_logfile_t *file); |
||||
bool f2b_logfile_rotated(const f2b_logfile_t *file); |
||||
bool f2b_logfile_getline(const f2b_logfile_t *file, char *buf, size_t bufsize); |
||||
|
||||
#endif /* F2B_LOGFILE_H_ */ |
@ -0,0 +1,48 @@
|
||||
/* Copyright 2016 Alex 'AdUser' Z (ad_user@runbox.com)
|
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 as |
||||
* published by the Free Software Foundation. |
||||
*/ |
||||
#include "common.h" |
||||
#include "log.h" |
||||
#include "config.h" |
||||
#include "source.h" |
||||
|
||||
void usage() { |
||||
fprintf(stderr, "Usage: source-test <library.so> <init string>\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
|
||||
int main(int argc, char *argv[]) { |
||||
f2b_config_param_t param = { .name = "load", .value = "", .next = 0x0 }; |
||||
f2b_config_section_t config = { .name = "test", .type = t_source, .param = 0x0, .next = 0x0 }; |
||||
f2b_source_t *source = NULL; |
||||
char buf[1024] = ""; |
||||
bool reset; |
||||
|
||||
if (argc < 2) |
||||
usage(); |
||||
|
||||
config.param = ¶m; |
||||
snprintf(param.value, sizeof(param.value), "%s", argv[1]); |
||||
|
||||
if ((source = f2b_source_create(&config, argv[2], f2b_log_error_cb)) == false) |
||||
usage(); |
||||
|
||||
if (f2b_source_start(source) == false) { |
||||
f2b_log_msg(log_error, "source start error: %s", f2b_source_error(source)); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
|
||||
while (1) { |
||||
reset = true; |
||||
while (f2b_source_next(source, buf, sizeof(buf), reset)) { |
||||
reset = false; |
||||
fputs(buf, stderr); |
||||
} |
||||
sleep(1); |
||||
} |
||||
|
||||
return EXIT_SUCCESS; |
||||
} |
@ -0,0 +1,113 @@
|
||||
/* Copyright 2016 Alex 'AdUser' Z (ad_user@runbox.com)
|
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 as |
||||
* published by the Free Software Foundation. |
||||
*/ |
||||
#include "common.h" |
||||
#include "source.h" |
||||
|
||||
#define SOURCE_LIBRARY_PARAM "load" |
||||
|
||||
f2b_source_t * |
||||
f2b_source_create(f2b_config_section_t *config, const char *init, void (*errcb)(const char *)) { |
||||
f2b_config_param_t *param = NULL; |
||||
f2b_source_t *source = NULL; |
||||
int flags = RTLD_NOW | RTLD_LOCAL; |
||||
const char *dlerr = NULL; |
||||
|
||||
assert(config != NULL); |
||||
assert(config->type == t_source); |
||||
|
||||
param = f2b_config_param_find(config->param, SOURCE_LIBRARY_PARAM); |
||||
if (!param) { |
||||
f2b_log_msg(log_error, "can't find '%s' param in source config", SOURCE_LIBRARY_PARAM); |
||||
return NULL; |
||||
} |
||||
|
||||
if ((source = calloc(1, sizeof(f2b_source_t))) == NULL) |
||||
return NULL; |
||||
|
||||
if ((source->h = dlopen(param->value, flags)) == NULL) |
||||
goto cleanup; |
||||
if ((*(void **) (&source->create) = dlsym(source->h, "create")) == NULL) |
||||
goto cleanup; |
||||
if ((*(void **) (&source->config) = dlsym(source->h, "config")) == NULL) |
||||
goto cleanup; |
||||
if ((*(void **) (&source->ready) = dlsym(source->h, "ready")) == NULL) |
||||
goto cleanup; |
||||
if ((*(void **) (&source->error) = dlsym(source->h, "error")) == NULL) |
||||
goto cleanup; |
||||
if ((*(void **) (&source->errcb) = dlsym(source->h, "errcb")) == NULL) |
||||
goto cleanup; |
||||
if ((*(void **) (&source->start) = dlsym(source->h, "start")) == NULL) |
||||
goto cleanup; |
||||
if ((*(void **) (&source->next) = dlsym(source->h, "next")) == NULL) |
||||
goto cleanup; |
||||
if ((*(void **) (&source->stop) = dlsym(source->h, "stop")) == NULL) |
||||
goto cleanup; |
||||
if ((*(void **) (&source->destroy) = dlsym(source->h, "destroy")) == NULL) |
||||
goto cleanup; |
||||
|
||||
if ((source->cfg = source->create(init)) == NULL) { |
||||
f2b_log_msg(log_error, "source create config failed"); |
||||
goto cleanup; |
||||
} |
||||
|
||||
/* try init */ |
||||
for (param = config->param; param != NULL; param = param->next) { |
||||
if (strcmp(param->name, SOURCE_LIBRARY_PARAM) == 0) |
||||
continue; |
||||
if (source->config(source->cfg, param->name, param->value)) |
||||
continue; |
||||
f2b_log_msg(log_warn, "param pair not accepted by source '%s': %s=%s", |
||||
config->name, param->name, param->value); |
||||
} |
||||
|
||||
if (errcb) |
||||
source->errcb(source->cfg, errcb); |
||||
|
||||
if (source->ready(source->cfg)) |
||||
return source; |
||||
|
||||
/* still not ready */ |
||||
f2b_log_msg(log_error, "source '%s' not fully configured", config->name); |
||||
|
||||
cleanup: |
||||
dlerr = dlerror(); |
||||
if (dlerr) |
||||
f2b_log_msg(log_error, "source load error: %s", dlerr); |
||||
if (source->h) { |
||||
if (source->cfg && source->destroy) |
||||
source->destroy(source->cfg); |
||||
dlclose(source->h); |
||||
} |
||||
free(source); |
||||
return NULL; |
||||
} |
||||
|
||||
void |
||||
f2b_source_destroy(f2b_source_t *source) { |
||||
assert(source != NULL); |
||||
source->destroy(source->cfg); |
||||
dlclose(source->h); |
||||
free(source); |
||||
} |
||||
|
||||
bool |
||||
f2b_source_next(f2b_source_t *source, char *buf, size_t bufsize, bool reset) { |
||||
assert(source != NULL); |
||||
return source->next(source->cfg, buf, bufsize, reset); |
||||
} |
||||
|
||||
#define SOURCE_CMD_ARG0(CMD, RETURNS) \ |
||||
RETURNS \
|
||||
f2b_source_ ## CMD(f2b_source_t *source) { \
|
||||
assert(source != NULL); \
|
||||
return source->CMD(source->cfg); \
|
||||
} |
||||
|
||||
SOURCE_CMD_ARG0(error, const char *) |
||||
SOURCE_CMD_ARG0(start, bool) |
||||
SOURCE_CMD_ARG0(stop, bool) |
||||
SOURCE_CMD_ARG0(ready, bool) |
@ -0,0 +1,34 @@
|
||||
/* Copyright 2016 Alex 'AdUser' Z (ad_user@runbox.com)
|
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 as |
||||
* published by the Free Software Foundation. |
||||
*/ |
||||
#ifndef F2B_SOURCE_H_ |
||||
#define F2B_SOURCE_H_ |
||||
|
||||
#include "config.h" |
||||
#include "log.h" |
||||
|
||||
typedef struct f2b_source_t { |
||||
void *h; |
||||
void *cfg; |
||||
void *(*create) (const char *init); |
||||
bool (*config) (void *cfg, const char *key, const char *value); |
||||
bool (*ready) (void *cfg); |
||||
char *(*error) (void *cfg); |
||||
void (*errcb) (void *cfg, void (*cb)(const char *errstr)); |
||||
bool (*start) (void *cfg); |
||||
bool (*next) (void *cfg, char *buf, size_t bufsize, bool reset); |
||||
bool (*stop) (void *cfg); |
||||
void (*destroy) (void *cfg); |
||||
} f2b_source_t; |
||||
|
||||
f2b_source_t * f2b_source_create (f2b_config_section_t *config, const char *init, void (*errcb)(const char *)); |
||||
void f2b_source_destroy (f2b_source_t *s); |
||||
bool f2b_source_start (f2b_source_t *s); |
||||
bool f2b_source_next (f2b_source_t *s, char *buf, size_t bufsize, bool reset); |
||||
bool f2b_source_stop (f2b_source_t *s); |
||||
const char * f2b_source_error (f2b_source_t *s); |
||||
|
||||
#endif /* F2B_SOURCE_H_ */ |
@ -0,0 +1,10 @@
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON) |
||||
set(SOURCES "") |
||||
|
||||
add_library("f2b_source_files" MODULE "files.c" "../strlcpy.c") |
||||
list(APPEND SOURCES "f2b_source_files") |
||||
|
||||
message(STATUS "- Sources : ${SOURCES}") |
||||
|
||||
install(TARGETS ${SOURCES} |
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) |
@ -0,0 +1,227 @@
|
||||
/* Copyright 2016 Alex 'AdUser' Z (ad_user@runbox.com)
|
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 as |
||||
* published by the Free Software Foundation. |
||||
*/ |
||||
#include "source.h" |
||||
|
||||
#include <limits.h> |
||||
#include <sys/file.h> |
||||
#include <sys/stat.h> |
||||
|
||||
#include <glob.h> |
||||
|
||||
typedef struct f2b_file_t { |
||||
struct f2b_file_t *next; |
||||
bool opened; |
||||
char path[PATH_MAX]; |
||||
FILE *fd; |
||||
struct stat st; |
||||
} f2b_file_t; |
||||
|
||||
struct _config { |
||||
char path[256]; |
||||
char error[256]; |
||||
void (*errcb)(char *errstr); |
||||
f2b_file_t *files; |
||||
f2b_file_t *current; |
||||
}; |
||||
|
||||
static bool |
||||
file_open(f2b_file_t *file, const char *path) { |
||||
struct stat st; |
||||
char buf[PATH_MAX] = ""; |
||||
|
||||
assert(file != NULL); |
||||
assert(path != NULL || file->path[0] != '\0'); |
||||
|
||||
strlcpy(buf, path ? path : file->path, sizeof(buf)); |
||||
|
||||
memset(file, 0x0, sizeof(f2b_file_t)); |
||||
|
||||
if (stat(buf, &st) != 0) |
||||
return false; |
||||
|
||||
if (!(S_ISREG(st.st_mode) || S_ISFIFO(st.st_mode))) |
||||
return false; |
||||
|
||||
if ((file->fd = fopen(buf, "r")) == NULL) |
||||
return false; |
||||
|
||||
if (S_ISREG(st.st_mode) && fseek(file->fd, 0, SEEK_END) < 0) |
||||
return false; |
||||
|
||||
memcpy(&file->st, &st, sizeof(st)); |
||||
strlcpy(file->path, buf, sizeof(file->path)); |
||||
file->opened = true; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
static void |
||||
file_close(f2b_file_t *file) { |
||||
assert(file != NULL); |
||||
|
||||
if (file->fd) |
||||
fclose(file->fd); |
||||
|
||||
file->opened = false; |
||||
file->fd = NULL; |
||||
} |
||||
|
||||
static bool |
||||
file_rotated(const f2b_file_t *file) { |
||||
struct stat st; |
||||
|
||||
assert(file != NULL); |
||||
|
||||
if (!file->opened) |
||||
return true; |
||||
|
||||
if (stat(file->path, &st) != 0) |
||||
return true; |
||||
|
||||
if (file->st.st_dev != st.st_dev || |
||||
file->st.st_ino != st.st_ino || |
||||
file->st.st_size > st.st_size) |
||||
return true; |
||||
|
||||
return false; |
||||
} |
||||
|
||||
static bool |
||||
file_getline(const f2b_file_t *file, char *buf, size_t bufsize) { |
||||
assert(file != NULL); |
||||
assert(buf != NULL); |
||||
|
||||
if (feof(file->fd)) |
||||
clearerr(file->fd); |
||||
/* fread()+EOF set is implementation defined */ |
||||
if (fgets(buf, bufsize, file->fd) != NULL) |
||||
return true; |
||||
|
||||
return false; |
||||
} |
||||
|
||||
cfg_t * |
||||
create(const char *init) { |
||||
cfg_t *cfg = NULL; |
||||
assert(init != NULL); |
||||
if ((cfg = calloc(1, sizeof(cfg_t))) == NULL) |
||||
return NULL; |
||||
strlcpy(cfg->path, init, sizeof(cfg->path)); |
||||
return cfg; |
||||
} |
||||
|
||||
bool |
||||
config(cfg_t *cfg, const char *key, const char *value) { |
||||
assert(cfg != NULL); |
||||
assert(key != NULL); |
||||
assert(value != NULL); |
||||
/* no options */ |
||||
return false; |
||||
} |
||||
|
||||
bool |
||||
ready(cfg_t *cfg) { |
||||
assert(cfg != NULL); |
||||
if (cfg->path[0] == '\0') |
||||
return false; |
||||
return true; |
||||
} |
||||
|
||||
char * |
||||
error(cfg_t *cfg) { |
||||
assert(cfg != NULL); |
||||
|
||||
return cfg->error; |
||||
} |
||||
|
||||
void |
||||
errcb(cfg_t *cfg, void (*cb)(char *errstr)) { |
||||
assert(cfg != NULL); |
||||
assert(cb != NULL); |
||||
|
||||
cfg->errcb = cb; |
||||
} |
||||
|
||||
bool |
||||
start(cfg_t *cfg) { |
||||
f2b_file_t *file = NULL; |
||||
glob_t globbuf; |
||||
|
||||
assert(cfg != NULL); |
||||
|
||||
if (glob(cfg->path, GLOB_MARK | GLOB_NOESCAPE, NULL, &globbuf) != 0) |
||||
return NULL; |
||||
|
||||
for (size_t i = 0; i < globbuf.gl_pathc; i++) { |
||||
if ((file = calloc(1, sizeof(f2b_file_t))) == NULL) |
||||
continue; |
||||
if (file_open(file, globbuf.gl_pathv[i]) == false) { |
||||
if (cfg->errcb) { |
||||
snprintf(cfg->error, sizeof(cfg->error), "can't open file: %s -- %s", |
||||
globbuf.gl_pathv[i], strerror(errno)); |
||||
cfg->errcb(cfg->error); |
||||
} |
||||
free(file); |
||||
continue; |
||||
} |
||||
if (cfg->files == NULL) { |
||||
cfg->files = file; |
||||
} else { |
||||
file->next = cfg->files; |
||||
cfg->files = file; |
||||
} |
||||
} |
||||
|
||||
globfree(&globbuf); |
||||
return true; |
||||
} |
||||
|
||||
bool |
||||
stop(cfg_t *cfg) { |
||||
f2b_file_t *next = NULL; |
||||
|
||||
for (; cfg->files != NULL; cfg->files = next) { |
||||
next = cfg->files->next; |
||||
file_close(cfg->files); |
||||
free(cfg->files); |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
bool |
||||
next(cfg_t *cfg, char *buf, size_t bufsize, bool reset) { |
||||
assert(cfg != NULL); |
||||
assert(buf != NULL); |
||||
assert(bufsize > 0); |
||||
|
||||
if (reset || cfg->current == NULL) |
||||
cfg->current = cfg->files; |
||||
|
||||
for (f2b_file_t *file = cfg->current; file != NULL; file = file->next) { |
||||
if (file_rotated(file)) |
||||
file_close(file); |
||||
if (!file->opened && !file_open(file, NULL)) { |
||||
if (cfg->errcb) { |
||||
snprintf(cfg->error, sizeof(cfg->error), "can't open file -- %s", file->path); |
||||
cfg->errcb(cfg->error); |
||||
} |
||||
continue; |
||||
} |
||||
if (file_getline(file, buf, bufsize)) |
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
void |
||||
destroy(cfg_t *cfg) { |
||||
assert(cfg != NULL); |
||||
|
||||
free(cfg); |
||||
} |
@ -0,0 +1,29 @@
|
||||
/* Copyright 2016 Alex 'AdUser' Z (ad_user@runbox.com)
|
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License version 2 as |
||||
* published by the Free Software Foundation. |
||||
*/ |
||||
#include <assert.h> |
||||
#include <errno.h> |
||||
#include <stdbool.h> |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include <unistd.h> |
||||
|
||||
#include "../strlcpy.h" |
||||
|
||||
#define INIT_MAX 256 |
||||
|
||||
typedef struct _config cfg_t; |
||||
|
||||
extern cfg_t *create(const char *init); |
||||
extern bool config(cfg_t *c, const char *key, const char *value); |
||||
extern bool ready(cfg_t *c); |
||||
extern char *error(cfg_t *c); |
||||
extern void errcb(cfg_t *c, void (*cb)(char *errstr)); |
||||
extern bool start(cfg_t *c); |
||||
extern bool next(cfg_t *c, char *buf, size_t bufsize, bool reset); |
||||
extern bool stop(cfg_t *c); |
||||
extern void destroy(cfg_t *c); |
@ -1,58 +0,0 @@
|
||||
#include "../src/common.h" |
||||
#include "../src/logfile.h" |
||||
|
||||
int main() { |
||||
f2b_logfile_t file; |
||||
char filename[] = "/tmp/f2b-test.XXXXXX"; |
||||
int fd = 0; |
||||
int ret; |
||||
bool res; |
||||
FILE *wfd = NULL; |
||||
char buf[2048]; |
||||
|
||||
UNUSED(res); |
||||
UNUSED(ret); |
||||
|
||||
fd = mkstemp(filename); |
||||
assert(fd > 0); |
||||
wfd = fdopen(fd, "a"); |
||||
assert(wfd != NULL); |
||||
ret = fputs("test1\n", wfd); |
||||
assert(ret > 0); |
||||
ret = fflush(wfd); |
||||
assert(ret == 0); |
||||
|
||||
res = f2b_logfile_open(&file, filename); |
||||
assert(res == true); |
||||
res = f2b_logfile_getline(&file, buf, sizeof(buf)); |
||||
assert(res == false); |
||||
|
||||
ret = fputs("test2\n", wfd); |
||||
assert(ret > 0); |
||||
ret = fflush(wfd); |
||||
assert(ret == 0); |
||||
|
||||
res = f2b_logfile_getline(&file, buf, sizeof(buf)); |
||||
assert(res == true); |
||||
ret = strncmp(buf, "test2\n", sizeof(buf)); |
||||
assert(ret == 0); |
||||
|
||||
res = f2b_logfile_getline(&file, buf, sizeof(buf)); |
||||
assert(res == false); |
||||
|
||||
fclose(wfd); |
||||
close(fd); |
||||
unlink(filename); |
||||
|
||||
wfd = fopen(filename, "a"); |
||||
assert(wfd != NULL); |
||||
|
||||
res = f2b_logfile_rotated(&file); |
||||
assert(res == true); |
||||
|
||||
f2b_logfile_close(&file); |
||||
fclose(wfd); |
||||
unlink(filename); |
||||
|
||||
exit(0); |
||||
} |
Loading…
Reference in new issue