Initial revision
This commit is contained in:
commit
1243156a5e
87 changed files with 27214 additions and 0 deletions
14
lib/Makefile.am
Normal file
14
lib/Makefile.am
Normal file
|
@ -0,0 +1,14 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
noinst_LIBRARIES = libvpn.a
|
||||
|
||||
INCLUDES = -I. -I$(top_builddir)
|
||||
|
||||
libvpn_a_SOURCES = xmalloc.c pidfile.c utils.c
|
||||
|
||||
libvpn_a_LIBADD = @LIBOBJS@ @ALLOCA@
|
||||
libvpn_a_DEPENDENCIES = $(libvpn_a_LIBADD)
|
||||
|
||||
noinst_HEADERS = xalloc.h pidfile.h utils.h
|
||||
|
||||
EXTRA_DIST = README
|
1
lib/README
Normal file
1
lib/README
Normal file
|
@ -0,0 +1 @@
|
|||
The files in this directory were merely copied from fileutils 4.0.
|
494
lib/alloca.c
Normal file
494
lib/alloca.c
Normal file
|
@ -0,0 +1,494 @@
|
|||
/* alloca.c -- allocate automatically reclaimed memory
|
||||
(Mostly) portable public-domain implementation -- D A Gwyn
|
||||
|
||||
This implementation of the PWB library alloca function,
|
||||
which is used to allocate space off the run-time stack so
|
||||
that it is automatically reclaimed upon procedure exit,
|
||||
was inspired by discussions with J. Q. Johnson of Cornell.
|
||||
J.Otto Tennant <jot@cray.com> contributed the Cray support.
|
||||
|
||||
There are some preprocessor constants that can
|
||||
be defined when compiling for your specific system, for
|
||||
improved efficiency; however, the defaults should be okay.
|
||||
|
||||
The general concept of this implementation is to keep
|
||||
track of all alloca-allocated blocks, and reclaim any
|
||||
that are found to be deeper in the stack than the current
|
||||
invocation. This heuristic does not reclaim storage as
|
||||
soon as it becomes invalid, but it will do so eventually.
|
||||
|
||||
As a special case, alloca(0) reclaims storage without
|
||||
allocating any. It is a good idea to use alloca(0) in
|
||||
your main control loop, etc. to force garbage collection. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef emacs
|
||||
# include "blockinput.h"
|
||||
#endif
|
||||
|
||||
/* If compiling with GCC 2, this file's not needed. */
|
||||
#if !defined (__GNUC__) || __GNUC__ < 2
|
||||
|
||||
/* If someone has defined alloca as a macro,
|
||||
there must be some other way alloca is supposed to work. */
|
||||
# ifndef alloca
|
||||
|
||||
# ifdef emacs
|
||||
# ifdef static
|
||||
/* actually, only want this if static is defined as ""
|
||||
-- this is for usg, in which emacs must undefine static
|
||||
in order to make unexec workable
|
||||
*/
|
||||
# ifndef STACK_DIRECTION
|
||||
you
|
||||
lose
|
||||
-- must know STACK_DIRECTION at compile-time
|
||||
# endif /* STACK_DIRECTION undefined */
|
||||
# endif /* static */
|
||||
# endif /* emacs */
|
||||
|
||||
/* If your stack is a linked list of frames, you have to
|
||||
provide an "address metric" ADDRESS_FUNCTION macro. */
|
||||
|
||||
# if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||
long i00afunc ();
|
||||
# define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
|
||||
# else
|
||||
# define ADDRESS_FUNCTION(arg) &(arg)
|
||||
# endif
|
||||
|
||||
# if __STDC__
|
||||
typedef void *pointer;
|
||||
# else
|
||||
typedef char *pointer;
|
||||
# endif
|
||||
|
||||
# ifndef NULL
|
||||
# define NULL 0
|
||||
# endif
|
||||
|
||||
/* Different portions of Emacs need to call different versions of
|
||||
malloc. The Emacs executable needs alloca to call xmalloc, because
|
||||
ordinary malloc isn't protected from input signals. On the other
|
||||
hand, the utilities in lib-src need alloca to call malloc; some of
|
||||
them are very simple, and don't have an xmalloc routine.
|
||||
|
||||
Non-Emacs programs expect this to call xmalloc.
|
||||
|
||||
Callers below should use malloc. */
|
||||
|
||||
# ifndef emacs
|
||||
# define malloc xmalloc
|
||||
# endif
|
||||
extern pointer malloc ();
|
||||
|
||||
/* Define STACK_DIRECTION if you know the direction of stack
|
||||
growth for your system; otherwise it will be automatically
|
||||
deduced at run-time.
|
||||
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
|
||||
# ifndef STACK_DIRECTION
|
||||
# define STACK_DIRECTION 0 /* Direction unknown. */
|
||||
# endif
|
||||
|
||||
# if STACK_DIRECTION != 0
|
||||
|
||||
# define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
|
||||
|
||||
# else /* STACK_DIRECTION == 0; need run-time code. */
|
||||
|
||||
static int stack_dir; /* 1 or -1 once known. */
|
||||
# define STACK_DIR stack_dir
|
||||
|
||||
static void
|
||||
find_stack_direction ()
|
||||
{
|
||||
static char *addr = NULL; /* Address of first `dummy', once known. */
|
||||
auto char dummy; /* To get stack address. */
|
||||
|
||||
if (addr == NULL)
|
||||
{ /* Initial entry. */
|
||||
addr = ADDRESS_FUNCTION (dummy);
|
||||
|
||||
find_stack_direction (); /* Recurse once. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Second entry. */
|
||||
if (ADDRESS_FUNCTION (dummy) > addr)
|
||||
stack_dir = 1; /* Stack grew upward. */
|
||||
else
|
||||
stack_dir = -1; /* Stack grew downward. */
|
||||
}
|
||||
}
|
||||
|
||||
# endif /* STACK_DIRECTION == 0 */
|
||||
|
||||
/* An "alloca header" is used to:
|
||||
(a) chain together all alloca'ed blocks;
|
||||
(b) keep track of stack depth.
|
||||
|
||||
It is very important that sizeof(header) agree with malloc
|
||||
alignment chunk size. The following default should work okay. */
|
||||
|
||||
# ifndef ALIGN_SIZE
|
||||
# define ALIGN_SIZE sizeof(double)
|
||||
# endif
|
||||
|
||||
typedef union hdr
|
||||
{
|
||||
char align[ALIGN_SIZE]; /* To force sizeof(header). */
|
||||
struct
|
||||
{
|
||||
union hdr *next; /* For chaining headers. */
|
||||
char *deep; /* For stack depth measure. */
|
||||
} h;
|
||||
} header;
|
||||
|
||||
static header *last_alloca_header = NULL; /* -> last alloca header. */
|
||||
|
||||
/* Return a pointer to at least SIZE bytes of storage,
|
||||
which will be automatically reclaimed upon exit from
|
||||
the procedure that called alloca. Originally, this space
|
||||
was supposed to be taken from the current stack frame of the
|
||||
caller, but that method cannot be made to work for some
|
||||
implementations of C, for example under Gould's UTX/32. */
|
||||
|
||||
pointer
|
||||
alloca (size)
|
||||
unsigned size;
|
||||
{
|
||||
auto char probe; /* Probes stack depth: */
|
||||
register char *depth = ADDRESS_FUNCTION (probe);
|
||||
|
||||
# if STACK_DIRECTION == 0
|
||||
if (STACK_DIR == 0) /* Unknown growth direction. */
|
||||
find_stack_direction ();
|
||||
# endif
|
||||
|
||||
/* Reclaim garbage, defined as all alloca'd storage that
|
||||
was allocated from deeper in the stack than currently. */
|
||||
|
||||
{
|
||||
register header *hp; /* Traverses linked list. */
|
||||
|
||||
# ifdef emacs
|
||||
BLOCK_INPUT;
|
||||
# endif
|
||||
|
||||
for (hp = last_alloca_header; hp != NULL;)
|
||||
if ((STACK_DIR > 0 && hp->h.deep > depth)
|
||||
|| (STACK_DIR < 0 && hp->h.deep < depth))
|
||||
{
|
||||
register header *np = hp->h.next;
|
||||
|
||||
free ((pointer) hp); /* Collect garbage. */
|
||||
|
||||
hp = np; /* -> next header. */
|
||||
}
|
||||
else
|
||||
break; /* Rest are not deeper. */
|
||||
|
||||
last_alloca_header = hp; /* -> last valid storage. */
|
||||
|
||||
# ifdef emacs
|
||||
UNBLOCK_INPUT;
|
||||
# endif
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return NULL; /* No allocation required. */
|
||||
|
||||
/* Allocate combined header + user data storage. */
|
||||
|
||||
{
|
||||
register pointer new = malloc (sizeof (header) + size);
|
||||
/* Address of header. */
|
||||
|
||||
((header *) new)->h.next = last_alloca_header;
|
||||
((header *) new)->h.deep = depth;
|
||||
|
||||
last_alloca_header = (header *) new;
|
||||
|
||||
/* User storage begins just after header. */
|
||||
|
||||
return (pointer) ((char *) new + sizeof (header));
|
||||
}
|
||||
}
|
||||
|
||||
# if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||
|
||||
# ifdef DEBUG_I00AFUNC
|
||||
# include <stdio.h>
|
||||
# endif
|
||||
|
||||
# ifndef CRAY_STACK
|
||||
# define CRAY_STACK
|
||||
# ifndef CRAY2
|
||||
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
|
||||
struct stack_control_header
|
||||
{
|
||||
long shgrow:32; /* Number of times stack has grown. */
|
||||
long shaseg:32; /* Size of increments to stack. */
|
||||
long shhwm:32; /* High water mark of stack. */
|
||||
long shsize:32; /* Current size of stack (all segments). */
|
||||
};
|
||||
|
||||
/* The stack segment linkage control information occurs at
|
||||
the high-address end of a stack segment. (The stack
|
||||
grows from low addresses to high addresses.) The initial
|
||||
part of the stack segment linkage control information is
|
||||
0200 (octal) words. This provides for register storage
|
||||
for the routine which overflows the stack. */
|
||||
|
||||
struct stack_segment_linkage
|
||||
{
|
||||
long ss[0200]; /* 0200 overflow words. */
|
||||
long sssize:32; /* Number of words in this segment. */
|
||||
long ssbase:32; /* Offset to stack base. */
|
||||
long:32;
|
||||
long sspseg:32; /* Offset to linkage control of previous
|
||||
segment of stack. */
|
||||
long:32;
|
||||
long sstcpt:32; /* Pointer to task common address block. */
|
||||
long sscsnm; /* Private control structure number for
|
||||
microtasking. */
|
||||
long ssusr1; /* Reserved for user. */
|
||||
long ssusr2; /* Reserved for user. */
|
||||
long sstpid; /* Process ID for pid based multi-tasking. */
|
||||
long ssgvup; /* Pointer to multitasking thread giveup. */
|
||||
long sscray[7]; /* Reserved for Cray Research. */
|
||||
long ssa0;
|
||||
long ssa1;
|
||||
long ssa2;
|
||||
long ssa3;
|
||||
long ssa4;
|
||||
long ssa5;
|
||||
long ssa6;
|
||||
long ssa7;
|
||||
long sss0;
|
||||
long sss1;
|
||||
long sss2;
|
||||
long sss3;
|
||||
long sss4;
|
||||
long sss5;
|
||||
long sss6;
|
||||
long sss7;
|
||||
};
|
||||
|
||||
# else /* CRAY2 */
|
||||
/* The following structure defines the vector of words
|
||||
returned by the STKSTAT library routine. */
|
||||
struct stk_stat
|
||||
{
|
||||
long now; /* Current total stack size. */
|
||||
long maxc; /* Amount of contiguous space which would
|
||||
be required to satisfy the maximum
|
||||
stack demand to date. */
|
||||
long high_water; /* Stack high-water mark. */
|
||||
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
|
||||
long hits; /* Number of internal buffer hits. */
|
||||
long extends; /* Number of block extensions. */
|
||||
long stko_mallocs; /* Block allocations by $STKOFEN. */
|
||||
long underflows; /* Number of stack underflow calls ($STKRETN). */
|
||||
long stko_free; /* Number of deallocations by $STKRETN. */
|
||||
long stkm_free; /* Number of deallocations by $STKMRET. */
|
||||
long segments; /* Current number of stack segments. */
|
||||
long maxs; /* Maximum number of stack segments so far. */
|
||||
long pad_size; /* Stack pad size. */
|
||||
long current_address; /* Current stack segment address. */
|
||||
long current_size; /* Current stack segment size. This
|
||||
number is actually corrupted by STKSTAT to
|
||||
include the fifteen word trailer area. */
|
||||
long initial_address; /* Address of initial segment. */
|
||||
long initial_size; /* Size of initial segment. */
|
||||
};
|
||||
|
||||
/* The following structure describes the data structure which trails
|
||||
any stack segment. I think that the description in 'asdef' is
|
||||
out of date. I only describe the parts that I am sure about. */
|
||||
|
||||
struct stk_trailer
|
||||
{
|
||||
long this_address; /* Address of this block. */
|
||||
long this_size; /* Size of this block (does not include
|
||||
this trailer). */
|
||||
long unknown2;
|
||||
long unknown3;
|
||||
long link; /* Address of trailer block of previous
|
||||
segment. */
|
||||
long unknown5;
|
||||
long unknown6;
|
||||
long unknown7;
|
||||
long unknown8;
|
||||
long unknown9;
|
||||
long unknown10;
|
||||
long unknown11;
|
||||
long unknown12;
|
||||
long unknown13;
|
||||
long unknown14;
|
||||
};
|
||||
|
||||
# endif /* CRAY2 */
|
||||
# endif /* not CRAY_STACK */
|
||||
|
||||
# ifdef CRAY2
|
||||
/* Determine a "stack measure" for an arbitrary ADDRESS.
|
||||
I doubt that "lint" will like this much. */
|
||||
|
||||
static long
|
||||
i00afunc (long *address)
|
||||
{
|
||||
struct stk_stat status;
|
||||
struct stk_trailer *trailer;
|
||||
long *block, size;
|
||||
long result = 0;
|
||||
|
||||
/* We want to iterate through all of the segments. The first
|
||||
step is to get the stack status structure. We could do this
|
||||
more quickly and more directly, perhaps, by referencing the
|
||||
$LM00 common block, but I know that this works. */
|
||||
|
||||
STKSTAT (&status);
|
||||
|
||||
/* Set up the iteration. */
|
||||
|
||||
trailer = (struct stk_trailer *) (status.current_address
|
||||
+ status.current_size
|
||||
- 15);
|
||||
|
||||
/* There must be at least one stack segment. Therefore it is
|
||||
a fatal error if "trailer" is null. */
|
||||
|
||||
if (trailer == 0)
|
||||
abort ();
|
||||
|
||||
/* Discard segments that do not contain our argument address. */
|
||||
|
||||
while (trailer != 0)
|
||||
{
|
||||
block = (long *) trailer->this_address;
|
||||
size = trailer->this_size;
|
||||
if (block == 0 || size == 0)
|
||||
abort ();
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
if ((block <= address) && (address < (block + size)))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the result to the offset in this segment and add the sizes
|
||||
of all predecessor segments. */
|
||||
|
||||
result = address - block;
|
||||
|
||||
if (trailer == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (trailer->this_size <= 0)
|
||||
abort ();
|
||||
result += trailer->this_size;
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
}
|
||||
while (trailer != 0);
|
||||
|
||||
/* We are done. Note that if you present a bogus address (one
|
||||
not in any segment), you will get a different number back, formed
|
||||
from subtracting the address of the first block. This is probably
|
||||
not what you want. */
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
# else /* not CRAY2 */
|
||||
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
|
||||
Determine the number of the cell within the stack,
|
||||
given the address of the cell. The purpose of this
|
||||
routine is to linearize, in some sense, stack addresses
|
||||
for alloca. */
|
||||
|
||||
static long
|
||||
i00afunc (long address)
|
||||
{
|
||||
long stkl = 0;
|
||||
|
||||
long size, pseg, this_segment, stack;
|
||||
long result = 0;
|
||||
|
||||
struct stack_segment_linkage *ssptr;
|
||||
|
||||
/* Register B67 contains the address of the end of the
|
||||
current stack segment. If you (as a subprogram) store
|
||||
your registers on the stack and find that you are past
|
||||
the contents of B67, you have overflowed the segment.
|
||||
|
||||
B67 also points to the stack segment linkage control
|
||||
area, which is what we are really interested in. */
|
||||
|
||||
stkl = CRAY_STACKSEG_END ();
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
|
||||
/* If one subtracts 'size' from the end of the segment,
|
||||
one has the address of the first word of the segment.
|
||||
|
||||
If this is not the first segment, 'pseg' will be
|
||||
nonzero. */
|
||||
|
||||
pseg = ssptr->sspseg;
|
||||
size = ssptr->sssize;
|
||||
|
||||
this_segment = stkl - size;
|
||||
|
||||
/* It is possible that calling this routine itself caused
|
||||
a stack overflow. Discard stack segments which do not
|
||||
contain the target address. */
|
||||
|
||||
while (!(this_segment <= address && address <= stkl))
|
||||
{
|
||||
# ifdef DEBUG_I00AFUNC
|
||||
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
|
||||
# endif
|
||||
if (pseg == 0)
|
||||
break;
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
this_segment = stkl - size;
|
||||
}
|
||||
|
||||
result = address - this_segment;
|
||||
|
||||
/* If you subtract pseg from the current end of the stack,
|
||||
you get the address of the previous stack segment's end.
|
||||
This seems a little convoluted to me, but I'll bet you save
|
||||
a cycle somewhere. */
|
||||
|
||||
while (pseg != 0)
|
||||
{
|
||||
# ifdef DEBUG_I00AFUNC
|
||||
fprintf (stderr, "%011o %011o\n", pseg, size);
|
||||
# endif
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
result += size;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
# endif /* not CRAY2 */
|
||||
# endif /* CRAY */
|
||||
|
||||
# endif /* no alloca */
|
||||
#endif /* not GCC version 2 */
|
39
lib/malloc.c
Normal file
39
lib/malloc.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/* Work around bug on some systems where malloc (0) fails.
|
||||
Copyright (C) 1997 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
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* written by Jim Meyering */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#undef malloc
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
char *malloc ();
|
||||
|
||||
/* Allocate an N-byte block of memory from the heap.
|
||||
If N is zero, allocate a 1-byte block. */
|
||||
|
||||
char *
|
||||
rpl_malloc (n)
|
||||
size_t n;
|
||||
{
|
||||
if (n == 0)
|
||||
n = 1;
|
||||
return malloc (n);
|
||||
}
|
391
lib/memcmp.c
Normal file
391
lib/memcmp.c
Normal file
|
@ -0,0 +1,391 @@
|
|||
/* Copyright (C) 1991, 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
|
||||
Contributed by Torbjorn Granlund (tege@sics.se).
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the GNU C Library.
|
||||
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#undef __ptr_t
|
||||
#if defined __cplusplus || (defined __STDC__ && __STDC__)
|
||||
# define __ptr_t void *
|
||||
#else /* Not C++ or ANSI C. */
|
||||
# undef const
|
||||
# define const
|
||||
# define __ptr_t char *
|
||||
#endif /* C++ or ANSI C. */
|
||||
|
||||
#ifndef __P
|
||||
# if defined __GNUC__ || (defined __STDC__ && __STDC__)
|
||||
# define __P(args) args
|
||||
# else
|
||||
# define __P(args) ()
|
||||
# endif /* GCC. */
|
||||
#endif /* Not __P. */
|
||||
|
||||
#if defined HAVE_STRING_H || defined _LIBC
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
#undef memcmp
|
||||
|
||||
#ifdef _LIBC
|
||||
|
||||
# include <memcopy.h>
|
||||
|
||||
#else /* Not in the GNU C library. */
|
||||
|
||||
# include <sys/types.h>
|
||||
|
||||
/* Type to use for aligned memory operations.
|
||||
This should normally be the biggest type supported by a single load
|
||||
and store. Must be an unsigned type. */
|
||||
# define op_t unsigned long int
|
||||
# define OPSIZ (sizeof(op_t))
|
||||
|
||||
/* Threshold value for when to enter the unrolled loops. */
|
||||
# define OP_T_THRES 16
|
||||
|
||||
/* Type to use for unaligned operations. */
|
||||
typedef unsigned char byte;
|
||||
|
||||
# ifndef WORDS_BIGENDIAN
|
||||
# define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
|
||||
# else
|
||||
# define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2)))
|
||||
# endif
|
||||
|
||||
#endif /* In the GNU C library. */
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# define CMP_LT_OR_GT(a, b) ((a) > (b) ? 1 : -1)
|
||||
#else
|
||||
# define CMP_LT_OR_GT(a, b) memcmp_bytes ((a), (b))
|
||||
#endif
|
||||
|
||||
/* BE VERY CAREFUL IF YOU CHANGE THIS CODE! */
|
||||
|
||||
/* The strategy of this memcmp is:
|
||||
|
||||
1. Compare bytes until one of the block pointers is aligned.
|
||||
|
||||
2. Compare using memcmp_common_alignment or
|
||||
memcmp_not_common_alignment, regarding the alignment of the other
|
||||
block after the initial byte operations. The maximum number of
|
||||
full words (of type op_t) are compared in this way.
|
||||
|
||||
3. Compare the few remaining bytes. */
|
||||
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
/* memcmp_bytes -- Compare A and B bytewise in the byte order of the machine.
|
||||
A and B are known to be different.
|
||||
This is needed only on little-endian machines. */
|
||||
|
||||
static int memcmp_bytes __P((op_t, op_t));
|
||||
|
||||
# ifdef __GNUC__
|
||||
__inline
|
||||
# endif
|
||||
static int
|
||||
memcmp_bytes (a, b)
|
||||
op_t a, b;
|
||||
{
|
||||
long int srcp1 = (long int) &a;
|
||||
long int srcp2 = (long int) &b;
|
||||
op_t a0, b0;
|
||||
|
||||
do
|
||||
{
|
||||
a0 = ((byte *) srcp1)[0];
|
||||
b0 = ((byte *) srcp2)[0];
|
||||
srcp1 += 1;
|
||||
srcp2 += 1;
|
||||
}
|
||||
while (a0 == b0);
|
||||
return a0 - b0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int memcmp_common_alignment __P((long, long, size_t));
|
||||
|
||||
/* memcmp_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN `op_t'
|
||||
objects (not LEN bytes!). Both SRCP1 and SRCP2 should be aligned for
|
||||
memory operations on `op_t's. */
|
||||
#ifdef __GNUC__
|
||||
__inline
|
||||
#endif
|
||||
static int
|
||||
memcmp_common_alignment (srcp1, srcp2, len)
|
||||
long int srcp1;
|
||||
long int srcp2;
|
||||
size_t len;
|
||||
{
|
||||
op_t a0, a1;
|
||||
op_t b0, b1;
|
||||
|
||||
switch (len % 4)
|
||||
{
|
||||
default: /* Avoid warning about uninitialized local variables. */
|
||||
case 2:
|
||||
a0 = ((op_t *) srcp1)[0];
|
||||
b0 = ((op_t *) srcp2)[0];
|
||||
srcp1 -= 2 * OPSIZ;
|
||||
srcp2 -= 2 * OPSIZ;
|
||||
len += 2;
|
||||
goto do1;
|
||||
case 3:
|
||||
a1 = ((op_t *) srcp1)[0];
|
||||
b1 = ((op_t *) srcp2)[0];
|
||||
srcp1 -= OPSIZ;
|
||||
srcp2 -= OPSIZ;
|
||||
len += 1;
|
||||
goto do2;
|
||||
case 0:
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
|
||||
return 0;
|
||||
a0 = ((op_t *) srcp1)[0];
|
||||
b0 = ((op_t *) srcp2)[0];
|
||||
goto do3;
|
||||
case 1:
|
||||
a1 = ((op_t *) srcp1)[0];
|
||||
b1 = ((op_t *) srcp2)[0];
|
||||
srcp1 += OPSIZ;
|
||||
srcp2 += OPSIZ;
|
||||
len -= 1;
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
|
||||
goto do0;
|
||||
/* Fall through. */
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
a0 = ((op_t *) srcp1)[0];
|
||||
b0 = ((op_t *) srcp2)[0];
|
||||
if (a1 != b1)
|
||||
return CMP_LT_OR_GT (a1, b1);
|
||||
|
||||
do3:
|
||||
a1 = ((op_t *) srcp1)[1];
|
||||
b1 = ((op_t *) srcp2)[1];
|
||||
if (a0 != b0)
|
||||
return CMP_LT_OR_GT (a0, b0);
|
||||
|
||||
do2:
|
||||
a0 = ((op_t *) srcp1)[2];
|
||||
b0 = ((op_t *) srcp2)[2];
|
||||
if (a1 != b1)
|
||||
return CMP_LT_OR_GT (a1, b1);
|
||||
|
||||
do1:
|
||||
a1 = ((op_t *) srcp1)[3];
|
||||
b1 = ((op_t *) srcp2)[3];
|
||||
if (a0 != b0)
|
||||
return CMP_LT_OR_GT (a0, b0);
|
||||
|
||||
srcp1 += 4 * OPSIZ;
|
||||
srcp2 += 4 * OPSIZ;
|
||||
len -= 4;
|
||||
}
|
||||
while (len != 0);
|
||||
|
||||
/* This is the right position for do0. Please don't move
|
||||
it into the loop. */
|
||||
do0:
|
||||
if (a1 != b1)
|
||||
return CMP_LT_OR_GT (a1, b1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int memcmp_not_common_alignment __P((long, long, size_t));
|
||||
|
||||
/* memcmp_not_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN
|
||||
`op_t' objects (not LEN bytes!). SRCP2 should be aligned for memory
|
||||
operations on `op_t', but SRCP1 *should be unaligned*. */
|
||||
#ifdef __GNUC__
|
||||
__inline
|
||||
#endif
|
||||
static int
|
||||
memcmp_not_common_alignment (srcp1, srcp2, len)
|
||||
long int srcp1;
|
||||
long int srcp2;
|
||||
size_t len;
|
||||
{
|
||||
op_t a0, a1, a2, a3;
|
||||
op_t b0, b1, b2, b3;
|
||||
op_t x;
|
||||
int shl, shr;
|
||||
|
||||
/* Calculate how to shift a word read at the memory operation
|
||||
aligned srcp1 to make it aligned for comparison. */
|
||||
|
||||
shl = 8 * (srcp1 % OPSIZ);
|
||||
shr = 8 * OPSIZ - shl;
|
||||
|
||||
/* Make SRCP1 aligned by rounding it down to the beginning of the `op_t'
|
||||
it points in the middle of. */
|
||||
srcp1 &= -OPSIZ;
|
||||
|
||||
switch (len % 4)
|
||||
{
|
||||
default: /* Avoid warning about uninitialized local variables. */
|
||||
case 2:
|
||||
a1 = ((op_t *) srcp1)[0];
|
||||
a2 = ((op_t *) srcp1)[1];
|
||||
b2 = ((op_t *) srcp2)[0];
|
||||
srcp1 -= 1 * OPSIZ;
|
||||
srcp2 -= 2 * OPSIZ;
|
||||
len += 2;
|
||||
goto do1;
|
||||
case 3:
|
||||
a0 = ((op_t *) srcp1)[0];
|
||||
a1 = ((op_t *) srcp1)[1];
|
||||
b1 = ((op_t *) srcp2)[0];
|
||||
srcp2 -= 1 * OPSIZ;
|
||||
len += 1;
|
||||
goto do2;
|
||||
case 0:
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
|
||||
return 0;
|
||||
a3 = ((op_t *) srcp1)[0];
|
||||
a0 = ((op_t *) srcp1)[1];
|
||||
b0 = ((op_t *) srcp2)[0];
|
||||
srcp1 += 1 * OPSIZ;
|
||||
goto do3;
|
||||
case 1:
|
||||
a2 = ((op_t *) srcp1)[0];
|
||||
a3 = ((op_t *) srcp1)[1];
|
||||
b3 = ((op_t *) srcp2)[0];
|
||||
srcp1 += 2 * OPSIZ;
|
||||
srcp2 += 1 * OPSIZ;
|
||||
len -= 1;
|
||||
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
|
||||
goto do0;
|
||||
/* Fall through. */
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
a0 = ((op_t *) srcp1)[0];
|
||||
b0 = ((op_t *) srcp2)[0];
|
||||
x = MERGE(a2, shl, a3, shr);
|
||||
if (x != b3)
|
||||
return CMP_LT_OR_GT (x, b3);
|
||||
|
||||
do3:
|
||||
a1 = ((op_t *) srcp1)[1];
|
||||
b1 = ((op_t *) srcp2)[1];
|
||||
x = MERGE(a3, shl, a0, shr);
|
||||
if (x != b0)
|
||||
return CMP_LT_OR_GT (x, b0);
|
||||
|
||||
do2:
|
||||
a2 = ((op_t *) srcp1)[2];
|
||||
b2 = ((op_t *) srcp2)[2];
|
||||
x = MERGE(a0, shl, a1, shr);
|
||||
if (x != b1)
|
||||
return CMP_LT_OR_GT (x, b1);
|
||||
|
||||
do1:
|
||||
a3 = ((op_t *) srcp1)[3];
|
||||
b3 = ((op_t *) srcp2)[3];
|
||||
x = MERGE(a1, shl, a2, shr);
|
||||
if (x != b2)
|
||||
return CMP_LT_OR_GT (x, b2);
|
||||
|
||||
srcp1 += 4 * OPSIZ;
|
||||
srcp2 += 4 * OPSIZ;
|
||||
len -= 4;
|
||||
}
|
||||
while (len != 0);
|
||||
|
||||
/* This is the right position for do0. Please don't move
|
||||
it into the loop. */
|
||||
do0:
|
||||
x = MERGE(a2, shl, a3, shr);
|
||||
if (x != b3)
|
||||
return CMP_LT_OR_GT (x, b3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rpl_memcmp (s1, s2, len)
|
||||
const __ptr_t s1;
|
||||
const __ptr_t s2;
|
||||
size_t len;
|
||||
{
|
||||
op_t a0;
|
||||
op_t b0;
|
||||
long int srcp1 = (long int) s1;
|
||||
long int srcp2 = (long int) s2;
|
||||
op_t res;
|
||||
|
||||
if (len >= OP_T_THRES)
|
||||
{
|
||||
/* There are at least some bytes to compare. No need to test
|
||||
for LEN == 0 in this alignment loop. */
|
||||
while (srcp2 % OPSIZ != 0)
|
||||
{
|
||||
a0 = ((byte *) srcp1)[0];
|
||||
b0 = ((byte *) srcp2)[0];
|
||||
srcp1 += 1;
|
||||
srcp2 += 1;
|
||||
res = a0 - b0;
|
||||
if (res != 0)
|
||||
return res;
|
||||
len -= 1;
|
||||
}
|
||||
|
||||
/* SRCP2 is now aligned for memory operations on `op_t'.
|
||||
SRCP1 alignment determines if we can do a simple,
|
||||
aligned compare or need to shuffle bits. */
|
||||
|
||||
if (srcp1 % OPSIZ == 0)
|
||||
res = memcmp_common_alignment (srcp1, srcp2, len / OPSIZ);
|
||||
else
|
||||
res = memcmp_not_common_alignment (srcp1, srcp2, len / OPSIZ);
|
||||
if (res != 0)
|
||||
return res;
|
||||
|
||||
/* Number of bytes remaining in the interval [0..OPSIZ-1]. */
|
||||
srcp1 += len & -OPSIZ;
|
||||
srcp2 += len & -OPSIZ;
|
||||
len %= OPSIZ;
|
||||
}
|
||||
|
||||
/* There are just a few bytes to compare. Use byte memory operations. */
|
||||
while (len != 0)
|
||||
{
|
||||
a0 = ((byte *) srcp1)[0];
|
||||
b0 = ((byte *) srcp2)[0];
|
||||
srcp1 += 1;
|
||||
srcp2 += 1;
|
||||
res = a0 - b0;
|
||||
if (res != 0)
|
||||
return res;
|
||||
len -= 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef weak_alias
|
||||
# undef bcmp
|
||||
weak_alias (memcmp, bcmp)
|
||||
#endif
|
131
lib/pidfile.c
Normal file
131
lib/pidfile.c
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
pidfile.c - interact with pidfiles
|
||||
Copyright (c) 1995 Martin Schulze <Martin.Schulze@Linux.DE>
|
||||
|
||||
This file is part of the sysklogd package, a kernel and system log daemon.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA
|
||||
*/
|
||||
|
||||
/* left unaltered for tinc -- Ivo Timmermans */
|
||||
/*
|
||||
* Sat Aug 19 13:24:33 MET DST 1995: Martin Schulze
|
||||
* First version (v0.2) released
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
/* read_pid
|
||||
*
|
||||
* Reads the specified pidfile and returns the read pid.
|
||||
* 0 is returned if either there's no pidfile, it's empty
|
||||
* or no pid can be read.
|
||||
*/
|
||||
int read_pid (char *pidfile)
|
||||
{
|
||||
FILE *f;
|
||||
int pid;
|
||||
|
||||
if (!(f=fopen(pidfile,"r")))
|
||||
return 0;
|
||||
fscanf(f,"%d", &pid);
|
||||
fclose(f);
|
||||
return pid;
|
||||
}
|
||||
|
||||
/* check_pid
|
||||
*
|
||||
* Reads the pid using read_pid and looks up the pid in the process
|
||||
* table (using /proc) to determine if the process already exists. If
|
||||
* so 1 is returned, otherwise 0.
|
||||
*/
|
||||
int check_pid (char *pidfile)
|
||||
{
|
||||
int pid = read_pid(pidfile);
|
||||
|
||||
/* Amazing ! _I_ am already holding the pid file... */
|
||||
if ((!pid) || (pid == getpid ()))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The 'standard' method of doing this is to try and do a 'fake' kill
|
||||
* of the process. If an ESRCH error is returned the process cannot
|
||||
* be found -- GW
|
||||
*/
|
||||
/* But... errno is usually changed only on error.. */
|
||||
if (kill(pid, 0) && errno == ESRCH)
|
||||
return(0);
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
/* write_pid
|
||||
*
|
||||
* Writes the pid to the specified file. If that fails 0 is
|
||||
* returned, otherwise the pid.
|
||||
*/
|
||||
int write_pid (char *pidfile)
|
||||
{
|
||||
FILE *f;
|
||||
int fd;
|
||||
int pid;
|
||||
|
||||
if ( ((fd = open(pidfile, O_RDWR|O_CREAT, 0644)) == -1)
|
||||
|| ((f = fdopen(fd, "r+")) == NULL) ) {
|
||||
fprintf(stderr, "Can't open or create %s.\n", pidfile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (flock(fd, LOCK_EX|LOCK_NB) == -1) {
|
||||
fscanf(f, "%d", &pid);
|
||||
fclose(f);
|
||||
printf("Can't lock, lock is held by pid %d.\n", pid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pid = getpid();
|
||||
if (!fprintf(f,"%d\n", pid)) {
|
||||
printf("Can't write pid , %s.\n", strerror(errno));
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
fflush(f);
|
||||
|
||||
if (flock(fd, LOCK_UN) == -1) {
|
||||
printf("Can't unlock pidfile %s, %s.\n", pidfile, strerror(errno));
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
/* remove_pid
|
||||
*
|
||||
* Remove the the specified file. The result from unlink(2)
|
||||
* is returned
|
||||
*/
|
||||
int remove_pid (char *pidfile)
|
||||
{
|
||||
return unlink (pidfile);
|
||||
}
|
||||
|
50
lib/pidfile.h
Normal file
50
lib/pidfile.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
pidfile.h - interact with pidfiles
|
||||
Copyright (c) 1995 Martin Schulze <Martin.Schulze@Linux.DE>
|
||||
|
||||
This file is part of the sysklogd package, a kernel and system log daemon.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
|
||||
*/
|
||||
|
||||
/* read_pid
|
||||
*
|
||||
* Reads the specified pidfile and returns the read pid.
|
||||
* 0 is returned if either there's no pidfile, it's empty
|
||||
* or no pid can be read.
|
||||
*/
|
||||
int read_pid (char *pidfile);
|
||||
|
||||
/* check_pid
|
||||
*
|
||||
* Reads the pid using read_pid and looks up the pid in the process
|
||||
* table (using /proc) to determine if the process already exists. If
|
||||
* so 1 is returned, otherwise 0.
|
||||
*/
|
||||
int check_pid (char *pidfile);
|
||||
|
||||
/* write_pid
|
||||
*
|
||||
* Writes the pid to the specified file. If that fails 0 is
|
||||
* returned, otherwise the pid.
|
||||
*/
|
||||
int write_pid (char *pidfile);
|
||||
|
||||
/* remove_pid
|
||||
*
|
||||
* Remove the the specified file. The result from unlink(2)
|
||||
* is returned
|
||||
*/
|
||||
int remove_pid (char *pidfile);
|
44
lib/realloc.c
Normal file
44
lib/realloc.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/* Work around bug on some systems where realloc (NULL, 0) fails.
|
||||
Copyright (C) 1997 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
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* written by Jim Meyering */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#undef realloc
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
char *malloc ();
|
||||
char *realloc ();
|
||||
|
||||
/* Change the size of an allocated block of memory P to N bytes,
|
||||
with error checking. If N is zero, change it to 1. If P is NULL,
|
||||
use malloc. */
|
||||
|
||||
char *
|
||||
rpl_realloc (p, n)
|
||||
char *p;
|
||||
size_t n;
|
||||
{
|
||||
if (n == 0)
|
||||
n = 1;
|
||||
if (p == 0)
|
||||
return malloc (n);
|
||||
return realloc (p, n);
|
||||
}
|
26
lib/utils.c
Normal file
26
lib/utils.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
utils.c -- gathering of some stupid small functions
|
||||
Copyright (C) 1999 Ivo Timmermans <zarq@iname.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <utils.h>
|
||||
|
||||
volatile int cp_line;
|
||||
volatile char *cp_file;
|
||||
|
30
lib/utils.h
Normal file
30
lib/utils.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
utils.h -- header file for utils.c
|
||||
Copyright (C) 1999 Ivo Timmermans <zarq@iname.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __TINC_UTILS_H__
|
||||
#define __TINC_UTILS_H__
|
||||
|
||||
#define min(a,b) (((a)<(b))?(a):(b))
|
||||
|
||||
#define cp { cp_line = __LINE__; cp_file = __FILE__; }
|
||||
|
||||
extern volatile int cp_line;
|
||||
extern volatile char *cp_file;
|
||||
|
||||
#endif /* __TINC_UTILS_H__ */
|
21
lib/xalloc.h
Normal file
21
lib/xalloc.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef PARAMS
|
||||
# if defined PROTOTYPES || (defined __STDC__ && __STDC__)
|
||||
# define PARAMS(Args) Args
|
||||
# else
|
||||
# define PARAMS(Args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Exit value when the requested amount of memory is not available.
|
||||
The caller may set it to some other value. */
|
||||
extern int xalloc_exit_failure;
|
||||
|
||||
/* FIXME: describe */
|
||||
extern char *const xalloc_msg_memory_exhausted;
|
||||
|
||||
/* FIXME: describe */
|
||||
extern void (*xalloc_fail_func) ();
|
||||
|
||||
void *xmalloc PARAMS ((size_t n));
|
||||
void *xcalloc PARAMS ((size_t n, size_t s));
|
||||
void *xrealloc PARAMS ((void *p, size_t n));
|
133
lib/xmalloc.c
Normal file
133
lib/xmalloc.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
/* xmalloc.c -- malloc with out of memory checking
|
||||
Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 97 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
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
void *calloc ();
|
||||
void *malloc ();
|
||||
void *realloc ();
|
||||
void free ();
|
||||
#endif
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(Text) gettext (Text)
|
||||
#else
|
||||
# define textdomain(Domain)
|
||||
# define _(Text) Text
|
||||
#endif
|
||||
#define N_(Text) Text
|
||||
|
||||
#include "error.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
#ifndef EXIT_FAILURE
|
||||
# define EXIT_FAILURE 1
|
||||
#endif
|
||||
|
||||
/* Prototypes for functions defined here. */
|
||||
#if defined (__STDC__) && __STDC__
|
||||
void *xmalloc (size_t n);
|
||||
void *xcalloc (size_t n, size_t s);
|
||||
void *xrealloc (void *p, size_t n);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_DONE_WORKING_MALLOC_CHECK
|
||||
you must run the autoconf test for a properly working malloc -- see malloc.m4
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_DONE_WORKING_REALLOC_CHECK
|
||||
you must run the autoconf test for a properly working realloc -- see realloc.m4
|
||||
#endif
|
||||
|
||||
/* Exit value when the requested amount of memory is not available.
|
||||
The caller may set it to some other value. */
|
||||
int xalloc_exit_failure = EXIT_FAILURE;
|
||||
|
||||
/* FIXME: describe */
|
||||
char *const xalloc_msg_memory_exhausted = N_("Memory exhausted");
|
||||
|
||||
/* FIXME: describe */
|
||||
void (*xalloc_fail_func) () = 0;
|
||||
|
||||
#if __STDC__ && (HAVE_VPRINTF || HAVE_DOPRNT)
|
||||
void error (int, int, const char *, ...);
|
||||
#else
|
||||
void error ();
|
||||
#endif
|
||||
|
||||
static void
|
||||
xalloc_fail ()
|
||||
{
|
||||
if (xalloc_fail_func)
|
||||
(*xalloc_fail_func) ();
|
||||
error (xalloc_exit_failure, 0, xalloc_msg_memory_exhausted);
|
||||
}
|
||||
|
||||
/* Allocate N bytes of memory dynamically, with error checking. */
|
||||
|
||||
void *
|
||||
xmalloc (n)
|
||||
size_t n;
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = malloc (n);
|
||||
if (p == 0)
|
||||
xalloc_fail ();
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Change the size of an allocated block of memory P to N bytes,
|
||||
with error checking.
|
||||
If P is NULL, run xmalloc. */
|
||||
|
||||
void *
|
||||
xrealloc (p, n)
|
||||
void *p;
|
||||
size_t n;
|
||||
{
|
||||
p = realloc (p, n);
|
||||
if (p == 0)
|
||||
xalloc_fail ();
|
||||
return p;
|
||||
}
|
||||
|
||||
#ifdef NOT_USED
|
||||
|
||||
/* Allocate memory for N elements of S bytes, with error checking. */
|
||||
|
||||
void *
|
||||
xcalloc (n, s)
|
||||
size_t n, s;
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = calloc (n, s);
|
||||
if (p == 0)
|
||||
xalloc_fail ();
|
||||
return p;
|
||||
}
|
||||
|
||||
#endif /* NOT_USED */
|
Loading…
Add table
Add a link
Reference in a new issue