* progress in moving all the fileaccess over to a wrapper system that can do fd based...
authoroetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa>
Wed, 23 May 2007 20:42:13 +0000 (20:42 +0000)
committeroetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa>
Wed, 23 May 2007 20:42:13 +0000 (20:42 +0000)
* small fixes left and right to improve code quality and stability.
-- Bernhard Fischer rep dot nop gmail com

git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk/program@1075 a5681a0c-68f1-0310-ab6d-d61299d08faa

20 files changed:
configure.ac
src/Makefile.am
src/rrd.h
src/rrd_dump.c
src/rrd_fetch.c
src/rrd_first.c
src/rrd_hw.c
src/rrd_hw.h
src/rrd_info.c
src/rrd_last.c
src/rrd_lastupdate.c
src/rrd_open.c
src/rrd_resize.c
src/rrd_restore.c
src/rrd_stat.c
src/rrd_thread_safe.c
src/rrd_tool.h
src/rrd_tune.c
src/rrd_update.c
src/unused.h

index 09e0260..83bf7e6 100644 (file)
@@ -52,12 +52,89 @@ AH_TOP([
  ])
 
 AH_BOTTOM([
+/* make sure that we pickup the correct stuff from all headers */
+#define _XOPEN_SOURCE 600
+#if HAVE_FEATURES_H
+# include <features.h>
+#endif
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+#ifndef MAXPATH
+# ifdef PATH_MAX
+#  define MAXPATH PATH_MAX
+# endif
+#endif
+#ifndef MAXPATH
+/* else try the BSD variant */
+# ifdef MAXPATHLEN
+#  define MAXPATH MAXPATHLEN
+# endif
+#endif
+
+#if HAVE_ERRNO_H
+# include <errno.h>
+#endif
+
+#if HAVE_SYS_MMAN_H
+# include <sys/mman.h>
+#endif
+#if !defined HAVE_MADVISE && defined HAVE_POSIX_MADVISE
+/* use posix_madvise family */
+# define madvise posix_madvise
+# define MADV_NORMAL POSIX_MADV_NORMAL
+# define MADV_RANDOM POSIX_MADV_RANDOM
+# define MADV_SEQUENTIAL POSIX_MADV_SEQUENTIAL
+# define MADV_WILLNEED POSIX_MADV_WILLNEED
+# define MADV_DONTNEED POSIX_MADV_DONTNEED
+#endif
+#if defined HAVE_MADVISE || defined HAVE_POSIX_MADVISE
+# define USE_MADVISE 1
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
 /* enable posix_fadvise on linux */
 #if defined(HAVE_POSIX_FADVISE) && defined(HAVE_FCNTL_H)
-#define _XOPEN_SOURCE 600
 #include <fcntl.h>
 #endif
 
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+#if HAVE_SYS_TIMES_H
+# include <sys/times.h>
+#endif
+
+#if HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#if (defined(__svr4__) && defined(__sun__))
+/* Solaris headers (pre 2.6) don't have a getrusage prototype.
+   Use this instead. */
+extern int getrusage(int, struct rusage *);
+#endif /* __svr4__ && __sun__ */
+#endif
+
+
 /* define strrchr, strchr and memcpy, memmove in terms of bsd funcs
    make sure you are NOT using bcopy, index or rindex in the code */
       
@@ -85,20 +162,58 @@ char *strchr (), *strrchr ();
 #  include <malloc/malloc.h>
 #endif
 
+#if HAVE_STDIO_H
+# include <stdio.h>
+#endif
+
+#if HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+
+#if HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#if HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if HAVE_SYS_NDIR_H
+#  include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+#  include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+#  include <ndir.h>
+# endif
+#endif
+
+#ifdef MUST_DISABLE_SIGFPE
+# include <signal.h>
+#endif
+
+#ifdef MUST_DISABLE_FPMASK
+# include <floatingpoint.h>
+#endif
+
+
 #ifdef HAVE_MATH_H
-#  include <math.h>
+# include <math.h>
 #endif
 
 #ifdef HAVE_FLOAT_H
-#  include <float.h>
+# include <float.h>
 #endif
 
 #ifdef HAVE_IEEEFP_H
-#  include <ieeefp.h>
+# include <ieeefp.h>
 #endif
 
 #ifdef HAVE_FP_CLASS_H
-#  include <fp_class.h>
+# include <fp_class.h>
 #endif
 
 /* for Solaris */
@@ -199,16 +314,16 @@ AC_PROG_CC
 AC_PROG_CPP
 AC_PROG_LIBTOOL
 
-dnl which flags does the compile support?
-if test "$GCC" = "yes"; then
-  for flag in -fno-strict-aliasing -Wall -std=gnu99 -pedantic -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline -W; do
-    oCFLAGS=$CFLAGS
+dnl which flags does the compiler support?
+if test "x$GCC" = "xyes"; then
+  for flag in -fno-strict-aliasing -Wall -std=c99 -pedantic -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline -W; do
+    oCFLAGS="$CFLAGS"
     CFLAGS="$CFLAGS $flag"
     cachename=rd_cv_gcc_flag_`echo $flag|sed 's/[[^A-Za-z]]/_/g'`
     AC_CACHE_CHECK([if gcc likes the $flag flag], $cachename,
        [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[return 0 ]])],[eval $cachename=yes],[eval $cachename=no])])
     if eval test \$$cachename = no; then
-         CFLAGS=$oCFLAGS
+         CFLAGS="$oCFLAGS"
     fi
   done
 fi
@@ -222,7 +337,7 @@ CONFIGURE_PART(Checking for Header Files)
 dnl Checks for header files.
 AC_HEADER_STDC
 AC_HEADER_DIRENT
-AC_CHECK_HEADERS(sys/stat.h sys/types.h fcntl.h locale.h fp_class.h malloc.h unistd.h ieeefp.h math.h sys/times.h sys/param.h sys/resource.h float.h)
+AC_CHECK_HEADERS(features.h sys/stat.h sys/types.h fcntl.h locale.h fp_class.h malloc.h unistd.h ieeefp.h math.h sys/times.h sys/param.h sys/resource.h signal.h float.h stdio.h stdlib.h errno.h string.h ctype.h)
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
@@ -247,50 +362,102 @@ AC_C_BIGENDIAN
 dnl for each function found we get a definition in config.h 
 dnl of the form HAVE_FUNCTION
 
-AC_CHECK_FUNCS(tzset mbstowcs opendir readdir chdir chroot getuid setlocale strerror strerror_r snprintf vsnprintf fpclass class fp_class isnan memmove strchr mktime getrusage gettimeofday posix_fadvise madvise)
+AC_CHECK_FUNCS(tzset mbstowcs opendir readdir chdir chroot getuid setlocale strerror strerror_r snprintf vsnprintf fpclass class fp_class isnan memmove strchr mktime getrusage gettimeofday posix_fadvise)
 
-AC_CHECK_DECLS(fdatasync, [], [], [#include <unistd.h>])
-AC_CHECK_DECLS(posix_fadvise, [], [], [#define _XOPEN_SOURCE 600
-#include <fcntl.h>])
-AC_CHECK_DECLS(madvise, [], [], [#include <sys/mman.h>])
+dnl Could use these to know if we need to provide a prototype
+dnl AC_CHECK_DECLS(fdatasync, [], [], [#include <unistd.h>])
+dnl AC_CHECK_DECLS(posix_fadvise, [], [], [#define _XOPEN_SOURCE 600
+dnl #include <fcntl.h>])
 
-if test "x$enable_mmap" = xyes; then
+dnl XXX: dunno about windows.. add AC_CHECK_FUNCS(munmap) there too?
+if test "x$enable_mmap" = "xyes"; then
   case "$host" in
-    *cygwin*)
-       # the normal mmap test does not work in cygwin
-       AC_CHECK_FUNCS(mmap)
-       if [ "x${ac_cv_func_mmap}" = xyes ]; then
-         ac_cv_func_mmap_fixed_mapped=yes
-       fi
-    ;;
-    *)
-       AC_FUNC_MMAP
-    ;;
+  *cygwin*)
+    # the normal mmap test does not work in cygwin
+    AC_CHECK_FUNCS(mmap)
+    if test "x$ac_cv_func_mmap" = "xyes"; then
+      ac_cv_func_mmap_fixed_mapped=yes
+    fi
+  ;;
+  *)
+    AC_CHECK_HEADERS(sys/mman.h)
+    AC_FUNC_MMAP
+    AC_CHECK_FUNCS(mmap munmap)
+    AC_CHECK_DECLS(madvise, [], [], [#if HAVE_SYS_MMAN_H
+                                    # include <sys/mman.h>
+                                    #endif])
+    if test "x$ac_cv_have_decl_madvise" = "xyes";
+    then
+      AC_CHECK_FUNCS(madvise)
+    else
+      AC_CHECK_FUNCS(posix_madvise)
+      if test "x$ac_cv_func_posix_madvise" != "xyes"; then
+        AC_MSG_WARN([madvise() nor posix_madvise() found.])
+      fi
+    fi
+  ;;
   esac
+  if test "x$ac_cv_func_mmap" != "xyes";
+  then
+    AC_MSG_ERROR([--enable-mmap requested but mmap() was not detected])
+  fi
 fi
 
 
 CONFIGURE_PART(IEEE Math Checks)
  
-dnl HP-UX 11.00 does not have finite but does have isfinite as a macro so we need
+
 dnl actual code to check if this works
 AC_CHECK_FUNCS(fpclassify, ,
   [AC_MSG_CHECKING(for fpclassify with <math.h>)
     AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <math.h>
 volatile int x;volatile float f; ]], [[x = fpclassify(f)]])],[AC_MSG_RESULT(yes)
       AC_DEFINE(HAVE_FPCLASSIFY)],[AC_MSG_RESULT(no)])])
-AC_CHECK_FUNCS(finite, ,
-  [AC_CHECK_FUNCS(isfinite, ,
-    [AC_MSG_CHECKING(for isfinite with <math.h>)
-    AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <math.h>
-volatile int x;volatile float f;  ]], [[x = isfinite(f)]])],[AC_MSG_RESULT(yes)
-      AC_DEFINE(HAVE_ISFINITE)],[AC_MSG_RESULT(no)])])])
+
 AC_CHECK_FUNCS(isinf, ,
   [AC_MSG_CHECKING(for isinf with <math.h>)
     AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <math.h>
 volatile int x;volatile float f;  ]], [[x = isinf(f)]])],[AC_MSG_RESULT(yes)
       AC_DEFINE(HAVE_ISINF)],[AC_MSG_RESULT(no)])])
 
+dnl finite is BSD, isfinite is C99, so prefer the latter
+AC_CACHE_CHECK([whether isfinite is broken],[have_broken_isfinite],[
+AC_TRY_RUN([
+#ifdef HAVE_MATH_H
+#include <math.h>
+#endif
+#ifdef HAVE_FLOAT_H
+#include <float.h>
+#endif
+int main ()
+{
+#ifdef isfinite
+#ifdef LDBL_MAX
+  if (!isfinite(LDBL_MAX)) return 1;
+#endif
+#ifdef DBL_MAX
+  if (!isfinite(DBL_MAX)) return 1;
+#endif
+#endif
+return 0;
+}],[
+have_broken_isfinite=no],have_broken_isfinite=yes,[
+case "${target}" in
+  hppa*-*-hpux*) have_broken_isfinite=yes ;;
+  *) have_broken_isfinite=no ;;
+esac])
+])
+if test "x$have_broken_isfinite" = "xno"; then
+  AC_DEFINE(HAVE_ISFINITE)
+else
+AC_CHECK_FUNCS(finite,[],
+  [AC_CHECK_FUNCS(isfinite,[],
+      [AC_MSG_CHECKING(for isfinite with <math.h>)
+       AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <math.h>
+volatile int x;volatile float f;  ]],[[x = isfinite(f)]])],[AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_ISFINITE)],[AC_MSG_RESULT(no)])])])
+fi
+
 AC_FULL_IEEE
 
 CONFIGURE_PART(Resolve Portability Issues)
index 5ed0558..6fd4364 100644 (file)
@@ -30,22 +30,22 @@ RRD_C_FILES =               \
        hash_32.c       \
        pngsize.c       \
        rrd_create.c    \
-       rrd_dump.c      \
-       rrd_fetch.c     \
        rrd_graph.c     \
        rrd_graph_helper.c      \
+       rrd_version.c   \
        rrd_last.c      \
        rrd_lastupdate.c        \
        rrd_first.c     \
-       rrd_resize.c    \
        rrd_restore.c   \
-       rrd_tune.c      \
-       rrd_version.c   \
        rrd_xport.c     \
         art_rgba_svp.c \
        rrd_gfx.c \
        rrd_afm.c rrd_afm_data.c \
-       rrd_tool.c
+       rrd_dump.c      \
+       rrd_fetch.c     \
+       rrd_tool.c      \
+       rrd_resize.c \
+       rrd_tune.c
 
 noinst_HEADERS = \
         art_rgba_svp.h \
