83 Commits

Author SHA1 Message Date
2174a1960d Version 5.5 2014-03-13 19:19:19 +01:00
7c9565ec41 cvsimport 2014-02-27 00:52:57 +00:00
96af45583a remove TAILQ_END and __dead hacks 2014-02-23 15:49:58 +01:00
8ddc90665e cvsimport 2014-02-08 02:49:30 +00:00
8653141b4b cvsimport 2014-02-03 21:07:47 +00:00
b923524a8e cvsimport 2014-02-02 21:34:05 +00:00
c7d4add2f2 cvsimport 2014-02-01 00:25:04 +00:00
24f9bfb3ec cvsimport 2014-01-30 22:41:16 +00:00
1fd3fc4997 cvsimport 2014-01-29 22:30:00 +00:00
2b233f0548 cvsimport 2014-01-28 20:22:21 +00:00
5fd119daea cvsimport 2014-01-24 22:38:02 +00:00
371902b3c9 cvsimport 2014-01-21 15:42:44 +00:00
86b149ad25 cvsimport 2014-01-03 15:29:06 +00:00
f4c289b9e6 cvsimport 2014-01-03 14:23:50 +00:00
b387351df1 cvsimport 2013-12-17 16:12:18 +00:00
291e0dc088 add update.sh which I use for importing from CVS 2013-12-17 18:34:04 +01:00
44e2a2505b cvsimport 2013-12-16 19:02:17 +00:00
75b69c0b04 cvsimport 2013-12-13 22:39:13 +00:00
ddb67559f6 cvsimport 2013-12-13 15:56:44 +00:00
0cad4ef6e0 cvsimport 2013-12-13 12:57:57 +00:00
140028e905 cvsimport 2013-12-11 22:14:23 +00:00
2951979832 cvsimport 2013-12-08 13:51:38 +00:00
27513daee2 Revert "use u_char for buffers in yylex"
This reverts commit 03b19f1487.

