mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Sync with fdm.
This commit is contained in:
		
							
								
								
									
										28
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
# $Id: Makefile,v 1.1.1.1 2007-07-09 19:03:33 nicm Exp $
 | 
			
		||||
# $Id: Makefile,v 1.2 2007-07-25 23:13:18 nicm Exp $
 | 
			
		||||
 | 
			
		||||
.SUFFIXES: .c .o .y .l .h
 | 
			
		||||
.SUFFIXES: .c .o .y .h
 | 
			
		||||
.PHONY: clean
 | 
			
		||||
 | 
			
		||||
PROG= tmux
 | 
			
		||||
@@ -10,19 +10,22 @@ OS!= uname
 | 
			
		||||
REL!= uname -r
 | 
			
		||||
DATE!= date +%Y%m%d-%H%M
 | 
			
		||||
 | 
			
		||||
SRCS= tmux.c server.c buffer.c buffer-poll.c xmalloc.c input.c screen.c \
 | 
			
		||||
      window.c session.c local.c log.c command.c
 | 
			
		||||
HDRS= tmux.h
 | 
			
		||||
# This must be empty as OpenBSD includes it in default CFLAGS.
 | 
			
		||||
DEBUG=
 | 
			
		||||
 | 
			
		||||
SRCS= tmux.c server.c buffer.c buffer-poll.c xmalloc.c xmalloc-debug.c \
 | 
			
		||||
      input.c screen.c window.c session.c local.c log.c command.c
 | 
			
		||||
 | 
			
		||||
LEX= lex
 | 
			
		||||
YACC= yacc -d
 | 
			
		||||
 | 
			
		||||
CC= cc
 | 
			
		||||
INCDIRS+= -I. -I- -I/usr/local/include
 | 
			
		||||
CFLAGS+= -DBUILD="\"$(VERSION) ($(DATE))\""
 | 
			
		||||
.ifdef DEBUG
 | 
			
		||||
CFLAGS+= -g -ggdb -DDEBUG
 | 
			
		||||
LDFLAGS+= -Wl,-E
 | 
			
		||||
.endif
 | 
			
		||||
#CFLAGS+= -pedantic -std=c99
 | 
			
		||||
#CFLAGS+= -Wredundant-decls  -Wdisabled-optimization -Wendif-labels
 | 
			
		||||
CFLAGS+= -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
 | 
			
		||||
CFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
 | 
			
		||||
CFLAGS+= -Wwrite-strings -Wshadow -Wpointer-arith -Wcast-qual -Wsign-compare
 | 
			
		||||
@@ -35,29 +38,22 @@ INSTALLMAN= install -g bin -o root -m 444
 | 
			
		||||
LDFLAGS+= -L/usr/local/lib
 | 
			
		||||
LIBS+= -lutil -lncurses
 | 
			
		||||
 | 
			
		||||
OBJS= ${SRCS:S/.c/.o/:S/.y/.o/:S/.l/.o/}
 | 
			
		||||
OBJS= ${SRCS:S/.c/.o/:S/.y/.o/}
 | 
			
		||||
 | 
			
		||||
CLEANFILES= ${PROG} *.o .depend *~ ${PROG}.core *.log
 | 
			
		||||
 | 
			
		||||
.c.o:
 | 
			
		||||
		${CC} ${CFLAGS} ${INCDIRS} -c ${.IMPSRC} -o ${.TARGET}
 | 
			
		||||
 | 
			
		||||
.l.o:
 | 
			
		||||
		${LEX} ${.IMPSRC}
 | 
			
		||||
		${CC} ${CFLAGS} ${INCDIRS} -c lex.yy.c -o ${.TARGET}
 | 
			
		||||
 | 
			
		||||
.y.o:
 | 
			
		||||
		${YACC} ${.IMPSRC}
 | 
			
		||||
		${CC} ${CFLAGS} ${INCDIRS} -c y.tab.c -o ${.TARGET}
 | 
			
		||||
 | 
			
		||||
all:		.depend ${PROG}
 | 
			
		||||
all:		${PROG}
 | 
			
		||||
 | 
			
		||||
${PROG}:	${OBJS}
 | 
			
		||||
		${CC} ${LDFLAGS} -o ${PROG} ${LIBS} ${OBJS}
 | 
			
		||||
 | 
			
		||||
.depend:	${HDRS}
 | 
			
		||||
		-mkdep ${CFLAGS} ${INCDIRS} ${SRCS:M*.c}
 | 
			
		||||
 | 
			
		||||
depend:
 | 
			
		||||
		mkdep ${CFLAGS} ${INCDIRS} ${SRCS:M*.c}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										38
									
								
								buffer.c
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								buffer.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: buffer.c,v 1.1.1.1 2007-07-09 19:03:33 nicm Exp $ */
 | 
			
		||||
/* $Id: buffer.c,v 1.2 2007-07-25 23:13:18 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -29,7 +29,7 @@ buffer_create(size_t size)
 | 
			
		||||
	struct buffer	*b;
 | 
			
		||||
 | 
			
		||||
	if (size == 0)
 | 
			
		||||
		log_fatalx("buffer_create: zero size");
 | 
			
		||||
		fatalx("zero size");
 | 
			
		||||
 | 
			
		||||
	b = xcalloc(1, sizeof *b);
 | 
			
		||||
 | 
			
		||||
@@ -60,7 +60,7 @@ void
 | 
			
		||||
buffer_ensure(struct buffer *b, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	if (size == 0)
 | 
			
		||||
		log_fatalx("buffer_ensure: zero size");
 | 
			
		||||
		fatalx("zero size");
 | 
			
		||||
 | 
			
		||||
	if (BUFFER_FREE(b) >= size)
 | 
			
		||||
		return;
 | 
			
		||||
@@ -79,9 +79,9 @@ void
 | 
			
		||||
buffer_add(struct buffer *b, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	if (size == 0)
 | 
			
		||||
		log_fatalx("buffer_add: zero size");
 | 
			
		||||
		fatalx("zero size");
 | 
			
		||||
	if (size > b->space - b->size)
 | 
			
		||||
		log_fatalx("buffer_add: overflow");
 | 
			
		||||
		fatalx("overflow");
 | 
			
		||||
 | 
			
		||||
	b->size += size;
 | 
			
		||||
}
 | 
			
		||||
@@ -91,9 +91,9 @@ void
 | 
			
		||||
buffer_reverse_add(struct buffer *b, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	if (size == 0)
 | 
			
		||||
		log_fatalx("buffer_reverse_add: zero size");
 | 
			
		||||
		fatalx("zero size");
 | 
			
		||||
	if (size > b->size)
 | 
			
		||||
		log_fatalx("buffer_reverse_add: underflow");
 | 
			
		||||
		fatalx("underflow");
 | 
			
		||||
 | 
			
		||||
	b->size -= size;
 | 
			
		||||
}
 | 
			
		||||
@@ -103,9 +103,9 @@ void
 | 
			
		||||
buffer_remove(struct buffer *b, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	if (size == 0)
 | 
			
		||||
		log_fatalx("buffer_remove: zero size");
 | 
			
		||||
		fatalx("zero size");
 | 
			
		||||
	if (size > b->size)
 | 
			
		||||
		log_fatalx("buffer_remove: underflow");
 | 
			
		||||
		fatalx("underflow");
 | 
			
		||||
 | 
			
		||||
	b->size -= size;
 | 
			
		||||
	b->off += size;
 | 
			
		||||
@@ -116,9 +116,9 @@ void
 | 
			
		||||
buffer_reverse_remove(struct buffer *b, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	if (size == 0)
 | 
			
		||||
		log_fatalx("buffer_reverse_remove: zero size");
 | 
			
		||||
		fatalx("zero size");
 | 
			
		||||
	if (size > b->off)
 | 
			
		||||
		log_fatalx("buffer_reverse_remove: overflow");
 | 
			
		||||
		fatalx("overflow");
 | 
			
		||||
 | 
			
		||||
	b->size += size;
 | 
			
		||||
	b->off -= size;
 | 
			
		||||
@@ -129,9 +129,9 @@ void
 | 
			
		||||
buffer_insert_range(struct buffer *b, size_t base, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	if (size == 0)
 | 
			
		||||
		log_fatalx("buffer_insert_range: zero size");
 | 
			
		||||
		fatalx("zero size");
 | 
			
		||||
	if (base > b->size)
 | 
			
		||||
		log_fatalx("buffer_insert_range: range overflows buffer");
 | 
			
		||||
		fatalx("range outside buffer");
 | 
			
		||||
 | 
			
		||||
	buffer_ensure(b, size);
 | 
			
		||||
	memmove(b->base + b->off + base + size,
 | 
			
		||||
@@ -144,11 +144,11 @@ void
 | 
			
		||||
buffer_delete_range(struct buffer *b, size_t base, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	if (size == 0)
 | 
			
		||||
		log_fatalx("buffer_delete_range: zero size");
 | 
			
		||||
		fatalx("zero size");
 | 
			
		||||
	if (size > b->size)
 | 
			
		||||
		log_fatalx("buffer_delete_range: size too big");
 | 
			
		||||
		fatalx("size too big");
 | 
			
		||||
	if (base + size > b->size)
 | 
			
		||||
		log_fatalx("buffer_delete_range: range overflows buffer");
 | 
			
		||||
		fatalx("range outside buffer");
 | 
			
		||||
 | 
			
		||||
	memmove(b->base + b->off + base,
 | 
			
		||||
	    b->base + b->off + base + size, b->size - base - size);
 | 
			
		||||
@@ -160,7 +160,7 @@ void
 | 
			
		||||
buffer_write(struct buffer *b, const void *data, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	if (size == 0)
 | 
			
		||||
		log_fatalx("buffer_write: zero size");
 | 
			
		||||
		fatalx("zero size");
 | 
			
		||||
 | 
			
		||||
	buffer_ensure(b, size);
 | 
			
		||||
	memcpy(BUFFER_IN(b), data, size);
 | 
			
		||||
@@ -172,9 +172,9 @@ void
 | 
			
		||||
buffer_read(struct buffer *b, void *data, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	if (size == 0)
 | 
			
		||||
		log_fatalx("buffer_read: zero size");
 | 
			
		||||
		fatalx("zero size");
 | 
			
		||||
	if (size > b->size)
 | 
			
		||||
		log_fatalx("buffer_read: underflow");
 | 
			
		||||
		fatalx("underflow");
 | 
			
		||||
 | 
			
		||||
	memcpy(data, BUFFER_OUT(b), size);
 | 
			
		||||
	buffer_remove(b, size);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										50
									
								
								local.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								local.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: local.c,v 1.3 2007-07-09 19:39:47 nicm Exp $ */
 | 
			
		||||
