/*1* SPDX-License-Identifier: ISC2*3* Copyright (c) 2019-2020 Todd C. Miller <[email protected]>4*5* Permission to use, copy, modify, and distribute this software for any6* purpose with or without fee is hereby granted, provided that the above7* copyright notice and this permission notice appear in all copies.8*9* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES10* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF11* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR12* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES13* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN14* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF15* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.16*/1718#include <config.h>1920#ifndef HAVE_GETDELIM2122#include <stdio.h>23#include <stdlib.h>24#include <string.h>25#include <limits.h>2627#include <sudo_compat.h>2829ssize_t30sudo_getdelim(char ** restrict buf, size_t * restrict bufsize, int delim,31FILE * restrict fp)32{33char *cp, *ep;34int ch;3536if (*buf == NULL || *bufsize == 0) {37char *tmp = realloc(*buf, LINE_MAX);38if (tmp == NULL)39return -1;40*buf = tmp;41*bufsize = LINE_MAX;42}43cp = *buf;44ep = cp + *bufsize;4546do {47if (cp + 1 >= ep) {48char *newbuf = reallocarray(*buf, *bufsize, 2);49if (newbuf == NULL)50goto bad;51*bufsize *= 2;52cp = newbuf + (cp - *buf);53ep = newbuf + *bufsize;54*buf = newbuf;55}56if ((ch = getc(fp)) == EOF) {57if (feof(fp))58break;59goto bad;60}61*cp++ = ch;62} while (ch != delim);6364/* getdelim(3) should never return a length of 0. */65if (cp != *buf) {66*cp = '\0';67return (ssize_t)(cp - *buf);68}69bad:70/* Error, push back what was read if possible. */71while (cp > *buf) {72if (ungetc(*cp--, fp) == EOF)73break;74}75return -1;76}77#endif /* HAVE_GETDELIM */787980