This merely generates pointer signedness warnings for strtonum() and
lookup() and problems with the const char * prototype of xstrdup().
2013-12-06 23:16:54 +01:00
873763f4c6 cvsimport 2013-12-02 20:01:19 +00:00
3c78191e2e cvsimport 2013-11-12 21:25:00 +00:00
2037332bb7 cvsimport 2013-11-02 19:13:56 +00:00
caf8b315ab cvsimport 2013-11-01 14:07:19 +00:00
0c99788f66 cvsimport 2013-10-25 19:46:16 +00:00
0d6e8a9146 Makefile: rm -f is enough 2013-10-16 23:05:51 +02:00
f3477539bb cvsimport 2013-10-07 13:40:26 +00:00
0dec9e849d cvsimport 2013-07-16 14:30:48 +00:00
93bfc4a5c1 cvsimport 2013-07-10 14:15:58 +00:00
ba9baaf671 cvsimport 2013-06-23 17:57:50 +00:00
9a12ca3520 cvsimport 2013-06-20 02:33:57 +00:00
c30653b1c3 cvsimport 2013-06-03 20:33:17 +00:00
5515a365ba cvsimport 2013-05-29 22:41:51 +02:00
843f18aaee cvsimport 2013-04-30 21:12:20 +00:00
6f185bb03c cvsimport 2013-04-14 16:13:17 +00:00
a957ed7c7d cvsimport 2013-04-05 17:36:02 +00:00
cfc19dba7e cvsimport 2013-03-09 21:55:56 +00:00
9c6226faa8 cvsimport 2013-01-13 13:55:12 +00:00
104c7d5de3 cvsimport 2013-01-06 01:01:26 +00:00
f77166194f cvsimport 2012-12-19 15:21:34 +00:00
878eb6bf05 cvsimport 2012-11-28 14:32:44 +00:00
b4315a3fda Use vendored queue.h everywhere 2012-11-26 16:27:22 +01:00
9088b86b14 Vendor OpenBSD queue.h,v 1.36 2012-11-26 16:26:41 +01:00
319d4e179e cvsimport 2012-11-26 16:17:45 +01:00
e27f649ae7 cvsimport 2012-11-01 01:10:47 +00:00
c42043ede7 cvsimport 2012-10-29 19:46:03 +00:00
a2d0cbcf97 cvsimport 2012-09-12 15:09:33 +00:00
b18e365cb3 cvsimport 2012-08-07 14:05:49 +00:00
1545eb0837 cvsimport 2012-07-18 21:53:22 +00:00
8f587e6c80 cvsimport 2012-05-20 15:27:16 +02:00
0bb88fa567 define YYSTYPE_IS_DECLARED to work with bison 2.3 2012-05-04 17:46:42 +02:00
3bf492d2e9 compile with -D_GNU_SOURCE to get all relevant prototypes 2012-05-04 17:44:27 +02:00
601779351c Version 5.1 2012-05-02 14:26:57 +02:00
5f79bace21 Add release target to Makefile 2012-05-02 14:26:36 +02:00
de5efc6a54 Define compatibility macros only if they are needed 2012-05-02 14:26:14 +02:00
1603d18560 cvsimport 2011-12-29 20:48:38 +00:00
96ebac8b04 fix pkg-config packages 2011-12-12 16:17:39 +01:00
cbe46b651f cvsimport 2011-11-06 02:03:47 +00:00
901a75d3c6 cvsimport 2011-10-17 18:18:38 +00:00
58077c157b cvsimport 2011-10-12 15:43:50 +00:00
ce34d0066e Add README 2011-10-05 17:48:47 +02:00
7c7a5bdcdc rewrite Makefile 2011-10-05 17:48:33 +02:00
54c1b90725 cvsimport 2011-09-19 07:23:03 +00:00
3c67ec8ccc cvsimport 2011-09-13 09:17:30 +00:00
b1d81b7eb6 cvsimport 2011-09-08 12:35:33 +00:00
513c35dca9 cvsimport 2011-08-04 20:53:37 +02:00
f067809af4 cvsimport 2011-05-15 17:58:47 +00:00
a90a0b5705 cvsimport 2011-05-07 17:15:37 +00:00
2bac9a6be9 cvsimport 2011-05-03 19:28:18 +02:00
9eaece0541 cvsimport 2011-02-18 11:50:01 +00:00
5bc15cdb58 cvsimport 2010-12-24 23:42:39 +01:00
10622cf40d Add protoypes, fixes segfaults on x86 2010-09-26 14:51:23 +02:00
a64855f9cc Improve CFLAGS 2010-09-26 14:51:02 +02:00
e6d9effa8d Use yacc instead of byacc 2010-09-26 01:46:05 +02:00
b11c12e99b Merge branch 'origin' into linux 2010-09-26 01:43:12 +02:00
c9a14a8f40 cvsimport 2010-07-30 12:28:19 +00:00
e0c9657773 cvsimport 2010-05-22 22:32:08 +00:00
oga
f769df540d cvsimport 2010-04-12 16:17:46 +00:00
d90ab51111 Add missing functions 2010-02-21 19:18:12 +01:00
50aff37f50 Import linux.patch
Patch largely based on cwmbuild.sh from http://tamentis.com/hacks/cwm/
written by Bertrand Janin, updated by Christian Neukirchen.
2010-02-21 19:15:27 +01:00
23 changed files with 1014 additions and 32 deletions

View File

