mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +00:00 
			
		
		
		
	Fixed fgetln(3) implementation (from Joerg Jung) which does not depend on *BSD
fgets(3) semantics.
This commit is contained in:
		
							
								
								
									
										102
									
								
								compat/fgetln.c
									
									
									
									
									
								
							
							
						
						
									
										102
									
								
								compat/fgetln.c
									
									
									
									
									
								
							@@ -1,43 +1,26 @@
 | 
			
		||||
/*	$NetBSD: fgetln.c,v 1.3 2007/08/07 02:06:58 lukem Exp $	*/
 | 
			
		||||
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1998 The NetBSD Foundation, Inc.
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2015 Joerg Jung <jung@openbsd.org>
 | 
			
		||||
 *
 | 
			
		||||
 * This code is derived from software contributed to The NetBSD Foundation
 | 
			
		||||
 * by Christos Zoulas.
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 NetBSD Foundation 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 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.
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
/*
 | 
			
		||||
 * portable fgetln() version, NOT reentrant
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
@@ -45,41 +28,34 @@ char *
 | 
			
		||||
fgetln(FILE *fp, size_t *len)
 | 
			
		||||
{
 | 
			
		||||
	static char *buf = NULL;
 | 
			
		||||
	static size_t bufsiz = 0;
 | 
			
		||||
	char *ptr;
 | 
			
		||||
	static size_t bufsz = 0;
 | 
			
		||||
	size_t r = 0;
 | 
			
		||||
	char *p;
 | 
			
		||||
	int c, e;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if (buf == NULL) {
 | 
			
		||||
		bufsiz = BUFSIZ;
 | 
			
		||||
		if ((buf = malloc(bufsiz)) == NULL)
 | 
			
		||||
	if (!fp || !len) {
 | 
			
		||||
		errno = EINVAL;
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (fgets(buf, bufsiz, fp) == NULL)
 | 
			
		||||
	if (!buf) {
 | 
			
		||||
		if (!(buf = calloc(1, BUFSIZ)))
 | 
			
		||||
			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;
 | 
			
		||||
		bufsz = BUFSIZ;
 | 
			
		||||
	}
 | 
			
		||||
	while ((c = getc(fp)) != EOF) {
 | 
			
		||||
		buf[r++] = c;
 | 
			
		||||
		if (r == bufsz) {
 | 
			
		||||
			if (!(p = reallocarray(buf, 2, bufsz))) {
 | 
			
		||||
				e = errno;
 | 
			
		||||
				free(buf);
 | 
			
		||||
			errno = oerrno;
 | 
			
		||||
			buf = NULL;
 | 
			
		||||
				errno = e;
 | 
			
		||||
				buf = NULL, bufsz = 0;
 | 
			
		||||
				return NULL;
 | 
			
		||||
		} else
 | 
			
		||||
			buf = nbuf;
 | 
			
		||||
 | 
			
		||||
		*len = bufsiz;
 | 
			
		||||
		if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL)
 | 
			
		||||
			return buf;
 | 
			
		||||
 | 
			
		||||
		bufsiz = nbufsiz;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
	*len = (ptr - buf) + 1;
 | 
			
		||||
	return buf;
 | 
			
		||||
			buf = p, bufsz = 2 * bufsz;
 | 
			
		||||
		}
 | 
			
		||||
		if (c == '\n')
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	return (*len = r) ? buf : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user