Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Postfix/src/cleanup/   (Postfix Mailserver Version 3.11©)  Datei vom 19.1.2017 mit Größe 6 kB image not shown  

Quelle  cleanup_region.c

  Sprache: C
 

/*++
/* NAME
/* cleanup_region 3
/* SUMMARY
/* queue file region manager
/* SYNOPSIS
/* #include "cleanup.h"
/*
/* void cleanup_region_init(state)
/* CLEANUP_STATE *state;
/*
/* CLEANUP_REGION *cleanup_region_open(state, space_needed)
/* CLEANUP_STATE *state;
/* ssize_t space_needed;
/*
/* int cleanup_region_close(state, rp)
/* CLEANUP_STATE *state;
/* CLEANUP_REGION *rp;
/*
/* CLEANUP_REGION *cleanup_region_return(state, rp)
/* CLEANUP_STATE *state;
/* CLEANUP_REGION *rp;
/*
/* void cleanup_region_done(state)
/* CLEANUP_STATE *state;
/* DESCRIPTION
/* This module maintains queue file regions. Regions are created
/* on-the-fly and can be reused multiple times. Each region
/* structure consists of a file offset, a length (0 for an
/* open-ended region at the end of the file), a write offset
/* (maintained by the caller), and list linkage. Region
/* boundaries are not enforced by this module. It is up to the
/* caller to ensure that they stay within bounds.
/*
/* cleanup_region_init() performs mandatory initialization and
/* overlays an initial region structure over an already existing
/* queue file. This function must not be called before the
/* queue file is complete.
/*
/* cleanup_region_open() opens an existing region or creates
/* a new region that can accommodate at least the specified
/* amount of space. A new region is an open-ended region at
/* the end of the file; it must be closed (see next) before
/* unrelated data can be appended to the same file.
/*
/* cleanup_region_close() indicates that a region will not be
/* updated further. With an open-ended region, the region's
/* end is frozen just before the caller-maintained write offset.
/* With a close-ended region, unused space (beginning at the
/* caller-maintained write offset) may be returned to the free
/* pool.
/*
/* cleanup_region_return() returns a list of regions to the
/* free pool, and returns a null pointer. To avoid fragmentation,
/* adjacent free regions may be coalesced together.
/*
/* cleanup_region_done() destroys all in-memory information
/* that was allocated for administering queue file regions.
/*
/* Arguments:
/* .IP state
/* Queue file and message processing state. This state is
/* updated as records are processed and as errors happen.
/* .IP space_needed
/* The minimum region size needed.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/


/* System library. */

#include <sys_defs.h>
#include <sys/stat.h>

/* Utility library. */

#include <msg.h>
#include <mymalloc.h>
#include <warn_stat.h>

/* Application-specific. */

#include <cleanup.h>

/* cleanup_region_alloc - create queue file region */

static CLEANUP_REGION *cleanup_region_alloc(off_t start, off_t len)
{
    CLEANUP_REGION *rp;

    rp = (CLEANUP_REGION *) mymalloc(sizeof(*rp));
    rp->write_offs = rp->start = start;
    rp->len = len;
    rp->next = 0;

    return (rp);
}

/* cleanup_region_free - destroy region list */

static CLEANUP_REGION *cleanup_region_free(CLEANUP_REGION *regions)
{
    CLEANUP_REGION *rp;
    CLEANUP_REGION *next;

    for (rp = regions; rp != 0; rp = next) {
 next = rp->next;
 myfree((void *) rp);
    }
    return (0);
}

/* cleanup_region_init - create initial region overlay */

void    cleanup_region_init(CLEANUP_STATE *state)
{
    const char *myname = "cleanup_region_init";

    /*
     * Sanity check.
     */

    if (state->free_regions != 0 || state->body_regions != 0)
 msg_panic("%s: repeated call", myname);

    /*
     * Craft the first regions on the fly, from circumstantial evidence.
     */

    state->body_regions =
 cleanup_region_alloc(state->append_hdr_pt_target,
     state->xtra_offset - state->append_hdr_pt_target);
    if (msg_verbose)
 msg_info("%s: body start %ld len %ld",
   myname, (long) state->body_regions->start, (long) state->body_regions->len);
}

/* cleanup_region_open - open existing region or create new region */

CLEANUP_REGION *cleanup_region_open(CLEANUP_STATE *state, ssize_t len)
{
    const char *myname = "cleanup_region_open";
    CLEANUP_REGION **rpp;
    CLEANUP_REGION *rp;
    struct stat st;

    /*
     * Find the first region that is large enough, or create a new region.
     */

    for (rpp = &state->free_regions; /* see below */ ; rpp = &(rp->next)) {

 /*
  * Create an open-ended region at the end of the queue file. We
  * freeze the region size after we stop writing to it. XXX Assume
  * that fstat() returns a file size that is never less than the file
  * append offset. It is not a problem if fstat() returns a larger
  * result; we would just waste some space.
 */

 if ((rp = *rpp) == 0) {
     if (fstat(vstream_fileno(state->dst), &st) < 0)
  msg_fatal("%s: fstat file %s: %m", myname, cleanup_path);
     rp = cleanup_region_alloc(st.st_size, 0);
     break;
 }

 /*
  * Reuse an existing region.
 */

 if (rp->len >= len) {
     (*rpp) = rp->next;
     rp->next = 0;
     rp->write_offs = rp->start;
     break;
 }

 /*
  * Skip a too small region.
 */

 if (msg_verbose)
     msg_info("%s: skip start %ld len %ld < %ld",
       myname, (long) rp->start, (long) rp->len, (long) len);
    }
    if (msg_verbose)
 msg_info("%s: done start %ld len %ld",
   myname, (long) rp->start, (long) rp->len);
    return (rp);
}

/* cleanup_region_close - freeze queue file region size */

void    cleanup_region_close(CLEANUP_STATE *unused_state, CLEANUP_REGION *rp)
{
    const char *myname = "cleanup_region_close";

    /*
     * If this region is still open ended, freeze the size. If this region is
     * closed, some future version of this routine may shrink the size and
     * return the unused portion to the free pool.
     */

    if (rp->len == 0)
 rp->len = rp->write_offs - rp->start;
    if (msg_verbose)
 msg_info("%s: freeze start %ld len %ld",
   myname, (long) rp->start, (long) rp->len);
}

/* cleanup_region_return - return region list to free pool */

CLEANUP_REGION *cleanup_region_return(CLEANUP_STATE *state, CLEANUP_REGION *rp)
{
    CLEANUP_REGION **rpp;

    for (rpp = &state->free_regions; (*rpp) != 0; rpp = &(*rpp)->next)
  /* void */ ;
    *rpp = rp;
    return (0);
}

/* cleanup_region_done - destroy region metadata */

void    cleanup_region_done(CLEANUP_STATE *state)
{
    if (state->free_regions != 0)
 state->free_regions = cleanup_region_free(state->free_regions);
    if (state->body_regions != 0)
 state->body_regions = cleanup_region_free(state->body_regions);
}

Messung V0.5 in Prozent
C=76 H=94 G=85

¤ Dauer der Verarbeitung: 0.0 Sekunden  (vorverarbeitet am  2026-08-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.