@ -1,24 +1,47 @@
# $OpenBSD$ # cwm makefile for BSD make and GNU make
# uses pkg-config, DESTDIR and PREFIX
.include <bsd.xconf.mk>
PROG= cwm PROG= cwm
PREFIX= /usr/local
SRCS= calmwm.c screen.c xmalloc.c client.c menu.c \ SRCS= calmwm.c screen.c xmalloc.c client.c menu.c \
search.c util.c xutil.c conf.c xevents.c group.c \ search.c util.c xutil.c conf.c xevents.c group.c \
kbfunc.c mousefunc.c parse.y kbfunc.c mousefunc.c parse.y
CPPFLAGS+= -I${X11BASE}/include -I${X11BASE}/include/freetype2 -I${.CURDIR} OBJS= calmwm.o screen.o xmalloc.o client.o menu.o \
search.o util.o xutil.o conf.o xevents.o group.o \
kbfunc.o mousefunc.o strlcpy.o strlcat.o y.tab.o \
strtonum.o fgetln.o
CFLAGS+= -Wall CPPFLAGS+= `pkg-config --cflags fontconfig x11 xft xinerama xrandr`
LDADD+= -L${X11BASE}/lib -lXft -lXrender -lX11 -lxcb -lXau -lXdmcp \ CFLAGS= -Wall -O2 -g -D_GNU_SOURCE
-lfontconfig -lexpat -lfreetype -lz -lXinerama -lXrandr -lXext
MANDIR= ${X11BASE}/man/man LDFLAGS+= `pkg-config --libs fontconfig x11 xft xinerama xrandr`
MAN= cwm.1 cwmrc.5
obj: _xenocara_obj MANPREFIX= ${PREFIX}/share/man
.include <bsd.prog.mk> all: ${PROG}
.include <bsd.xorg.mk>
clean:
rm -f ${OBJS} ${PROG} y.tab.c
y.tab.c: parse.y
yacc parse.y
${PROG}: ${OBJS} y.tab.o
${CC} ${OBJS} ${LDFLAGS} -o ${PROG}
.c.o:
${CC} -c ${CFLAGS} ${CPPFLAGS} $<
install: ${PROG}
install -d ${DESTDIR}${PREFIX}/bin ${DESTDIR}${MANPREFIX}/man1 ${DESTDIR}${MANPREFIX}/man5
install -m 755 cwm ${DESTDIR}${PREFIX}/bin
install -m 644 cwm.1 ${DESTDIR}${MANPREFIX}/man1
install -m 644 cwmrc.5 ${DESTDIR}${MANPREFIX}/man5
release:
VERSION=$$(git describe --tags | sed 's/^v//;s/-[^.]*$$//') && \
git archive --prefix=cwm-$$VERSION/ -o cwm-$$VERSION.tar.gz HEAD

88
README Normal file
View File

