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