Compare commits

...
19 Commits
Author SHA1 Message Date
Joachim Nilsson e1f8224666 Update ChangeLog and bump version for release v1.3.0
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2016-01-07 02:58:06 +01:00
Joachim Nilsson 84650d8836 Update include file boiler plate
We're not in Kansas anymore, Toto.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2016-01-07 02:58:06 +01:00
Joachim Nilsson b4fbd54a8c Update copyright years
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2016-01-07 02:58:06 +01:00
Joachim Nilsson c14c6a1e62 pidfile.c: Add LITE #ifdef pidfile and comment LITE mtime extension
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2016-01-07 02:58:06 +01:00
Joachim Nilsson 8aecba2b7a strtonum.c: Update to OpenBSD v1.7, style tweaks
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2016-01-07 02:58:06 +01:00
Joachim Nilsson 74dcaddc55 strlcat.c: Update to OpenBSD v1.14, readability fixes
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2016-01-07 02:57:59 +01:00
Joachim Nilsson c5a36ff7bd strlcpy.c: Update to OpenBSD v1.12, readability fixes
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2016-01-07 02:57:51 +01:00
Joachim Nilsson 3371e42035 queue.h: Update to OpenBSD v1.43 -- NOTE: Removes CIRCLEQ support!
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2016-01-07 02:03:10 +01:00
Joachim Nilsson 4e57a78255 README: Update section on OpenBSD Functions as well
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2016-01-06 13:35:35 +01:00
Joachim Nilsson ce3bd4ec8a README: Update documentation for pidfile() fn
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2016-01-06 13:31:32 +01:00
Joachim Nilsson 805571a7ef ChangeLog: Fix missing README link
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2016-01-05 13:34:41 +01:00
Joachim Nilsson 36435997bf ChangeLog: Fix Markdown links
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2016-01-05 13:33:34 +01:00
Joachim Nilsson f961889724 Add documentation for new macros and prepare ChangeLog for v1.3.0
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2016-01-05 13:27:40 +01:00
Tobias Waldekranz 6605fb9771 Makefile: Make sure queue.h and conio.h also are installed
This patch adds the BSD queue.h and the Borland inspired conio.h to the
install-dev Makefile target.

Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2016-01-05 13:17:16 +01:00
Tobias Waldekranz 61254279b9 lite.h: Add min() and max() macros
These macros take care to avoid double evaluation.

Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2016-01-05 13:16:34 +01:00
Joachim Nilsson e42aca8856 Makefile: Split install-dev taget into install-dev and install-data
This makes it possible to skip installing any unnecessary cruft.
Useful for embedded targets.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2016-01-05 13:14:37 +01:00
Joachim Nilsson 16611f3e5f Add ChangeLog to project and bump version for new release cycle
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2016-01-05 13:13:26 +01:00
Joachim Nilsson 975df87d6b Update unit test for pidfile()
Add ocular verification step for mtime update when pidfile() is
called more than once.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2015-12-17 00:15:18 +01:00
Joachim Nilsson 148027674a pidfile: Only update mtime i called multiple times
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2015-12-16 18:40:34 +01:00
12 changed files with 229 additions and 232 deletions

No files matched your search