index 3873033..ce712d5 100644 (file)
--- a/src/rrd.h
+++ b/src/rrd.h
@@ -52,6 +52,8 @@ extern "C" {
 #ifndef _RRDLIB_H
 #define _RRDLIB_H
 
+#include <sys/types.h> /* for off_t */
+#include <unistd.h> /* for off_t */
 #include <time.h>
 #include <stdio.h> /* for FILE */
 
@@ -60,6 +62,15 @@ typedef double       rrd_value_t;         /* the data storage type is
                                            * double */
 /* END rrd_format.h */
 
+/* information about an rrd file */
+typedef struct rrd_file_t {
+       int   fd;         /* file descriptor if this rrd file */
+       char* file_start; /* start address of an open rrd file */
+       off_t header_len; /* length of the header of this rrd file */
+       off_t file_len;   /* total size of the rrd file */
+       off_t pos;        /* current pos in file */
+} rrd_file_t;
+
 /* main function blocks */
 int    rrd_create(int, char **);
 int    rrd_update(int, char **);
@@ -143,7 +154,7 @@ void   rrd_free_context (struct rrd_context *buf);
 /* int    rrd_test_error_r (struct rrd_context *); */
 /* char  *rrd_get_error_r  (struct rrd_context *); */
 
-int  LockRRD(FILE *);
+int  LockRRD(int in_file);
 
 #endif /* _RRDLIB_H */
 
index c8cc7ee..5d76896 100644 (file)
@@ -77,13 +77,14 @@ rrd_dump_r(const char *filename, char *outname)
     time_t       now;
     char         somestring[255];
     rrd_value_t  my_cdp;
-    long         rra_base, rra_start, rra_next;
-    FILE        *in_file;
+    off_t         rra_base, rra_start, rra_next;
+    rrd_file_t  *rrd_file;
                FILE                            *out_file;
     rrd_t        rrd;
     rrd_value_t  value;
     struct tm    tm;
-    if(rrd_open(filename, &in_file,&rrd, RRD_READONLY)==-1){
+    rrd_file = rrd_open(filename, &rrd, RRD_READONLY);
+    if (rrd_file == NULL) {
        rrd_free(&rrd);
        return(-1);
     }
@@ -151,7 +152,7 @@ rrd_dump_r(const char *filename, char *outname)
 
     fputs("<!-- Round Robin Archives -->", out_file);
 
-    rra_base=ftell(in_file);    
+    rra_base = rrd_file->header_len;
     rra_next = rra_base;
 
     for(i=0;i<rrd.stat_head->rra_cnt;i++){
@@ -314,7 +315,7 @@ rrd_dump_r(const char *filename, char *outname)
        fprintf(out_file, "\t\t</cdp_prep>\n");
 
        fprintf(out_file, "\t\t<database>\n");
-       fseek(in_file,(rra_start
+       rrd_seek(rrd_file,(rra_start
                       +(rrd.rra_ptr[i].cur_row+1)
                       * rrd.stat_head->ds_cnt
                       * sizeof(rrd_value_t)),SEEK_SET);
@@ -323,7 +324,7 @@ rrd_dump_r(const char *filename, char *outname)
        for(ix=0;ix<rrd.rra_def[i].row_cnt;ix++){           
            ii++;
            if (ii>=rrd.rra_def[i].row_cnt) {
-               fseek(in_file,rra_start,SEEK_SET);
+               rrd_seek(rrd_file,rra_start,SEEK_SET);
                ii=0; /* wrap if max row cnt is reached */
            }
            now = (rrd.live_head->last_up 
@@ -339,8 +340,8 @@ rrd_dump_r(const char *filename, char *outname)
 # error "Need strftime"
 #endif
            fprintf(out_file, "\t\t\t<!-- %s / %d --> <row>",somestring,(int)now);
-           for(iii=0;iii<rrd.stat_head->ds_cnt;iii++){                  
-               fread(&my_cdp,sizeof(rrd_value_t),1,in_file);           
+           for(iii=0;iii<rrd.stat_head->ds_cnt;iii++){
+               rrd_read(rrd_file, &my_cdp,sizeof(rrd_value_t)*1);
                if (isnan(my_cdp)){
                  fprintf(out_file, "<v> NaN </v>");
                } else {
@@ -350,11 +351,11 @@ rrd_dump_r(const char *filename, char *outname)
            fprintf(out_file, "</row>\n");
        }
        fprintf(out_file, "\t\t</database>\n\t</rra>\n");
-       
+
     }
     fprintf(out_file, "</rrd>\n");
     rrd_free(&rrd);
-    fclose(in_file);
+    close(rrd_file->fd);
     if (out_file != stdout)
     {
       fclose(out_file);
@@ -362,6 +363,3 @@ rrd_dump_r(const char *filename, char *outname)
     return(0);
 }
 
-
-
-
index 1b85edb..4b0f2b5 100644 (file)
@@ -194,7 +194,6 @@ rrd_fetch_fn(
     rrd_value_t    **data)     /* two dimensional array containing the data */
 {
     long           i,ii;
-    FILE           *in_file;
     time_t         cal_start,cal_end, rra_start_time,rra_end_time;
     long  best_full_rra=0, best_part_rra=0, chosen_rra=0, rra_pointer=0;
     long  best_full_step_diff=0, best_part_step_diff=0, tmp_step_diff=0, tmp_match=0, best_match=0;
@@ -203,9 +202,12 @@ rrd_fetch_fn(
     int            first_full = 1;
     int            first_part = 1;
     rrd_t     rrd;
+    rrd_file_t     *rrd_file;
     rrd_value_t    *data_ptr;
     unsigned long  rows;
+#ifdef HAVE_POSIX_FADVISE
     long  rrd_head_size;
+#endif
 
 #ifdef DEBUG
 fprintf(stderr,"Entered rrd_fetch_fn() searching for the best match\n");
@@ -213,17 +215,19 @@ fprintf(stderr,"Looking for: start %10lu end %10lu step %5lu\n",
                                                *start,*end,*step);
 #endif
 
-    if(rrd_open(filename,&in_file,&rrd, RRD_READONLY)==-1)
+    rrd_file = rrd_open(filename,&rrd, RRD_READONLY);
+    if (rrd_file == NULL)
        return(-1);
 
-    rrd_head_size = ftell(in_file);
-    
+#ifdef HAVE_POSIX_FADVISE
+    rrd_head_size = rrd_file->header_len;
+#endif
     /* when was the really last update of this file ? */
 
     if (((*ds_namv) = (char **) malloc(rrd.stat_head->ds_cnt * sizeof(char*)))==NULL){
        rrd_set_error("malloc fetch ds_namv array");
        rrd_free(&rrd);
-       fclose(in_file);
+       close(rrd_file->fd);
        return(-1);
     }
     
@@ -232,7 +236,7 @@ fprintf(stderr,"Looking for: start %10lu end %10lu step %5lu\n",
            rrd_set_error("malloc fetch ds_namv entry");
            rrd_free(&rrd);
            free(*ds_namv);
-           fclose(in_file);
+           close(rrd_file->fd);
            return(-1);
        }
        strncpy((*ds_namv)[i],rrd.ds_def[i].ds_nam,DS_NAM_SIZE-1);
@@ -312,7 +316,7 @@ fprintf(stderr,"partial match, not best\n");
     else {
        rrd_set_error("the RRD does not contain an RRA matching the chosen CF");
        rrd_free(&rrd);
-       fclose(in_file);
+       close(rrd_file->fd);
        return(-1);
     }
        
@@ -340,14 +344,14 @@ fprintf(stderr,"partial match, not best\n");
              free((*ds_namv)[i]);
        free(*ds_namv);
        rrd_free(&rrd);
-       fclose(in_file);
+       close(rrd_file->fd);
        return(-1);
     }
     
     data_ptr=(*data);
     
     /* find base address of rra */
-    rra_base=ftell(in_file);
+    rra_base = rrd_file->header_len;
     for(i=0;i<chosen_rra;i++)
        rra_base += ( *ds_cnt
                      * rrd.rra_def[i].row_cnt
@@ -373,7 +377,7 @@ fprintf(stderr,"partial match, not best\n");
     else 
        rra_pointer = rrd.rra_ptr[chosen_rra].cur_row+1+start_offset;
     
-    if(fseek(in_file,(rra_base 
+    if(rrd_seek(rrd_file,(rra_base 
                   + (rra_pointer
                      * *ds_cnt
                      * sizeof(rrd_value_t))),SEEK_SET) != 0){
@@ -384,7 +388,7 @@ fprintf(stderr,"partial match, not best\n");
        rrd_free(&rrd);
        free(*data);
        *data = NULL;
-       fclose(in_file);
+       close(rrd_file->fd);
        return(-1);
 
     }
@@ -425,7 +429,7 @@ fprintf(stderr,"partial match, not best\n");
             * be wrapped*/
            if (rra_pointer >= (signed)rrd.rra_def[chosen_rra].row_cnt) {
                rra_pointer -= rrd.rra_def[chosen_rra].row_cnt;
-               if(fseek(in_file,(rra_base+rra_pointer
+               if(rrd_seek(rrd_file,(rra_base+rra_pointer
                               * *ds_cnt
                               * sizeof(rrd_value_t)),SEEK_SET) != 0){
                    rrd_set_error("wrap seek in RRA did fail");
@@ -435,17 +439,17 @@ fprintf(stderr,"partial match, not best\n");
                    rrd_free(&rrd);
                    free(*data);
                    *data = NULL;
-                   fclose(in_file);
+                   close(rrd_file->fd);
                    return(-1);
                }
 #ifdef DEBUG
                fprintf(stderr,"wrap seek ...\n");
-#endif     
+#endif
            }
-           
-           if(fread(data_ptr,
-                    sizeof(rrd_value_t),
-                    *ds_cnt,in_file) != rrd.stat_head->ds_cnt){
+
+           if(rrd_read(rrd_file,data_ptr,
+                    sizeof(rrd_value_t)* (*ds_cnt))
+                   != (ssize_t)(sizeof(rrd_value_t)*(*ds_cnt)*rrd.stat_head->ds_cnt)){
                rrd_set_error("fetching cdp from rra");
                for (ii=0;(unsigned)ii<*ds_cnt;ii++)
                    free((*ds_namv)[ii]);
@@ -453,15 +457,15 @@ fprintf(stderr,"partial match, not best\n");
                rrd_free(&rrd);
                free(*data);
                *data = NULL;
-               fclose(in_file);
+               close(rrd_file->fd);
                return(-1);
            }
 #ifdef HAVE_POSIX_FADVISE
        /* don't pollute the buffer cache with data read from the file. We do this while reading to 
           keep damage minimal */
-       if (0 != posix_fadvise(fileno(in_file), rrd_head_size, 0, POSIX_FADV_DONTNEED)) {
+       if (0 != posix_fadvise(rrd_file->fd, rrd_head_size, 0, POSIX_FADV_DONTNEED)) {
            rrd_set_error("setting POSIX_FADV_DONTNEED on '%s': %s",filename, rrd_strerror(errno));
-           fclose(in_file);
+           close(rrd_file->fd);
            return(-1);
        } 
 #endif
@@ -482,12 +486,12 @@ fprintf(stderr,"partial match, not best\n");
     rrd_free(&rrd);
 #ifdef HAVE_POSIX_FADVISE
     /* and just to be sure we drop everything except the header at the end */
-    if (0 != posix_fadvise(fileno(in_file), rrd_head_size, 0, POSIX_FADV_DONTNEED)) {
+    if (0 != posix_fadvise(rrd_file->fd, rrd_head_size, 0, POSIX_FADV_DONTNEED)) {
            rrd_set_error("setting POSIX_FADV_DONTNEED on '%s': %s",filename, rrd_strerror(errno));
-           fclose(in_file);
+           close(rrd_file->fd);
            return(-1);
     } 
 #endif     
-    fclose(in_file);
+    close(rrd_file->fd);
     return(0);
 }
index f4e8d40..3782d4a 100644 (file)
@@ -55,13 +55,14 @@ rrd_first(int argc, char **argv)
 time_t
 rrd_first_r(const char *filename, const int rraindex)
 {
-    long rra_start,
+    off_t rra_start,
          timer;
     time_t then;
-    FILE *in_file;
     rrd_t rrd;
+    rrd_file_t *rrd_file;
 
-    if(rrd_open(filename,&in_file,&rrd, RRD_READONLY)==-1){
+    rrd_file = rrd_open(filename,&rrd, RRD_READONLY);
+    if (rrd_file == NULL) {
         rrd_set_error("could not open RRD");
         return(-1);
     }
@@ -69,12 +70,12 @@ rrd_first_r(const char *filename, const int rraindex)
     if((rraindex < 0) || (rraindex >= (int)rrd.stat_head->rra_cnt)) {
         rrd_set_error("invalid rraindex number");
         rrd_free(&rrd);
-        fclose(in_file);
+        close(rrd_file->fd);
         return(-1);
     }
 
-    rra_start = ftell(in_file);    
-    fseek(in_file,
+    rra_start = rrd_file->header_len;
+    rrd_seek(rrd_file,
           (rra_start +
            (rrd.rra_ptr[rraindex].cur_row+1) *
            rrd.stat_head->ds_cnt *
@@ -82,7 +83,7 @@ rrd_first_r(const char *filename, const int rraindex)
           SEEK_SET);
     timer = - (rrd.rra_def[rraindex].row_cnt-1);
     if (rrd.rra_ptr[rraindex].cur_row + 1 > rrd.rra_def[rraindex].row_cnt) {
-      fseek(in_file,rra_start,SEEK_SET);
+      rrd_seek(rrd_file,rra_start,SEEK_SET);
     }
     then = (rrd.live_head->last_up -
             rrd.live_head->last_up %
@@ -91,10 +92,8 @@ rrd_first_r(const char *filename, const int rraindex)
             rrd.rra_def[rraindex].pdp_cnt*rrd.stat_head->pdp_step);
 
     rrd_free(&rrd);
-    fclose(in_file);
+    close(rrd_file->fd);
+    rrd_close(rrd_file);
     return(then);
 }
 
-
-
-
index dccde50..9218f59 100644 (file)
@@ -108,7 +108,7 @@ update_hwpredict(rrd_t *rrd, unsigned long cdp_idx, unsigned long rra_idx,
 
 int
 lookup_seasonal(rrd_t *rrd, unsigned long rra_idx, unsigned long rra_start,
-                               FILE *rrd_file, unsigned long offset, rrd_value_t **seasonal_coef)
+                               rrd_file_t* rrd_file, unsigned long offset, rrd_value_t **seasonal_coef)
 {
    unsigned long pos_tmp;
    /* rra_ptr[].cur_row points to the rra row to be written; this function
@@ -131,10 +131,10 @@ lookup_seasonal(rrd_t *rrd, unsigned long rra_idx, unsigned long rra_start,
          return -1;
    }
 
-   if (!fseek(rrd_file,pos_tmp,SEEK_SET))
+   if (!rrd_seek(rrd_file,pos_tmp,SEEK_SET))
    {
-      if (fread(*seasonal_coef,sizeof(rrd_value_t),rrd->stat_head->ds_cnt,rrd_file)
-                 == rrd -> stat_head -> ds_cnt)
+      if (rrd_read(rrd_file,*seasonal_coef,sizeof(rrd_value_t)*rrd->stat_head->ds_cnt)
+                 == (ssize_t)(sizeof(rrd_value_t)*rrd->stat_head->ds_cnt))
          {
                 /* success! */
          /* we can safely ignore the rule requiring a seek operation between read
@@ -511,7 +511,7 @@ erase_violations(rrd_t *rrd, unsigned long cdp_idx, unsigned long rra_idx)
  * length = 5% of the period. */
 int
 apply_smoother(rrd_t *rrd, unsigned long rra_idx, unsigned long rra_start,
-               FILE *rrd_file)
+               rrd_file_t *rrd_file)
 {
    unsigned long i, j, k;
    unsigned long totalbytes;
@@ -536,21 +536,23 @@ apply_smoother(rrd_t *rrd, unsigned long rra_idx, unsigned long rra_start,
    }
 
    /* rra_start is at the beginning of this rra */
-   if (fseek(rrd_file,rra_start,SEEK_SET))
+   if (rrd_seek(rrd_file,rra_start,SEEK_SET))
    {
          rrd_set_error("seek to rra %d failed", rra_start);
          free(rrd_values);
          return -1;
    }
-   fflush(rrd_file);
+   rrd_flush(rrd_file);
    /* could read all data in a single block, but we need to
     * check for NA values */
    for (i = 0; i < row_count; ++i)
    {
          for (j = 0; j < row_length; ++j)
          {
-                fread(&(rrd_values[i*row_length + j]),sizeof(rrd_value_t),1,rrd_file);
-                /* should check fread for errors... */
+                if (rrd_read(rrd_file, &(rrd_values[i*row_length + j]),sizeof(rrd_value_t)*1)
+                        != (ssize_t)(sizeof(rrd_value_t)*1)) {
+                        rrd_set_error("reading value failed: %s", rrd_strerror(errno));
+                }
                 if (isnan(rrd_values[i*row_length + j])) {
                        /* can't apply smoothing, still uninitialized values */
 #ifdef DEBUG
@@ -627,8 +629,8 @@ apply_smoother(rrd_t *rrd, unsigned long rra_idx, unsigned long rra_start,
         (rrd->cdp_prep[offset]).scratch[CDP_hw_intercept].u_val += baseline[j];
    }
    /* flush cdp to disk */
-   fflush(rrd_file);
-   if (fseek(rrd_file,sizeof(stat_head_t) + 
+   rrd_flush(rrd_file);
+   if (rrd_seek(rrd_file,sizeof(stat_head_t) + 
          rrd->stat_head->ds_cnt * sizeof(ds_def_t) +
          rrd->stat_head->rra_cnt * sizeof(rra_def_t) + 
          sizeof(live_head_t) +
@@ -638,11 +640,11 @@ apply_smoother(rrd_t *rrd, unsigned long rra_idx, unsigned long rra_start,
          free(rrd_values);
          return -1;
    }
-   if (fwrite( rrd -> cdp_prep,
-         sizeof(cdp_prep_t),
-         (rrd->stat_head->rra_cnt) * rrd->stat_head->ds_cnt, rrd_file
-         != (rrd->stat_head->rra_cnt) * (rrd->stat_head->ds_cnt) )
-   { 
+   if (rrd_write(rrd_file, rrd -> cdp_prep,
+         sizeof(cdp_prep_t)*
+                 (rrd->stat_head->rra_cnt) * rrd->stat_head->ds_cnt
+         != (ssize_t)(sizeof(cdp_prep_t)*(rrd->stat_head->rra_cnt) * (rrd->stat_head->ds_cnt)))
+   {
          rrd_set_error("apply_smoother: cdp_prep write failed");
          free(rrd_values);
          return -1;
@@ -650,23 +652,23 @@ apply_smoother(rrd_t *rrd, unsigned long rra_idx, unsigned long rra_start,
    } /* endif CF_SEASONAL */ 
 
    /* flush updated values to disk */
-   fflush(rrd_file);
-   if (fseek(rrd_file,rra_start,SEEK_SET))
+   rrd_flush(rrd_file);
+   if (rrd_seek(rrd_file,rra_start,SEEK_SET))
    {
          rrd_set_error("apply_smoother: seek to pos %d failed", rra_start);
          free(rrd_values);
          return -1;
    }
    /* write as a single block */
-   if (fwrite(rrd_values,sizeof(rrd_value_t),row_length*row_count,rrd_file)
-         != row_length*row_count)
+   if (rrd_write(rrd_file,rrd_values,sizeof(rrd_value_t)*row_length*row_count)
+         != (ssize_t)(sizeof(rrd_value_t)*row_length*row_count))
    {
          rrd_set_error("apply_smoother: write failed to %lu",rra_start);
          free(rrd_values);
          return -1;
    }
 
-   fflush(rrd_file);
+   rrd_flush(rrd_file);
    free(rrd_values);
    free(baseline);
    return 0;
@@ -675,7 +677,7 @@ apply_smoother(rrd_t *rrd, unsigned long rra_idx, unsigned long rra_start,
 /* Reset aberrant behavior model coefficients, including intercept, slope,
  * seasonal, and seasonal deviation for the specified data source. */
 void
-reset_aberrant_coefficients(rrd_t *rrd, FILE *rrd_file, unsigned long ds_idx)
+reset_aberrant_coefficients(rrd_t *rrd, rrd_file_t *rrd_file, unsigned long ds_idx)
 {
    unsigned long cdp_idx, rra_idx, i;
    unsigned long cdp_start, rra_start;
@@ -709,19 +711,19 @@ reset_aberrant_coefficients(rrd_t *rrd, FILE *rrd_file, unsigned long ds_idx)
                rrd->cdp_prep[cdp_idx].scratch[CDP_hw_seasonal].u_val = DNAN;
                rrd->cdp_prep[cdp_idx].scratch[CDP_hw_last_seasonal].u_val = DNAN;
                        /* move to first entry of data source for this rra */
-                       fseek(rrd_file,rra_start + ds_idx * sizeof(rrd_value_t),SEEK_SET);
+                       rrd_seek(rrd_file,rra_start + ds_idx * sizeof(rrd_value_t),SEEK_SET);
                        /* entries for the same data source are not contiguous, 
                         * temporal entries are contiguous */
                for (i = 0; i < rrd->rra_def[rra_idx].row_cnt; ++i)
                        {
-                          if (fwrite(&nan_buffer,sizeof(rrd_value_t),1,rrd_file) != 1)
+                          if (rrd_write(rrd_file,&nan_buffer,sizeof(rrd_value_t)*1) != sizeof(rrd_value_t)*1)
                           {
                   rrd_set_error(
                                  "reset_aberrant_coefficients: write failed data source %lu rra %s",
                                  ds_idx,rrd->rra_def[rra_idx].cf_nam);
                                  return;
                           } 
-                          fseek(rrd_file,(rrd->stat_head->ds_cnt - 1) * 
+                          rrd_seek(rrd_file,(rrd->stat_head->ds_cnt - 1) * 
                                  sizeof(rrd_value_t),SEEK_CUR);
                        }
                        break;
@@ -735,14 +737,14 @@ reset_aberrant_coefficients(rrd_t *rrd, FILE *rrd_file, unsigned long ds_idx)
          rra_start += rrd->rra_def[rra_idx].row_cnt * rrd->stat_head->ds_cnt * 
                 sizeof(rrd_value_t);
    }
-   fseek(rrd_file,cdp_start,SEEK_SET);
-   if (fwrite( rrd -> cdp_prep,
-         sizeof(cdp_prep_t),
-         (rrd->stat_head->rra_cnt) * rrd->stat_head->ds_cnt, rrd_file
-         != (rrd->stat_head->rra_cnt) * (rrd->stat_head->ds_cnt) )
+   rrd_seek(rrd_file,cdp_start,SEEK_SET);
+   if (rrd_write(rrd_file,rrd->cdp_prep,
+         sizeof(cdp_prep_t)*
+         (rrd->stat_head->rra_cnt) * rrd->stat_head->ds_cnt) 
+         != (ssize_t)(sizeof(cdp_prep_t)*(rrd->stat_head->rra_cnt) * (rrd->stat_head->ds_cnt)))
    {
          rrd_set_error("reset_aberrant_coefficients: cdp_prep write failed");
-         return;
+         return;/*XXX: delme */
    }
 }
 
index 89220b4..bd5502c 100644 (file)
@@ -11,11 +11,11 @@ int update_aberrant_CF(rrd_t *rrd, rrd_value_t pdp_val, enum cf_en current_cf,
 int create_hw_contingent_rras(rrd_t *rrd, unsigned short period, 
    unsigned long hashed_name);
 int lookup_seasonal(rrd_t *rrd, unsigned long rra_idx, unsigned long rra_start,
-   FILE *rrd_file, unsigned long offset, rrd_value_t **seasonal_coef);
+   rrd_file_t* rrd_file, unsigned long offset, rrd_value_t **seasonal_coef);
 void erase_violations(rrd_t *rrd, unsigned long cdp_idx, unsigned long rra_idx);
 int apply_smoother(rrd_t *rrd, unsigned long rra_idx, unsigned long rra_start,
-   FILE *rrd_file);
-void reset_aberrant_coefficients(rrd_t *rrd, FILE *rrd_file, unsigned long ds_idx);
+   rrd_file_t *rrd_file);
+void reset_aberrant_coefficients(rrd_t *rrd, rrd_file_t *rrd_file, unsigned long ds_idx);
 void init_hwpredict_cdp(cdp_prep_t *);
 void init_seasonal_cdp(cdp_prep_t *);
 #define BURNIN_CYCLES 3
index d5ccbc5..2160962 100644 (file)
@@ -83,17 +83,18 @@ rrd_info(int argc, char **argv) {
 info_t *
 rrd_info_r(char *filename) {   
     unsigned int i,ii=0;
-    FILE         *in_file;
     rrd_t        rrd;
     info_t       *data,*cd;
     infoval      info;
+    rrd_file_t*  rrd_file;
        enum cf_en   current_cf;
        enum dst_en  current_ds;
 
-    if(rrd_open(filename,&in_file,&rrd, RRD_READONLY)==-1){
+    rrd_file = rrd_open(filename,&rrd, RRD_READONLY);
+    if (rrd_file == NULL) {
        return(NULL);
     }
-    fclose(in_file);
+    close(rrd_file->fd);
 
     info.u_str=filename;
     cd=info_push(NULL,sprintf_alloc("filename"),    RD_I_STR, info);
@@ -233,6 +234,7 @@ rrd_info_r(char *filename) {
     }
        }
        rrd_free(&rrd);
+    rrd_close(rrd_file);
     return(data);
 
 }
index c4b4b26..0f9ab9b 100644 (file)
@@ -23,17 +23,18 @@ rrd_last(int argc, char **argv)
 time_t
 rrd_last_r(const char *filename)
 {
-    FILE       *in_file;
     time_t       lastup;
+    rrd_file_t*        rrd_file;
 
     rrd_t       rrd;
 
-    if(rrd_open(filename, &in_file, &rrd, RRD_READONLY)==-1){
+    rrd_file = rrd_open(filename, &rrd, RRD_READONLY);
+    if (rrd_file == NULL)
         return(-1);
-    }
+
     lastup = rrd.live_head->last_up;
     rrd_free(&rrd);
-    fclose(in_file);
+    rrd_close(rrd_file);
     return(lastup);
 }
 
index 169c49d..abba277 100644 (file)
@@ -13,8 +13,8 @@ rrd_lastupdate(int argc, char **argv, time_t *last_update,
                  unsigned long *ds_cnt, char ***ds_namv, char ***last_ds) {
     unsigned long i=0;
     char        *filename;
-    FILE         *in_file;
     rrd_t        rrd;
+    rrd_file_t*        rrd_file;
 
     if(argc < 2){
         rrd_set_error("please specify an rrd");
@@ -22,10 +22,9 @@ rrd_lastupdate(int argc, char **argv, time_t *last_update,
     }
     filename = argv[1];
 
-    if(rrd_open(filename,&in_file,&rrd, RRD_READONLY)==-1){
+    rrd_file = rrd_open(filename, &rrd, RRD_READONLY);
+    if (rrd_file == NULL)
        return(-1);
-    }
-    fclose(in_file);
 
     *last_update=rrd.live_head->last_up;
     *ds_cnt = rrd.stat_head->ds_cnt;
@@ -50,5 +49,6 @@ rrd_lastupdate(int argc, char **argv, time_t *last_update,
     }
 
     rrd_free(&rrd);
+    rrd_close(rrd_file);
     return(0); 
 }
index 3740750..c29741c 100644 (file)
  *****************************************************************************/
 
 #include "rrd_tool.h"
+#include "unused.h"
 #define MEMBLK 8192
 
 /* open a database file, return its header and a open filehandle */
 /* positioned to the first cdp in the first rra */
 
-int
-rrd_open(const char *file_name, FILE **in_file, rrd_t *rrd, int rdwr)    
+rrd_file_t*
+rrd_open(const char * const file_name, rrd_t *rrd, unsigned rdwr)
 {
+       int flags = 0;
+       mode_t mode = S_IRUSR;
+       int version, prot = PROT_READ;
+       off_t offset = 0;
+       char *data;
+       struct stat statb;
+       rrd_file_t *rrd_file = malloc(sizeof(rrd_file_t));
+       if (rrd_file == NULL) {
+               rrd_set_error("allocating rrd_file descriptor for '%s'",
+                       file_name);
+               return NULL;
+       }
+       memset(rrd_file, 0, sizeof(rrd_file_t));
+       rrd_init(rrd);
+       if (rdwr == RRD_READWRITE) {
+               mode |= S_IWUSR;
+               prot |= PROT_WRITE;
+       } else if (rdwr == RRD_CREAT) {
+               mode |= S_IWUSR;
+               prot |= PROT_WRITE;
+               flags |= (O_CREAT|O_TRUNC);
+       }
+#ifdef O_NONBLOCK
+       flags |= O_NONBLOCK;
+#endif
 
-    
-    char *mode = NULL;
-    int version;
-    
-    rrd_init(rrd);
-    if (rdwr == RRD_READONLY) {
-        mode = "rb";
-    } else {
-        mode = "rb+";
-    }
-    
-    if (((*in_file) = fopen(file_name,mode)) == NULL ){
-        rrd_set_error("opening '%s': %s",file_name, rrd_strerror(errno));
-        return (-1);
-    }
+       if ((rrd_file->fd = open(file_name, flags, mode)) < 0 ){
+               rrd_set_error("opening '%s': %s",file_name, rrd_strerror(errno));
+               return NULL;
+       }
+
+       /* ???: length = lseek(rrd_file->fd, 0, SEEK_END); */
+       /* ??? locking the whole area of the file may overdo it a bit, does it? */
+       if ((fstat(rrd_file->fd, &statb)) < 0) {
+               rrd_set_error("fstat '%s': %s",file_name, rrd_strerror(errno));
+               goto out_close;
+       }
+       rrd_file->file_len = statb.st_size;
 
 #ifdef HAVE_POSIX_FADVISE
     /* In general we need no read-ahead when dealing with rrd_files.
        When we stop reading, it is highly unlikely that we start up again.
        In this manner we actually save time and diskaccess (and buffer cache).
-       Thanks to Dave Plonka for the Idea of using POSIX_FADV_RANDOM here. */       
-    if (0 != posix_fadvise(fileno(*in_file), 0, 0, POSIX_FADV_RANDOM)) {
+       Thanks to Dave Plonka for the Idea of using POSIX_FADV_RANDOM here. */
+    if (0 != posix_fadvise(rrd_file->fd, 0, 0, POSIX_FADV_RANDOM)) {
         rrd_set_error("setting POSIX_FADV_RANDOM on '%s': %s",file_name, rrd_strerror(errno));
-        fclose(*in_file);
-        return(-1);
-     }    
+        goto out_close;
+     }
 #endif
 
 /*
         if (rdwr == RRD_READWRITE)
         {
-           if (setvbuf((*in_file),NULL,_IONBF,2)) {
+           if (setvbuf((rrd_file->fd),NULL,_IONBF,2)) {
                   rrd_set_error("failed to disable the stream buffer\n");
                   return (-1);
            }
         }
 */
-    
-#define MYFREAD(MYVAR,MYVART,MYCNT) \
-    if ((MYVAR = malloc(sizeof(MYVART) * MYCNT)) == NULL) {\
-        rrd_set_error("" #MYVAR " malloc"); \
-        fclose(*in_file); \
-        return (-1); } \
-    fread(MYVAR,sizeof(MYVART),MYCNT, *in_file); 
-
-
-    MYFREAD(rrd->stat_head, stat_head_t,  1)
-    /* lets see if the first read worked */
-    if (ferror( *in_file ) || feof(*in_file)) {
-        rrd_set_error("reading the cookie off %s faild",file_name);
-        fclose(*in_file);
-        return(-1);
-    }        
+       data = mmap(0, rrd_file->file_len, prot, MAP_SHARED,
+               rrd_file->fd, offset);
+
+       /* lets see if the first read worked */
+       if (data == MAP_FAILED) {
+               rrd_set_error("error mmaping file '%s'",file_name);
+               goto out_close;
+       }
+       rrd_file->file_start = data;
+#ifdef USE_MADVISE
+       if (rrd == NULL) { /*XXX: currently not used! */
+               /* We will read everything in a moment (copying) */
+               madvise(data, rrd_file->file_len, MADV_WILLNEED|MADV_SEQUENTIAL);
+               goto out_done;
+       }
+       /* We do not need to read anything in for the moment */
+       madvise(data, rrd_file->file_len, MADV_DONTNEED);
+#endif
+
+#ifdef USE_MADVISE
+       /* the stat_head will be needed soonish, so hint accordingly */
+       madvise(data+offset, sizeof(stat_head_t), MADV_WILLNEED);
+#endif
+
+       rrd->stat_head = (stat_head_t*)(data + offset);
+       offset += sizeof(stat_head_t);
 
         /* lets do some test if we are on track ... */
-        if (strncmp(rrd->stat_head->cookie,RRD_COOKIE,4) != 0){
-            rrd_set_error("'%s' is not an RRD file",file_name);
-            free(rrd->stat_head);
-            rrd->stat_head = NULL; 
-            fclose(*in_file);
-            return(-1);}
-
-        if (rrd->stat_head->float_cookie != FLOAT_COOKIE){
-            rrd_set_error("This RRD was created on other architecture");
-            free(rrd->stat_head);
-            rrd->stat_head = NULL; 
-            fclose(*in_file);
-            return(-1);}
-
-    version = atoi(rrd->stat_head->version);
-
-        if (version > atoi(RRD_VERSION)){
+       if (memcmp(rrd->stat_head->cookie,RRD_COOKIE,sizeof(RRD_COOKIE)) != 0) {
+               rrd_set_error("'%s' is not an RRD file",file_name);
+               goto out_nullify_head;
+       }
+
+       if (rrd->stat_head->float_cookie != FLOAT_COOKIE){
+               rrd_set_error("This RRD was created on other architecture");
+               goto out_nullify_head;
+       }
+
+       version = atoi(rrd->stat_head->version);
+
+       if (version > atoi(RRD_VERSION)) {
             rrd_set_error("can't handle RRD file version %s",
                         rrd->stat_head->version);
-            free(rrd->stat_head);
-            rrd->stat_head = NULL; 
-            fclose(*in_file);
-            return(-1);}
+            goto out_nullify_head;
+       }
 
+#ifdef USE_MADVISE
+       /* the ds_def will be needed soonish, so hint accordingly */
+       madvise(data+offset, sizeof(ds_def_t)*rrd->stat_head->ds_cnt, MADV_WILLNEED);
+#endif
+       rrd->ds_def = (ds_def_t*)(data + offset);
+       offset += sizeof(ds_def_t) * rrd->stat_head->ds_cnt;
+
+#ifdef USE_MADVISE
+       /* the rra_def will be needed soonish, so hint accordingly */
+       madvise(data+offset, sizeof(rra_def_t)*rrd->stat_head->rra_cnt, MADV_WILLNEED);
+#endif
+       rrd->rra_def = (rra_def_t*)(data + offset);
+       offset += sizeof(rra_def_t) * rrd->stat_head->rra_cnt;
 
-    MYFREAD(rrd->ds_def,    ds_def_t,     rrd->stat_head->ds_cnt)
-    MYFREAD(rrd->rra_def,   rra_def_t,    rrd->stat_head->rra_cnt)
     /* handle different format for the live_head */
-    if(version < 3) {
+       if (version < 3) {
             rrd->live_head = (live_head_t *)malloc(sizeof(live_head_t));
-            if(rrd->live_head == NULL) {
+            if (rrd->live_head == NULL) {
                 rrd_set_error("live_head_t malloc");
-                fclose(*in_file); 
-                return (-1);
+                goto out_close;
             }
-                fread(&rrd->live_head->last_up, sizeof(long), 1, *in_file); 
-                rrd->live_head->last_up_usec = 0;
-    }
-    else {
-            MYFREAD(rrd->live_head, live_head_t, 1)
-    }
-    MYFREAD(rrd->pdp_prep,  pdp_prep_t,   rrd->stat_head->ds_cnt)
-    MYFREAD(rrd->cdp_prep,  cdp_prep_t,   (rrd->stat_head->rra_cnt
-                                             * rrd->stat_head->ds_cnt))
-    MYFREAD(rrd->rra_ptr,   rra_ptr_t,    rrd->stat_head->rra_cnt)
-#undef MYFREAD
+               memmove(&rrd->live_head->last_up, data+offset, sizeof(long));
+               rrd->live_head->last_up_usec = 0;
+       } else {
+#ifdef USE_MADVISE
+               /* the live_head will be needed soonish, so hint accordingly */
+               madvise(data+offset, sizeof(live_head_t), MADV_WILLNEED);
+#endif
+               rrd->live_head = (live_head_t*)(data + offset);
+               offset += sizeof(live_head_t);
+       }
+// This doesn't look like it needs madvise
+       rrd->pdp_prep = (pdp_prep_t*)(data + offset);
+       offset += sizeof(pdp_prep_t) * rrd->stat_head->ds_cnt;
+
+// This could benefit from madvise()ing
+       rrd->cdp_prep = (cdp_prep_t*)(data + offset);
+       offset += sizeof(cdp_prep_t) *
+                               (rrd->stat_head->rra_cnt * rrd->stat_head->ds_cnt);
 
-    return(0);
+// This could benefit from madvise()ing
+       rrd->rra_ptr = (rra_ptr_t*)(data + offset);
+       offset += sizeof(rra_ptr_t) * rrd->stat_head->rra_cnt;
+#ifdef USE_MADVISE
+out_done:
+#endif
+       rrd_file->header_len = offset;
+       rrd_file->pos = offset;
+/* we could close(rrd_file->fd); here, the mapping is still valid anyway */
+       return (rrd_file);
+out_nullify_head:
+       rrd->stat_head = NULL;
+out_close:
+       close(rrd_file->fd);
+       return NULL;
+}
+
+/* Close a reference to an rrd_file.  */
+int rrd_close(rrd_file_t* rrd_file) {
+       int ret = 0;
+#ifdef HAVE_MMAP
+       ret = munmap(rrd_file->file_start, rrd_file->file_len);
+//     if (ret != 0)
+//             rrd_set_error("munmap rrd_file");
+#endif
+       free(rrd_file);
+       rrd_file = NULL;
+       return ret;
+}
+
+/* Set position of rrd_file.  */
+off_t rrd_seek(rrd_file_t* rrd_file, off_t off, int whence) {
+       off_t ret = 0;
+#ifdef HAVE_MMAP
+       if (whence == SEEK_SET)
+               rrd_file->pos = off;
+       else if (whence == SEEK_CUR)
+               rrd_file->pos += off;
+       else if (whence == SEEK_END)
+               rrd_file->pos = rrd_file->file_len + off;
+#else
+       ret = lseek(rrd_file->fd, off, whence);
+       if (ret < 0)
+               rrd_set_error("lseek: %s", rrd_strerror(errno));
+       rrd_file->pos = ret;
+#endif
+//XXX: mimic fseek, which returns 0 upon success
+       return ret == -1; //XXX: or just ret to mimic lseek
+}
+
+/* Get current position in rrd_file.  */
+off_t rrd_tell(rrd_file_t* rrd_file) {
+       return rrd_file->pos;
+}
+
+/* read count bytes into buffer buf, starting at rrd_file->pos.
+ * Returns the number of bytes read.  */
+ssize_t rrd_read(rrd_file_t* rrd_file, void*buf, size_t count) {
+#ifdef HAVE_MMAP
+       char* pos = rrd_file->file_start + rrd_file->pos;
+       buf = memmove(buf, pos, count);
+       return count;
+#else
+       ssize_t ret;
+       ret = read(rrd_file->fd, buf, count);
+       //XXX: eventually add generic rrd_set_error(""); here
+       return ret;
+#endif
+}
+
+/* write count bytes from buffer buf to the current position
+ * rrd_file->pos of rrd_file->fd.  */
+ssize_t rrd_write(rrd_file_t * rrd_file, const void*buf, size_t count) {
+       ssize_t ret = count;
+#ifdef HAVE_MMAP
+       char *off, *new_pos;
+       off = rrd_file->file_start + rrd_file->pos;
+       new_pos = memmove(rrd_file->file_start + rrd_file->pos, buf, count);
+       ret = new_pos - off;
+#else
+       ret = write(rrd_file->fd, buf, count)
+#endif
+       return ret;
+}
+
+/* flush all data pending to be written to FD.  */
+void rrd_flush(rrd_file_t* rrd_file)
+{
+       if (fdatasync(rrd_file->fd) != 0) {
+               rrd_set_error("flushing fd %d: %s", rrd_file->fd,
+                       rrd_strerror(errno));
+       }
 }
 
 void rrd_init(rrd_t *rrd)
@@ -189,24 +323,26 @@ void rrd_init(rrd_t *rrd)
     rrd->rrd_value = NULL;
 }
 
-void rrd_free(rrd_t *rrd)
+void rrd_free(rrd_t UNUSED(*rrd))
 {
-    if (rrd->stat_head) free(rrd->stat_head);
-    if (rrd->ds_def) free(rrd->ds_def);
-    if (rrd->rra_def) free(rrd->rra_def);
-    if (rrd->live_head) free(rrd->live_head);
-    if (rrd->rra_ptr) free(rrd->rra_ptr);
-    if (rrd->pdp_prep) free(rrd->pdp_prep);
-    if (rrd->cdp_prep) free(rrd->cdp_prep);
-    if (rrd->rrd_value) free(rrd->rrd_value);
+#ifndef HAVE_MMAP
+    if (atoi(rrd->stat_head->version) < 3)
+           free(rrd->live_head);
+    free(rrd->stat_head);
+    free(rrd->ds_def);
+    free(rrd->rra_def);
+    free(rrd->rra_ptr);
+    free(rrd->pdp_prep);
+    free(rrd->cdp_prep);
+    free(rrd->rrd_value);
+#endif
 }
 
 /* routine used by external libraries to free memory allocated by
  * rrd library */
 void rrd_freemem(void *mem)
 {
-
-    if (mem) free(mem);
+       free(mem);
 }
 
 int readfile(const char *file_name, char **buffer, int skipfirst){
@@ -251,4 +387,3 @@ int readfile(const char *file_name, char **buffer, int skipfirst){
     return writecnt;
 }
 
-
index c1bdda2..9fdd7c1 100644 (file)
@@ -12,7 +12,6 @@ int
 rrd_resize(int argc, char **argv)
 {
     char               *infilename,outfilename[11]="resize.rrd";
-    FILE               *infile,*outfile;
     rrd_t              rrdold,rrdnew;
     rrd_value_t                buffer;
     int                        version;
@@ -21,6 +20,7 @@ rrd_resize(int argc, char **argv)
     unsigned long      target_rra;
     int                        grow=0,shrink=0;
     char               *endptr;
+    rrd_file_t         *rrd_file, *rrd_out_file;
 
     infilename=argv[1];
     if (!strcmp(infilename,"resize.rrd")) {
@@ -51,21 +51,22 @@ rrd_resize(int argc, char **argv)
     if (shrink) modify = -modify;
 
 
-    if (rrd_open(infilename, &infile, &rrdold, RRD_READWRITE)==-1) {
+    rrd_file = rrd_open(infilename, &rrdold, RRD_READWRITE);
+    if (rrd_file == NULL) {
         rrd_set_error("could not open RRD");
         return(-1);
     }
-    if (LockRRD(infile) != 0) {
+    if (LockRRD(rrd_file->fd) != 0) {
         rrd_set_error("could not lock original RRD");
         rrd_free(&rrdold);
-        fclose(infile);
+        close(rrd_file->fd);
         return(-1);
     }
 
     if (target_rra >= rrdold.stat_head->rra_cnt) {
         rrd_set_error("no such RRA in this RRD");
         rrd_free(&rrdold);
-        fclose(infile);
+        close(rrd_file->fd);
         return(-1);
     }
 
@@ -73,10 +74,23 @@ rrd_resize(int argc, char **argv)
        if ((long)rrdold.rra_def[target_rra].row_cnt <= -modify) {
            rrd_set_error("This RRA is not that big");
            rrd_free(&rrdold);
-           fclose(infile);
+           close(rrd_file->fd);
            return(-1);
        }
 
+    rrd_out_file = rrd_open(outfilename, &rrdnew, RRD_CREAT);
+    if (rrd_out_file == NULL) {
+        rrd_set_error("Can't create '%s': %s",outfilename, rrd_strerror(errno));
+        return(-1);
+    }
+    if (LockRRD(rrd_out_file->fd) != 0) {
+        rrd_set_error("could not lock new RRD");
+        rrd_free(&rrdold);
+        close(rrd_file->fd);
+        close(rrd_out_file->fd);
+        return(-1);
+    }
+/*XXX: do one write for those parts of header that are unchanged */
     rrdnew.stat_head = rrdold.stat_head;
     rrdnew.ds_def    = rrdold.ds_def;
     rrdnew.rra_def   = rrdold.rra_def;
@@ -93,29 +107,20 @@ rrd_resize(int argc, char **argv)
        default: {
                rrd_set_error("Do not know how to handle RRD version %s",rrdold.stat_head->version);
                rrd_free(&rrdold);      
-               fclose(infile);
+               close(rrd_file->fd);
                return(-1);
                }
     }
 
-    if ((outfile=fopen(outfilename,"wb"))==NULL) {
-        rrd_set_error("Can't create '%s'",outfilename);
-        return(-1);
-    }
-    if (LockRRD(outfile) != 0) {
-        rrd_set_error("could not lock new RRD");
-        rrd_free(&rrdold);
-        fclose(infile);
-        fclose(outfile);
-        return(-1);
-    }
-    fwrite(rrdnew.stat_head, sizeof(stat_head_t),1,outfile);
-    fwrite(rrdnew.ds_def,sizeof(ds_def_t),rrdnew.stat_head->ds_cnt,outfile);
-    fwrite(rrdnew.rra_def,sizeof(rra_def_t),rrdnew.stat_head->rra_cnt,outfile);
-    fwrite(rrdnew.live_head,sizeof(live_head_t),1,outfile);
-    fwrite(rrdnew.pdp_prep,sizeof(pdp_prep_t),rrdnew.stat_head->ds_cnt,outfile);
-    fwrite(rrdnew.cdp_prep,sizeof(cdp_prep_t),rrdnew.stat_head->ds_cnt*rrdnew.stat_head->rra_cnt,outfile);
-    fwrite(rrdnew.rra_ptr,sizeof(rra_ptr_t),rrdnew.stat_head->rra_cnt,outfile);
+
+/* XXX: Error checking? */
+    rrd_write(rrd_out_file,rrdnew.stat_head, sizeof(stat_head_t)*1);
+    rrd_write(rrd_out_file,rrdnew.ds_def,sizeof(ds_def_t)*rrdnew.stat_head->ds_cnt);
+    rrd_write(rrd_out_file,rrdnew.rra_def,sizeof(rra_def_t)*rrdnew.stat_head->rra_cnt);
+    rrd_write(rrd_out_file,rrdnew.live_head,sizeof(live_head_t)*1);
+    rrd_write(rrd_out_file,rrdnew.pdp_prep,sizeof(pdp_prep_t)*rrdnew.stat_head->ds_cnt);
+    rrd_write(rrd_out_file,rrdnew.cdp_prep,sizeof(cdp_prep_t)*rrdnew.stat_head->ds_cnt*rrdnew.stat_head->rra_cnt);
+    rrd_write(rrd_out_file,rrdnew.rra_ptr,sizeof(rra_ptr_t)*rrdnew.stat_head->rra_cnt);
 
     /* Move the CDPs from the old to the new database.
     ** This can be made (much) faster but isn't worth the effort. Clarity
@@ -129,8 +134,8 @@ rrd_resize(int argc, char **argv)
         l+=rrdnew.stat_head->ds_cnt * rrdnew.rra_def[rra].row_cnt;
     }
     while (l>0) {
-        fread(&buffer,sizeof(rrd_value_t),1,infile);
-        fwrite(&buffer,sizeof(rrd_value_t),1,outfile);
+        rrd_read(rrd_file,&buffer,sizeof(rrd_value_t)*1);
+        rrd_write(rrd_out_file,&buffer,sizeof(rrd_value_t)*1);
         l--;
     }
     /* Move data in this RRA, either removing or adding some rows
@@ -141,14 +146,14 @@ rrd_resize(int argc, char **argv)
         */
         l = rrdnew.stat_head->ds_cnt * (rrdnew.rra_ptr[target_rra].cur_row+1);
         while (l>0) {
-            fread(&buffer,sizeof(rrd_value_t),1,infile);
-            fwrite(&buffer,sizeof(rrd_value_t),1,outfile);
+            rrd_read(rrd_file,&buffer,sizeof(rrd_value_t)*1);
+            rrd_write(rrd_out_file,&buffer,sizeof(rrd_value_t)*1);
             l--;
         }
         buffer=DNAN;
         l=rrdnew.stat_head->ds_cnt * modify;
         while (l>0) {
-            fwrite(&buffer,sizeof(rrd_value_t),1,outfile);
+            rrd_write(rrd_out_file,&buffer,sizeof(rrd_value_t)*1);
             l--;
         }
     } else {
@@ -161,7 +166,7 @@ rrd_resize(int argc, char **argv)
         remove_end=(rrdnew.rra_ptr[target_rra].cur_row-modify)%rrdnew.rra_def[target_rra].row_cnt;
         if (remove_end <= (signed long int)rrdnew.rra_ptr[target_rra].cur_row) {
             while (remove_end >= 0) {
-                fseek(infile,sizeof(rrd_value_t)*rrdnew.stat_head->ds_cnt,SEEK_CUR);
+                rrd_seek(rrd_file,sizeof(rrd_value_t)*rrdnew.stat_head->ds_cnt,SEEK_CUR);
                 rrdnew.rra_ptr[target_rra].cur_row--;
                 rrdnew.rra_def[target_rra].row_cnt--;
                 remove_end--;
@@ -172,12 +177,12 @@ rrd_resize(int argc, char **argv)
         for (l=0;l<=rrdnew.rra_ptr[target_rra].cur_row;l++) {
             unsigned int tmp;
             for (tmp=0;tmp<rrdnew.stat_head->ds_cnt;tmp++) {
-                fread(&buffer,sizeof(rrd_value_t),1,infile);
-                fwrite(&buffer,sizeof(rrd_value_t),1,outfile);
+                rrd_read(rrd_file,&buffer,sizeof(rrd_value_t)*1);
+                rrd_write(rrd_out_file,&buffer,sizeof(rrd_value_t)*1);
             }
         }
         while (modify<0) {
-            fseek(infile,sizeof(rrd_value_t)*rrdnew.stat_head->ds_cnt,SEEK_CUR);
+            rrd_seek(rrd_file,sizeof(rrd_value_t)*rrdnew.stat_head->ds_cnt,SEEK_CUR);
             rrdnew.rra_def[target_rra].row_cnt--;
             modify++;
         }
@@ -185,21 +190,20 @@ rrd_resize(int argc, char **argv)
     /* Move the rest of the CDPs
     */
     while (1) {
-       fread(&buffer,sizeof(rrd_value_t),1,infile);
-       if (feof(infile))
+       if (rrd_read(rrd_file,&buffer,sizeof(rrd_value_t)*1) <= 0)
            break;
-        fwrite(&buffer,sizeof(rrd_value_t),1,outfile);
+        rrd_write(rrd_out_file,&buffer,sizeof(rrd_value_t)*1);
     }
     rrdnew.rra_def[target_rra].row_cnt += modify;
-    fseek(outfile,sizeof(stat_head_t)+sizeof(ds_def_t)*rrdnew.stat_head->ds_cnt,SEEK_SET);
-    fwrite(rrdnew.rra_def,sizeof(rra_def_t),rrdnew.stat_head->rra_cnt, outfile);
-    fseek(outfile,sizeof(live_head_t),SEEK_CUR);
-    fseek(outfile,sizeof(pdp_prep_t)*rrdnew.stat_head->ds_cnt,SEEK_CUR);
-    fseek(outfile,sizeof(cdp_prep_t)*rrdnew.stat_head->ds_cnt*rrdnew.stat_head->rra_cnt,SEEK_CUR);
-    fwrite(rrdnew.rra_ptr,sizeof(rra_ptr_t),rrdnew.stat_head->rra_cnt, outfile);
-    
-    fclose(outfile);
+    rrd_seek(rrd_out_file,sizeof(stat_head_t)+sizeof(ds_def_t)*rrdnew.stat_head->ds_cnt,SEEK_SET);
+    rrd_write(rrd_out_file,rrdnew.rra_def,sizeof(rra_def_t)*rrdnew.stat_head->rra_cnt);
+    rrd_seek(rrd_out_file,sizeof(live_head_t),SEEK_CUR);
+    rrd_seek(rrd_out_file,sizeof(pdp_prep_t)*rrdnew.stat_head->ds_cnt,SEEK_CUR);
+    rrd_seek(rrd_out_file,sizeof(cdp_prep_t)*rrdnew.stat_head->ds_cnt*rrdnew.stat_head->rra_cnt,SEEK_CUR);
+    rrd_write(rrd_out_file,rrdnew.rra_ptr,sizeof(rra_ptr_t)*rrdnew.stat_head->rra_cnt);
+
+    close(rrd_out_file->fd);
     rrd_free(&rrdold);
-    fclose(infile);
+    close(rrd_file->fd);
     return(0);
 }
index 1da3a59..b283f91 100644 (file)
@@ -22,7 +22,7 @@ int skipxml(char **);
 int eat_tag(char **, char *);
 int read_tag(char **, char *, char *, void *);
 int xml2rrd(char*, rrd_t*, char);
-int rrd_write(char *, rrd_t *, char);
+int rrd_creat(char *, rrd_t *, char);
 void parse_patch1028_RRA_params(char **buf, rrd_t *rrd, int rra_index);
 void parse_patch1028_CDP_params(char **buf, rrd_t *rrd, int rra_index, int ds_index);
 void parse_FAILURES_history(char **buf, rrd_t *rrd, int rra_index, int ds_index);
@@ -461,7 +461,7 @@ int xml2rrd(char* buf, rrd_t* rrd, char rc){
 /* create and empty rrd file according to the specs given */
 
 int
-rrd_write(char *file_name, rrd_t *rrd, char force_overwrite)
+rrd_creat(char *file_name, rrd_t *rrd, char force_overwrite)
 {
     unsigned long    i,ii,val_cnt;
     FILE             *rrd_file=NULL;
@@ -584,7 +584,7 @@ rrd_restore(int argc, char **argv)
 
     free(buf);
 
-    if(rrd_write(argv[optind+1],&rrd,force_overwrite)==-1){
+    if(rrd_creat(argv[optind+1],&rrd,force_overwrite)==-1){
        rrd_free(&rrd); 
        return -1;      
     };
index 74969bd..189b579 100644 (file)
@@ -6,6 +6,8 @@
 
 #include "rrd_tool.h"
 
+XXX: This file is not compiled. Is this on purpose?
+
 extern char *tzname[2];
 
 stat_node
@@ -16,11 +18,12 @@ rrd_stat(int argc, char **argv)
     char         somestring[255];
     rrd_value_t  my_cdp;
     long         rra_base, rra_start, rra_next;
-    FILE                  *in_file;
     rrd_t             rrd;
+    rrd_file_t  *rrd_file;
 
 
-    if(rrd_open(argv[1],&in_file,&rrd, RRD_READONLY)==-1){
+    rrd_file = rrd_open(argv[1],&rrd, RRD_READONLY);
+    if (rrd_file == NULL) {
        return(-1);
     }
     puts("<!-- Round Robin Database Dump -->");
@@ -66,7 +69,7 @@ rrd_stat(int argc, char **argv)
 
     puts("<!-- Round Robin Archives -->");
 
-    rra_base=ftell(in_file);    
+    rra_base = rrd_file->header_len;
     rra_next = rra_base;
 
     for(i=0;i<rrd.stat_head->rra_cnt;i++){
@@ -97,7 +100,7 @@ rrd_stat(int argc, char **argv)
        printf("\t\t</cdp_prep>\n");
 
        printf("\t\t<database>\n");
-       fseek(in_file,(rra_start
+       rrd_seek(rrd_file,(rra_start
                       +(rrd.rra_ptr[i].cur_row+1)
                       * rrd.stat_head->ds_cnt
                       * sizeof(rrd_value_t)),SEEK_SET);
@@ -106,7 +109,7 @@ rrd_stat(int argc, char **argv)
        for(ix=0;ix<rrd.rra_def[i].row_cnt;ix++){           
            ii++;
            if (ii>=rrd.rra_def[i].row_cnt) {
-               fseek(in_file,rra_start,SEEK_SET);
+               rrd_seek(rrd_file,rra_start,SEEK_SET);
                ii=0; /* wrap if max row cnt is reached */
            }
            now = (rrd.live_head->last_up 
@@ -122,7 +125,7 @@ rrd_stat(int argc, char **argv)
 #endif
            printf("\t\t\t<!-- %s --> <row>",somestring);
            for(iii=0;iii<rrd.stat_head->ds_cnt;iii++){                  
-               fread(&my_cdp,sizeof(rrd_value_t),1,in_file);           
+               rrd_read(rrd_file,&my_cdp,sizeof(rrd_value_t)*1);
                if (isnan(my_cdp)){
                  printf("<v> NaN </v>");
                } else {
@@ -136,7 +139,7 @@ rrd_stat(int argc, char **argv)
     }
     printf("</rrd>\n");
     rrd_free(&rrd);
-    fclose(in_file);
+    close(rrd_file->fd);
     return(0);
 }
 
index ca99202..4714327 100644 (file)
@@ -52,7 +52,7 @@ struct rrd_context *rrd_get_context(void) {
 const char *rrd_strerror(int err) {
     struct rrd_context *ctx = rrd_get_context();
     if (strerror_r(err, ctx->lib_errstr, ctx->errlen)) 
-         return "strerror_r faild. sorry!"; 
+         return "strerror_r failed. sorry!"; 
     else 
          return ctx->lib_errstr; 
 }
index 6663c56..f8ab9c4 100644 (file)
@@ -7,7 +7,6 @@
 extern "C" {
 #endif
 
-
 #ifndef _RRD_TOOL_H
 #define _RRD_TOOL_H
 
@@ -17,89 +16,6 @@ extern "C" {
 #include "../win32/config.h"
 #endif
 
-#ifdef MUST_DISABLE_SIGFPE
-#include <signal.h>
-#endif
-
-#ifdef MUST_DISABLE_FPMASK
-#include <floatingpoint.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <ctype.h>
-
-#if HAVE_SYS_PARAM_H
-#  include <sys/param.h>
-#endif
-
-#ifndef MAXPATH
-#  define MAXPATH 1024
-#endif
-
-#if HAVE_MATH_H
-# include <math.h>
-#endif
-/* Sorry: don't know autoconf as well how to check the exist of
-   dirent.h ans sys/stat.h
-*/
-
-#if HAVE_DIRENT_H
-# include <dirent.h>
-# define NAMLEN(dirent) strlen((dirent)->d_name)
-#else
-# define dirent direct
-# define NAMLEN(dirent) (dirent)->d_namlen
-# if HAVE_SYS_NDIR_H
-#  include <sys/ndir.h>
-# endif
-# if HAVE_SYS_DIR_H
-#  include <sys/dir.h>
-# endif
-# if HAVE_NDIR_H
-#  include <ndir.h>
-# endif
-#endif
-
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#if HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# else
-#  include <time.h>
-# endif
-#endif
-
-#if HAVE_SYS_TIMES_H
-# include <sys/times.h>
-#endif
-
-
-#if HAVE_SYS_RESOURCE_H
-# include <sys/resource.h>
-#if (defined(__svr4__) && defined(__sun__))
-/* Solaris headers (pre 2.6) don't have a getrusage prototype.
-   Use this instead. */
-extern int getrusage(int, struct rusage *);
-#endif /* __svr4__ && __sun__ */
-#endif
-
 #include "rrd.h"
 
 #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
@@ -133,7 +49,7 @@ int isnan(double value);
 
 #ifndef min
 #define min(a,b) ((a) < (b) ? (a) : (b))
-#endif                                                   
+#endif
 
 #define DIM(x) (sizeof(x)/sizeof(x[0]))
 
@@ -180,11 +96,18 @@ void rrd_free(rrd_t *rrd);
 void rrd_freemem(void *mem);
 void rrd_init(rrd_t *rrd);
 
-int rrd_open(const char *file_name, FILE **in_file, rrd_t *rrd, int rdwr);
+rrd_file_t* rrd_open(const char * const file_name, rrd_t *rrd, unsigned rdwr);
+int rrd_close(rrd_file_t* rrd_file);
+ssize_t rrd_read(rrd_file_t* rrd_file, void*buf, size_t count);
+ssize_t rrd_write(rrd_file_t* rrd_file, const void*buf, size_t count);
+void rrd_flush(rrd_file_t* rrd_file);
+off_t rrd_seek(rrd_file_t* rrd_file, off_t off, int whence);
+off_t rrd_tell(rrd_file_t* rrd_file);
 int readfile(const char *file, char **buffer, int skipfirst);
 
 #define RRD_READONLY    0
 #define RRD_READWRITE   1
+#define RRD_CREAT       2
 
 enum cf_en cf_conv(const char *string);
 enum dst_en dst_conv(char *string);
index 8aa1630..61dc6ad 100644 (file)
@@ -51,7 +51,6 @@ int
 rrd_tune(int argc, char **argv)    
 {   
     rrd_t               rrd;
-    FILE               *rrd_file;
     int                 matches;
     int                 optcnt = 0;
     long                ds;
@@ -61,14 +60,15 @@ rrd_tune(int argc, char **argv)
     double              min;
     double              max;
     char                dst[DST_SIZE];
+    rrd_file_t         *rrd_file;
     optind = 0; opterr = 0;  /* initialize getopt */
 
 
-    if(rrd_open(argv[1],&rrd_file,&rrd, RRD_READWRITE)==-1){
+    rrd_file = rrd_open(argv[1],&rrd,RRD_READWRITE);
+    if (rrd_file == NULL) {
         return -1;
     }
 
-    
     while (1){
        static struct option long_options[] =
        {
@@ -102,12 +102,12 @@ rrd_tune(int argc, char **argv)
            if ((matches = sscanf(optarg, DS_NAM_FMT ":%ld",ds_nam,&heartbeat)) != 2){
                rrd_set_error("invalid arguments for heartbeat");
                rrd_free(&rrd);
-               fclose(rrd_file);
+               close(rrd_file->fd);
                return -1;
            }
            if ((ds=ds_match(&rrd,ds_nam))==-1){
                rrd_free(&rrd);
-                fclose(rrd_file);
+                close(rrd_file->fd);
                return -1;
            }
            rrd.ds_def[ds].par[DS_mrhb_cnt].u_cnt = heartbeat;
@@ -117,12 +117,12 @@ rrd_tune(int argc, char **argv)
            if ((matches = sscanf(optarg,DS_NAM_FMT ":%lf",ds_nam,&min)) <1){
                rrd_set_error("invalid arguments for minimum ds value");
                rrd_free(&rrd);
-                fclose(rrd_file);
+                close(rrd_file->fd);
                return -1;
            }
            if ((ds=ds_match(&rrd,ds_nam))==-1){
                rrd_free(&rrd);
-                fclose(rrd_file);
+                close(rrd_file->fd);
                return -1;
            }
 
@@ -135,12 +135,12 @@ rrd_tune(int argc, char **argv)
            if ((matches = sscanf(optarg, DS_NAM_FMT ":%lf",ds_nam,&max)) <1){
                rrd_set_error("invalid arguments for maximum ds value");
                rrd_free(&rrd);
-               fclose(rrd_file);
+               close(rrd_file->fd);
                return -1;
            }
            if ((ds=ds_match(&rrd,ds_nam))==-1){
                rrd_free(&rrd);
-               fclose(rrd_file);
+               close(rrd_file->fd);
                return -1;
            }
            if(matches == 1) 
@@ -152,17 +152,17 @@ rrd_tune(int argc, char **argv)
            if ((matches = sscanf(optarg, DS_NAM_FMT ":" DST_FMT ,ds_nam,dst)) != 2){
                rrd_set_error("invalid arguments for data source type");
                rrd_free(&rrd);
-               fclose(rrd_file);
+               close(rrd_file->fd);
                return -1;
            }
            if ((ds=ds_match(&rrd,ds_nam))==-1){
                rrd_free(&rrd);
-               fclose(rrd_file);
+               close(rrd_file->fd);
                return -1;
            }
            if ((int)dst_conv(dst) == -1){
                rrd_free(&rrd);
-               fclose(rrd_file);
+               close(rrd_file->fd);
                return -1;
            }
            strncpy(rrd.ds_def[ds].dst,dst,DST_SIZE-1);
@@ -180,12 +180,12 @@ rrd_tune(int argc, char **argv)
                 sscanf(optarg,DS_NAM_FMT ":" DS_NAM_FMT , ds_nam,ds_new)) != 2){
                rrd_set_error("invalid arguments for data source type");
                rrd_free(&rrd);
-               fclose(rrd_file);
+               close(rrd_file->fd);
                return -1;
            }
            if ((ds=ds_match(&rrd,ds_nam))==-1){
                rrd_free(&rrd);
-               fclose(rrd_file);
+               close(rrd_file->fd);
                return -1;
            }
            strncpy(rrd.ds_def[ds].ds_nam,ds_new,DS_NAM_SIZE-1);
@@ -243,19 +243,19 @@ rrd_tune(int argc, char **argv)
                if (sscanf(optarg,DS_NAM_FMT,ds_nam) != 1){
                rrd_set_error("invalid argument for aberrant-reset");
                rrd_free(&rrd);
-               fclose(rrd_file);
+               close(rrd_file->fd);
                return -1;
            }
            if ((ds=ds_match(&rrd,ds_nam))==-1){
            /* ds_match handles it own errors */        
                rrd_free(&rrd);
-               fclose(rrd_file);
+               close(rrd_file->fd);
                return -1;
            }
            reset_aberrant_coefficients(&rrd,rrd_file,(unsigned long) ds);
                if (rrd_test_error()) {
                   rrd_free(&rrd);
-                  fclose(rrd_file);
+                  close(rrd_file->fd);
                   return -1;
                }
                break;
@@ -265,20 +265,19 @@ rrd_tune(int argc, char **argv)
             else
                 rrd_set_error("unknown option '%s'",argv[optind-1]);
            rrd_free(&rrd);         
-            fclose(rrd_file);
+            close(rrd_file->fd);
             return -1;
         }
     }
        if(optcnt>0){
        
-       fseek(rrd_file,0,SEEK_SET);
-       fwrite(rrd.stat_head,
-              sizeof(stat_head_t),1, rrd_file);
-       fwrite(rrd.ds_def,
-              sizeof(ds_def_t), rrd.stat_head->ds_cnt, rrd_file);
+       rrd_seek(rrd_file,0,SEEK_SET);
+       rrd_write(rrd_file,rrd.stat_head, sizeof(stat_head_t)*1);
+       rrd_write(rrd_file,rrd.ds_def,
+              sizeof(ds_def_t)* rrd.stat_head->ds_cnt);
        /* need to write rra_defs for RRA parameter changes */
-       fwrite(rrd.rra_def, sizeof(rra_def_t), rrd.stat_head->rra_cnt,
-                  rrd_file);
+       rrd_write(rrd_file,rrd.rra_def,
+               sizeof(rra_def_t)*rrd.stat_head->rra_cnt);
     } else {
        int i;
        for(i=0;i< (int)rrd.stat_head->ds_cnt;i++)
@@ -296,7 +295,7 @@ rrd_tune(int argc, char **argv)
            free(buffer);
                }
     }
-    fclose(rrd_file);
+    close(rrd_file->fd);
     rrd_free(&rrd);
     return 0;
 }
index ed79a6a..f1242f3 100644 (file)
@@ -70,21 +70,21 @@ static void normalize_time(struct timeval *t)
 }
 
 /* Local prototypes */
-int LockRRD(FILE *rrd_file);
+int LockRRD(int in_file);
 #ifdef HAVE_MMAP
 info_t *write_RRA_row (rrd_t *rrd, unsigned long rra_idx, 
                                        unsigned long *rra_current,
                                        unsigned short CDP_scratch_idx,
 #ifndef DEBUG
-FILE UNUSED(*rrd_file),
+int UNUSED(in_file),
 #else
-FILE *rrd_file,
+int in_file,
 #endif
                                        info_t *pcdp_summary, time_t *rra_time, void *rrd_mmaped_file);
 #else
 info_t *write_RRA_row (rrd_t *rrd, unsigned long rra_idx, 
                                        unsigned long *rra_current,
-                                       unsigned short CDP_scratch_idx, FILE *rrd_file,
+                                       unsigned short CDP_scratch_idx, int in_file,
                                        info_t *pcdp_summary, time_t *rra_time);
 #endif
 int rrd_update_r(const char *filename, const char *tmplt, int argc, const char **argv);
@@ -234,7 +234,6 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
                                            transported by the tmplt index */
     unsigned long    tmpl_cnt = 2;       /* time and data */
 
-    FILE             *rrd_file;
     rrd_t            rrd;
     time_t           current_time = 0;
     time_t           rra_time = 0;      /* time of update for a RRA */
@@ -261,12 +260,7 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
     rpnstack_t       rpnstack; /* used for COMPUTE DS */
     int                     version;  /* rrd version */
     char             *endptr; /* used in the conversion */
-
-#ifdef HAVE_MMAP
-    void            *rrd_mmaped_file;
-    unsigned long    rrd_filesize;
-#endif
-
+    rrd_file_t*      rrd_file;
 
     rpnstack_init(&rpnstack);
 
@@ -275,10 +269,9 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
        rrd_set_error("Not enough arguments");
        return -1;
     }
-    
-    
 
-    if(rrd_open(filename,&rrd_file,&rrd, RRD_READWRITE)==-1){
+    rrd_file = rrd_open(filename,&rrd, RRD_READWRITE);
+    if (rrd_file == NULL) {
        return -1;
     }
 
@@ -294,39 +287,40 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
        current_time_usec = 0;
     }
 
-    rra_current = rra_start = rra_begin = ftell(rrd_file);
+    rra_current = rra_start = rra_begin = rrd_file->header_len;
     /* This is defined in the ANSI C standard, section 7.9.5.3:
 
         When a file is opened with udpate mode ('+' as the second
         or third character in the ... list of mode argument
-        variables), both input and ouptut may be performed on the
+        variables), both input and output may be performed on the
         associated stream.  However, ...  input may not be directly
         followed by output without an intervening call to a file
-        positioning function, unless the input oepration encounters
+        positioning function, unless the input operation encounters
         end-of-file. */
-#ifdef HAVE_MMAP
-    fseek(rrd_file, 0, SEEK_END);
-    rrd_filesize = ftell(rrd_file);
-    fseek(rrd_file, rra_current, SEEK_SET);
+#if 0//def HAVE_MMAP
+rrd_filesize = rrd_file->file_size;
+    fseek(rrd_file->fd, 0, SEEK_END);
+    rrd_filesize = ftell(rrd_file->fd);
+    fseek(rrd_file->fd, rra_current, SEEK_SET);
 #else
-    fseek(rrd_file, 0, SEEK_CUR);
+//    fseek(rrd_file->fd, 0, SEEK_CUR);
 #endif
 
     
     /* get exclusive lock to whole file.
      * lock gets removed when we close the file.
      */
-    if (LockRRD(rrd_file) != 0) {
+    if (LockRRD(rrd_file->fd) != 0) {
       rrd_set_error("could not lock RRD");
       rrd_free(&rrd);
-      fclose(rrd_file);
+      close(rrd_file->fd);
       return(-1);   
     } 
 
     if((updvals = malloc( sizeof(char*) * (rrd.stat_head->ds_cnt+1)))==NULL){
        rrd_set_error("allocating updvals pointer array");
        rrd_free(&rrd);
-        fclose(rrd_file);
+        close(rrd_file->fd);
        return(-1);
     }
 
@@ -335,7 +329,7 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
        rrd_set_error("allocating pdp_temp ...");
        free(updvals);
        rrd_free(&rrd);
-        fclose(rrd_file);
+        close(rrd_file->fd);
        return(-1);
     }
 
@@ -345,7 +339,7 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
        free(pdp_temp);
        free(updvals);
        rrd_free(&rrd);
-        fclose(rrd_file);
+        close(rrd_file->fd);
        return(-1);
     }
     /* initialize tmplt redirector */
@@ -377,14 +371,14 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
                    rrd_set_error("tmplt contains more DS definitions than RRD");
                    free(updvals); free(pdp_temp);
                    free(tmpl_idx); rrd_free(&rrd);
-                   fclose(rrd_file); return(-1);
+                   close(rrd_file->fd); return(-1);
                }
                if ((tmpl_idx[tmpl_cnt++] = ds_match(&rrd,dsname)) == -1){
                    rrd_set_error("unknown DS name '%s'",dsname);
                    free(updvals); free(pdp_temp);
                    free(tmplt_copy);
                    free(tmpl_idx); rrd_free(&rrd);
-                   fclose(rrd_file); return(-1);
+                   close(rrd_file->fd); return(-1);
                } else {
                  /* the first element is always the time */
                  tmpl_idx[tmpl_cnt-1]++; 
@@ -407,16 +401,16 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
        free(pdp_temp);
        free(tmpl_idx);
        rrd_free(&rrd);
-        fclose(rrd_file);
+        close(rrd_file->fd);
        return(-1);
     }
 
-#ifdef HAVE_MMAP
+#if 0//def HAVE_MMAP
     rrd_mmaped_file = mmap(0, 
-                       rrd_filesize
+                       rrd_file->file_len
                        PROT_READ | PROT_WRITE, 
                        MAP_SHARED, 
-                       fileno(rrd_file), 
+                       fileno(in_file), 
                        0);
     if (rrd_mmaped_file == MAP_FAILED) {
         rrd_set_error("error mmapping file %s", filename);
@@ -424,10 +418,10 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
        free(pdp_temp);
        free(tmpl_idx);
        rrd_free(&rrd);
-        fclose(rrd_file);
+        close(rrd_file->fd);
        return(-1);
     }
-#ifdef HAVE_MADVISE
+#ifdef USE_MADVISE
     /* when we use mmaping we tell the kernel the mmap equivalent
        of POSIX_FADV_RANDOM */
     madvise(rrd_mmaped_file,rrd_filesize,POSIX_MADV_RANDOM);
@@ -449,9 +443,9 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
                 free(tmpl_idx);
                 rrd_free(&rrd);
 #ifdef HAVE_MMAP
-               munmap(rrd_mmaped_file, rrd_filesize);
+               rrd_close(rrd_file);
 #endif
-                fclose(rrd_file);
+                close(rrd_file->fd);
                 return(-1);
          }
        /* initialize all ds input to unknown except the first one
@@ -542,7 +536,7 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
        /* seek to the beginning of the rra's */
        if (rra_current != rra_begin) {
 #ifndef HAVE_MMAP
-           if(fseek(rrd_file, rra_begin, SEEK_SET) != 0) {
+           if(rrd_seek(rrd_file, rra_begin, SEEK_SET) != 0) {
                rrd_set_error("seek error in rrd");
                free(step_start);
                break;
@@ -939,7 +933,7 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
                         }
                  }
 
-             rra_current = ftell(rrd_file); 
+             rra_current = rrd_tell(rrd_file);
                } /* if cf is DEVSEASONAL or SEASONAL */
 
         if (rrd_test_error()) break;
@@ -1174,7 +1168,7 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
                         lookup_seasonal(&rrd,i,rra_start,rrd_file,
                                    elapsed_pdp_st + (scratch_idx == CDP_primary_val ? 1 : 2),
                                &seasonal_coef);
-                 rra_current = ftell(rrd_file);
+                 rra_current = rrd_tell(rrd_file);
                          }
                          if (rrd_test_error()) break;
                      /* loop over data soures within each RRA */
@@ -1205,7 +1199,7 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
 
                /* write the first row */
 #ifdef DEBUG
-        fprintf(stderr,"  -- RRA Preseek %ld\n",ftell(rrd_file));
+        fprintf(stderr,"  -- RRA Preseek %ld\n",rrd_file->pos);
 #endif
            rrd.rra_ptr[i].cur_row++;
            if (rrd.rra_ptr[i].cur_row >= rrd.rra_def[i].row_cnt)
@@ -1215,7 +1209,7 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
                   (rrd.stat_head->ds_cnt)*(rrd.rra_ptr[i].cur_row)*sizeof(rrd_value_t);
                if(rra_pos_tmp != rra_current) {
 #ifndef HAVE_MMAP
-                  if(fseek(rrd_file, rra_pos_tmp, SEEK_SET) != 0){
+                  if(rrd_seek(rrd_file, rra_pos_tmp, SEEK_SET) != 0){
                      rrd_set_error("seek error in rrd");
                      break;
                   }
@@ -1224,7 +1218,7 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
                }
 
 #ifdef DEBUG
-           fprintf(stderr,"  -- RRA Postseek %ld\n",ftell(rrd_file));
+           fprintf(stderr,"  -- RRA Postseek %ld\n",rrd_file->pos);
 #endif
                scratch_idx = CDP_primary_val;
                if (pcdp_summary != NULL)
@@ -1234,10 +1228,10 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
                   - ((rra_step_cnt[i]-1)*rrd.rra_def[i].pdp_cnt*rrd.stat_head->pdp_step);
                }
 #ifdef HAVE_MMAP
-               pcdp_summary = write_RRA_row(&rrd, i, &rra_current, scratch_idx, rrd_file, 
-                  pcdp_summary, &rra_time, rrd_mmaped_file);
+               pcdp_summary = write_RRA_row(&rrd, i, &rra_current, scratch_idx, rrd_file->fd
+                  pcdp_summary, &rra_time, rrd_file->file_start);
 #else
-               pcdp_summary = write_RRA_row(&rrd, i, &rra_current, scratch_idx, rrd_file, 
+               pcdp_summary = write_RRA_row(&rrd, i, &rra_current, scratch_idx, rrd_file->fd
                   pcdp_summary, &rra_time);
 #endif
                if (rrd_test_error()) break;
@@ -1255,13 +1249,13 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
                          /* wrap */
                          rrd.rra_ptr[i].cur_row = 0;
                          /* seek back to beginning of current rra */
-                     if (fseek(rrd_file, rra_start, SEEK_SET) != 0)
+                     if (rrd_seek(rrd_file, rra_start, SEEK_SET) != 0)
                          {
                         rrd_set_error("seek error in rrd");
                         break;
                          }
 #ifdef DEBUG
-                 fprintf(stderr,"  -- Wraparound Postseek %ld\n",ftell(rrd_file));
+                 fprintf(stderr,"  -- Wraparound Postseek %ld\n",rrd_file->pos);
 #endif
                          rra_current = rra_start;
                   }
@@ -1272,10 +1266,10 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
                      - ((rra_step_cnt[i]-2)*rrd.rra_def[i].pdp_cnt*rrd.stat_head->pdp_step);
                   }
 #ifdef HAVE_MMAP
-                  pcdp_summary = write_RRA_row(&rrd, i, &rra_current, scratch_idx, rrd_file,
-                     pcdp_summary, &rra_time, rrd_mmaped_file);
+                  pcdp_summary = write_RRA_row(&rrd, i, &rra_current, scratch_idx, rrd_file->fd,
+                     pcdp_summary, &rra_time, rrd_file->file_start);
 #else
-                  pcdp_summary = write_RRA_row(&rrd, i, &rra_current, scratch_idx, rrd_file,
+                  pcdp_summary = write_RRA_row(&rrd, i, &rra_current, scratch_idx, rrd_file->fd,
                      pcdp_summary, &rra_time);
 #endif
                }
@@ -1302,7 +1296,7 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
     rpnstack_free(&rpnstack);
 
 #ifdef HAVE_MMAP
-    if (munmap(rrd_mmaped_file, rrd_filesize) == -1) {
+    if (munmap(rrd_file->file_start, rrd_file->file_len) == -1) {
             rrd_set_error("error writing(unmapping) file: %s", filename);
     }
 #endif    
@@ -1314,14 +1308,14 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
        rrd_free(&rrd);
        free(pdp_temp);
        free(pdp_new);
-       fclose(rrd_file);
+       close(rrd_file->fd);
        return(-1);
     }
 
     /* aargh ... that was tough ... so many loops ... anyway, its done.
      * we just need to write back the live header portion now*/
 
-    if (fseek(rrd_file, (sizeof(stat_head_t)
+    if (rrd_seek(rrd_file, (sizeof(stat_head_t)
                         + sizeof(ds_def_t)*rrd.stat_head->ds_cnt 
                         + sizeof(rra_def_t)*rrd.stat_head->rra_cnt),
              SEEK_SET) != 0) {
@@ -1331,76 +1325,75 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
        rrd_free(&rrd);
        free(pdp_temp);
        free(pdp_new);
-       fclose(rrd_file);
+       close(rrd_file->fd);
        return(-1);
     }
 
     if(version >= 3) {
-           if(fwrite( rrd.live_head,
-                      sizeof(live_head_t), 1, rrd_file) != 1){
-               rrd_set_error("fwrite live_head to rrd");
+           if(rrd_write(rrd_file, rrd.live_head,
+                      sizeof(live_head_t)*1) != sizeof(live_head_t)*1){
+               rrd_set_error("rrd_write live_head to rrd");
                free(updvals);
                rrd_free(&rrd);
                free(tmpl_idx);
                free(pdp_temp);
                free(pdp_new);
-               fclose(rrd_file);
+               close(rrd_file->fd);
                return(-1);
            }
     }
     else {
-           if(fwrite( &rrd.live_head->last_up,
-                      sizeof(time_t), 1, rrd_file) != 1){
-               rrd_set_error("fwrite live_head to rrd");
+           if(rrd_write(rrd_file, &rrd.live_head->last_up,
+                      sizeof(time_t)*1) != sizeof(time_t)*1){
+               rrd_set_error("rrd_write live_head to rrd");
                free(updvals);
                rrd_free(&rrd);
                free(tmpl_idx);
                free(pdp_temp);
                free(pdp_new);
-               fclose(rrd_file);
+               close(rrd_file->fd);
                return(-1);
            }
     }
            
 
-    if(fwrite( rrd.pdp_prep,
-              sizeof(pdp_prep_t),
-              rrd.stat_head->ds_cnt, rrd_file) != rrd.stat_head->ds_cnt){
-       rrd_set_error("ftwrite pdp_prep to rrd");
+    if(rrd_write(rrd_file, rrd.pdp_prep,
+              sizeof(pdp_prep_t)*rrd.stat_head->ds_cnt)
+           != (ssize_t)(sizeof(pdp_prep_t)*rrd.stat_head->ds_cnt)){
+       rrd_set_error("rrd_write pdp_prep to rrd");
        free(updvals);
        rrd_free(&rrd);
        free(tmpl_idx);
        free(pdp_temp);
        free(pdp_new);
-       fclose(rrd_file);
+       close(rrd_file->fd);
        return(-1);
     }
 
-    if(fwrite( rrd.cdp_prep,
-              sizeof(cdp_prep_t),
-              rrd.stat_head->rra_cnt *rrd.stat_head->ds_cnt, rrd_file) 
-       != rrd.stat_head->rra_cnt *rrd.stat_head->ds_cnt){
+    if(rrd_write(rrd_file, rrd.cdp_prep,
+              sizeof(cdp_prep_t)*rrd.stat_head->rra_cnt *rrd.stat_head->ds_cnt)
+       != (ssize_t)(sizeof(cdp_prep_t)*rrd.stat_head->rra_cnt *rrd.stat_head->ds_cnt)){
 
-       rrd_set_error("ftwrite cdp_prep to rrd");
+       rrd_set_error("rrd_write cdp_prep to rrd");
        free(updvals);
        free(tmpl_idx);
        rrd_free(&rrd);
        free(pdp_temp);
        free(pdp_new);
-       fclose(rrd_file);
+       close(rrd_file->fd);
        return(-1);
     }
 
-    if(fwrite( rrd.rra_ptr,
-              sizeof(rra_ptr_t)
-              rrd.stat_head->rra_cnt,rrd_file) != rrd.stat_head->rra_cnt){
-       rrd_set_error("fwrite rra_ptr to rrd");
+    if(rrd_write(rrd_file, rrd.rra_ptr,
+              sizeof(rra_ptr_t)* rrd.stat_head->rra_cnt)
+           != (ssize_t)(sizeof(rra_ptr_t)*rrd.stat_head->rra_cnt)){
+       rrd_set_error("rrd_write rra_ptr to rrd");
        free(updvals);
        free(tmpl_idx);
        rrd_free(&rrd);
        free(pdp_temp);
        free(pdp_new);
-       fclose(rrd_file);
+       close(rrd_file->fd);
        return(-1);
     }
     
@@ -1411,23 +1404,13 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
        will let the data off the hook as soon as it is written when if it is from a previous
        update cycle. Calling fdsync to force things is much too hard here. */
 
-    if (0 != posix_fadvise(fileno(rrd_file), rra_begin, 0, POSIX_FADV_DONTNEED)) {
+    if (0 != posix_fadvise(rrd_file->fd, rra_begin, 0, POSIX_FADV_DONTNEED)) {
          rrd_set_error("setting POSIX_FADV_DONTNEED on '%s': %s",filename, rrd_strerror(errno));
-         fclose(rrd_file);
+         close(rrd_file->fd);
          return(-1);
     } 
 #endif
-
-    /* OK now close the files and free the memory */
-    if(fclose(rrd_file) != 0){
-       rrd_set_error("closing rrd");
-       free(updvals);
-       free(tmpl_idx);
-       rrd_free(&rrd);
-       free(pdp_temp);
-       free(pdp_new);
-       return(-1);
-    }
+    /*XXX: ? */rrd_flush(rrd_file);
 
     /* calling the smoothing code here guarantees at most
         * one smoothing operation per rrd_update call. Unfortunately,
@@ -1436,7 +1419,7 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
         * critical except during the burning cycles. */
        if (schedule_smooth)
        {
-         rrd_file = fopen(filename,"rb+");
+//       in_file = fopen(filename,"rb+");
           
 
          rra_start = rra_begin;
@@ -1457,14 +1440,26 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
          }
 #ifdef HAVE_POSIX_FADVISExxx
           /* same procedure as above ... */
-          if (0 != posix_fadvise(fileno(rrd_file), rra_begin, 0, POSIX_FADV_DONTNEED)) {
+          if (0 != posix_fadvise(rrd_file->fd, rra_begin, 0, POSIX_FADV_DONTNEED)) {
              rrd_set_error("setting POSIX_FADV_DONTNEED on '%s': %s",filename, rrd_strerror(errno));
-             fclose(rrd_file);
+             close(rrd_file->fd);
              return(-1);
           } 
 #endif
-         fclose(rrd_file);
+         close(rrd_file->fd);
        }
+
+    /* OK now close the files and free the memory */
+    if(close(rrd_file->fd) != 0){
+       rrd_set_error("closing rrd");
+       free(updvals);
+       free(tmpl_idx);
+       rrd_free(&rrd);
+       free(pdp_temp);
+       free(pdp_new);
+       return(-1);
+    }
+
     rrd_free(&rrd);
     free(updvals);
     free(tmpl_idx);
@@ -1480,19 +1475,16 @@ _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv
  * returns 0 on success
  */
 int
-LockRRD(FILE *rrdfile)
+LockRRD(int in_file)
 {
-    int        rrd_fd;         /* File descriptor for RRD */
     int        rcstat;
 
-    rrd_fd = fileno(rrdfile);
-
        {
 #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
     struct _stat st;
 
-    if ( _fstat( rrd_fd, &st ) == 0 ) {
-           rcstat = _locking ( rrd_fd, _LK_NBLCK, st.st_size );
+    if ( _fstat( in_file, &st ) == 0 ) {
+           rcstat = _locking ( in_file, _LK_NBLCK, st.st_size );
     } else {
            rcstat = -1;
     }
@@ -1503,7 +1495,7 @@ LockRRD(FILE *rrdfile)
     lock.l_start = 0;        /* start of file */
     lock.l_whence = SEEK_SET;   /* end of file */
 
-    rcstat = fcntl(rrd_fd, F_SETLK, &lock);
+    rcstat = fcntl(in_file, F_SETLK, &lock);
 #endif
        }
 
@@ -1516,15 +1508,15 @@ info_t
 *write_RRA_row (rrd_t *rrd, unsigned long rra_idx, unsigned long *rra_current,
               unsigned short CDP_scratch_idx, 
 #ifndef DEBUG
-FILE UNUSED(*rrd_file),
+int UNUSED(in_file),
 #else
-FILE *rrd_file,
+int in_file,
 #endif
                   info_t *pcdp_summary, time_t *rra_time, void *rrd_mmaped_file)
 #else
 info_t
 *write_RRA_row (rrd_t *rrd, unsigned long rra_idx, unsigned long *rra_current,
-              unsigned short CDP_scratch_idx, FILE *rrd_file,
+              unsigned short CDP_scratch_idx, int in_file,
                   info_t *pcdp_summary, time_t *rra_time)
 #endif
 {
@@ -1537,7 +1529,7 @@ info_t
       cdp_idx =rra_idx * (rrd -> stat_head->ds_cnt) + ds_idx;
 #ifdef DEBUG
          fprintf(stderr,"  -- RRA WRITE VALUE %e, at %ld CF:%s\n",
-            rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val,ftell(rrd_file),
+            rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val,rrd_file->pos,
             rrd -> rra_def[rra_idx].cf_nam);
 #endif 
       if (pcdp_summary != NULL)
@@ -1555,8 +1547,8 @@ info_t
                          &(rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val),
                          sizeof(rrd_value_t));
 #else
-         if(fwrite(&(rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val),
-                sizeof(rrd_value_t),1,rrd_file) != 1)
+         if(rrd_write(rrd_file,&(rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val),
+                sizeof(rrd_value_t)*1) != sizeof(rrd_value_t)*1)
          { 
             rrd_set_error("writing rrd");
             return 0;
index b5ac841..ecaa4de 100644 (file)
@@ -1,5 +1,8 @@
-/* define a macro to wrap variables in that would
-   otherwhise generate UNUSED variable warnings */
+/* define a macro to wrap variables that would
+   otherwise generate UNUSED variable warnings
+   Note that GCC's attribute unused only supresses the warning, so
+   it is perfectly safe to declare something unused although it is not.
+*/
 
 #ifdef UNUSED
 #elif defined(__GNUC__)