Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
UKCPROG(3)		   Library Functions Manual		    UKCPROG(3)

       ukcprog - Library of utilities for C programmers

       In source code,

	      #include <ukcprog.h>

       and link	with

	      cc ... -lukcprog

       This  is	 a  UKC	 library,  available  for  the	UNIX and VMS operating
       systems,	and for	MS-DOS.	 The source code is freely available so	if you
       want  to	 make  a  source release of your application you can include a
       copy of the source of this library as well.

       The ukcprog library contains generally useful low level routines.   The
       ukcprog.h  header  file contains	prototypes for the routines as well as
       defining	some useful macros and types.

	      #ifdef __STDC__
	      #define PROTO(a)	  a
	      typedef void *voidptr;
	      #define PROTO(a)	  ()
	      #define const
	      #define volatile
	      #define signed
	      typedef char *voidptr;

       The definitions of const,  volatile  and	 signed	 allow	these  ANSI  C
       keywords	 to  be	 used  in  code	 which	must be	portable to pre-ANSI C

       The voidptr typedef is similarly	there to help with code	 for  pre-ANSI
       compilers  which	do not support the `void *' type.  Functions which are
       documented here as returning `void *' return `char  *'  when  compiling
       with a non-ANSI C compiler.

       The  PROTO  macro  is  useful for declaring function prototypes for use
       with ANSI C while still allowing	the  code  to  be  compiled  with  K&R
       compilers.  It is used thus:

	      int myfunc PROTO((int arg1, char *arg2));

       With an ANSI C compiler this expands to

	      int myfunc (int arg1, char *arg2);

       whereas a pre-ANSI compiler sees:

	      int myfunc ();

       Note  the  double  brackets;  these  are	 necessary  to	make  all  the
       parameters a single argument to the PROTO macro.

	      #ifndef FALSE
	      #define FALSE   0
	      #ifndef TRUE
	      #define TRUE    1
	      #ifndef bool
	      #define bool int

       These define the	commonly used TRUE and FALSE  macros  to  their	 usual
       values.	 The  definitions  are	protected  in  case  these are already
       defined.	 The bool macro	is intended to be used to  declared  variables
       that are	conceptually boolean.  A #define is used rather	than a typedef
       because there might already be a	typedef	for bool.

	      #ifdef __STDC__
	      #define CAT(a,b)	      a	## b
	      #define _IDENT(a)	a
	      #define CAT(a,b) _IDENT(a)b
	      #endif /*	!__STDC__ */

       The CAT macro can be used to glue two tokens together in	the  same  way
       as the ANSI C ##	operator.  CAT also works with many (but not all) pre-
       ANSI C preprocessors.

	      void panic(const char *message)

	      typedef void (*panic_handler_t)(const char *message);
	      panic_handler_t install_panic_handler(panic_hander_t handler)

       By default panic() produces a message on	stderr of the form

	      fatal internal error: something (aborting)...

       It then calls abort(3) to produce  a  core  dump.   Alternative	`panic
       handlers'  can be installed using install_panic_handler() which returns
       the previous handler.  Panic handlers can perform tidy-up  tasks,  such
       as removing temporary files or calling chdir(2) to arrange for the core
       to land in a safe place.	 If a panic handler is called and returns then
       the default action is carried out.

	      void *e_malloc(size_t size)
	      void *e_realloc(void *old, size_t	size)
	      char *strsave(const char *str)

       e_malloc()   and	  e_realloc()	are  error-checking  versions  of  the
       corresponding routines in the standard C	library.  They call panic() if
       the   request   fails.	e_realloc()  behaves  according	 to  the  ANSI
       specification for realloc(); that is, if	old is NULL  it	 behaves  like
       malloc()	and if size is 0, it behaves like free().  strsave() allocates
       some memory using e_malloc(), copies str	into it, and returns a pointer
       to the copy.

	      char *fpgetline(FILE *fp)

       fpgetline()  reads  characters  from  the standard IO stream fp until a
       newline character or EOF	is encountered.	 fpgetline() returns  NULL  if
       EOF  or an error	occurred before	any characters were read; otherwise it
       returns a pointer to the	NUL terminated line.  fpgetline() never	adds a
       newline	to the buffer.	The user can check for a missing final newline
       in a file  by  checking	the  EOF  flag	of  the	 stream	 pointer  when
       fpgetline() returns a non-NULL pointer.

       When  fpgetline()  returns  NULL	the caller should check	with ferror(3)
       whether the cause was EOF or an error reading the stream	fp.

       fpgetline() returns a pointer to	a static buffer	 that  is  resized  as
       necessary  to handle long lines.	 The caller can	modify the contents of
       the buffer but must not free it or realloc it.	The  buffer  is	 valid
       only until the next call	of fpgetline().

	      char *config_trim_line(char *line)

       config_trim_line() trims	comments and white space in place from a line.
       First it	scans for the first `#'	character in the line.	 If  there  is
       one  it	is  removed along with any following characters.  Then leading
       and trailing whitespace	characters  (as	 defined  by  isspace(3))  are
       removed.	  config_trim_line()  returns  a  pointer  to the trimmed line
       (which will point into the line that it was given).

       A typical use of	this routine is	to skip	blank lines and	comments  from
       a configuration file.

	      typedef void (*errf_ofunc_t)(const char *string);

	      void errf(const char *fmt, ...)
	      char *strf(const char *fmt, ...)

	      errf_ofunc_t errf_set_ofunc(errf_ofunc_t func)
	      const char *errf_set_prefix(const	char *prefix)
	      const char *errf_get_prefix(void)
	      void_errf_set_progname(const char	*progname)
	      const char *errf_get_progname(void)
	      char *formf(char *buffer,	int buffer_size,
			  const	char *format, va_list args)
	      void errf_usage(const char *usage)

       These  routines	form the basis of a generalised	error handling system.
       errf() formats an error message,	much like printf(3), but  then	passes
       the  formatted  text  to	 the  `current	output function'.  The default
       output function appends a newline  to  the  message  and	 sends	it  to
       stderr.	  An   alternative  output  function  can  be  installed  with
       errf_set_ofunc(); it returns the	old one	which can be  re-installed  as
       required.   The	default	 output	 function  can	optionally  prefix the
       message	with   a   fixed   string;   this   can	  be   inserted	  with
       errf_set_prefix().   A  pointer	to  the	 current prefix	is returned by
       errf_get_prefix().  By convention, this prefix is derived from the name
       of  the	program.   errf_set_progname() is a convenience	routine	which,
       when passed argv[0], munges it in an operating system specific  way  to
       produce	the  program  name and sets the	prefix to something that looks
       `nice'.	A pointer to the program name (after munging) can be  obtained
       by errf_get_progname().	A usage	line can be sent to the	current	output
       function	by errf_usage(); it prefixes

	      Usage: progname

       to its argument,	and exits with status 1.

       strf() formats a	string in the  same  way  as  errf(),  but  returns  a
       pointer to a buffer obtained from malloc(3) that	contains the result.

       formf() is used in the internal implementation of errf()	and strf() and
       logf() (see below) and is  not  for  the	 faint-hearted.	  It  is  made
       visible	 because   it  is  useful  if  you  need  to  implement	 other
       errf()-style functions.	In addition to the normal format  conversions,
       formf()	provides  `%m' which inserts an	error message corresponding to
       the current value of errno into the output string.

	      int logf_set_ofile PROTO((const char *filename, const char *prefix));
	      void logf(int level, const char *fmt, ...)
	      int logf_set_level PROTO((int level));
	      void logf_errf_ofunc PROTO((const	char *str));

       These routines are an alternative to syslog (3) for  applications  that
       need  to	 log  messages	to  a  specified file.	logf() handles the fmt
       format string and arguments in the same same way	as errf().   If	 there
       has  been  no prior call	to logf_set_ofile() (see below)	the message is
       displayed on stderr, prefixed with the current date and time.   If  the
       output  is  going  to a file, logf() tries to ensure that messages from
       multiple	processes to a single log file are interleaved correctly.

       The level argument specifies the	class of the message;  it  is  one  of
       LG_DEBUG, LG_INFO, or LG_ERR (which are in increasing numerical order).
       Messages	at a level less	than the current log level are discarded.  The
       default	log  level  is	LG_INFO; it can	be set using logf_set_level(),
       which also returns the previous log level.  The log levels  LG_ALL  and
       LG_LOG  are  valid  only	in calls to logf_set_level(); LG_ALL means log
       all messages and	LG_LOG means log  only	messages  relating  to	logf()

       logf_set_ofile()	 sets the output file for logf() messages.  If the log
       file does not exist logf_set_ofile() attempts to	create	it;  otherwise
       it  is  opened  for writing (without discarding any existing contents).
       If the attempt to create	or open	the file fails,	logf_set_ofile() gives
       an  error  message  and	returns	-1, otherwise it returns zero.	If the
       prefix argument is not NULL, the	string specified is prepended  to  all
       future log messages.  logf_set_ofile() makes a copy of the string so it
       need not	be preserved after the call.

       logf_errf_ofunc() logs the message str at  level	 LG_ERR.   It  can  be
       passed  as  an  output function to errf_set_ofunc() to arrange that all
       error messages are sent to a log	file.

       ssplit()	splits a string	into a vector of words,	 treating  occurrences
       in the string of	any of the characters in the delimiters	string as word

       If the delimiters string	starts with  a	NUL  character	then  multiple
       adjacent	delimiters and leading delimiters generate zero	length fields.
       Otherwise,  leading  delimiter  characters  are	skipped	 and  multiple
       adjacent	delimiters are treated as a single delimiter.  Thus

	      char **words = ssplit(line, " \t");

       will to a shell-like split of a command line into words,	and

	      char **fields = ssplit(pwline, "\0:");

       would be	good for splitting lines from the password file.

       ssplit()	returns	a NULL terminated vector of words.  The	space for this
       vector and the pointed to words is allocated with a  (single)  call  to
       e_malloc().  ssplit() thus never	returns	NULL; it aborts	the program by
       calling panic() if memory runs out.

       The vector returned by ssplit() should be freed	when  it  is  finished
       with by passing it to free().

	      int get_host_addr(const char *hostname, struct in_addr *p_addr)

       get_host_addr()	 looks	 up   the   IP	 address   of  hostname	 using
       gethostbyaddr(3).  If the lookup	succeeds it sets  *p_addr  to  the  IP
       address	of  the	 host  in  network byte	order.	If the lookup fails it
       gives an	error  message	with  errf()  and  returns  -1.	  If  hostname
       consists	 of  four decimal numbers separated by dots then get_host_addr
       parses this as an IP quad and does not call gethostbyname.

	      int get_service_port(const char *servname, int *p_port)

       get_service_port	looks up the port number of the	TCP  service  servname
       using  getservbyname(3).	  If  it  succeeds it sets *p_port to the port
       number in network byte order.  Otherwise	it gives an error message with
       errf()  and  returns  -1.   If servname is an ASCII decimal number then
       get_service_port() returns that number (again in	network	byte order).

	      ebuf_t *ebuf_create(bool errors_are_fatal);
	      void ebuf_reset(ebuf_t *eb);
	      ebuf_t *ebuf_start(ebuf_t	*eb, bool errors_are_fatal);
	      int ebuf_add(ebuf_t *eb, const char *buf,	int count);
	      char *ebuf_get(ebuf_t *eb, int *p_len);
	      void ebuf_free(ebuf_t *eb);

       These routines implement	variable sized	contiguous  buffers  to	 which
       data  can  be  appended	at any time.  ebuf_create() creates a new zero
       length buffer.  The errors_are_fatal parameter controls the handling of
       errors;	if  it	is  TRUE then all of the routines will call panic() on

       ebuf_add() appends count	bytes of memory	pointed	 at  by	 data  to  the
       buffer	eb   (which  must  have	 been  created	using  ebuf_create()).
       ebuf_add() returns zero on success.  On failure it panics or returns -1
       (depending   on	 the  setting  of  errors_are_fatal  in	 the  call  of

       ebuf_get() returns a pointer to the current  contents  of  eb;  if  the
       p_len  parameter	 is not	NULL the current length	of the buffer in bytes
       is stored there.	 The returned buffer and length	are only valid	up  to
       the next	call of	ebuf_add(), ebuf_reset() or ebuf_free().

       ebuf_reset() frees the data associated with eb and resets the length to
       zero.  Furthur calls of ebuf_add() can be used to add fresh data	to eb.
       ebuf_free() frees and destroys eb.

       ebuf_start()  is	a convenience routine which either creates or resets a
       buffer.	If eb is NULL it calls ebuf_create() with the  supplied	 value
       of  errors_are_fatal.   If  eb  is  not	NULL  then  it	is  passed  to
       ebuf_reset().  The routine is intended  to  be  used  like  for	static
       buffers in the following	way:

	      void foo(void)
		   static ebuf_t *eb = NULL;

		   eb =	ebuf_start(eb, TRUE);

       The  first  time	 the  function	is  called  the	 buffer	is created; on
       subsequent calls	it is reset.

	      alloc_pool_t *alloc_create_pool(void)

	      void *alloc(alloc_pool_t *ap, int	nbytes)
	      void *alloc_ck(alloc_pool_t *ap, int nbytes)

       alloc_create_pool() creates a memory allocation `pool'  and  returns  a
       handle  referring  to  it.  alloc() allocates memory like malloc(3) but
       from the	specified pool rather from the general malloc arena.   alloc()
       calls  e_malloc()  to  obtain  memory  in  reasonably large chunks when
       necessary.  This	means that it  never  returns  NULL;  the  program  is
       aborted	via  panic()  if  there	 is insufficient memory	to satisfy the
       request.	 The alternative interface alloc_ck() returns NULL if it  runs
       out  of	memory;	it is otherwise	identical to alloc().  Memory obtained
       with alloc() cannot be freed individually; only	entire	pools  can  be

	      void alloc_free_pool(alloc_pool_t	*ap)
	      void alloc_reset_pool(alloc_pool_t *ap)

       alloc_free_pool()  frees	 an alloc pool,	releasing all memory allocated
       from it with alloc().  The pool is no longer  valid  after  this	 call.
       alloc_reset_pool()  conceptually	frees all the memory associated	with a
       pool but	does not return	it via free().	The  pool  remains  valid  and
       subsequent  calls  to  alloc() allocate memory from the existing	memory
       associated with the pool	if possible.

       These routines are suitable for applications which make lots  of	 small
       allocations  for	 a  data  structure  which  is	to be freed in one go.
       alloc() is much faster than malloc() as it does not do the  bookkeeping
       to  support  individual	freeing	 of  allocated memory.	It also	has no
       space overhead other than that necessary	to correctly align objects  in

       alloc_create_pool()  is	a  lightweight	routine	- it involves a	single
       call to malloc()	plus some assignments to initialise  the  pool	header
       structure.   It	is  thus  reasonable  to  use  the alloc() routines in
       situations where	there are only going to	be a  few  tens	 of  calls  to

	      bool alloc_set_default_debug_flag(bool val)
	      bool alloc_set_debug_flag(alloc_pool_t *ap, bool val)

       By  default  all	 memory	 obtained with alloc() and related routines is
       initialised to the repeated byte	0x53.	When  memory  is  freed	 (with
       alloc_free_pool(),  alloc_reset_pool() or alloc_release()) it is	set to
       the repeated byte 0x42.	This is	intended  to  trap  erroneous  use  of
       uninitialised  data  and	 data  that  has  been freed - newly allocated
       memory contains obvious garbage and freed memory	is immediately stamped

       Of  course  these safety	features cost speed, so	they can be turned off
       globally	or per-pool.  alloc_set_debug_flag() sets the  debugging  flag
       for  a  pool; memory will be initialised	to garbage and stamped on when
       freed only of the  flag	is  non-zero.	alloc_set_default_debug_flag()
       sets  the  value	 of  the flag used for pools created from then on with
       alloc_create_pool().  Both routines return the previous	value  of  the
       flag they set.

	      char *allocstr(alloc_pool_t *ap, int nbytes)
	      char *allocstr_ck(alloc_pool_t *ap, int nbytes)

       allocstr()  is like alloc() except that it assumes that no alignment is
       required.  It is	thus suitable only for allocating space	 for  strings.
       allocstr()  is  implemented such	that interspersed calls	to alloc() and
       allocstr() will pack both the strings and the other objects tightly  in
       memory  with  no	 space	wasted on alignment.  allocstr() never returns
       NULL - it panics	like alloc() if	there is no memory.  allocstr_ck()  is
       the  same  as  allocstr()  except  that	it returns NULL	if there is no

	      char *alloc_strdup(alloc_pool_t *ap, const char *s)

       alloc_strdup() is a convenience routine that returns  a	pointer	 to  a
       copy  of	 a string allocated using allocstr().  Note that it will never
       return NULL as it uses allocstr() rather	than allocstr_ck().

	      alloc_mark_t *alloc_mark(alloc_pool_t *ap)
	      void alloc_release(alloc_pool_t *ap, alloc_mark_t	*am)

       alloc_mark() returns an opaque  handle  that  `remembers'  the  current
       position	 in  an	 alloc	pool.	A  subsequent  call to alloc_release()
       conceptually frees  all	memory	allocated  from	 the  pool  since  the
       corresponding  call of alloc_mark().  Subsequent	calls to alloc() et al
       will reuse the freed memory.  A call to alloc_release() renders invalid
       any  marks that were returned after the alloc_mark() call that returned
       the mark	being passed to	alloc_release().

	      const char *ukcprog_version(void)

       ukcprog_version() returns a string giving the current version number of
       the library.

       This library treads rather freely on the	name space.

       Godfrey Paul
       Mark Russell

       Computing Laboratory, University	of Kent	at Canterbury.

UKC Local			 February 1991			    UKCPROG(3)


Want to link to this manual page? Use this URL:

home | help