@ -0,0 +1,88 @@
This is a port of OpenBSD's excellent cwm[0] to Linux and other
Unices.
cwm is a window manager for X11 which contains many features that
concentrate on the efficiency and transparency of window
management. cwm also aims to maintain the simplest and most
pleasant aesthetic.
This port requires pkg-config, Xft, Xinerama and Xrandr. The included Makefile
should work with both GNU make and BSD make.
This version actively tracks changes in the OpenBSD CVS repository.
Releases are roughly coordinated.
The revision controlled version is at https://github.com/chneukirchen/cwm
Releases can be found at http://chneukirchen.org/releases
You are welcome to join the IRC channel ##cwm on Freenode to talk about cwm.
ChangeLog:
2012-05-02: First public release 5.1 of portable cwm.
2014-04-13: Second public release 5.5 of portable cwm.
User visible changes (for a full list including smaller bug fixes, see
http://www.openbsd.org/plus.html ff.)
Changes made between OpenBSD 5.1 and 5.2
* Fixed cwm(1) atom (WM_PROTOCOLS) style handing; closing a window will no
longer close entire application if the client supports CLIENT_PROTO_DELETE.
* Re-implement atom handing for more consistent separation of cwm(1) and
Extended Window Manager Hints.
* cwm(1) better integrated into the freedesktop.org Window Manager
Specification Project.
Changes made between OpenBSD 5.2 and 5.3
* Set the initial cwm(1) group to "1".
* Added cwm(1) per-group vert/horiz tiling support with new bind commands
"vtile" and "htile."
* Made cwm(1) screen font an Xft(3) font.
* Specific last match for autogroup in cwmrc(5).
* Tab completion support for cwm(1) menus.
* Allow cwm(1) clients to be resized from a max state.
* Multibyte input to cwm(1) menu code now possible.
Changes made between OpenBSD 5.3 and 5.4
* Added support for mouse based group {,r}cycle to cwmrc(5).
* Allow mouse button4 and button5 in cwmrc(5).
* Made cwm(1) check for, and honour, CWStackMode and CWSibling change requests
during a ConfigureRequest event.
* Honour PATH search order for cwm(1)'s exec.
Changes made between OpenBSD 5.5 and 5.4
* Only set the cwm(1) urgency flag if the client is not active.
* Allow the cwm(1) config parser continue parsing even after encountering an
error.
* cwm(1) now follows the EWMH spec: if the cardinal returned is 0xFFFFFFFF (-1)
then the window should appear on all desktops.
* Made cwm(1) supply a more useful title for windows launched via the ssh(1)
command menu ("[ssh] ").
* Allowed cwm(1) to accept _NET_WM_DESKTOP and _NET_CURRENT_DESKTOP
ClientMessage.
* Implemented cwm(1) support for _NET_WM_STATE_FULLSCREEN hint, with keybinding
changes: CM-f "fullscreen", CM-m "maximize".
* Instead of using the work area, use the Xinerama area for cwm(1) snap
calculations.
* Save-set when cwm(1) is re-exec'ing so as to not lose State on our hidden
clients.
* Added cwmrc(5) support for XUrgency and matching
_NET_WM_STATE_DEMANDS_ATTENTION ewmh hint, with configurable urgencyborder.
* Prepend the group shortcut in the cwm(1) client search menu;
prepend shortcut in unhide menu.
* If not hidden during an UnmapNotify event, cwm(1) will now un-manage the
client.
* Like "gap", made cwm(1) "snapdist" per-screen.
* Removed cwmrc(5) option to bind a key by keycode with brackets, which never
worked. Users should be using keysym names not keycodes.
* Re-added cwm(1) support for WM_TAKE_FOCUS. Solves keyboard input focus loss
for java apps.
* For cwm(1) clients that support WM_TAKE_FOCUS in their WM_PROTOCOLS property,
send a ClientMessage event.
--Christian Neukirchen <chneukirchen@gmail.com>
[0]: http://www.openbsd.org/cgi-bin/cvsweb/xenocara/app/cwm/

View File

@ -19,7 +19,7 @@
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/queue.h> #include "queue.h"
#include <sys/wait.h> #include <sys/wait.h>
#include <err.h> #include <err.h>
@ -219,7 +219,7 @@ sigchld_cb(int which)
errno = save_errno; errno = save_errno;
} }
__dead void void
usage(void) usage(void)
{ {
extern char *__progname; extern char *__progname;

View File

@ -21,6 +21,12 @@
#ifndef _CALMWM_H_ #ifndef _CALMWM_H_
#define _CALMWM_H_ #define _CALMWM_H_
/* prototypes for portable-included functions */
char *fgetln(FILE *, size_t *);
long long strtonum(const char *, long long, long long, const char **);
size_t strlcpy(char *, const char *, size_t);
size_t strlcat(char *, const char *, size_t);
#include <X11/XKBlib.h> #include <X11/XKBlib.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <X11/Xft/Xft.h> #include <X11/Xft/Xft.h>
@ -367,7 +373,7 @@ enum {
extern Atom cwmh[CWMH_NITEMS]; extern Atom cwmh[CWMH_NITEMS];
extern Atom ewmh[EWMH_NITEMS]; extern Atom ewmh[EWMH_NITEMS];
__dead void usage(void); void usage(void);
void client_applysizehints(struct client_ctx *); void client_applysizehints(struct client_ctx *);
void client_config(struct client_ctx *); void client_config(struct client_ctx *);

View File

@ -19,7 +19,7 @@
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/queue.h> #include "queue.h"
#include <assert.h> #include <assert.h>
#include <err.h> #include <err.h>

2
conf.c
View File

@ -19,7 +19,7 @@
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/queue.h> #include "queue.h"
#include <sys/stat.h> #include <sys/stat.h>
#include <err.h> #include <err.h>

106
fgetln.c Normal file
View File

@ -0,0 +1,106 @@
/* $NetBSD: fgetln.c,v 1.9 2008/04/29 06:53:03 martin Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#if !HAVE_FGETLN
#include <stdlib.h>
#ifndef HAVE_NBTOOL_CONFIG_H
/* These headers are required, but included from nbtool_config.h */
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#endif
char *
fgetln(FILE *fp, size_t *len)
{
static char *buf = NULL;
static size_t bufsiz = 0;
char *ptr;
if (buf == NULL) {
bufsiz = BUFSIZ;
if ((buf = malloc(bufsiz)) == NULL)
return NULL;
}
if (fgets(buf, bufsiz, fp) == NULL)
return NULL;
*len = 0;
while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
size_t nbufsiz = bufsiz + BUFSIZ;
char *nbuf = realloc(buf, nbufsiz);
if (nbuf == NULL) {
int oerrno = errno;
free(buf);
errno = oerrno;
buf = NULL;
return NULL;
} else
buf = nbuf;
if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) {
buf[bufsiz] = '\0';
*len = strlen(buf);
return buf;
}
*len = bufsiz;
bufsiz = nbufsiz;
}
*len = (ptr - buf) + 1;
return buf;
}
#endif
#ifdef TEST
int
main(int argc, char *argv[])
{
char *p;
size_t len;
while ((p = fgetln(stdin, &len)) != NULL) {
(void)printf("%zu %s", len, p);
free(p);
}
return 0;
}
#endif

View File

@ -20,7 +20,7 @@
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/queue.h> #include "queue.h"
#include <assert.h> #include <assert.h>
#include <err.h> #include <err.h>

View File

@ -19,7 +19,7 @@
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/queue.h> #include "queue.h"
#include <dirent.h> #include <dirent.h>
#include <err.h> #include <err.h>

2
menu.c
View File

@ -20,7 +20,7 @@
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/queue.h> #include "queue.h"
#include <ctype.h> #include <ctype.h>
#include <err.h> #include <err.h>

View File

@ -20,7 +20,7 @@
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/queue.h> #include "queue.h"
#include <err.h> #include <err.h>
#include <errno.h> #include <errno.h>

12
parse.y
View File

@ -35,6 +35,8 @@
#include "calmwm.h" #include "calmwm.h"
#define YYSTYPE_IS_DECLARED
TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files); TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
static struct file { static struct file {
TAILQ_ENTRY(file) entry; TAILQ_ENTRY(file) entry;
@ -304,9 +306,9 @@ lookup(char *s)
#define MAXPUSHBACK 128 #define MAXPUSHBACK 128
u_char *parsebuf; char *parsebuf;
int parseindex; int parseindex;
u_char pushback_buffer[MAXPUSHBACK]; char pushback_buffer[MAXPUSHBACK];
int pushback_index = 0; int pushback_index = 0;
int int
@ -399,8 +401,8 @@ findeol(void)
int int
yylex(void) yylex(void)
{ {
u_char buf[8096]; char buf[8096];
u_char *p; char *p;
int quotec, next, c; int quotec, next, c;
int token; int token;
@ -441,7 +443,7 @@ yylex(void)
yyerror("string too long"); yyerror("string too long");
return (findeol()); return (findeol());
} }
*p++ = c; *p++ = (char)c;
} }
yylval.v.string = xstrdup(buf); yylval.v.string = xstrdup(buf);
return (STRING); return (STRING);

