1*23a1cceaSRoger A. Faulkner /* 2*23a1cceaSRoger A. Faulkner * CDDL HEADER START 3*23a1cceaSRoger A. Faulkner * 4*23a1cceaSRoger A. Faulkner * The contents of this file are subject to the terms of the 5*23a1cceaSRoger A. Faulkner * Common Development and Distribution License (the "License"). 6*23a1cceaSRoger A. Faulkner * You may not use this file except in compliance with the License. 7*23a1cceaSRoger A. Faulkner * 8*23a1cceaSRoger A. Faulkner * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*23a1cceaSRoger A. Faulkner * or http://www.opensolaris.org/os/licensing. 10*23a1cceaSRoger A. Faulkner * See the License for the specific language governing permissions 11*23a1cceaSRoger A. Faulkner * and limitations under the License. 12*23a1cceaSRoger A. Faulkner * 13*23a1cceaSRoger A. Faulkner * When distributing Covered Code, include this CDDL HEADER in each 14*23a1cceaSRoger A. Faulkner * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*23a1cceaSRoger A. Faulkner * If applicable, add the following below this CDDL HEADER, with the 16*23a1cceaSRoger A. Faulkner * fields enclosed by brackets "[]" replaced with your own identifying 17*23a1cceaSRoger A. Faulkner * information: Portions Copyright [yyyy] [name of copyright owner] 18*23a1cceaSRoger A. Faulkner * 19*23a1cceaSRoger A. Faulkner * CDDL HEADER END 20*23a1cceaSRoger A. Faulkner */ 21*23a1cceaSRoger A. Faulkner 22*23a1cceaSRoger A. Faulkner /* 23*23a1cceaSRoger A. Faulkner * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 24*23a1cceaSRoger A. Faulkner */ 25*23a1cceaSRoger A. Faulkner 26*23a1cceaSRoger A. Faulkner #include "lint.h" 27*23a1cceaSRoger A. Faulkner #include "file64.h" 28*23a1cceaSRoger A. Faulkner #include "mtlib.h" 29*23a1cceaSRoger A. Faulkner #include <stdio.h> 30*23a1cceaSRoger A. Faulkner #include <errno.h> 31*23a1cceaSRoger A. Faulkner #include <thread.h> 32*23a1cceaSRoger A. Faulkner #include <synch.h> 33*23a1cceaSRoger A. Faulkner #include <unistd.h> 34*23a1cceaSRoger A. Faulkner #include <limits.h> 35*23a1cceaSRoger A. Faulkner #include <malloc.h> 36*23a1cceaSRoger A. Faulkner #include <sys/types.h> 37*23a1cceaSRoger A. Faulkner #include "stdiom.h" 38*23a1cceaSRoger A. Faulkner 39*23a1cceaSRoger A. Faulkner #define LINESZ 128 /* initial guess for a NULL *lineptr */ 40*23a1cceaSRoger A. Faulkner 41*23a1cceaSRoger A. Faulkner ssize_t 42*23a1cceaSRoger A. Faulkner getdelim(char **_RESTRICT_KYWD lineptr, size_t *_RESTRICT_KYWD n, 43*23a1cceaSRoger A. Faulkner int delimiter, FILE *_RESTRICT_KYWD iop) 44*23a1cceaSRoger A. Faulkner { 45*23a1cceaSRoger A. Faulkner rmutex_t *lk; 46*23a1cceaSRoger A. Faulkner char *ptr; 47*23a1cceaSRoger A. Faulkner size_t size; 48*23a1cceaSRoger A. Faulkner int c; 49*23a1cceaSRoger A. Faulkner size_t cnt; 50*23a1cceaSRoger A. Faulkner 51*23a1cceaSRoger A. Faulkner if (lineptr == NULL || n == NULL || 52*23a1cceaSRoger A. Faulkner delimiter < 0 || delimiter > UCHAR_MAX) { 53*23a1cceaSRoger A. Faulkner errno = EINVAL; 54*23a1cceaSRoger A. Faulkner return (-1); 55*23a1cceaSRoger A. Faulkner } 56*23a1cceaSRoger A. Faulkner 57*23a1cceaSRoger A. Faulkner if (*lineptr == NULL || *n < LINESZ) { /* initial allocation */ 58*23a1cceaSRoger A. Faulkner if ((*lineptr = realloc(*lineptr, LINESZ)) == NULL) { 59*23a1cceaSRoger A. Faulkner errno = ENOMEM; 60*23a1cceaSRoger A. Faulkner return (-1); 61*23a1cceaSRoger A. Faulkner } 62*23a1cceaSRoger A. Faulkner *n = LINESZ; 63*23a1cceaSRoger A. Faulkner } 64*23a1cceaSRoger A. Faulkner ptr = *lineptr; 65*23a1cceaSRoger A. Faulkner size = *n; 66*23a1cceaSRoger A. Faulkner cnt = 0; 67*23a1cceaSRoger A. Faulkner 68*23a1cceaSRoger A. Faulkner FLOCKFILE(lk, iop); 69*23a1cceaSRoger A. Faulkner 70*23a1cceaSRoger A. Faulkner _SET_ORIENTATION_BYTE(iop); 71*23a1cceaSRoger A. Faulkner 72*23a1cceaSRoger A. Faulkner do { 73*23a1cceaSRoger A. Faulkner c = (--iop->_cnt < 0) ? __filbuf(iop) : *iop->_ptr++; 74*23a1cceaSRoger A. Faulkner if (c == EOF) 75*23a1cceaSRoger A. Faulkner break; 76*23a1cceaSRoger A. Faulkner *ptr++ = c; 77*23a1cceaSRoger A. Faulkner if (++cnt == size) { /* must reallocate */ 78*23a1cceaSRoger A. Faulkner if ((ptr = realloc(*lineptr, 2 * size)) == NULL) { 79*23a1cceaSRoger A. Faulkner FUNLOCKFILE(lk); 80*23a1cceaSRoger A. Faulkner ptr = *lineptr + size - 1; 81*23a1cceaSRoger A. Faulkner *ptr = '\0'; 82*23a1cceaSRoger A. Faulkner errno = ENOMEM; 83*23a1cceaSRoger A. Faulkner return (-1); 84*23a1cceaSRoger A. Faulkner } 85*23a1cceaSRoger A. Faulkner *lineptr = ptr; 86*23a1cceaSRoger A. Faulkner ptr += size; 87*23a1cceaSRoger A. Faulkner *n = size = 2 * size; 88*23a1cceaSRoger A. Faulkner } 89*23a1cceaSRoger A. Faulkner } while (c != delimiter); 90*23a1cceaSRoger A. Faulkner 91*23a1cceaSRoger A. Faulkner *ptr = '\0'; 92*23a1cceaSRoger A. Faulkner 93*23a1cceaSRoger A. Faulkner FUNLOCKFILE(lk); 94*23a1cceaSRoger A. Faulkner if (cnt > SSIZE_MAX) { 95*23a1cceaSRoger A. Faulkner errno = EOVERFLOW; 96*23a1cceaSRoger A. Faulkner return (-1); 97*23a1cceaSRoger A. Faulkner } 98*23a1cceaSRoger A. Faulkner return (cnt ? cnt : -1); 99*23a1cceaSRoger A. Faulkner } 100*23a1cceaSRoger A. Faulkner 101*23a1cceaSRoger A. Faulkner ssize_t 102*23a1cceaSRoger A. Faulkner getline(char **_RESTRICT_KYWD lineptr, size_t *_RESTRICT_KYWD n, 103*23a1cceaSRoger A. Faulkner FILE *_RESTRICT_KYWD iop) 104*23a1cceaSRoger A. Faulkner { 105*23a1cceaSRoger A. Faulkner return (getdelim(lineptr, n, '\n', iop)); 106*23a1cceaSRoger A. Faulkner } 107