X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flibpspp%2Fpool.c;h=3150c9056b2eb8c91b42662fddf2c590263a9455;hb=983dc88647eb2826dd866c8109cf3968ce1e79a9;hp=ecf263abcda8ec26324b25bb46b0045cf161e336;hpb=9f087e7aa4cdff1d5d46d5e188c0017a9d2d0029;p=pspp diff --git a/src/libpspp/pool.c b/src/libpspp/pool.c index ecf263abcd..3150c9056b 100644 --- a/src/libpspp/pool.c +++ b/src/libpspp/pool.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 2010, 2011, 2012 Free Software Foundation, Inc. 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 @@ -15,14 +15,18 @@ along with this program. If not, see . */ #include -#include "pool.h" + +#include "libpspp/pool.h" + +#include #include -#include -#include "message.h" -#include "str.h" -#include "size_max.h" -#include "xalloc.h" +#include "libpspp/assertion.h" +#include "libpspp/message.h" +#include "libpspp/temp-file.h" +#include "libpspp/str.h" + +#include "gl/xalloc.h" /* Fast, low-overhead memory block suballocator. */ struct pool @@ -45,6 +49,7 @@ enum { POOL_GIZMO_MALLOC, POOL_GIZMO_FILE, + POOL_GIZMO_TEMP_FILE, POOL_GIZMO_SUBPOOL, POOL_GIZMO_REGISTERED, }; @@ -64,7 +69,7 @@ struct pool_gizmo /* Type-dependent info. */ union { - FILE *file; /* POOL_GIZMO_FILE. */ + FILE *file; /* POOL_GIZMO_FILE, POOL_GIZMO_TEMP_FILE. */ struct pool *subpool; /* POOL_GIZMO_SUBPOOL. */ /* POOL_GIZMO_REGISTERED. */ @@ -91,10 +96,16 @@ union align void (*fp) (void); long l; double d; + + /* glibc jmp_buf on ia64 requires 16-byte alignment. This ensures it. */ + size_t s[2]; }; /* This should be the alignment size used by malloc(). The size of - the union above is correct, if not optimal, in all known cases. */ + the union above is correct, if not optimal, in all known cases. + + This is normally 8 bytes for 32-bit architectures and 16 bytes for 64-bit + architectures. */ #define ALIGN_SIZE sizeof (union align) /* DISCRETE_BLOCKS may be declared as nonzero to prevent @@ -294,7 +305,8 @@ pool_alloc (struct pool *pool, size_t amt) void * pool_alloc_unaligned (struct pool *pool, size_t amt) { - assert (pool != NULL); + if (pool == NULL) + return xmalloc (amt); #ifndef DISCRETE_BLOCKS /* Strings need not be aligned on any boundary, but some @@ -364,6 +376,19 @@ pool_strdup (struct pool *pool, const char *string) return pool_clone_unaligned (pool, string, strlen (string) + 1); } +/* Duplicates the SIZE bytes of STRING, plus a trailing 0 byte, + and returns a pointer to the duplicate. For use only with + strings, because the returned pointere may not be aligned + properly for other types. */ +char * +pool_strdup0 (struct pool *pool, const char *string, size_t size) +{ + char *new_string = pool_alloc_unaligned (pool, size + 1); + memcpy (new_string, string, size); + new_string[size] = '\0'; + return new_string; +} + /* Formats FORMAT with the given ARGS in memory allocated from POOL and returns the formatted string. */ char * @@ -742,41 +767,78 @@ pool_fclose (struct pool *pool, FILE *file) return fclose (file); } -/* Creates a temporary file with tmpfile() and returns a handle to it - if successful or a null pointer if not. +/* Attaches FILE to POOL. The file will be closed automatically when POOL is destroyed, or it may be closed explicitly in advance using pool_fclose(), or detached from the pool with pool_detach_file(). */ +void +pool_attach_file (struct pool *pool, FILE *file) +{ + struct pool_gizmo *g = pool_alloc (pool, sizeof *g); + g->type = POOL_GIZMO_FILE; + g->p.file = file; + add_gizmo (pool, g); +} + +/* Detaches FILE from POOL. */ +void +pool_detach_file (struct pool *pool, FILE *file) +{ + struct pool_gizmo *g; + + for (g = pool->gizmos; g; g = g->next) + if (g->type == POOL_GIZMO_FILE && g->p.file == file) + { + delete_gizmo (pool, g); + return; + } +} + +/* Creates a temporary file with create_temp_file() and returns a handle to it + if successful or a null pointer if not. + The file will be closed automatically when POOL is destroyed, or it + may be closed explicitly in advance using pool_fclose_temp_file(), or + detached from the pool with pool_detach_temp_file(). */ FILE * -pool_tmpfile (struct pool *pool) +pool_create_temp_file (struct pool *pool) { - FILE *file = tmpfile (); + FILE *file = create_temp_file (); if (file != NULL) - pool_attach_file (pool, file); + pool_attach_temp_file (pool, file); return file; } -/* Attaches FILE to POOL. +/* Closes file FILE managed by POOL. + FILE must have been opened with create_temp_file(). */ +void +pool_fclose_temp_file (struct pool *pool, FILE *file) +{ + assert (pool && file); + pool_detach_temp_file (pool, file); + close_temp_file (file); +} + +/* Attaches FILE, which must have been opened with create_temp_file(), to POOL. The file will be closed automatically when POOL is destroyed, or it - may be closed explicitly in advance using pool_fclose(), or - detached from the pool with pool_detach_file(). */ + may be closed explicitly in advance using pool_fclose_temp_file(), or + detached from the pool with pool_detach_temp_file(). */ void -pool_attach_file (struct pool *pool, FILE *file) +pool_attach_temp_file (struct pool *pool, FILE *file) { struct pool_gizmo *g = pool_alloc (pool, sizeof *g); - g->type = POOL_GIZMO_FILE; + g->type = POOL_GIZMO_TEMP_FILE; g->p.file = file; add_gizmo (pool, g); } -/* Detaches FILE from POOL. */ +/* Detaches FILE that was opened with create_temp_file() from POOL. */ void -pool_detach_file (struct pool *pool, FILE *file) +pool_detach_temp_file (struct pool *pool, FILE *file) { struct pool_gizmo *g; for (g = pool->gizmos; g; g = g->next) - if (g->type == POOL_GIZMO_FILE && g->p.file == file) + if (g->type == POOL_GIZMO_TEMP_FILE && g->p.file == file) { delete_gizmo (pool, g); return; @@ -934,6 +996,9 @@ free_gizmo (struct pool_gizmo *gizmo) case POOL_GIZMO_FILE: fclose (gizmo->p.file); /* Ignore errors. */ break; + case POOL_GIZMO_TEMP_FILE: + close_temp_file (gizmo->p.file); /* Ignore errors. */ + break; case POOL_GIZMO_SUBPOOL: gizmo->p.subpool->parent = NULL; pool_destroy (gizmo->p.subpool);