/* $Id: local.c,v 1.4 2007-07-25 23:13:18 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -214,13 +214,13 @@ local_init(struct buffer **in, struct buffer **out)
 | 
			
		||||
	struct local_key *lk;
 | 
			
		||||
 | 
			
		||||
	if ((tty = ttyname(STDOUT_FILENO)) == NULL)
 | 
			
		||||
		log_fatal("ttyname");
 | 
			
		||||
		fatal("ttyname failed");
 | 
			
		||||
	if ((local_fd = open(tty, O_RDWR)) == -1)
 | 
			
		||||
		log_fatal("open(\"%s\")", tty);
 | 
			
		||||
		fatal("open failed");
 | 
			
		||||
	if ((mode = fcntl(local_fd, F_GETFL)) == -1)
 | 
			
		||||
		log_fatal("fcntl");
 | 
			
		||||
		fatal("fcntl failed");
 | 
			
		||||
	if (fcntl(local_fd, F_SETFL, mode|O_NONBLOCK) == -1)
 | 
			
		||||
		log_fatal("fcntl");
 | 
			
		||||
		fatal("fcntl failed");
 | 
			
		||||
 | 
			
		||||
	*in = local_in = buffer_create(BUFSIZ);
 | 
			
		||||
	*out = local_out = buffer_create(BUFSIZ);
 | 
			
		||||
@@ -228,13 +228,13 @@ local_init(struct buffer **in, struct buffer **out)
 | 
			
		||||
	setupterm(NULL, STDOUT_FILENO, NULL);
 | 
			
		||||
 | 
			
		||||
	if (tcgetattr(local_fd, &local_tio) != 0)
 | 
			
		||||
		log_fatal("tcgetattr");
 | 
			
		||||
		fatal("tcgetattr failed");
 | 
			
		||||
	memcpy(&tio, &local_tio, sizeof tio);
 | 
			
		||||
	tio.c_iflag &= ~(IXON|IXOFF|ICRNL|INLCR);
 | 
			
		||||
	tio.c_oflag &= ~(OPOST|ONLCR|OCRNL|ONLRET);
 | 
			
		||||
	tio.c_lflag &= ~(IEXTEN|ICANON|ECHO|ECHOE|ECHOKE|ECHOCTL|ISIG);
 | 
			
		||||
	if (tcsetattr(local_fd, TCSANOW, &tio) != 0)
 | 
			
		||||
		log_fatal("tcsetattr");
 | 
			
		||||
		fatal("tcsetattr failed");
 | 
			
		||||
 | 
			
		||||
	if (enter_ca_mode != NULL)
 | 
			
		||||
		local_putp(enter_ca_mode);
 | 
			
		||||
@@ -281,7 +281,7 @@ local_done(void)
 | 
			
		||||
	xfree(local_out);
 | 
			
		||||
 | 
			
		||||
	if (tcsetattr(local_fd, TCSANOW, &local_tio) != 0)
 | 
			
		||||
		log_fatal("tcsetattr");
 | 
			
		||||
		fatal("tcsetattr failed");
 | 
			
		||||
	close(local_fd);
 | 
			
		||||
 | 
			
		||||
	if (keypad_local != NULL)
 | 
			
		||||
@@ -303,7 +303,7 @@ local_putc(int c)
 | 
			
		||||
	u_char	ch = c;
 | 
			
		||||
 | 
			
		||||
	if (c < 0 || c > (int) UCHAR_MAX)
 | 
			
		||||
		log_fatalx("local_putc: invalid character");
 | 
			
		||||
		fatalx("invalid character");
 | 
			
		||||
 | 
			
		||||
	if (debug_level > 1) {
 | 
			
		||||
		f = fopen("tmux-out.log", "a+");
 | 
			
		||||
@@ -320,7 +320,7 @@ void
 | 
			
		||||
local_putp(const char *s)
 | 
			
		||||
{
 | 
			
		||||
	if (s == NULL)
 | 
			
		||||
		log_fatalx("local_putp: null pointer");
 | 
			
		||||
		fatalx("null pointer");
 | 
			
		||||
 | 
			
		||||
	tputs(s, 1, local_putc);
 | 
			
		||||
}
 | 
			
		||||
@@ -402,7 +402,7 @@ local_output(struct buffer *b, size_t size)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (size < 1)
 | 
			
		||||
			log_fatalx("local_output: underflow");
 | 
			
		||||
			fatalx("underflow");
 | 
			
		||||
		size--;
 | 
			
		||||
		ch = input_extract8(b);
 | 
			
		||||
 | 
			
		||||
@@ -410,7 +410,7 @@ local_output(struct buffer *b, size_t size)
 | 
			
		||||
		switch (ch) {
 | 
			
		||||
		case CODE_CURSORUP:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				log_fatalx("local_output: underflow");
 | 
			
		||||
				fatalx("underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			if (parm_up_cursor == NULL) {
 | 
			
		||||
@@ -421,7 +421,7 @@ local_output(struct buffer *b, size_t size)
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_CURSORDOWN:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				log_fatalx("local_output: underflow");
 | 
			
		||||
				fatalx("underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			if (parm_down_cursor == NULL) {
 | 
			
		||||
@@ -432,7 +432,7 @@ local_output(struct buffer *b, size_t size)
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_CURSORRIGHT:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				log_fatalx("local_output: underflow");
 | 
			
		||||
				fatalx("underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			if (parm_right_cursor == NULL) {
 | 
			
		||||
@@ -443,7 +443,7 @@ local_output(struct buffer *b, size_t size)
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_CURSORLEFT:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				log_fatalx("local_output: underflow");
 | 
			
		||||
				fatalx("underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			if (parm_left_cursor == NULL) {
 | 
			
		||||
@@ -454,7 +454,7 @@ local_output(struct buffer *b, size_t size)
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_CURSORMOVE:
 | 
			
		||||
			if (size < 4)
 | 
			
		||||
				log_fatalx("local_output: underflow");
 | 
			
		||||
				fatalx("underflow");
 | 
			
		||||
			size -= 4;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			ub = input_extract16(b);
 | 
			
		||||
@@ -501,7 +501,7 @@ local_output(struct buffer *b, size_t size)
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_INSERTLINE:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				log_fatalx("local_output: underflow");
 | 
			
		||||
				fatalx("underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			if (parm_insert_line == NULL) {
 | 
			
		||||
@@ -512,7 +512,7 @@ local_output(struct buffer *b, size_t size)
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_DELETELINE:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				log_fatalx("local_output: underflow");
 | 
			
		||||
				fatalx("underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			if (parm_delete_line == NULL) {
 | 
			
		||||
@@ -523,7 +523,7 @@ local_output(struct buffer *b, size_t size)
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_INSERTCHARACTER:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				log_fatalx("local_output: underflow");
 | 
			
		||||
				fatalx("underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			if (parm_ich == NULL) {
 | 
			
		||||
@@ -534,7 +534,7 @@ local_output(struct buffer *b, size_t size)
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_DELETECHARACTER:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				log_fatalx("local_output: underflow");
 | 
			
		||||
				fatalx("underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			if (parm_dch == NULL) {
 | 
			
		||||
@@ -573,7 +573,7 @@ local_output(struct buffer *b, size_t size)
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_SCROLLREGION:
 | 
			
		||||
			if (size < 4)
 | 
			
		||||
				log_fatalx("local_output: underflow");
 | 
			
		||||
				fatalx("underflow");
 | 
			
		||||
			size -= 4;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
			ub = input_extract16(b);
 | 
			
		||||
@@ -631,18 +631,18 @@ local_output(struct buffer *b, size_t size)
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_TITLE:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				log_fatalx("local_output: underflow");
 | 
			
		||||
				fatalx("underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
 | 
			
		||||
			if (size < ua)
 | 
			
		||||
				log_fatalx("local_output: underflow");
 | 
			
		||||
				fatalx("underflow");
 | 
			
		||||
			size -= ua;
 | 
			
		||||
			buffer_remove(b, ua);
 | 
			
		||||
			break;
 | 
			
		||||
		case CODE_ATTRIBUTES:
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				log_fatalx("local_output: underflow");
 | 
			
		||||
				fatalx("underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			ua = input_extract16(b);
 | 
			
		||||
 | 
			
		||||
@@ -657,7 +657,7 @@ local_output(struct buffer *b, size_t size)
 | 
			
		||||
 | 
			
		||||
			while (ua-- != 0) {
 | 
			
		||||
				if (size < 2)
 | 
			
		||||
					log_fatalx("local_output: underflow");
 | 
			
		||||
					fatalx("underflow");
 | 
			
		||||
				size -= 2;
 | 
			
		||||
				ub = input_extract16(b);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										50
									
								
								log.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								log.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: log.c,v 1.1.1.1 2007-07-09 19:03:33 nicm Exp $ */
 | 
			
		||||
/* $Id: log.c,v 1.2 2007-07-25 23:13:18 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -35,11 +35,14 @@ FILE	*log_stream;
 | 
			
		||||
/* Debug level. */
 | 
			
		||||
int	 log_level;
 | 
			
		||||
 | 
			
		||||
/* Open log. */
 | 
			
		||||
/* Open logging. */
 | 
			
		||||
void
 | 
			
		||||