568
queue.h Normal file
View File

@ -0,0 +1,568 @@
/* $OpenBSD: "queue.h",v 1.36 2012/04/11 13:29:14 naddy Exp $ */
/* $NetBSD: "queue.h",v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)"queue.h" 8.5 (Berkeley) 8/20/94
*/
#ifndef _SYS_QUEUE_H_
#define _SYS_QUEUE_H_
/*
* This file defines five types of data structures: singly-linked lists,
* lists, simple queues, tail queues, and circular queues.
*
*
* A singly-linked list is headed by a single forward pointer. The elements
* are singly linked for minimum space and pointer manipulation overhead at
* the expense of O(n) removal for arbitrary elements. New elements can be
* added to the list after an existing element or at the head of the list.
* Elements being removed from the head of the list should use the explicit
* macro for this purpose for optimum efficiency. A singly-linked list may
* only be traversed in the forward direction. Singly-linked lists are ideal
* for applications with large datasets and few or no removals or for
* implementing a LIFO queue.
*
* A list is headed by a single forward pointer (or an array of forward
* pointers for a hash table header). The elements are doubly linked
* so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before
* or after an existing element or at the head of the list. A list
* may only be traversed in the forward direction.
*
* A simple queue is headed by a pair of pointers, one the head of the
* 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
* head of the list. New elements can be added to the list before or after
* an existing element, at the head of the list, or at the end of the
* list. A simple queue may only be traversed in the forward direction.
*
* A tail 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 doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or
* 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.
*
* A circle 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 doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or after
* 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.
*/
#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
#define _Q_INVALIDATE(a) (a) = ((void *)-1)
#else
#define _Q_INVALIDATE(a)
#endif
/*
* Singly-linked List definitions.
*/
#define SLIST_HEAD(name, type) \
struct name { \
struct type *slh_first; /* first element */ \
}
#define SLIST_HEAD_INITIALIZER(head) \
{ NULL }
#define SLIST_ENTRY(type) \
struct { \
struct type *sle_next; /* next element */ \
}
/*
* Singly-linked List access methods.
*/
#define SLIST_FIRST(head) ((head)->slh_first)
#define SLIST_END(head) NULL
#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
#define SLIST_FOREACH(var, head, field) \
for((var) = SLIST_FIRST(head); \
(var) != SLIST_END(head); \
(var) = SLIST_NEXT(var, field))
#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = SLIST_FIRST(head); \
(var) && ((tvar) = SLIST_NEXT(var, field), 1); \
(var) = (tvar))
/*
* Singly-linked List functions.
*/
#define SLIST_INIT(head) { \
SLIST_FIRST(head) = SLIST_END(head); \
}
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
(elm)->field.sle_next = (slistelm)->field.sle_next; \
(slistelm)->field.sle_next = (elm); \
} while (0)
#define SLIST_INSERT_HEAD(head, elm, field) do { \
(elm)->field.sle_next = (head)->slh_first; \
(head)->slh_first = (elm); \
} while (0)
#define SLIST_REMOVE_AFTER(elm, field) do { \
(elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \
} while (0)
#define SLIST_REMOVE_HEAD(head, field) do { \
(head)->slh_first = (head)->slh_first->field.sle_next; \
} while (0)
#define SLIST_REMOVE(head, elm, type, field) do { \
if ((head)->slh_first == (elm)) { \
SLIST_REMOVE_HEAD((head), field); \
} else { \
struct type *curelm = (head)->slh_first; \
\
while (curelm->field.sle_next != (elm)) \
curelm = curelm->field.sle_next; \
curelm->field.sle_next = \
curelm->field.sle_next->field.sle_next; \
_Q_INVALIDATE((elm)->field.sle_next); \
} \
} while (0)
/*
* List definitions.
*/
#define LIST_HEAD(name, type) \
struct name { \
struct type *lh_first; /* first element */ \
}
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* address of previous next element */ \
}
/*
* List access methods
*/
#define LIST_FIRST(head) ((head)->lh_first)
#define LIST_END(head) NULL
#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
#define LIST_FOREACH(var, head, field) \
for((var) = LIST_FIRST(head); \
(var)!= LIST_END(head); \
(var) = LIST_NEXT(var, field))
#define LIST_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = LIST_FIRST(head); \
(var) && ((tvar) = LIST_NEXT(var, field), 1); \
(var) = (tvar))
/*
* List functions.
*/
#define LIST_INIT(head) do { \
LIST_FIRST(head) = LIST_END(head); \
} while (0)
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
(listelm)->field.le_next->field.le_prev = \
&(elm)->field.le_next; \
(listelm)->field.le_next = (elm); \
(elm)->field.le_prev = &(listelm)->field.le_next; \
} while (0)
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.le_prev = (listelm)->field.le_prev; \
(elm)->field.le_next = (listelm); \
*(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &(elm)->field.le_next; \
} while (0)
#define LIST_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
(head)->lh_first = (elm); \
(elm)->field.le_prev = &(head)->lh_first; \
} while (0)
#define LIST_REMOVE(elm, field) do { \
if ((elm)->field.le_next != NULL) \
(elm)->field.le_next->field.le_prev = \
(elm)->field.le_prev; \
*(elm)->field.le_prev = (elm)->field.le_next; \
_Q_INVALIDATE((elm)->field.le_prev); \
_Q_INVALIDATE((elm)->field.le_next); \
} while (0)
#define LIST_REPLACE(elm, elm2, field) do { \
if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
(elm2)->field.le_next->field.le_prev = \
&(elm2)->field.le_next; \
(elm2)->field.le_prev = (elm)->field.le_prev; \
*(elm2)->field.le_prev = (elm2); \
_Q_INVALIDATE((elm)->field.le_prev); \
_Q_INVALIDATE((elm)->field.le_next); \
} while (0)
/*
* Simple queue definitions.
*/
#define SIMPLEQ_HEAD(name, type) \
struct name { \
struct type *sqh_first; /* first element */ \
struct type **sqh_last; /* addr of last next element */ \
}
#define SIMPLEQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).sqh_first }
#define SIMPLEQ_ENTRY(type) \
struct { \
struct type *sqe_next; /* next element */ \
}
/*
* Simple queue access methods.
*/
#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
#define SIMPLEQ_END(head) NULL
#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
#define SIMPLEQ_FOREACH(var, head, field) \
for((var) = SIMPLEQ_FIRST(head); \
(var) != SIMPLEQ_END(head); \
(var) = SIMPLEQ_NEXT(var, field))
#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = SIMPLEQ_FIRST(head); \
(var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \
(var) = (tvar))
/*
* Simple queue functions.
*/
#define SIMPLEQ_INIT(head) do { \
(head)->sqh_first = NULL; \
(head)->sqh_last = &(head)->sqh_first; \
} while (0)
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
(head)->sqh_last = &(elm)->field.sqe_next; \
(head)->sqh_first = (elm); \
} while (0)
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.sqe_next = NULL; \
*(head)->sqh_last = (elm); \
(head)->sqh_last = &(elm)->field.sqe_next; \
} while (0)
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
(head)->sqh_last = &(elm)->field.sqe_next; \
(listelm)->field.sqe_next = (elm); \
} while (0)
#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
(head)->sqh_last = &(head)->sqh_first; \
} while (0)
#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
== NULL) \
(head)->sqh_last = &(elm)->field.sqe_next; \
} while (0)
/*
* Tail queue definitions.
*/
#define TAILQ_HEAD(name, type) \
struct name { \
struct type *tqh_first; /* first element */ \
struct type **tqh_last; /* addr of last next element */ \
}
#define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
#define TAILQ_ENTRY(type) \
struct { \
struct type *tqe_next; /* next element */ \
struct type **tqe_prev; /* address of previous next element */ \
}
/*
* tail queue access methods
*/
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_END(head) NULL
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
/* XXX */
#define TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
#define TAILQ_EMPTY(head) \
(TAILQ_FIRST(head) == TAILQ_END(head))
#define TAILQ_FOREACH(var, head, field) \
for((var) = TAILQ_FIRST(head); \
(var) != TAILQ_END(head); \
(var) = TAILQ_NEXT(var, field))
#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = TAILQ_FIRST(head); \
(var) != TAILQ_END(head) && \
((tvar) = TAILQ_NEXT(var, field), 1); \
(var) = (tvar))
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
for((var) = TAILQ_LAST(head, headname); \
(var) != TAILQ_END(head); \
(var) = TAILQ_PREV(var, headname, field))
#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
for ((var) = TAILQ_LAST(head, headname); \
(var) != TAILQ_END(head) && \
((tvar) = TAILQ_PREV(var, headname, field), 1); \
(var) = (tvar))
/*
* Tail queue functions.
*/
#define TAILQ_INIT(head) do { \
(head)->tqh_first = NULL; \
(head)->tqh_last = &(head)->tqh_first; \
} while (0)
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
(head)->tqh_first->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(head)->tqh_first = (elm); \
(elm)->field.tqe_prev = &(head)->tqh_first; \
} while (0)
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.tqe_next = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
(head)->tqh_last = &(elm)->field.tqe_next; \
} while (0)
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
(elm)->field.tqe_next->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(listelm)->field.tqe_next = (elm); \
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
} while (0)
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
(elm)->field.tqe_next = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (0)
#define TAILQ_REMOVE(head, elm, field) do { \
if (((elm)->field.tqe_next) != NULL) \
(elm)->field.tqe_next->field.tqe_prev = \
(elm)->field.tqe_prev; \
else \
(head)->tqh_last = (elm)->field.tqe_prev; \
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
_Q_INVALIDATE((elm)->field.tqe_prev); \
_Q_INVALIDATE((elm)->field.tqe_next); \
} while (0)
#define TAILQ_REPLACE(head, elm, elm2, field) do { \
if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
(elm2)->field.tqe_next->field.tqe_prev = \
&(elm2)->field.tqe_next; \
else \
(head)->tqh_last = &(elm2)->field.tqe_next; \
(elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
*(elm2)->field.tqe_prev = (elm2); \
_Q_INVALIDATE((elm)->field.tqe_prev); \
_Q_INVALIDATE((elm)->field.tqe_next); \
} while (0)
/*
* Circular queue definitions.
*/
#define CIRCLEQ_HEAD(name, type) \
struct name { \
struct type *cqh_first; /* first element */ \
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)
#endif /* !_SYS_QUEUE_H_ */

