From 5bb7ae3e5d1692d8f4468d13221d1c2c91ba2c4c Mon Sep 17 00:00:00 2001 From: thib Date: Sun, 9 Nov 2008 16:24:04 +0000 Subject: [PATCH] - Started to work on fifo_list to be used as serial_queue --- .gitignore | 7 ++ fcrontab.c | 2 +- fifo_list.c | 252 ++++++++++++++++++++++++++++++++++++++++++++++++++++ fifo_list.h | 64 +++++++++++++ u_list.c | 3 - 5 files changed, 324 insertions(+), 4 deletions(-) create mode 100644 fifo_list.c create mode 100644 fifo_list.h diff --git a/.gitignore b/.gitignore index 5db7943..b54ed4c 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,10 @@ doc/stylesheets/fcron-doc.dsl PREVIOUS_VERSION doc/fcron-doc.mod exe_list_test +doc/en/HTML/ +doc/en/man/ +doc/en/txt/ +doc/fr/HTML/ +doc/fr/man/ +doc/fr/txt/ + diff --git a/fcrontab.c b/fcrontab.c index cfe31c5..2405b78 100644 --- a/fcrontab.c +++ b/fcrontab.c @@ -511,7 +511,7 @@ edit_file(char *buf) } } snprintf(editorcmd, sizeof(editorcmd), "%s %s", cureditor, tmp_str); - chdir(tmp_path); + chdir(tmp_path); /* to make sure the editor can stat() the cur dir */ execlp(shell, shell, "-c", editorcmd, tmp_str, NULL); error_e("Error while running \"%s\"", cureditor); goto exiterr; diff --git a/fifo_list.c b/fifo_list.c new file mode 100644 index 0000000..c798b3c --- /dev/null +++ b/fifo_list.c @@ -0,0 +1,252 @@ +/* + * FCRON - periodic command scheduler + * + * Copyright 2000-2008 Thibault Godouet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * The GNU General Public License can also be found in the file + * `LICENSE' that comes with the fcron source distribution. + */ + + /* $Id: temp_file.c,v 1.6 2007/04/14 18:04:19 thib Exp thib $ */ + +/* + * 'First in first out' list of generic items + */ + +#include "global.h" +#include "fcron.h" +#include "fifo_list.h" + +/* private functions: */ +int fifo_list_resize_array(fifo_list_t *l); +#define Sizeof_fifo_list(list) ((list)->entry_size * (list)->array_size) +fifo_list_entry_t *fifo_list_last(fifo_list_t *l); + +fifo_list_t * +fifo_list_init(size_t entry_size, int init_size, int grow_size) +/* Create a new fifo list + * Returns the newly created unordered list + * Enough memory to hold init_size entries will initially be allocated, + * and it will grow by grow_size entries when more space is needed. + * Dies on error. */ +{ + fifo_list_t *l = NULL; + + /* sanity check */ + if ( entry_size < 1 || init_size < 1 || grow_size < 1 ) + die("Invalid arguments for fifo_list_init(): entry_size=%d, init_size=%d, " + "grow_size=%d", entry_size, init_size, grow_size); + + /* Allocate the list structure: */ + l = calloc(1, sizeof(struct fifo_list_t)); + if ( l == NULL ) + die_e("Failed creating a new fifo list: could not calloc() fifo_list_t " + "(entry_size: %d)", entry_size); + + /* Initialize the structure and allocate the array: */ + l->max_entries = l->num_entries = 0; + l->array_size = init_size; + l->entry_size = entry_size; + l->grow_size = grow_size; + l->first_entry = l->cur_entry = NULL; + l->entries_array = calloc(init_size, entry_size); + if ( l->entries_array == NULL ) + die_e("Failed creating a new fifo list: could not calloc array" + "(entry_size: %d, init_size: %d)", entry_size, init_size); + + return l; +} + +fifo_list_entry_t * +fifo_list_last(fifo_list_t *l) +/* Returns the pointer of the last entry in the list, or NULL if l is empty */ +{ + fifo_list_entry *e = NULL; + + if ( l->num_entries <= 0 ) + return NULL; + + e = (fifo_list_entry_t *) + ( (char *)l->entries_array + l->entry_size * ( l->num_entries - 1 ) ); + if ( e >= (fifo_list_entry_t *) ( (char *)l->entries_array + Sizeof_fifo_list(l) ) ) + e -= Sizeof_fifo_list(l); +} + +int +fifo_list_resize_array(fifo_list_t *l) +/* Resize l's entries_array up to l->max_entries + * Returns OK on success, ERR if the array is already at maximum size */ +{ + fifo_list_entry_t *e = NULL; + int offset = 0; + int old_size = l->array_size; + + /* sanity check */ + if ( l == NULL ) + die("Invalid argument for fifo_list_resize_array(): list=%d", l); + if ( l->max_entries > 0 && l->array_size >= l->max_entries ) { + debug("Resizing fifo_list_t failed because it is already at max size (size: %d)", + l->array_size); + return ERR; + } + + if ( l->cur_entry != NULL ) + /* Compute cur_entry's offset so as we can set cur_entry to the right place + * after we have allocated a new chunk of memory for the entries_array */ + offset = (char *) l->cur_entry - (char *) l->entries_array; + + l->array_size = (l->array_size + l->grow_size); + if ( l->max_entries > 0 && l->array_size > l->max_entries ) + l->array_size = l->max_entries; + + debug("Resizing fifo_list_t (old size: %d, new size: %d)...", old_size, l->array_size); + + if ( (e = calloc(l->array_size, l->entry_size)) == NULL ) + die_e("Could not calloc fifo_list_t to grow entries_array " + "(old size: %d, new size: %d)...", old_size, l->array_size); + + memcpy(e, l->entries_array, (l->entry_size * old_size)); + free_safe(l->entries_array); + l->entries_array = e; + + if ( l->cur_entry != NULL ) + l->cur_entry = (fifo_list_entry_t *) ( (char *) l->entries_array + offset ); + + return OK; +} + + +fifo_list_entry_t * +fifo_list_add(fifo_list_t *l, fifo_list_entry_t *e) +/* Add one entry to the list + * Returns a pointer to the added element, or NULL if list is already at max size */ +{ + fifo_list_entry_t *new = NULL; + + /* sanity check */ + if ( l == NULL || e == NULL ) + die("Invalid arguments for fifo_list_add(): list=%d, entry=%d", l, e); + + /* Check there is some space left, or resize the array */ + if ( l->num_entries >= l->array_size ) { + /* no more space: attempt to grow (the following function dies on error: */ + if ( fifo_list_resize_array(l) != OK ) + return NULL; + } + + l->num_entries++; + new = fifo_list_last(l); + memcpy(new, e, l->entry_size); + + return new; +} + +fifo_list_entry_t * +fifo_list_first(fifo_list_t *l) +/* Return the first entry of the list (then fifo_list_next() can be used) */ +{ + /* sanity check */ + if ( l == NULL ) + die("Invalid argument for fifo_list_first(): list=%d", l); + if ( l->cur_entry != NULL ) + die("fifo_list_first() called but there is already an iteration"); + + if (l->num_entries > 0) { + l->cur_entry = l->entries_array; + } + + return l->cur_entry; +} + +fifo_list_entry_t * +fifo_list_next(fifo_list_t *l) +/* Return the entry after e */ +{ + /* // WHAT IF I CALL _ADD() (+RESIZE?) OR _REMOVE() BETWEEN TWO _NEXT CALLS? */ + + /* sanity checks */ + if ( l == NULL ) + die("Invalid arguments for fifo_list_next(): list=%d", l); + if ( l->cur_entry == NULL ) + die("fifo_list_next() called outside an iteration: l->cur_entry=%d", l->cur_entry); + + if ( l->cur_removed > 0 ) { + l->cur_removed = 0; + /* the current entry has just been removed and replaced by another one: + * we can return the same pointer again. + * However if the removed entry was the last one then we reached the end + * of the list */ + if ( l->cur_entry > fifo_list_last(l) ) + l->cur_entry = NULL; + } + else { + /* cur_entry *not* removed (standard behavior) */ + + if ( l->cur_entry < fifo_list_last(l) ) + l->cur_entry = (fifo_list_entry_t *) ( (char *) l->cur_entry + l->entry_size); + else + /* reached the end of the list */ + l->cur_entry = NULL; + } + + return l->cur_entry; +} + +void +fifo_list_end_iteration(fifo_list_t *list) + /* Stop an iteration before _next() reached the end of the list by itself */ +{ + list->cur_entry = NULL; + list->cur_removed = 0; +} + + +void +fifo_list_remove_first(fifo_list_t *l) +{ + /* // MANAGE L->NEXT_ENTRY (+ SPECIAL CASE FIRST/LAST ENTRY) */ + fifo_list_entry_t *last = NULL; + + /* sanity checks */ + if ( l == NULL ) + die("Invalid arguments for fifo_list_remove(): list=%d", l); + if ( l->cur_entry == NULL ) + die("fifo_list_remove_cur() called outside of an iteration"); + + last = fifo_list_last(l); + if ( l->cur_entry < last ) { + /* Override e with the last entry */ + memcpy(l->cur_entry, last, l->entry_size); + } + /* erase the last entry and update the number of entries */ + memset(last, 0, l->entry_size); + l->num_entries--; + l->cur_removed = 1; + +} + +fifo_list_t * +fifo_list_destroy(fifo_list_t *list) + /* free() the memory allocated for list and returns NULL */ +{ + if ( list == NULL ) + die("Invalid argument for fifo_list_destroy(): list=%d", list); + + free_safe(list->entries_array); + free_safe(list); + return NULL; +} diff --git a/fifo_list.h b/fifo_list.h new file mode 100644 index 0000000..c8714ac --- /dev/null +++ b/fifo_list.h @@ -0,0 +1,64 @@ +/* + * FCRON - periodic command scheduler + * + * Copyright 2000-2008 Thibault Godouet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * The GNU General Public License can also be found in the file + * `LICENSE' that comes with the fcron source distribution. + */ + + /* $Id: temp_file.h,v 1.4 2007/04/14 18:04:20 thib Exp thib $ */ + +/* + * 'First in first out' list of generic items + */ + +#ifndef __FIFO_LIST_H__ +#define __FIFO_LIST_H__ + +#include +#include +#include +#include "subs.h" + +typedef void fifo_list_entry_t; + +typedef struct fifo_list_t { + /* PUBLIC: */ + int max_entries; /* max allowed element number (0: no limit) */ + int num_entries; /* READ ONLY: num of entries in the list now */ + /* PRIVATE: DO NOT ACCESS DIRECTLY */ + int array_size; /* size of the array (in number of entries) */ + size_t entry_size; /* number of element currently in the array */ + int grow_size; /* grow array by grow_size entries at a time */ + u_list_entry_t *first_entry; /* Current entry in iteration */ + u_list_entry_t *cur_entry; /* Current entry in iteration + * (null if not in iteration, i.e. X_first() has + * not been called or we reached the list end */ + u_list_entry_t *entries_array; /* pointer to the actual array */ +} fifo_list_t; + +/* functions prototypes */ +extern fifo_list_t *fifo_list_init(size_t entry_size, int init_size, int grow_size); +extern fifo_list_entry_t *fifo_list_add(fifo_list_t *list, fifo_list_entry_t *entry); +extern fifo_list_entry_t *fifo_list_first(fifo_list_t *list); +extern fifo_list_entry_t *fifo_list_next(fifo_list_t *list); +extern void fifo_list_end_iteration(fifo_list_t *list); +extern void fifo_list_remove_first(fifo_list_t *list); +extern fifo_list_t *fifo_list_destroy(fifo_list_t *list); + +#endif /* __FIFO_LIST_H__ */ diff --git a/u_list.c b/u_list.c index 25e6ed2..9c3843a 100644 --- a/u_list.c +++ b/u_list.c @@ -170,8 +170,6 @@ u_list_entry_t * u_list_next(u_list_t *l) /* Return the entry after e */ { - /* // WHAT IF I CALL _ADD() (+RESIZE?) OR _REMOVE() BETWEEN TWO _NEXT CALLS? */ - /* sanity checks */ if ( l == NULL ) die("Invalid arguments for u_list_next(): list=%d", l); @@ -212,7 +210,6 @@ u_list_end_iteration(u_list_t *list) void u_list_remove_cur(u_list_t *l) { - /* // MANAGE L->NEXT_ENTRY (+ SPECIAL CASE FIRST/LAST ENTRY) */ u_list_entry_t *last = NULL; /* sanity checks */ -- 2.50.1