log_open(FILE *f, int facility, int level)
 | 
			
		||||
{
 | 
			
		||||
	log_stream = f;
 | 
			
		||||
	if (f != NULL)
 | 
			
		||||
		setlinebuf(f);
 | 
			
		||||
 | 
			
		||||
	log_level = level;
 | 
			
		||||
 | 
			
		||||
	if (f == NULL)
 | 
			
		||||
@@ -61,32 +64,37 @@ log_close(void)
 | 
			
		||||
 | 
			
		||||
/* Write a log message. */
 | 
			
		||||
void
 | 
			
		||||
log_write(FILE *f, int priority, const char *fmt, ...)
 | 
			
		||||
log_write(FILE *f, int priority, const char *msg, ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list	ap;
 | 
			
		||||
 | 
			
		||||
	va_start(ap, fmt);
 | 
			
		||||
	log_vwrite(f, priority, fmt, ap);
 | 
			
		||||
	va_start(ap, msg);
 | 
			
		||||
	log_vwrite(f, priority, msg, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Write a log message. */
 | 
			
		||||
void
 | 
			
		||||
log_vwrite(FILE *f, int priority, const char *fmt, va_list ap)
 | 
			
		||||
log_vwrite(FILE *f, int priority, const char *msg, va_list ap)
 | 
			
		||||
{
 | 
			
		||||
	char	*fmt;
 | 
			
		||||
 | 
			
		||||
	if (!log_enabled)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (f == NULL)
 | 
			
		||||
		f = log_stream;
 | 
			
		||||
	if (f == NULL) {
 | 
			
		||||
		vsyslog(priority, fmt, ap);
 | 
			
		||||
		vsyslog(priority, msg, ap);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (asprintf(&fmt, "%s\n", msg) == -1)
 | 
			
		||||
		exit(1);
 | 
			
		||||
	if (vfprintf(f, fmt, ap) == -1)
 | 
			
		||||
		exit(1);
 | 
			
		||||
	if (fputc('\n', f) == EOF)
 | 
			
		||||
		exit(1);
 | 
			
		||||
	fflush(log_stream);
 | 
			
		||||
	fflush(f);
 | 
			
		||||
	free(fmt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Log a warning with error string. */
 | 
			
		||||
@@ -102,8 +110,8 @@ log_warn(const char *msg, ...)
 | 
			
		||||
	va_start(ap, msg);
 | 
			
		||||
	if (asprintf(&fmt, "%s: %s", msg, strerror(errno)) == -1)
 | 
			
		||||
		exit(1);
 | 
			
		||||
	log_vwrite(log_stream, LOG_CRIT, fmt, ap);
 | 
			
		||||
	xfree(fmt);
 | 
			
		||||
	log_vwrite(NULL, LOG_CRIT, fmt, ap);
 | 
			
		||||
	free(fmt);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -114,7 +122,7 @@ log_warnx(const char *msg, ...)
 | 
			
		||||
	va_list	ap;
 | 
			
		||||
 | 
			
		||||
	va_start(ap, msg);
 | 
			
		||||
	log_vwrite(log_stream, LOG_CRIT, msg, ap);
 | 
			
		||||
	log_vwrite(NULL, LOG_CRIT, msg, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -126,10 +134,10 @@ log_info(const char *msg, ...)
 | 
			
		||||
 | 
			
		||||
	if (log_level > -1) {
 | 
			
		||||
		va_start(ap, msg);
 | 
			
		||||
		if (log_stream == stderr)
 | 
			
		||||
		if (log_stream == stderr) /* XXX */
 | 
			
		||||
			log_vwrite(stdout, LOG_INFO, msg, ap);
 | 
			
		||||
		else
 | 
			
		||||
			log_vwrite(log_stream, LOG_INFO, msg, ap);
 | 
			
		||||
			log_vwrite(NULL, LOG_INFO, msg, ap);
 | 
			
		||||
		va_end(ap);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -142,7 +150,7 @@ log_debug(const char *msg, ...)
 | 
			
		||||
 | 
			
		||||
	if (log_level > 0) {
 | 
			
		||||
		va_start(ap, msg);
 | 
			
		||||
		log_vwrite(log_stream, LOG_DEBUG, msg, ap);
 | 
			
		||||
		log_vwrite(NULL, LOG_DEBUG, msg, ap);
 | 
			
		||||
		va_end(ap);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -155,7 +163,7 @@ log_debug2(const char *msg, ...)
 | 
			
		||||
 | 
			
		||||
	if (log_level > 1) {
 | 
			
		||||
		va_start(ap, msg);
 | 
			
		||||
		log_vwrite(log_stream, LOG_DEBUG, msg, ap);
 | 
			
		||||
		log_vwrite(NULL, LOG_DEBUG, msg, ap);
 | 
			
		||||
		va_end(ap);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -168,7 +176,7 @@ log_debug3(const char *msg, ...)
 | 
			
		||||
 | 
			
		||||
	if (log_level > 2) {
 | 
			
		||||
		va_start(ap, msg);
 | 
			
		||||
		log_vwrite(log_stream, LOG_DEBUG, msg, ap);
 | 
			
		||||
		log_vwrite(NULL, LOG_DEBUG, msg, ap);
 | 
			
		||||
		va_end(ap);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -185,13 +193,13 @@ log_vfatal(const char *msg, va_list ap)
 | 
			
		||||
	if (errno != 0) {
 | 
			
		||||
		if (asprintf(&fmt, "fatal: %s: %s", msg, strerror(errno)) == -1)
 | 
			
		||||
			exit(1);
 | 
			
		||||
		log_vwrite(log_stream, LOG_CRIT, fmt, ap);
 | 
			
		||||
		log_vwrite(NULL, LOG_CRIT, fmt, ap);
 | 
			
		||||
	} else {
 | 
			
		||||
		if (asprintf(&fmt, "fatal: %s", msg) == -1)
 | 
			
		||||
			exit(1);
 | 
			
		||||
		log_vwrite(log_stream, LOG_CRIT, fmt, ap);
 | 
			
		||||
		log_vwrite(NULL, LOG_CRIT, fmt, ap);
 | 
			
		||||
	}
 | 
			
		||||
	xfree(fmt);
 | 
			
		||||
	free(fmt);
 | 
			
		||||
 | 
			
		||||
	exit(1);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										114
									
								
								screen.c
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								screen.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: screen.c,v 1.2 2007-07-10 10:21:58 nicm Exp $ */
 | 
			
		||||
/* $Id: screen.c,v 1.3 2007-07-25 23:13:18 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -59,6 +59,12 @@ void	 screen_delete_characters(struct screen *, u_int, u_int, u_int);
 | 
			
		||||
#define screen_last_y(s) ((s)->sy - 1)
 | 
			
		||||
#define screen_last_x(s) ((s)->sx - 1)
 | 
			
		||||
 | 
			
		||||
#define screen_range_y(lx, rx) (((rx) - (lx)) + 1)
 | 
			
		||||
#define screen_range_x(ux, lx) (((lx) - (ux)) + 1)
 | 
			
		||||
 | 
			
		||||
#define screen_offset_y(py, ny) ((py) + (ny) - 1)
 | 
			
		||||
#define screen_offset_x(px, nx) ((px) + (nx) - 1)
 | 
			
		||||
 | 
			
		||||
/* Create a new screen. */
 | 
			
		||||
void
 | 
			
		||||
screen_create(struct screen *s, u_int sx, u_int sy)
 | 
			
		||||
@@ -180,7 +186,7 @@ screen_draw(struct screen *s, struct buffer *b, u_int uy, u_int ly)
 | 
			
		||||
	uint16_t	 n;
 | 
			
		||||
 | 
			
		||||
	if (uy > screen_last_y(s) || ly > screen_last_y(s) || ly < uy)
 | 
			
		||||
		log_fatalx("screen_draw_lines: bad range");
 | 
			
		||||
		fatalx("bad range");
 | 
			
		||||
 | 
			
		||||
	/* XXX. This is naive and rough right now. */
 | 
			
		||||
	attr = 0;
 | 
			
		||||
@@ -303,7 +309,7 @@ screen_make_lines(struct screen *s, u_int uy, u_int ly)
 | 
			
		||||
	log_debug("making lines %u:%u", uy, ly);
 | 
			
		||||
 | 
			
		||||
	if (uy > screen_last_y(s) || ly > screen_last_y(s) || ly < uy)
 | 
			
		||||
		log_fatalx("screen_make_lines: bad range");
 | 
			
		||||
		fatalx("bad range");
 | 
			
		||||
	
 | 
			
		||||
	for (i = uy; i <= ly; i++) {
 | 
			
		||||
		s->grid_data[i] = xmalloc(s->sx);
 | 
			
		||||
@@ -321,7 +327,7 @@ screen_free_lines(struct screen *s, u_int uy, u_int ly)
 | 
			
		||||
	log_debug("freeing lines %u:%u", uy, ly);
 | 
			
		||||
 | 
			
		||||
	if (uy > screen_last_y(s) || ly > screen_last_y(s) || ly < uy)
 | 
			
		||||
		log_fatalx("screen_free_lines: bad range");
 | 
			
		||||
		fatalx("bad range");
 | 
			
		||||
 | 
			
		||||
	for (i = uy; i <= ly; i++) {
 | 
			
		||||
		xfree(s->grid_data[i]);
 | 
			
		||||
@@ -344,18 +350,20 @@ screen_move_lines(struct screen *s, u_int dy, u_int uy, u_int ly)
 | 
			
		||||
	ny = (ly - uy) + 1;
 | 
			
		||||
 | 
			
		||||
	if (uy > screen_last_y(s) || ly > screen_last_y(s) || ly < uy)
 | 
			
		||||
		log_fatalx("screen_move_lines: bad range");
 | 
			
		||||
		fatalx("bad range");
 | 
			
		||||
	if (dy > screen_last_y(s))
 | 
			
		||||
		log_fatalx("screen_move_lines: bad destination");
 | 
			
		||||
		fatalx("bad destination");
 | 
			
		||||
	if (dy + ny - 1 > screen_last_y(s))
 | 
			
		||||
		log_fatalx("screen_move_lines: bad destination");
 | 
			
		||||
		fatalx("bad size");
 | 
			
		||||
	if (dy == uy)
 | 
			
		||||
		fatalx("null move");
 | 
			
		||||
 | 
			
		||||
	memmove(
 | 
			
		||||
	    s->grid_data + dy, s->grid_data + uy, ny * (sizeof *s->grid_data));
 | 
			
		||||
	    &s->grid_data[dy], &s->grid_data[uy], ny * (sizeof *s->grid_data));
 | 
			
		||||
	memmove(
 | 
			
		||||
	    s->grid_attr + dy, s->grid_attr + uy, ny * (sizeof *s->grid_attr));
 | 
			
		||||
	    &s->grid_attr[dy], &s->grid_attr[uy], ny * (sizeof *s->grid_attr));
 | 
			
		||||
	memmove(
 | 
			
		||||
	    s->grid_colr + dy, s->grid_colr + uy, ny * (sizeof *s->grid_colr));
 | 
			
		||||
	    &s->grid_colr[dy], &s->grid_colr[uy], ny * (sizeof *s->grid_colr));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Fill a range of lines. */
 | 
			
		||||
@@ -368,7 +376,7 @@ screen_fill_lines(
 | 
			
		||||
	log_debug("filling lines %u:%u", uy, ly);
 | 
			
		||||
 | 
			
		||||
	if (uy > screen_last_y(s) || ly > screen_last_y(s) || ly < uy)
 | 
			
		||||
		log_fatalx("screen_fill_lines: bad range");
 | 
			
		||||
		fatalx("bad range");
 | 
			
		||||
 | 
			
		||||
	for (i = uy; i <= ly; i++)
 | 
			
		||||
		screen_fill_line(s, i, data, attr, colr);
 | 
			
		||||
@@ -391,7 +399,7 @@ screen_character(struct screen *s, u_char ch)
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		if (ch < ' ')
 | 
			
		||||
			log_fatalx("screen_character: bad control: %hhu", ch);
 | 
			
		||||
			fatalx("bad control");
 | 
			
		||||
		screen_write_character(s, ch);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
@@ -662,7 +670,7 @@ screen_scroll_up(struct screen *s, u_int ny)
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log_fatalx("screen_scroll_up: %u %u", s->ry_upper, s->ry_lower);
 | 
			
		||||
	fatalx("unimplemented");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Scroll screen down. */
 | 
			
		||||
@@ -674,7 +682,7 @@ screen_scroll_down(struct screen *s, u_int ny)
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	log_fatalx("screen_scroll_down: %u %u", s->ry_upper, s->ry_lower);
 | 
			
		||||
	fatalx("unimplemented");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Fill entire screen. */
 | 
			
		||||
@@ -722,9 +730,9 @@ screen_fill_end_of_line(
 | 
			
		||||
	if (py > screen_last_y(s))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	memset(s->grid_data[py] + px, data, s->sx - px);
 | 
			
		||||
	memset(s->grid_attr[py] + px, attr, s->sx - px);
 | 
			
		||||
	memset(s->grid_colr[py] + px, colr, s->sx - px);
 | 
			
		||||
	memset(&s->grid_data[py][px], data, s->sx - px);
 | 
			
		||||
	memset(&s->grid_attr[py][px], attr, s->sx - px);
 | 
			
		||||
	memset(&s->grid_colr[py][px], colr, s->sx - px);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Fill to start of line. */
 | 
			
		||||
@@ -787,44 +795,64 @@ screen_delete_lines(struct screen *s, u_int py, u_int ny)
 | 
			
		||||
void
 | 
			
		||||
screen_insert_characters(struct screen *s, u_int px, u_int py, u_int nx)
 | 
			
		||||
{
 | 
			
		||||
	if (px >= s->sx || py >= s->sy)
 | 
			
		||||
	u_int	lx, rx;
 | 
			
		||||
 | 
			
		||||
	if (px > screen_last_x(s) || py > screen_last_y(s))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (px + nx > s->sx)
 | 
			
		||||
		nx = s->sx - px;
 | 
			
		||||
	lx = px;
 | 
			
		||||
	rx = screen_offset_x(px, nx);
 | 
			
		||||
	if (rx > screen_last_x(s))
 | 
			
		||||
		rx = screen_last_x(s);
 | 
			
		||||
 | 
			
		||||
	if (px - nx != s->sx) {
 | 
			
		||||
		memmove(s->grid_data[py] + px + nx,
 | 
			
		||||
		    s->grid_data[py] + px, s->sx - px - nx);
 | 
			
		||||
		memmove(s->grid_attr[py] + px + nx,
 | 
			
		||||
		    s->grid_attr[py] + px, s->sx - px - nx);
 | 
			
		||||
		memmove(s->grid_colr[py] + px + nx,
 | 
			
		||||
		    s->grid_colr[py] + px, s->sx - px - nx);
 | 
			
		||||
	/*
 | 
			
		||||
	 * Inserting a range from lx to rx, inclusive.
 | 
			
		||||
	 *
 | 
			
		||||
	 * - If rx is not the last x, move from lx to rx + 1.
 | 
			
		||||
	 * - Clear the range from lx to rx.
 | 
			
		||||
	 */
 | 
			
		||||
	if (rx != screen_last_x(s)) {
 | 
			
		||||
		nx = screen_range_x(rx + 1, screen_last_x(s));
 | 
			
		||||
		memmove(&s->grid_data[py][rx + 1], &s->grid_data[py][lx], nx);
 | 
			
		||||
		memmove(&s->grid_attr[py][rx + 1], &s->grid_attr[py][lx], nx);
 | 
			
		||||
		memmove(&s->grid_colr[py][rx + 1], &s->grid_colr[py][lx], nx);
 | 
			
		||||
	}
 | 
			
		||||
	memset(s->grid_data[py] + px, SCREEN_DEFDATA, nx);
 | 
			
		||||
	memset(s->grid_attr[py] + px, SCREEN_DEFATTR, nx);
 | 
			
		||||
	memset(s->grid_colr[py] + px, SCREEN_DEFCOLR, nx);
 | 
			
		||||
	memset(&s->grid_data[py][lx], SCREEN_DEFDATA, screen_range_x(lx, rx));
 | 
			
		||||
	memset(&s->grid_attr[py][lx], SCREEN_DEFATTR, screen_range_x(lx, rx));
 | 
			
		||||
	memset(&s->grid_colr[py][lx], SCREEN_DEFCOLR, screen_range_x(lx, rx));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Delete characters. */
 | 
			
		||||
void
 | 
			
		||||
screen_delete_characters(struct screen *s, u_int px, u_int py, u_int nx)
 | 
			
		||||
{
 | 
			
		||||
	if (px >= s->sx || py >= s->sy)
 | 
			
		||||
	u_int	lx, rx;
 | 
			
		||||
 | 
			
		||||
	if (px > screen_last_x(s) || py > screen_last_y(s))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (px + nx > s->sx)
 | 
			
		||||
		nx = s->sx - px;
 | 
			
		||||
	lx = px;
 | 
			
		||||
	rx = screen_offset_x(px, nx);
 | 
			
		||||
	if (rx > screen_last_x(s))
 | 
			
		||||
		rx = screen_last_x(s);
 | 
			
		||||
 | 
			
		||||
	if (px - nx != s->sx) {
 | 
			
		||||
		memmove(s->grid_data[py] + px,
 | 
			
		||||
		    s->grid_data[py] + px + nx, s->sx - px - nx);
 | 
			
		||||
		memmove(s->grid_attr[py] + px,
 | 
			
		||||
		    s->grid_attr[py] + px + nx, s->sx - px - nx);
 | 
			
		||||
		memmove(s->grid_colr[py] + px,
 | 
			
		||||
		    s->grid_colr[py] + px + nx, s->sx - px - nx);
 | 
			
		||||
	/*
 | 
			
		||||
	 * Deleting the range from lx to rx, inclusive.
 | 
			
		||||
	 *
 | 
			
		||||
	 * - If rx is not the last x, move the range from rx + 1 to lx.
 | 
			
		||||
	 * - Clear the range from the last x - (rx - lx)  to the last x.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	if (rx != screen_last_x(s)) {
 | 
			
		||||
		nx = screen_range_x(rx + 1, screen_last_x(s));
 | 
			
		||||
		memmove(&s->grid_data[py][lx], &s->grid_data[py][rx + 1], nx);
 | 
			
		||||
		memmove(&s->grid_attr[py][lx], &s->grid_attr[py][rx + 1], nx);
 | 
			
		||||
		memmove(&s->grid_colr[py][lx], &s->grid_colr[py][rx + 1], nx);
 | 
			
		||||
	}
 | 
			
		||||
	memset(s->grid_data[py] + px + nx, SCREEN_DEFDATA, s->sx - px - nx);
 | 
			
		||||
	memset(s->grid_attr[py] + px + nx, SCREEN_DEFATTR, s->sx - px - nx);
 | 
			
		||||
	memset(s->grid_colr[py] + px + nx, SCREEN_DEFCOLR, s->sx - px - nx);
 | 
			
		||||
 | 
			
		||||
	/* If lx == rx, then nx = 1. */ 
 | 
			
		||||
	nx = screen_range_x(lx, rx);
 | 
			
		||||
	memset(&s->grid_data[py][s->sx - nx], SCREEN_DEFDATA, nx);
 | 
			
		||||
	memset(&s->grid_attr[py][s->sx - nx], SCREEN_DEFATTR, nx);
 | 
			
		||||
	memset(&s->grid_colr[py][s->sx - nx], SCREEN_DEFCOLR, nx);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										78
									
								
								server.c
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								server.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: server.c,v 1.1.1.1 2007-07-09 19:03:42 nicm Exp $ */
 | 
			
		||||
/* $Id: server.c,v 1.2 2007-07-25 23:13:18 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -114,27 +114,27 @@ server_start(void)
 | 
			
		||||
	sz = strlcpy(sa.sun_path, socket_path, sizeof sa.sun_path);
 | 
			
		||||
	if (sz >= sizeof sa.sun_path) {
 | 
			
		||||
		errno = ENAMETOOLONG;
 | 
			
		||||
		log_fatal("socket");
 | 
			
		||||
		fatal("socket failed");
 | 
			
		||||
	}
 | 
			
		||||
	unlink(sa.sun_path);
 | 
			
		||||
 | 
			
		||||
	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
 | 
			
		||||
		log_fatal("socket");
 | 
			
		||||
		fatal("socket failed");
 | 
			
		||||
 | 
			
		||||
	mode = umask(S_IXUSR|S_IRWXG|S_IRWXO);
 | 
			
		||||
	if (bind(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1)
 | 
			
		||||
		log_fatal("bind");
 | 
			
		||||
		fatal("bind failed");
 | 
			
		||||
	umask(mode);
 | 
			
		||||
 | 
			
		||||
	if (listen(fd, 16) == -1)
 | 
			
		||||
		log_fatal("listen");
 | 
			
		||||
		fatal("listen failed");
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Detach into the background. This means the PID changes which will
 | 
			
		||||
	 * have to be fixed in some way at some point... XXX
 | 
			
		||||
	 */
 | 
			
		||||
	if (daemon(1, 1) != 0)
 | 
			
		||||
		log_fatal("daemon");
 | 
			
		||||
		fatal("daemon failed");
 | 
			
		||||
	log_debug("server daemonised, pid now %ld", (long) getpid());
 | 
			
		||||
 | 
			
		||||
	setproctitle("server (%s)", socket_path);
 | 
			
		||||
@@ -154,24 +154,24 @@ server_main(int srv_fd)
 | 
			
		||||
 | 
			
		||||
	act.sa_handler = SIG_IGN;
 | 
			
		||||
	if (sigaction(SIGPIPE, &act, NULL) != 0)
 | 
			
		||||
		log_fatal("sigaction");
 | 
			
		||||
		fatal("sigaction failed");
 | 
			
		||||
	if (sigaction(SIGUSR1, &act, NULL) != 0)
 | 
			
		||||
		log_fatal("sigaction");
 | 
			
		||||
		fatal("sigaction failed");
 | 
			
		||||
	if (sigaction(SIGUSR2, &act, NULL) != 0)
 | 
			
		||||
		log_fatal("sigaction");
 | 
			
		||||
		fatal("sigaction failed");
 | 
			
		||||
	if (sigaction(SIGINT, &act, NULL) != 0)
 | 
			
		||||
		log_fatal("sigaction");
 | 
			
		||||
		fatal("sigaction failed");
 | 
			
		||||
	if (sigaction(SIGQUIT, &act, NULL) != 0)
 | 
			
		||||
		log_fatal("sigaction");
 | 
			
		||||
		fatal("sigaction failed");
 | 
			
		||||
 | 
			
		||||
	ARRAY_INIT(&windows);
 | 
			
		||||
	ARRAY_INIT(&clients);
 | 
			
		||||
	ARRAY_INIT(&sessions);
 | 
			
		||||
 | 
			
		||||
	if ((mode = fcntl(srv_fd, F_GETFL)) == -1)
 | 
			
		||||
		log_fatal("fcntl");
 | 
			
		||||
		fatal("fcntl failed");
 | 
			
		||||
	if (fcntl(srv_fd, F_SETFL, mode|O_NONBLOCK) == -1)
 | 
			
		||||
		log_fatal("fcntl");
 | 
			
		||||
		fatal("fcntl failed");
 | 
			
		||||
 | 
			
		||||
	pfds = NULL;
 | 
			
		||||
	while (!sigterm) {
 | 
			
		||||
@@ -193,13 +193,13 @@ server_main(int srv_fd)
 | 
			
		||||
		if (poll(pfds, nfds, INFTIM) == -1) {
 | 
			
		||||
			if (errno == EAGAIN || errno == EINTR)
 | 
			
		||||
				continue;
 | 
			
		||||
			log_fatal("poll");
 | 
			
		||||
			fatal("poll failed");
 | 
			
		||||
		}
 | 
			
		||||
		pfd = pfds;
 | 
			
		||||
 | 
			
		||||
		/* Handle server socket. */
 | 
			
		||||
		if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP))
 | 
			
		||||
			log_fatalx("lost server socket");
 | 
			
		||||
			fatalx("lost server socket");
 | 
			
		||||
		if (pfd->revents & POLLIN) {
 | 
			
		||||
			accept_client(srv_fd);
 | 
			
		||||
			continue;
 | 
			
		||||
@@ -319,12 +319,12 @@ accept_client(int srv_fd)
 | 
			
		||||
	if (client_fd == -1) {
 | 
			
		||||
		if (errno == EAGAIN || errno == EINTR || errno == ECONNABORTED)
 | 
			
		||||
			return (NULL);
 | 
			
		||||
		log_fatal("accept");
 | 
			
		||||
		fatal("accept failed");
 | 
			
		||||
	}
 | 
			
		||||
	if ((mode = fcntl(client_fd, F_GETFL)) == -1)
 | 
			
		||||
		log_fatal("fcntl");
 | 
			
		||||
		fatal("fcntl failed");
 | 
			
		||||
	if (fcntl(client_fd, F_SETFL, mode|O_NONBLOCK) == -1)
 | 
			
		||||
		log_fatal("fcntl");
 | 
			
		||||
		fatal("fcntl failed");
 | 
			
		||||
 | 
			
		||||
	c = xmalloc(sizeof *c);
 | 
			
		||||
	c->fd = client_fd;
 | 
			
		||||
@@ -477,7 +477,7 @@ user_input(struct client *c, size_t in)
 | 
			
		||||
		key = input_extract8(c->in);
 | 
			
		||||
		if (key == '\e') {
 | 
			
		||||
			if (in < 2)
 | 
			
		||||
				log_fatalx("user_input: underflow");
 | 
			
		||||
				fatalx("underflow");
 | 
			
		||||
			in -= 2;
 | 
			
		||||
			key = (int16_t) input_extract16(c->in);
 | 
			
		||||
		}
 | 
			
		||||
@@ -762,7 +762,7 @@ process_identify_msg(struct client *c, struct hdr *hdr)
 | 
			
		||||
	struct identify_data	 data;
 | 
			
		||||
 | 
			
		||||
	if (hdr->size != sizeof data)
 | 
			
		||||
		log_fatalx("bad MSG_IDENTIFY size");
 | 
			
		||||
		fatalx("bad MSG_IDENTIFY size");
 | 
			
		||||
	buffer_read(c->in, &data, hdr->size);
 | 
			
		||||
 | 
			
		||||
	c->sx = data.sx;
 | 
			
		||||
@@ -779,7 +779,7 @@ process_identify_msg(struct client *c, struct hdr *hdr)
 | 
			
		||||
		    session_create(data.name, "/bin/ksh -l", c->sx, c->sy);
 | 
			
		||||
	}
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
		log_fatalx("process_identify_msg: session_create failed");
 | 
			
		||||
		fatalx("session_create failed");
 | 
			
		||||
 | 
			
		||||
	draw_client(c, 0, c->sy - 1);
 | 
			
		||||
}
 | 
			
		||||
@@ -789,12 +789,12 @@ void
 | 
			
		||||
process_create_msg(struct client *c, struct hdr *hdr)
 | 
			
		||||
{
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
		log_fatalx("MSG_CREATE before identified");
 | 
			
		||||
		fatalx("MSG_CREATE before identified");
 | 
			
		||||
	if (hdr->size != 0)
 | 
			
		||||
		log_fatalx("bad MSG_CREATE size");
 | 
			
		||||
		fatalx("bad MSG_CREATE size");
 | 
			
		||||
 | 
			
		||||
	if (session_new(c->session, "/bin/ksh -l", c->sx, c->sy) != 0)
 | 
			
		||||
		log_fatalx("process_create_msg: session_new failed");
 | 
			
		||||
		fatalx("session_new failed");
 | 
			
		||||
 | 
			
		||||
	draw_client(c, 0, c->sy - 1);
 | 
			
		||||
}
 | 
			
		||||
@@ -804,9 +804,9 @@ void
 | 
			
		||||
process_next_msg(struct client *c, struct hdr *hdr)
 | 
			
		||||
{
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
		log_fatalx("MSG_NEXT before identified");
 | 
			
		||||
		fatalx("MSG_NEXT before identified");
 | 
			
		||||
	if (hdr->size != 0)
 | 
			
		||||
		log_fatalx("bad MSG_NEXT size");
 | 
			
		||||
		fatalx("bad MSG_NEXT size");
 | 
			
		||||
 | 
			
		||||
	if (session_next(c->session) == 0)
 | 
			
		||||
		changed_window(c);
 | 
			
		||||
@@ -819,9 +819,9 @@ void
 | 
			
		||||
process_previous_msg(struct client *c, struct hdr *hdr)
 | 
			
		||||
{
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
		log_fatalx("MSG_PREVIOUS before identified");
 | 
			
		||||
		fatalx("MSG_PREVIOUS before identified");
 | 
			
		||||
	if (hdr->size != 0)
 | 
			
		||||
		log_fatalx("bad MSG_PREVIOUS size");
 | 
			
		||||
		fatalx("bad MSG_PREVIOUS size");
 | 
			
		||||
 | 
			
		||||
	if (session_previous(c->session) == 0)
 | 
			
		||||
		changed_window(c);
 | 
			
		||||
@@ -836,9 +836,9 @@ process_size_msg(struct client *c, struct hdr *hdr)
 | 
			
		||||
	struct size_data	data;
 | 
			
		||||
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
		log_fatalx("MSG_SIZE before identified");
 | 
			
		||||
		fatalx("MSG_SIZE before identified");
 | 
			
		||||
	if (hdr->size != sizeof data)
 | 
			
		||||
		log_fatalx("bad MSG_SIZE size");
 | 
			
		||||
		fatalx("bad MSG_SIZE size");
 | 
			
		||||
	buffer_read(c->in, &data, hdr->size);
 | 
			
		||||
 | 
			
		||||
	c->sx = data.sx;
 | 
			
		||||
@@ -857,7 +857,7 @@ void
 | 
			
		||||
process_input_msg(struct client *c, struct hdr *hdr)
 | 
			
		||||
{
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
		log_fatalx("MSG_INPUT before identified");
 | 
			
		||||
		fatalx("MSG_INPUT before identified");
 | 
			
		||||
 | 
			
		||||
	if (c->prompt == NULL)
 | 
			
		||||
		window_input(c->session->window, c->in, hdr->size);
 | 
			
		||||
@@ -872,9 +872,9 @@ process_refresh_msg(struct client *c, struct hdr *hdr)
 | 
			
		||||
	struct refresh_data	data;
 | 
			
		||||
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
		log_fatalx("MSG_REFRESH before identified");
 | 
			
		||||
		fatalx("MSG_REFRESH before identified");
 | 
			
		||||
	if (hdr->size != 0 && hdr->size != sizeof data)
 | 
			
		||||
		log_fatalx("bad MSG_REFRESH size");
 | 
			
		||||
		fatalx("bad MSG_REFRESH size");
 | 
			
		||||
 | 
			
		||||
	draw_client(c, 0, c->sy - 1);
 | 
			
		||||
}
 | 
			
		||||
@@ -886,9 +886,9 @@ process_select_msg(struct client *c, struct hdr *hdr)
 | 
			
		||||
	struct select_data	data;
 | 
			
		||||
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
		log_fatalx("MSG_SELECT before identified");
 | 
			
		||||
		fatalx("MSG_SELECT before identified");
 | 
			
		||||
	if (hdr->size != sizeof data)
 | 
			
		||||
		log_fatalx("bad MSG_SELECT size");
 | 
			
		||||
		fatalx("bad MSG_SELECT size");
 | 
			
		||||
	buffer_read(c->in, &data, hdr->size);
 | 
			
		||||
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
@@ -909,7 +909,7 @@ process_sessions_msg(struct client *c, struct hdr *hdr)
 | 
			
		||||
	u_int			 i, j;
 | 
			
		||||
 | 
			
		||||
	if (hdr->size != sizeof data)
 | 
			
		||||
		log_fatalx("bad MSG_SESSIONS size");
 | 
			
		||||
		fatalx("bad MSG_SESSIONS size");
 | 
			
		||||
	buffer_read(c->in, &data, hdr->size);
 | 
			
		||||
 | 
			
		||||
	data.sessions = 0;
 | 
			
		||||
@@ -946,7 +946,7 @@ process_windows_msg(struct client *c, struct hdr *hdr)
 | 
			
		||||
	u_int			 i;
 | 
			
		||||
 | 
			
		||||
	if (hdr->size != sizeof data)
 | 
			
		||||
		log_fatalx("bad MSG_WINDOWS size");
 | 
			
		||||
		fatalx("bad MSG_WINDOWS size");
 | 
			
		||||
	buffer_read(c->in, &data, hdr->size);
 | 
			
		||||
 | 
			
		||||
	s = session_find(data.name);
 | 
			
		||||
@@ -982,9 +982,9 @@ void
 | 
			
		||||
process_rename_msg(struct client *c, struct hdr *hdr)
 | 
			
		||||
{
 | 
			
		||||
	if (c->session == NULL)
 | 
			
		||||
		log_fatalx("MSG_RENAME before identified");
 | 
			
		||||
		fatalx("MSG_RENAME before identified");
 | 
			
		||||
	if (hdr->size != 0)
 | 
			
		||||
		log_fatalx("bad MSG_RENAME size");
 | 
			
		||||
		fatalx("bad MSG_RENAME size");
 | 
			
		||||
 | 
			
		||||
	user_start(c, "Window name: ",
 | 
			
		||||
	    c->session->window->name, MAXNAMELEN, rename_callback);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: session.c,v 1.1.1.1 2007-07-09 19:04:12 nicm Exp $ */
 | 
			
		||||
/* $Id: session.c,v 1.2 2007-07-25 23:13:18 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -76,7 +76,7 @@ session_destroy(struct session *s)
 | 
			
		||||
	u_int	i;
 | 
			
		||||
 | 
			
		||||
	if (session_index(s, &i) != 0)
 | 
			
		||||
		log_fatalx("session not found");
 | 
			
		||||
		fatalx("session not found");
 | 
			
		||||
	ARRAY_REMOVE(&sessions, i);
 | 
			
		||||
 | 
			
		||||
	while (!ARRAY_EMPTY(&s->windows))
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								tmux.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								tmux.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: tmux.c,v 1.1.1.1 2007-07-09 19:03:33 nicm Exp $ */
 | 
			
		||||
/* $Id: tmux.c,v 1.2 2007-07-25 23:13:18 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -237,7 +237,7 @@ main(int argc, char **argv)
 | 
			
		||||
		/* Handle SIGWINCH if necessary. */
 | 
			
		||||
		if (sigwinch) {
 | 
			
		||||
			if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
 | 
			
		||||
				log_fatal("ioctl(TIOCGWINSZ)");
 | 
			
		||||
				fatal("ioctl failed");
 | 
			
		||||
 | 
			
		||||
			hdr.code = MSG_SIZE;
 | 
			
		||||
			hdr.size = sizeof sd;
 | 
			
		||||
@@ -263,14 +263,14 @@ main(int argc, char **argv)
 | 
			
		||||
		if (poll(pfds, 2, INFTIM) == -1) {
 | 
			
		||||
			if (errno == EAGAIN || errno == EINTR)
 | 
			
		||||
				continue;
 | 
			
		||||
			log_fatal("poll");
 | 
			
		||||
			fatal("poll failed");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Read/write from sockets. */
 | 
			
		||||
		if (buffer_poll(&pfds[0], srv_in, srv_out) != 0)
 | 
			
		||||
			goto server_dead;
 | 
			
		||||
		if (buffer_poll(&pfds[1], loc_in, loc_out) != 0)
 | 
			
		||||
			log_fatalx("lost local socket");
 | 
			
		||||
			fatalx("lost local socket");
 | 
			
		||||
 | 
			
		||||
		/* Output flushed; pause if requested. */
 | 
			
		||||
		if (n)
 | 
			
		||||
@@ -341,7 +341,7 @@ process_server(struct buffer *srv_in)
 | 
			
		||||
			break;
 | 
			
		||||
		case MSG_PAUSE:
 | 
			
		||||
			if (hdr.size != 0)
 | 
			
		||||
				log_fatalx("bad MSG_PAUSE size");
 | 
			
		||||
				fatalx("bad MSG_PAUSE size");
 | 
			
		||||
			return (1);
 | 
			
		||||
		case MSG_EXIT:
 | 
			
		||||
			return (-1);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								tmux.h
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: tmux.h,v 1.1.1.1 2007-07-09 19:03:50 nicm Exp $ */
 | 
			
		||||
/* $Id: tmux.h,v 1.2 2007-07-25 23:13:18 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -20,6 +20,7 @@
 | 
			
		||||
#define NSCR_H
 | 
			
		||||
 | 
			
		||||
#include <sys/param.h>
 | 
			
		||||
#include <sys/tree.h>
 | 
			
		||||
#include <sys/queue.h>
 | 
			
		||||
 | 
			
		||||
#include <poll.h>
 | 
			
		||||
@@ -33,6 +34,10 @@ extern char	*__progname;
 | 
			
		||||
#define MAXNAMELEN	32
 | 
			
		||||
#define MAXTITLELEN	192
 | 
			
		||||
 | 
			
		||||
/* Fatal errors. */
 | 
			
		||||
#define fatal(msg) log_fatal("%s: %s", __func__, msg);
 | 
			
		||||
#define fatalx(msg) log_fatal("%s: %s", __func__, msg);
 | 
			
		||||
 | 
			
		||||
/* Definition to shut gcc up about unused arguments. */
 | 
			
		||||
#define unused __attribute__ ((unused))
 | 
			
		||||
 | 
			
		||||
@@ -580,4 +585,16 @@ int printflike3	 printpath(char *, size_t, const char *, ...);
 | 
			
		||||
char 		*xdirname(const char *);
 | 
			
		||||
char 		*xbasename(const char *);
 | 
			
		||||
 | 
			
		||||
/* xmalloc-debug.c */
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
#define xmalloc_caller() __builtin_return_address(0)
 | 
			
		||||
 | 
			
		||||
void		 xmalloc_clear(void);
 | 
			
		||||
void		 xmalloc_report(pid_t, const char *);
 | 
			
		||||
 | 
			
		||||
void		 xmalloc_new(void *, void *, size_t);
 | 
			
		||||
void		 xmalloc_change(void *, void *, void *, size_t);
 | 
			
		||||
void		 xmalloc_free(void *);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								window.c
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								window.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: window.c,v 1.1.1.1 2007-07-09 19:04:12 nicm Exp $ */
 | 
			
		||||
/* $Id: window.c,v 1.2 2007-07-25 23:13:18 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -78,23 +78,23 @@ window_create(const char *cmd, u_int sx, u_int sy)
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	case 0:
 | 
			
		||||
		if (setenv("TMUX", pid, 1) != 0)
 | 
			
		||||
			log_fatal("setenv");
 | 
			
		||||
			fatal("setenv failed");
 | 
			
		||||
		if (setenv("TERM", "screen", 1) != 0)
 | 
			
		||||
			log_fatal("setenv");
 | 
			
		||||
			fatal("setenv failed");
 | 
			
		||||
		log_close();
 | 
			
		||||
 | 
			
		||||
		execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL);
 | 
			
		||||
		log_fatal("execl");
 | 
			
		||||
		fatal("execl failed");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((mode = fcntl(fd, F_GETFL)) == -1)
 | 
			
		||||
		log_fatal("fcntl");
 | 
			
		||||
		fatal("fcntl failed");
 | 
			
		||||
	if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1)
 | 
			
		||||
		log_fatal("fcntl");
 | 
			
		||||
		fatal("fcntl failed");
 | 
			
		||||
 | 
			
		||||
	mode = 1;
 | 
			
		||||
	if (ioctl(fd, TIOCPKT, &mode) == -1)
 | 
			
		||||
		log_fatal("ioctl(TIOCPKT)");
 | 
			
		||||
		fatal("ioctl failed");
 | 
			
		||||
 | 
			
		||||
	w = xmalloc(sizeof *w);
 | 
			
		||||
	w->fd = fd;
 | 
			
		||||
@@ -156,7 +156,7 @@ window_remove(struct windows *ww, struct window *w)
 | 
			
		||||
	u_int	i;
 | 
			
		||||
 | 
			
		||||
	if (window_index(ww, w, &i) != 0)
 | 
			
		||||
		log_fatalx("window_remove: window not found");
 | 
			
		||||
		fatalx("window not found");
 | 
			
		||||
	ARRAY_REMOVE(ww, i);
 | 
			
		||||
 | 
			
		||||
	w->references--;
 | 
			
		||||
@@ -184,7 +184,7 @@ window_next(struct windows *ww, struct window *w)
 | 
			
		||||
	u_int	i;
 | 
			
		||||
 | 
			
		||||
	if (window_index(ww, w, &i) != 0)
 | 
			
		||||
		log_fatalx("window_next: window not found");
 | 
			
		||||
		fatalx("window not found");
 | 
			
		||||
 | 
			
		||||
	if (i == ARRAY_LENGTH(ww) - 1)
 | 
			
		||||
		return (NULL);
 | 
			
		||||
@@ -204,7 +204,7 @@ window_previous(struct windows *ww, struct window *w)
 | 
			
		||||
	u_int	i;
 | 
			
		||||
 | 
			
		||||
	if (window_index(ww, w, &i) != 0)
 | 
			
		||||
		log_fatalx("window_previous: window not found");
 | 
			
		||||
		fatalx("window not found");
 | 
			
		||||
	if (i == 0)
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	do {
 | 
			
		||||
@@ -241,7 +241,7 @@ window_resize(struct window *w, u_int sx, u_int sy)
 | 
			
		||||
	screen_resize(&w->screen, sx, sy);
 | 
			
		||||
 | 
			
		||||
	if (ioctl(w->fd, TIOCSWINSZ, &ws) == -1)
 | 
			
		||||
		log_fatal("ioctl(TIOCSWINSZ)");
 | 
			
		||||
		fatal("ioctl failed");
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -293,7 +293,7 @@ window_input(struct window *w, struct buffer *b, size_t size)
 | 
			
		||||
		key = input_extract8(b);
 | 
			
		||||
		if (key == '\e') {
 | 
			
		||||
			if (size < 2)
 | 
			
		||||
				log_fatalx("window_input: underflow");
 | 
			
		||||
				fatalx("underflow");
 | 
			
		||||
			size -= 2;
 | 
			
		||||
			key = (int16_t) input_extract16(b);
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										238
									
								
								xmalloc-debug.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										238
									
								
								xmalloc-debug.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,238 @@
 | 
			
		||||
/* $Id: xmalloc-debug.c,v 1.1 2007-07-25 23:13:18 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
 *
 | 
			
		||||
 * 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 MIND, 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
/* Single xmalloc allocated block. */
 | 
			
		||||
struct xmalloc_blk {
 | 
			
		||||
	void	*caller;
 | 
			
		||||
 | 
			
		||||
	void	*ptr;
 | 
			
		||||
	size_t	 size;
 | 
			
		||||
 | 
			
		||||
	SPLAY_ENTRY(xmalloc_blk) entry;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Splay tree of allocated blocks. */
 | 
			
		||||
SPLAY_HEAD(xmalloc_tree, xmalloc_blk);
 | 
			
		||||
struct xmalloc_tree xmalloc_tree = SPLAY_INITIALIZER(&xmalloc_tree);
 | 
			
		||||
 | 
			
		||||
/* Various statistics. */
 | 
			
		||||
size_t	xmalloc_allocated;
 | 
			
		||||
size_t	xmalloc_freed;
 | 
			
		||||
size_t	xmalloc_peak;
 | 
			
		||||
u_int	xmalloc_frees;
 | 
			
		||||
u_int	xmalloc_mallocs;
 | 
			
		||||
u_int	xmalloc_reallocs;
 | 
			
		||||
 | 
			
		||||
/* Print function. */
 | 
			
		||||
#define XMALLOC_PRINT log_debug3
 | 
			
		||||
 | 
			
		||||
/* Bytes of unallocated blocks and number of allocated blocks to show. */
 | 
			
		||||
#define XMALLOC_BYTES 8
 | 
			
		||||
#define XMALLOC_LINES 32
 | 
			
		||||
 | 
			
		||||
/* Macro to update peek usage variable. */
 | 
			
		||||
#define XMALLOC_UPDATE() do {						\
 | 
			
		||||
	if (xmalloc_allocated - xmalloc_freed > xmalloc_peak)		\
 | 
			
		||||
		xmalloc_peak = xmalloc_allocated - xmalloc_freed;	\
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
/* Tree functions. */
 | 
			
		||||
int xmalloc_cmp(struct xmalloc_blk *, struct xmalloc_blk *);
 | 
			
		||||
SPLAY_PROTOTYPE(xmalloc_tree, xmalloc_blk, entry, xmalloc_cmp);
 | 
			
		||||
SPLAY_GENERATE(xmalloc_tree, xmalloc_blk, entry, xmalloc_cmp);
 | 
			
		||||
 | 
			
		||||
/* Compare two blocks. */
 | 
			
		||||
int
 | 
			
		||||
xmalloc_cmp(struct xmalloc_blk *blk1, struct xmalloc_blk *blk2)
 | 
			
		||||
{
 | 
			
		||||
	uintptr_t	ptr1 = (uintptr_t) blk1->ptr;
 | 
			
		||||
	uintptr_t	ptr2 = (uintptr_t) blk2->ptr;
 | 
			
		||||
 | 
			
		||||
	if (ptr1 < ptr2)
 | 
			
		||||
		return (-1);
 | 
			
		||||
	if (ptr1 > ptr2)
 | 
			
		||||
		return (1);
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Clear statistics and block list; used to start fresh after fork(2). */
 | 
			
		||||
void
 | 
			
		||||
xmalloc_clear(void)
 | 
			
		||||
{
 | 
			
		||||
 	struct xmalloc_blk	*blk;
 | 
			
		||||
 | 
			
		||||
	xmalloc_allocated = 0;
 | 
			
		||||
	xmalloc_freed = 0;
 | 
			
		||||
	xmalloc_peak = 0;
 | 
			
		||||
	xmalloc_frees = 0;
 | 
			
		||||
	xmalloc_mallocs = 0;
 | 
			
		||||
	xmalloc_reallocs = 0;
 | 
			
		||||
 | 
			
		||||
	while (!SPLAY_EMPTY(&xmalloc_tree)) {
 | 
			
		||||
		blk = SPLAY_ROOT(&xmalloc_tree);
 | 
			
		||||
		SPLAY_REMOVE(xmalloc_tree, &xmalloc_tree, blk);
 | 
			
		||||
		free(blk);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Print report of statistics and unfreed blocks. */
 | 
			
		||||
void
 | 
			
		||||
xmalloc_report(pid_t pid, const char *hdr)
 | 
			
		||||
{
 | 
			
		||||
 	struct xmalloc_blk	*blk;
 | 
			
		||||
	u_char			*iptr;
 | 
			
		||||
 	char	 		 buf[4 * XMALLOC_BYTES + 1], *optr;
 | 
			
		||||
 	size_t		 	 len;
 | 
			
		||||
  	u_int	 		 n;
 | 
			
		||||
	Dl_info			 info;
 | 
			
		||||
 | 
			
		||||
 	XMALLOC_PRINT("%s: %ld: allocated=%zu, freed=%zu, difference=%zd, "
 | 
			
		||||
	    "peak=%zu", hdr, (long) pid, xmalloc_allocated, xmalloc_freed,
 | 
			
		||||
	    xmalloc_allocated - xmalloc_freed, xmalloc_peak);
 | 
			
		||||
 	XMALLOC_PRINT("%s: %ld: mallocs=%u, reallocs=%u, frees=%u", hdr,
 | 
			
		||||
	    (long) pid, xmalloc_mallocs, xmalloc_reallocs, xmalloc_frees);
 | 
			
		||||
 | 
			
		||||
	n = 0;
 | 
			
		||||
	SPLAY_FOREACH(blk, xmalloc_tree, &xmalloc_tree) {
 | 
			
		||||
		n++;
 | 
			
		||||
		if (n >= XMALLOC_LINES)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		len = blk->size;
 | 
			
		||||
		if (len > XMALLOC_BYTES)
 | 
			
		||||
			len = XMALLOC_BYTES;
 | 
			
		||||
 | 
			
		||||
		memset(&info, 0, sizeof info);
 | 
			
		||||
		if (dladdr(blk->caller, &info) == 0)
 | 
			
		||||
			info.dli_sname = info.dli_saddr = NULL;
 | 
			
		||||
 | 
			
		||||
		optr = buf;
 | 
			
		||||
		iptr = blk->ptr;
 | 
			
		||||
		for (; len > 0; len--) {
 | 
			
		||||
			if (isascii(*iptr) && !iscntrl(*iptr)) {
 | 
			
		||||
				*optr++ = *iptr++;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			*optr++ = '\\';
 | 
			
		||||
			*optr++ = '0' + ((*iptr >> 6) & 07);
 | 
			
		||||
			*optr++ = '0' + ((*iptr >> 3) & 07);
 | 
			
		||||
			*optr++ = '0' + (*iptr & 07);
 | 
			
		||||
			iptr++;
 | 
			
		||||
		}
 | 
			
		||||
		*optr = '\0';
 | 
			
		||||
 | 
			
		||||
		XMALLOC_PRINT("%s: %ld: %u, %s+0x%02tx: [%p %zu: %s]", hdr,
 | 
			
		||||
		    (long) pid, n, info.dli_sname, ((u_char *) blk->caller) -
 | 
			
		||||
		    ((u_char *) info.dli_saddr), blk->ptr, blk->size, buf);
 | 
			
		||||
	}
 | 
			
		||||
	XMALLOC_PRINT("%s: %ld: %u unfreed blocks", hdr, (long) pid, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Record a newly created block. */
 | 
			
		||||
void
 | 
			
		||||
xmalloc_new(void *caller, void *ptr, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	struct xmalloc_blk	*blk;
 | 
			
		||||
 | 
			
		||||
	xmalloc_allocated += size;
 | 
			
		||||
	XMALLOC_UPDATE();
 | 
			
		||||
 | 
			
		||||
	if ((blk = malloc(sizeof *blk)) == NULL)
 | 
			
		||||
		abort();
 | 
			
		||||
 | 
			
		||||
	blk->ptr = ptr;
 | 
			
		||||
	blk->size = size;
 | 
			
		||||
 | 
			
		||||
	blk->caller = caller;
 | 
			
		||||
 | 
			
		||||
	SPLAY_INSERT(xmalloc_tree, &xmalloc_tree, blk);
 | 
			
		||||
 | 
			
		||||
	xmalloc_mallocs++;
 | 
			
		||||
	XMALLOC_UPDATE();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Record changes to a block. */
 | 
			
		||||
void
 | 
			
		||||
xmalloc_change(void *caller, void *oldptr, void *newptr, size_t newsize)
 | 
			
		||||
{
 | 
			
		||||
	struct xmalloc_blk	*blk, key;
 | 
			
		||||
	ssize_t			 change;
 | 
			
		||||
 | 
			
		||||
	if (oldptr == NULL) {
 | 
			
		||||
		xmalloc_new(caller, newptr, newsize);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	key.ptr = oldptr;
 | 
			
		||||
	blk = SPLAY_FIND(xmalloc_tree, &xmalloc_tree, &key);
 | 
			
		||||
	if (blk == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	change = newsize - blk->size;
 | 
			
		||||
	if (change > 0)
 | 
			
		||||
		xmalloc_allocated += change;
 | 
			
		||||
	else
 | 
			
		||||
		xmalloc_freed -= change;
 | 
			
		||||
	XMALLOC_UPDATE();
 | 
			
		||||
 | 
			
		||||
	SPLAY_REMOVE(xmalloc_tree, &xmalloc_tree, blk);
 | 
			
		||||
 | 
			
		||||
 	blk->ptr = newptr;
 | 
			
		||||
	blk->size = newsize;
 | 
			
		||||
 | 
			
		||||
	blk->caller = caller;
 | 
			
		||||
 | 
			
		||||
	SPLAY_INSERT(xmalloc_tree, &xmalloc_tree, blk);
 | 
			
		||||
 | 
			
		||||
	xmalloc_reallocs++;
 | 
			
		||||
	XMALLOC_UPDATE();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Record a block free. */
 | 
			
		||||
void
 | 
			
		||||
xmalloc_free(void *ptr)
 | 
			
		||||
{
 | 
			
		||||
	struct xmalloc_blk	*blk, key;
 | 
			
		||||
 | 
			
		||||
	key.ptr = ptr;
 | 
			
		||||
	blk = SPLAY_FIND(xmalloc_tree, &xmalloc_tree, &key);
 | 
			
		||||
	if (blk == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	xmalloc_freed += blk->size;
 | 
			
		||||
 | 
			
		||||
	SPLAY_REMOVE(xmalloc_tree, &xmalloc_tree, blk);
 | 
			
		||||
	free(blk);
 | 
			
		||||
 | 
			
		||||
	xmalloc_frees++;
 | 
			
		||||
	XMALLOC_UPDATE();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* DEBUG */
 | 
			
		||||
							
								
								
									
										94
									
								
								xmalloc.c
									
									
									
									
									
								
							
							
						
						
									
										94
									
								
								xmalloc.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: xmalloc.c,v 1.1.1.1 2007-07-09 19:03:33 nicm Exp $ */
 | 
			
		||||
/* $Id: xmalloc.c,v 1.2 2007-07-25 23:13:18 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2004 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -16,14 +16,10 @@
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/param.h>
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <libgen.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
@@ -33,10 +29,10 @@ void *
 | 
			
		||||
ensure_for(void *buf, size_t *len, size_t size, size_t adj)
 | 
			
		||||
{
 | 
			
		||||
	if (adj == 0)
 | 
			
		||||
		log_fatalx("ensure_for: zero adj");
 | 
			
		||||
		fatalx("zero adj");
 | 
			
		||||
 | 
			
		||||
	if (SIZE_MAX - size < adj)
 | 
			
		||||
		log_fatalx("ensure_for: size + adj > SIZE_MAX");
 | 
			
		||||
		fatalx("size + adj > SIZE_MAX");
 | 
			
		||||
	size += adj;
 | 
			
		||||
 | 
			
		||||
	if (*len == 0) {
 | 
			
		||||
@@ -56,9 +52,9 @@ void *
 | 
			
		||||
ensure_size(void *buf, size_t *len, size_t nmemb, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	if (nmemb == 0 || size == 0)
 | 
			
		||||
		log_fatalx("ensure_size: zero size");
 | 
			
		||||
		fatalx("zero size");
 | 
			
		||||
	if (SIZE_MAX / nmemb < size)
 | 
			
		||||
		log_fatalx("ensure_size: nmemb * size > SIZE_MAX");
 | 
			
		||||
		fatalx("nmemb * size > SIZE_MAX");
 | 
			
		||||
 | 
			
		||||
	if (*len == 0) {
 | 
			
		||||
		*len = BUFSIZ;
 | 
			
		||||
@@ -91,12 +87,15 @@ xcalloc(size_t nmemb, size_t size)
 | 
			
		||||
        void	*ptr;
 | 
			
		||||
 | 
			
		||||
        if (size == 0 || nmemb == 0)
 | 
			
		||||
                log_fatalx("xcalloc: zero size");
 | 
			
		||||
                fatalx("zero size");
 | 
			
		||||
        if (SIZE_MAX / nmemb < size)
 | 
			
		||||
                log_fatalx("xcalloc: nmemb * size > SIZE_MAX");
 | 
			
		||||
                fatalx("nmemb * size > SIZE_MAX");
 | 
			
		||||
        if ((ptr = calloc(nmemb, size)) == NULL)
 | 
			
		||||
		log_fatal("xcalloc");
 | 
			
		||||
		fatal("xcalloc failed");
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	xmalloc_new(xmalloc_caller(), ptr, nmemb * size);
 | 
			
		||||
#endif
 | 
			
		||||
        return (ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -106,10 +105,13 @@ xmalloc(size_t size)
 | 
			
		||||
	void	*ptr;
 | 
			
		||||
 | 
			
		||||
        if (size == 0)
 | 
			
		||||
		log_fatalx("xmalloc: zero size");
 | 
			
		||||
                fatalx("zero size");
 | 
			
		||||
        if ((ptr = malloc(size)) == NULL)
 | 
			
		||||
		log_fatal("xmalloc");
 | 
			
		||||
		fatal("xmalloc failed");
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	xmalloc_new(xmalloc_caller(), ptr, size);
 | 
			
		||||
#endif
 | 
			
		||||
        return (ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -120,12 +122,15 @@ xrealloc(void *oldptr, size_t nmemb, size_t size)
 | 
			
		||||
	void	*newptr;
 | 
			
		||||
 | 
			
		||||
	if (newsize == 0)
 | 
			
		||||
                log_fatalx("xrealloc: zero size");
 | 
			
		||||
                fatalx("zero size");
 | 
			
		||||
        if (SIZE_MAX / nmemb < size)
 | 
			
		||||
                log_fatal("xrealloc: nmemb * size > SIZE_MAX");
 | 
			
		||||
                fatalx("nmemb * size > SIZE_MAX");
 | 
			
		||||
        if ((newptr = realloc(oldptr, newsize)) == NULL)
 | 
			
		||||
		log_fatal("xrealloc");
 | 
			
		||||
		fatal("xrealloc failed");
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	xmalloc_change(xmalloc_caller(), oldptr, newptr, nmemb * size);
 | 
			
		||||
#endif
 | 
			
		||||
        return (newptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -133,8 +138,12 @@ void
 | 
			
		||||
xfree(void *ptr)
 | 
			
		||||
{
 | 
			
		||||
	if (ptr == NULL)
 | 
			
		||||
		log_fatalx("xfree: null pointer");
 | 
			
		||||
		fatalx("null pointer");
 | 
			
		||||
	free(ptr);
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	xmalloc_free(ptr);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int printflike2
 | 
			
		||||
@@ -156,10 +165,12 @@ xvasprintf(char **ret, const char *fmt, va_list ap)
 | 
			
		||||
	int	i;
 | 
			
		||||
 | 
			
		||||
	i = vasprintf(ret, fmt, ap);
 | 
			
		||||
 | 
			
		||||
        if (i < 0 || *ret == NULL)
 | 
			
		||||
                log_fatal("xvasprintf");
 | 
			
		||||
                fatal("xvasprintf failed");
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	xmalloc_new(xmalloc_caller(), *ret, i + 1);
 | 
			
		||||
#endif
 | 
			
		||||
        return (i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -181,53 +192,24 @@ xvsnprintf(char *buf, size_t len, const char *fmt, va_list ap)
 | 
			
		||||
{
 | 
			
		||||
	int	i;
 | 
			
		||||
 | 
			
		||||
	if (len > INT_MAX) {
 | 
			
		||||
		errno = EINVAL;
 | 
			
		||||
		log_fatal("xvsnprintf");
 | 
			
		||||
	}
 | 
			
		||||
	if (len > INT_MAX)
 | 
			
		||||
		fatalx("len > INT_MAX");
 | 
			
		||||
 | 
			
		||||
	i = vsnprintf(buf, len, fmt, ap);
 | 
			
		||||
 | 
			
		||||
        if (i < 0)
 | 
			
		||||
                log_fatal("xvsnprintf");
 | 
			
		||||
                fatal("vsnprintf failed");
 | 
			
		||||
 | 
			
		||||
        return (i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Print a path. Same as xsnprintf, but return ENAMETOOLONG on truncation.
 | 
			
		||||
 */
 | 
			
		||||
int printflike3
 | 
			
		||||
printpath(char *buf, size_t len, const char *fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list	ap;
 | 
			
		||||
	int	n;
 | 
			
		||||
 | 
			
		||||
	if (len > INT_MAX) {
 | 
			
		||||
		errno = ENAMETOOLONG;
 | 
			
		||||
		return (1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	va_start(ap, fmt);
 | 
			
		||||
	n = xvsnprintf(buf, len, fmt, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
 | 
			
		||||
	if ((size_t) n > len) {
 | 
			
		||||
		errno = ENAMETOOLONG;
 | 
			
		||||
		return (1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Some system modify the path in place. This function and xbasename below
 | 
			
		||||
 * Some systems modify the path in place. This function and xbasename below
 | 
			
		||||
 * avoid that by using a temporary buffer.
 | 
			
		||||
 */
 | 
			
		||||
char *
 | 
			
		||||
xdirname(const char *src)
 | 
			
		||||
{
 | 
			
		||||
	char	dst[MAXPATHLEN];
 | 
			
		||||
	static char	dst[MAXPATHLEN];
 | 
			
		||||
 | 
			
		||||
	strlcpy(dst, src, sizeof dst);
 | 
			
		||||
	return (dirname(dst));
 | 
			
		||||
@@ -236,7 +218,7 @@ xdirname(const char *src)
 | 
			
		||||
char *
 | 
			
		||||
xbasename(const char *src)
 | 
			
		||||
{
 | 
			
		||||
	char	dst[MAXPATHLEN];
 | 
			
		||||
	static char	dst[MAXPATHLEN];
 | 
			
		||||
 | 
			
		||||
	strlcpy(dst, src, sizeof dst);
 | 
			
		||||
	return (basename(dst));
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user