View File

@ -19,7 +19,7 @@
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/queue.h> #include "queue.h"
#include <err.h> #include <err.h>
#include <errno.h> #include <errno.h>

View File

@ -19,7 +19,7 @@
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/queue.h> #include "queue.h"
#include <assert.h> #include <assert.h>
#include <err.h> #include <err.h>

61
strlcat.c Normal file
View File

@ -0,0 +1,61 @@
/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */
#ifndef HAVE_STRLCAT
#include <sys/types.h>
#include <string.h>
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
* If retval >= siz, truncation occurred.
*/
size_t
strlcat(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src)); /* count does not include NUL */
}
#endif /* !HAVE_STRLCAT */

57
strlcpy.c Normal file
View File

@ -0,0 +1,57 @@
/* $OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c */
#ifndef HAVE_STRLCPY
#include <sys/types.h>
#include <string.h>
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t
strlcpy(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0 && --n != 0) {
do {
if ((*d++ = *s++) == 0)
break;
} while (--n != 0);
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}
#endif /* !HAVE_STRLCPY */

70
strtonum.c Normal file
View File

@ -0,0 +1,70 @@
/* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ */
/*
* Copyright (c) 2004 Ted Unangst and Todd Miller
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* OPENBSD ORIGINAL: lib/libc/stdlib/strtonum.c */
#ifndef HAVE_STRTONUM
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
#define INVALID 1
#define TOOSMALL 2
#define TOOLARGE 3
long long
strtonum(const char *numstr, long long minval, long long maxval,
const char **errstrp)
{
long long ll = 0;
char *ep;
int error = 0;
struct errval {
const char *errstr;
int err;
} ev[4] = {
{ NULL, 0 },
{ "invalid", EINVAL },
{ "too small", ERANGE },
{ "too large", ERANGE },
};
ev[0].err = errno;
errno = 0;
if (minval > maxval)
error = INVALID;
else {
ll = strtoll(numstr, &ep, 10);
if (numstr == ep || *ep != '\0')
error = INVALID;
else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
error = TOOSMALL;
else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
error = TOOLARGE;
}
if (errstrp != NULL)
*errstrp = ev[error].errstr;
errno = ev[error].err;
if (error)
ll = 0;
return (ll);
}
#endif /* HAVE_STRTONUM */

1
update.sh Executable file
View File

@ -0,0 +1 @@
GIT_MERGE_AUTOEDIT=no git cvsimport -o master -v -k -m -d :pserver:anoncvs:anoncvs@mirror.planetunix.net:/cvs xenocara/app/cwm

2
util.c
View File

@ -19,7 +19,7 @@
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/queue.h> #include "queue.h"
#include <err.h> #include <err.h>
#include <errno.h> #include <errno.h>

View File

@ -25,7 +25,7 @@
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/queue.h> #include "queue.h"
#include <err.h> #include <err.h>
#include <errno.h> #include <errno.h>

View File

@ -19,7 +19,7 @@
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/queue.h> #include "queue.h"
#include <err.h> #include <err.h>
#include <errno.h> #include <errno.h>

View File

@ -19,7 +19,7 @@
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/queue.h> #include "queue.h"
#include <err.h> #include <err.h>
#include <errno.h> #include <errno.h>