Symlink
+1
View File
@@ -0,0 +1 @@
ChangeLog.md
+84
View File
@@ -0,0 +1,84 @@
Change Log
==========
All notable changes to the project are documented in this file.
[v1.3.0][] - 2016-01-07
-----------------------
### Changes
- Add highly useful typeless `min()`/`max()` macros to `lite.h`,
courtesy of Tobias Waldekranz
- Add BSD `queue.h` and Borland inspired `conio.h` to `install-dev`
target. Needed by [Finit][].
- Note, this release update `queue.h` to OpenBSD v1.43, which removes
support for circular queues (CIRCLEQ).
- Update `strlcpy.c` to OpenBSD v1.12, readability fixes.
- Update `strlcat.c` to OpenBSD v1.14, readability fixes.
- Update `strtonum.c` to OpenBSD v1.7, tiniest of style tweaks.
### Fixes
- Only update mtime if `pidfile()` is called more than once, do not
install multiple `atexit()` handlers.
- Add `#ifndef pidfile`, as for other BSD functions, in case the user
already have a local copy, or a C library with one.
[v1.2.0][] - 2015-11-23
-----------------------
### Changes
- Add simple parser for UNIX configuration files, e.g. `/etc/group`,
`/etc/passwd`, and `/etc/protocols`:
- `lfopen()`
- `lfclose()`
- `lftok()`
- `lfgetkey()`
- `lfgetint()`
- `fgetint()`
### Fixes
- Do not allow `VERSION` to be overloaded by build system.
- Make sure we don't inherit `LDFLAGS` from environment.
[v1.1.1][] - 2015-09-27
-----------------------
### Fixes
* Silence annoying warnings from GNU ar
* Fix macro definitions for compat APIs
[v1.1.0][] - 2015-09-16
-----------------------
### Changes
- Support for `make distdir` used by automake based projects
- `lite.h` move from `error.h` to more BSD friendly `err.h`
- Add highly useful `NELEMS()` and bitmanip macros
- Lots of autotests added
- Add support for running autotests from Travis
- Add `progress()` simple progress bar
- Add `tree()` simple command line tree replacement
- Bump `SONAME` to `libite.so.2` on behalf of [Finit][]
### Fixes
- `pidfile()` upgrade to OpenBSD r1.11
- Lots of README updates, fixes and additions
[v1.0.0][] - 2015-07-12
-----------------------
Initial extraction of frog DNA from [Finit][]. See [README][] for API details.
[UNRELEASED]: https://github.com/troglobit/libite/compare/v1.2.0...HEAD
[v1.2.0]: https://github.com/troglobit/libite/compare/v1.1.1...v1.2.0
[v1.1.1]: https://github.com/troglobit/libite/compare/v1.1.0...v1.1.1
[v1.1.0]: https://github.com/troglobit/libite/compare/v1.0.0...v1.1.0
[v1.0.0]: https://github.com/troglobit/libite/compare/TAIL...v1.0.0
[Finit]: https://github.com/troglobit/finit/
[README]: https://github.com/troglobit/libite/blob/v1.0.0/README.md
+1 -1
View File
@@ -4,7 +4,7 @@ the Finit code base and included pieces of software released under the ISC
and BSD licenses. See each respective file for license details. and BSD licenses. See each respective file for license details.
Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com> Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
Copyright (c) 2008-2015 Joachim Nilsson <troglobit@gmail.com> Copyright (c) 2008-2016 Joachim Nilsson <troglobit@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
+9 -7
View File
@@ -1,6 +1,6 @@
# libite -- Light-weight utility functions and C-library extensions # libite (LITE) -- Collection of frog DNA
# #
# Copyright (c) 2008-2015 Joachim Nilsson <troglobit@gmail.com> # Copyright (c) 2008-2016 Joachim Nilsson <troglobit@gmail.com>
# #
# Permission is hereby granted, free of charge, to any person obtaining a copy # Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal # of this software and associated documentation files (the "Software"), to deal
@@ -22,7 +22,7 @@
.PHONY: install test .PHONY: install test
#VERSION = $(shell git tag -l | tail -1) #VERSION = $(shell git tag -l | tail -1)
VERSION = 1.2.0 VERSION = 1.3.0
NAME = libite NAME = libite
PKG = $(NAME)-$(VERSION) PKG = $(NAME)-$(VERSION)
ARCHIVE = $(PKG).tar.xz ARCHIVE = $(PKG).tar.xz
@@ -31,8 +31,8 @@ CFLAGS += -fPIC
CPPFLAGS += -W -Wall CPPFLAGS += -W -Wall
LDFLAGS = $(EXTRA_LDFLAGS) LDFLAGS = $(EXTRA_LDFLAGS)
DISTFILES = README LICENSE DISTFILES = README ChangeLog LICENSE
HEADERS = lite.h HEADERS = lite.h queue.h conio.h
OBJS := chomp.o copyfile.o dir.o fexist.o fisdir.o fmode.o fsendfile.o OBJS := chomp.o copyfile.o dir.o fexist.o fisdir.o fmode.o fsendfile.o
OBJS += ifconfig.o lfile.o makepath.o pidfile.o pidfilefn.o progress.o OBJS += ifconfig.o lfile.o makepath.o pidfile.o pidfilefn.o progress.o
OBJS += rsync.o strlcpy.o strlcat.o strtonum.o tempfile.o tree.o OBJS += rsync.o strlcpy.o strlcat.o strtonum.o tempfile.o tree.o
@@ -90,13 +90,15 @@ install-dev:
$(PRINT) " INSTALL $(DESTDIR)$(libdir)/$(STATICLIB)\n" $(PRINT) " INSTALL $(DESTDIR)$(libdir)/$(STATICLIB)\n"
$(Q)install -d $(DESTDIR)$(libdir) $(Q)install -d $(DESTDIR)$(libdir)
$(Q)$(INSTALL) $(STATICLIB) $(DESTDIR)$(libdir)/$(STATICLIB) $(Q)$(INSTALL) $(STATICLIB) $(DESTDIR)$(libdir)/$(STATICLIB)
install-data:
$(Q)install -d $(DESTDIR)$(datadir) $(Q)install -d $(DESTDIR)$(datadir)
$(Q)for file in $(DISTFILES); do \ $(Q)for file in $(DISTFILES); do \
printf " INSTALL $(DESTDIR)$(datadir)/$$file\n"; \ printf " INSTALL $(DESTDIR)$(datadir)/$$file\n"; \
install -m 0644 $$file $(DESTDIR)$(datadir)/$$file; \ install -m 0644 $$file $(DESTDIR)$(datadir)/$$file; \
done done
install: install-exec install-dev install: install-exec install-dev install-data
uninstall: uninstall:
-$(Q)$(RM) -r $(DESTDIR)$(datadir) -$(Q)$(RM) -r $(DESTDIR)$(datadir)
+16 -5
View File
@@ -50,6 +50,10 @@ Helper Macros
Create a FIFO, like `mkfifo()`. Errors on stderr Create a FIFO, like `mkfifo()`. Errors on stderr
- `min(a,b)`/`max(a,b)`
These macros take care to avoid double evaluation.
- `touch(path)` - `touch(path)`
Create a file, or update mtime. Errors on stderr Create a file, or update mtime. Errors on stderr
@@ -172,20 +176,24 @@ Generic Functions
- `pidfile(basename)` - `pidfile(basename)`
Write a daemon pid file. Creates a pidfile in `_PATH_VARRUN` using Create a daemon PID file in `_PATH_VARRUN` using either `basename` or,
either `basename` or, if `basename` is `NULL`, `__progname`. The if `basename` is `NULL`, `__progname`. The file name has the form
file name has the form `/var/run/basename.pid`. `/var/run/basename.pid`.
Use this function to create a pid file for your daemon when it is Use this function to create a PID file for your daemon when it is
ready to receive signals. A client application may poll for the ready to receive signals. A client application may poll for the
existence of this file, so make sure to have your signal handlers existence of this file, so make sure to have your signal handlers
properly setup before calling this function. properly setup before calling this function.
The pidfile is removed when the program exits, using an `atexit()` The pidfile is removed when the program exits, using an `atexit()`
handler. However, depending on how the program terminates the file handler. However, depending on how the program terminates the file
may still exist even though the program is no longer running. This may still exist even though the program is no longer running. This
is only a problem for clients. is only a problem for clients.
Calling this function multiple times updates the mtime of the file.
Only one `atexit()` handler is created, regardless of the amount of
times the function is called.
See below for link to OpenBSD man page. See below for link to OpenBSD man page.
- `pidfile_read(pidfile)` - `pidfile_read(pidfile)`
@@ -233,6 +241,9 @@ The following are the popular OpenBSD string functions.
http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/pidfile.3 http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/pidfile.3
**Note:** this version of `pidfile()` has been extended to handle it
being called multiple times. See previous section for details.
- `strlcpy(dst, src, len)` - `strlcpy(dst, src, len)`
http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/strlcpy.3 http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/strlcpy.3
+19 -5
View File
@@ -1,7 +1,7 @@
/* Collection of utility funcs and C library extensions for finit & its plugins /* Collection of frog DNA
* *
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com> * Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
* Copyright (c) 2008-2015 Joachim Nilsson <troglobit@gmail.com> * Copyright (c) 2008-2016 Joachim Nilsson <troglobit@gmail.com>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@@ -22,8 +22,8 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#ifndef FINIT_LITE_H_ #ifndef LITE_H_
#define FINIT_LITE_H_ #define LITE_H_
#include <err.h> #include <err.h>
#include <stdio.h> #include <stdio.h>
@@ -181,12 +181,26 @@ static inline int string_case_compare (const char *a, const char *b)
return strlen (a) == strlen (b) && !strcasecmp (a, b); return strlen (a) == strlen (b) && !strcasecmp (a, b);
} }
#define min(a,b) \
({ \
__typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a < _b ? _a : _b; \
})
#define max(a,b) \
({ \
__typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; \
})
/* Compat */ /* Compat */
#define copy_filep(src,dst) fcopyfile(src,dst) #define copy_filep(src,dst) fcopyfile(src,dst)
#define pidfile_read_pid(file) pifile_read(file) #define pidfile_read_pid(file) pifile_read(file)
#define signal_pidfile(file,signo) pidfile_signal(file,signo) #define signal_pidfile(file,signo) pidfile_signal(file,signo)
#endif /* FINIT_LITE_H_ */ #endif /* LITE_H_ */
/** /**
* Local Variables: * Local Variables:
+10 -1
View File
@@ -37,7 +37,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
static char *pidfile_path; #ifndef pidfile
static char *pidfile_path = NULL;
static pid_t pidfile_pid; static pid_t pidfile_pid;
static void pidfile_cleanup(void); static void pidfile_cleanup(void);
@@ -83,6 +84,13 @@ pidfile(const char *basename)
} }
(void) fclose(f); (void) fclose(f);
/*
* LITE extension, no need to set up another atexit() handler
* if user only called us to update the mtime of the PID file
*/
if (pidfile_pid == pid)
return (0);
pidfile_pid = pid; pidfile_pid = pid;
if (atexit(pidfile_cleanup) < 0) { if (atexit(pidfile_cleanup) < 0) {
save_errno = errno; save_errno = errno;
@@ -104,3 +112,4 @@ pidfile_cleanup(void)
if (pidfile_path != NULL && pidfile_pid == getpid()) if (pidfile_path != NULL && pidfile_pid == getpid())
(void) unlink(pidfile_path); (void) unlink(pidfile_path);
} }
#endif
+9
View File
@@ -142,6 +142,8 @@ static void sigalrm_handler(int signo)
int main(void) int main(void)
{ {
char cmd[80];
snprintf(PIDFILE, sizeof(PIDFILE), "%s%s.pid", _PATH_VARRUN, __progname); snprintf(PIDFILE, sizeof(PIDFILE), "%s%s.pid", _PATH_VARRUN, __progname);
signal(SIGTERM, sigterm_handler); signal(SIGTERM, sigterm_handler);
@@ -157,6 +159,13 @@ int main(void)
printf("Reading pid file, should be %d ...\n", getpid()); printf("Reading pid file, should be %d ...\n", getpid());
printf("=> %d\n", pidfile_read(PIDFILE)); printf("=> %d\n", pidfile_read(PIDFILE));
/* Occular verification that calling pidfile() again updates mtime */
snprintf(cmd, sizeof(cmd), "ls -l --full-time %s", PIDFILE);
system(cmd);
printf("Before ^^ pidfile() vv after ...\n");
pidfile(NULL);
system(cmd);
printf("Signalling ourselves ...\n"); printf("Signalling ourselves ...\n");
return pidfile_signal(PIDFILE, SIGTERM); return pidfile_signal(PIDFILE, SIGTERM);
+31 -146
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: queue.h,v 1.38 2013/07/03 15:05:21 fgsch Exp $ */ /* $OpenBSD: queue.h,v 1.43 2015/12/28 19:38:40 millert Exp $ */
/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ /* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
/* /*
@@ -36,8 +36,8 @@
#define _SYS_QUEUE_H_ #define _SYS_QUEUE_H_
/* /*
* This file defines five types of data structures: singly-linked lists, * This file defines five types of data structures: singly-linked lists,
* lists, simple queues, tail queues, and circular queues. * lists, simple queues, tail queues and XOR simple queues.
* *
* *
* A singly-linked list is headed by a single forward pointer. The elements * A singly-linked list is headed by a single forward pointer. The elements
@@ -57,7 +57,7 @@
* or after an existing element or at the head of the list. A list * or after an existing element or at the head of the list. A list
* may only be traversed in the forward direction. * may only be traversed in the forward direction.
* *
* A simple queue is headed by a pair of pointers, one the head of the * A simple queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are singly * list and the other to the tail of the list. The elements are singly
* linked to save space, so elements can only be removed from the * linked to save space, so elements can only be removed from the
* head of the list. New elements can be added to the list before or after * head of the list. New elements can be added to the list before or after
@@ -71,13 +71,10 @@
* after an existing element, at the head of the list, or at the end of * after an existing element, at the head of the list, or at the end of
* the list. A tail queue may be traversed in either direction. * the list. A tail queue may be traversed in either direction.
* *
* A circle queue is headed by a pair of pointers, one to the head of the * An XOR simple queue is used in the same way as a regular simple queue.
* list and the other to the tail of the list. The elements are doubly * The difference is that the head structure also includes a "cookie" that
* linked so that an arbitrary element can be removed without a need to * is XOR'd with the queue pointer (first, last or next) to generate the
* traverse the list. New elements can be added to the list before or after * real pointer value.
* an existing element, at the head of the list, or at the end of the list.
* A circle queue may be traversed in either direction, but has a more
* complex end of list detection.
* *
* For details on the use of these macros, see the queue(3) manual page. * For details on the use of these macros, see the queue(3) manual page.
*/ */
@@ -95,15 +92,15 @@
struct name { \ struct name { \
struct type *slh_first; /* first element */ \ struct type *slh_first; /* first element */ \
} }
#define SLIST_HEAD_INITIALIZER(head) \ #define SLIST_HEAD_INITIALIZER(head) \
{ NULL } { NULL }
#define SLIST_ENTRY(type) \ #define SLIST_ENTRY(type) \
struct { \ struct { \
struct type *sle_next; /* next element */ \ struct type *sle_next; /* next element */ \
} }
/* /*
* Singly-linked List access methods. * Singly-linked List access methods.
*/ */
@@ -157,8 +154,8 @@ struct { \
curelm = curelm->field.sle_next; \ curelm = curelm->field.sle_next; \
curelm->field.sle_next = \ curelm->field.sle_next = \
curelm->field.sle_next->field.sle_next; \ curelm->field.sle_next->field.sle_next; \
_Q_INVALIDATE((elm)->field.sle_next); \
} \ } \
_Q_INVALIDATE((elm)->field.sle_next); \
} while (0) } while (0)
/* /*
@@ -179,7 +176,7 @@ struct { \
} }
/* /*
* List access methods * List access methods.
*/ */
#define LIST_FIRST(head) ((head)->lh_first) #define LIST_FIRST(head) ((head)->lh_first)
#define LIST_END(head) NULL #define LIST_END(head) NULL
@@ -316,6 +313,14 @@ struct { \
(head)->sqh_last = &(elm)->field.sqe_next; \ (head)->sqh_last = &(elm)->field.sqe_next; \
} while (0) } while (0)
#define SIMPLEQ_CONCAT(head1, head2) do { \
if (!SIMPLEQ_EMPTY((head2))) { \
*(head1)->sqh_last = (head2)->sqh_first; \
(head1)->sqh_last = (head2)->sqh_last; \
SIMPLEQ_INIT((head2)); \
} \
} while (0)
/* /*
* XOR Simple queue definitions. * XOR Simple queue definitions.
*/ */
@@ -395,7 +400,7 @@ struct { \
XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \ XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
} while (0) } while (0)
/* /*
* Tail queue definitions. * Tail queue definitions.
*/ */
@@ -414,8 +419,8 @@ struct { \
struct type **tqe_prev; /* address of previous next element */ \ struct type **tqe_prev; /* address of previous next element */ \
} }
/* /*
* tail queue access methods * Tail queue access methods.
*/ */
#define TAILQ_FIRST(head) ((head)->tqh_first) #define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_END(head) NULL #define TAILQ_END(head) NULL
@@ -516,133 +521,13 @@ struct { \
_Q_INVALIDATE((elm)->field.tqe_next); \ _Q_INVALIDATE((elm)->field.tqe_next); \
} while (0) } while (0)
/* #define TAILQ_CONCAT(head1, head2, field) do { \
* Circular queue definitions. if (!TAILQ_EMPTY(head2)) { \
*/ *(head1)->tqh_last = (head2)->tqh_first; \
#define CIRCLEQ_HEAD(name, type) \ (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
struct name { \ (head1)->tqh_last = (head2)->tqh_last; \
struct type *cqh_first; /* first element */ \ TAILQ_INIT((head2)); \
struct type *cqh_last; /* last element */ \ } \
}
#define CIRCLEQ_HEAD_INITIALIZER(head) \
{ CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
#define CIRCLEQ_ENTRY(type) \
struct { \
struct type *cqe_next; /* next element */ \
struct type *cqe_prev; /* previous element */ \
}
/*
* Circular queue access methods
*/
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
#define CIRCLEQ_END(head) ((void *)(head))
#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
#define CIRCLEQ_EMPTY(head) \
(CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
#define CIRCLEQ_FOREACH(var, head, field) \
for((var) = CIRCLEQ_FIRST(head); \
(var) != CIRCLEQ_END(head); \
(var) = CIRCLEQ_NEXT(var, field))
#define CIRCLEQ_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = CIRCLEQ_FIRST(head); \
(var) != CIRCLEQ_END(head) && \
((tvar) = CIRCLEQ_NEXT(var, field), 1); \
(var) = (tvar))
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
for((var) = CIRCLEQ_LAST(head); \
(var) != CIRCLEQ_END(head); \
(var) = CIRCLEQ_PREV(var, field))
#define CIRCLEQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
for ((var) = CIRCLEQ_LAST(head, headname); \
(var) != CIRCLEQ_END(head) && \
((tvar) = CIRCLEQ_PREV(var, headname, field), 1); \
(var) = (tvar))
/*
* Circular queue functions.
*/
#define CIRCLEQ_INIT(head) do { \
(head)->cqh_first = CIRCLEQ_END(head); \
(head)->cqh_last = CIRCLEQ_END(head); \
} while (0)
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
(elm)->field.cqe_prev = (listelm); \
if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \
(head)->cqh_last = (elm); \
else \
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
(listelm)->field.cqe_next = (elm); \
} while (0)
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm); \
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \
(head)->cqh_first = (elm); \
else \
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
(listelm)->field.cqe_prev = (elm); \
} while (0)
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
(elm)->field.cqe_next = (head)->cqh_first; \
(elm)->field.cqe_prev = CIRCLEQ_END(head); \
if ((head)->cqh_last == CIRCLEQ_END(head)) \
(head)->cqh_last = (elm); \
else \
(head)->cqh_first->field.cqe_prev = (elm); \
(head)->cqh_first = (elm); \
} while (0)
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.cqe_next = CIRCLEQ_END(head); \
(elm)->field.cqe_prev = (head)->cqh_last; \
if ((head)->cqh_first == CIRCLEQ_END(head)) \
(head)->cqh_first = (elm); \
else \
(head)->cqh_last->field.cqe_next = (elm); \
(head)->cqh_last = (elm); \
} while (0)
#define CIRCLEQ_REMOVE(head, elm, field) do { \
if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \
(head)->cqh_last = (elm)->field.cqe_prev; \
else \
(elm)->field.cqe_next->field.cqe_prev = \
(elm)->field.cqe_prev; \
if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \
(head)->cqh_first = (elm)->field.cqe_next; \
else \
(elm)->field.cqe_prev->field.cqe_next = \
(elm)->field.cqe_next; \
_Q_INVALIDATE((elm)->field.cqe_prev); \
_Q_INVALIDATE((elm)->field.cqe_next); \
} while (0)
#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
CIRCLEQ_END(head)) \
(head)->cqh_last = (elm2); \
else \
(elm2)->field.cqe_next->field.cqe_prev = (elm2); \
if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
CIRCLEQ_END(head)) \
(head)->cqh_first = (elm2); \
else \
(elm2)->field.cqe_prev->field.cqe_next = (elm2); \
_Q_INVALIDATE((elm)->field.cqe_prev); \
_Q_INVALIDATE((elm)->field.cqe_next); \
} while (0) } while (0)
#endif /* !_SYS_QUEUE_H_ */ #endif /* !_SYS_QUEUE_H_ */
+24 -33
View File
@@ -1,7 +1,7 @@
/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ /* $OpenBSD: strlcat.c,v 1.15 2015/03/02 21:41:08 millert Exp $ */
/* /*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> * Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -21,46 +21,37 @@
#ifndef strlcat #ifndef strlcat
/* /*
* Appends src to string dst of size siz (unlike strncat, siz is the * Appends src to string dst of size dsize (unlike strncat, dsize is the
* full size of dst, not space left). At most siz-1 characters * full size of dst, not space left). At most dsize-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)). * will be copied. Always NUL terminates (unless dsize <= strlen(dst)).
* Returns strlen(src) + MIN(siz, strlen(initial dst)). * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
* If retval >= siz, truncation occurred. * If retval >= dsize, truncation occurred.
*/ */
size_t size_t
strlcat(char *dst, const char *src, size_t siz) strlcat(char *dst, const char *src, size_t dsize)
{ {
char *d = dst; const char *odst = dst;
const char *s = src; const char *osrc = src;
size_t n = siz; size_t n = dsize;
size_t dlen; size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */ /* Find the end of dst and adjust bytes left but don't go past end. */
while (n-- != 0 && *d != '\0') while (n-- != 0 && *dst != '\0')
d++; dst++;
dlen = d - dst; dlen = dst - odst;
n = siz - dlen; n = dsize - dlen;
if (n == 0) if (n-- == 0)
return(dlen + strlen(s)); return(dlen + strlen(src));
while (*s != '\0') { while (*src != '\0') {
if (n != 1) { if (n != 0) {
*d++ = *s; *dst++ = *src;
n--; n--;
} }
s++; src++;
} }
*d = '\0'; *dst = '\0';
return(dlen + (s - src)); /* count does not include NUL */ return(dlen + (src - osrc)); /* count does not include NUL */
} }
#endif #endif
/**
* Local Variables:
* version-control: t
* c-file-style: "bsd"
* End:
*/
+18 -27
View File
@@ -1,7 +1,7 @@
/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ /* $OpenBSD: strlcpy.c,v 1.12 2015/01/15 03:54:12 millert Exp $ */
/* /*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> * Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -21,41 +21,32 @@
#ifndef strlcpy #ifndef strlcpy
/* /*
* Copy src to string dst of size siz. At most siz-1 characters * Copy string src to buffer dst of size dsize. At most dsize-1
* will be copied. Always NUL terminates (unless siz == 0). * chars will be copied. Always NUL terminates (unless dsize == 0).
* Returns strlen(src); if retval >= siz, truncation occurred. * Returns strlen(src); if retval >= dsize, truncation occurred.
*/ */
size_t size_t
strlcpy(char *dst, const char *src, size_t siz) strlcpy(char *dst, const char *src, size_t dsize)
{ {
char *d = dst; const char *osrc = src;
const char *s = src; size_t nleft = dsize;
size_t n = siz;
/* Copy as many bytes as will fit */ /* Copy as many bytes as will fit. */
if (n != 0) { if (nleft != 0) {
while (--n != 0) { while (--nleft != 0) {
if ((*d++ = *s++) == '\0') if ((*dst++ = *src++) == '\0')
break; break;
} }
} }
/* Not enough room in dst, add NUL and traverse rest of src */ /* Not enough room in dst, add NUL and traverse rest of src. */
if (n == 0) { if (nleft == 0) {
if (siz != 0) if (dsize != 0)
*d = '\0'; /* NUL-terminate dst */ *dst = '\0'; /* NUL-terminate dst */
while (*s++) while (*src++)
; ;
} }
return(s - src - 1); /* count does not include NUL */ return(src - osrc - 1); /* count does not include NUL */
} }
#endif #endif
/**
* Local Variables:
* version-control: t
* c-file-style: "bsd"
* End:
*/
+7 -7
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ */ /* $OpenBSD: strtonum.c,v 1.7 2013/04/17 18:40:58 tedu Exp $ */
/* /*
* Copyright (c) 2004 Ted Unangst and Todd Miller * Copyright (c) 2004 Ted Unangst and Todd Miller
@@ -22,17 +22,17 @@
#include <stdlib.h> #include <stdlib.h>
#ifndef strtonum #ifndef strtonum
#define INVALID 1 #define INVALID 1
#define TOOSMALL 2 #define TOOSMALL 2
#define TOOLARGE 3 #define TOOLARGE 3
long long long long
strtonum(const char *numstr, long long minval, long long maxval, strtonum(const char *numstr, long long minval, long long maxval,
const char **errstrp) const char **errstrp)
{ {
long long ll = 0; long long ll = 0;
char *ep;
int error = 0; int error = 0;
char *ep;
struct errval { struct errval {
const char *errstr; const char *errstr;
int err; int err;
@@ -45,9 +45,9 @@ strtonum(const char *numstr, long long minval, long long maxval,
ev[0].err = errno; ev[0].err = errno;
errno = 0; errno = 0;
if (minval > maxval) if (minval > maxval) {
error = INVALID; error = INVALID;
else { } else {
ll = strtoll(numstr, &ep, 10); ll = strtoll(numstr, &ep, 10);
if (numstr == ep || *ep != '\0') if (numstr == ep || *ep != '\0')
error = INVALID; error = INVALID;