diff options
Diffstat (limited to 'usr/src/lib/libnsl/common/nsl_stdio_prv.c')
-rw-r--r-- | usr/src/lib/libnsl/common/nsl_stdio_prv.c | 469 |
1 files changed, 0 insertions, 469 deletions
diff --git a/usr/src/lib/libnsl/common/nsl_stdio_prv.c b/usr/src/lib/libnsl/common/nsl_stdio_prv.c deleted file mode 100644 index efa8388262..0000000000 --- a/usr/src/lib/libnsl/common/nsl_stdio_prv.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "mt.h" -#include <stdlib.h> -#include <fcntl.h> -#include <errno.h> -#include <unistd.h> -#include <stddef.h> -#include <stdio.h> -#include <string.h> -#include <limits.h> - -#include "nsl_stdio_prv.h" - -/* - * This is a limited implementation to allow libraries to use - * stdio and avoid the limitation of 256 open file descriptors. - * The newly implemented stdio functions are closely based on - * the implementation in C library. - * To simplify, certain assumptions are made: - * - a file may be opened for either readonly or write only - * - file descriptors should not be shared between threads - * - only seek to beginning of file - * - ungetc may only work for the last char. ie., ungetc will work - * once (but not necessarily more) after a read - */ - -static int -_raise_fd(int fd) -{ - int nfd; - static const int min_fd = 256; - - if (fd >= min_fd) - return (fd); - - if ((nfd = fcntl(fd, F_DUPFD, min_fd)) == -1) { - /* - * If the shell limits [See limit(1)] the - * descriptors to 256, fcntl will fail - * and errno will be set to EINVAL. Since - * the intention is to ignore fcntl failures - * and continue working with 'fd', we should - * reset errno to _prevent_ apps relying on errno - * to treat this as an error. - */ - errno = 0; - return (fd); - } - - (void) close(fd); - - return (nfd); -} - -__NSL_FILE * -__nsl_fopen(const char *filename, const char *mode) -{ - int flag; - int oflag; - int fd; - __NSL_FILE *stream; - - if (mode == NULL || filename == NULL) { - errno = EINVAL; - return (NULL); - } - switch (mode[0]) { - default: - errno = EINVAL; - return (NULL); - case 'r': - flag = 0; - oflag = O_RDONLY; - break; - case 'w': - flag = __NSL_FILE_WRITE_ONLY; - oflag = O_WRONLY | O_TRUNC | O_CREAT; - break; - } - if (mode[1] != '\0') { - errno = EINVAL; - return (NULL); - } - - fd = open(filename, oflag | O_LARGEFILE, 0666); - if (fd < 0) - return (NULL); - - stream = (__NSL_FILE *)malloc(sizeof (__NSL_FILE)); - if (stream != NULL) { - stream->_nsl_file = _raise_fd(fd); - stream->_nsl_cnt = flag & __NSL_FILE_WRITE_ONLY ? - sizeof (stream->_nsl_base) : 0; - stream->_nsl_ptr = stream->_nsl_base; - stream->_nsl_flag = flag; - } else { - (void) close(fd); - } - - return (stream); -} - -int -__nsl_fclose(__NSL_FILE *stream) -{ - int res = 0; - - if (stream == NULL) - return (EOF); - - res = __nsl_fflush(stream); - - if (close(stream->_nsl_file) < 0) - res = EOF; - - free(stream); - - return (res); -} - -/* fill buffer, return 0 or EOF */ -static int -_filbuf(__NSL_FILE *stream) -{ - int res; - - stream->_nsl_ptr = stream->_nsl_base; - - if ((res = read(stream->_nsl_file, (char *)stream->_nsl_base, - __NSL_FILE_BUF_SIZE)) > 0) { - stream->_nsl_cnt = res; - return (0); - } else { - stream->_nsl_cnt = 0; - if (res == 0) - stream->_nsl_flag |= __NSL_FILE_EOF; - else - stream->_nsl_flag |= __NSL_FILE_ERR; - return (EOF); - } -} - -char * -__nsl_fgets(char *buf, int size, __NSL_FILE *stream) -{ - char *ptr = buf; - char *p; - int n; - - if (stream->_nsl_flag & __NSL_FILE_WRITE_ONLY) { - errno = EBADF; - return (NULL); - } - - size--; /* room for '\0' */ - while (size > 0) { - if (stream->_nsl_cnt == 0) { - if (_filbuf(stream) == EOF) - break; /* nothing left to read */ - } - n = (int)(size < stream->_nsl_cnt ? size : stream->_nsl_cnt); - if ((p = memccpy(ptr, (char *)stream->_nsl_ptr, '\n', - (size_t)n)) != NULL) - n = (int)(p - ptr); - ptr += n; - stream->_nsl_cnt -= n; - stream->_nsl_ptr += n; - if (p != NULL) - break; /* newline found */ - size -= n; - } - - if (ptr == buf) /* never read anything */ - return (NULL); - - *ptr = '\0'; - return (buf); -} - -int -__nsl_feof(__NSL_FILE *stream) -{ - return (stream->_nsl_flag & __NSL_FILE_EOF); -} - -int -__nsl_fseek(__NSL_FILE *stream, long offset, int whence) -{ - off_t p; - - stream->_nsl_flag &= ~(__NSL_FILE_EOF | __NSL_FILE_ERR); - - if (stream->_nsl_flag & __NSL_FILE_WRITE_ONLY) { - if (whence == SEEK_CUR) - offset -= sizeof (stream->_nsl_base) - stream->_nsl_cnt; - if (__nsl_fflush(stream) == EOF) - return (-1); - } else { - if (whence == SEEK_CUR) - offset -= stream->_nsl_cnt; - - stream->_nsl_cnt = 0; - stream->_nsl_ptr = stream->_nsl_base; - } - - p = lseek(stream->_nsl_file, (off_t)offset, whence); - return ((p == (off_t)-1) ? -1 : 0); -} - -void -__nsl_frewind(__NSL_FILE *stream) -{ - (void) __nsl_fseek(stream, 0, SEEK_SET); -} - -long -__nsl_ftell(__NSL_FILE *stream) -{ - ptrdiff_t adjust; - off64_t tres; - - if (stream->_nsl_flag & __NSL_FILE_WRITE_ONLY) - adjust = (ptrdiff_t) - (sizeof (stream->_nsl_base) - stream->_nsl_cnt); - else - adjust = (ptrdiff_t)(-stream->_nsl_cnt); - - tres = lseek64(stream->_nsl_file, 0, SEEK_CUR); - if (tres >= 0) - tres += adjust; - - if (tres > LONG_MAX) { - errno = EOVERFLOW; - return (EOF); - } - - return ((long)tres); -} - -size_t -__nsl_fread(void *ptr, size_t size, size_t nitems, __NSL_FILE *stream) -{ - ssize_t s; - char *dptr = (char *)ptr; - - /* is it a readable stream */ - if (stream->_nsl_flag & __NSL_FILE_WRITE_ONLY) { - stream->_nsl_flag |= __NSL_FILE_ERR; - errno = EBADF; - return (0); - } - - if (stream->_nsl_flag & __NSL_FILE_EOF) - return (0); - - s = size * nitems; - - while (s > 0) { - if (stream->_nsl_cnt < s) { - if (stream->_nsl_cnt > 0) { - (void) memcpy((void*)dptr, stream->_nsl_ptr, - stream->_nsl_cnt); - dptr += stream->_nsl_cnt; - s -= stream->_nsl_cnt; - } - /* - * filbuf clobbers _cnt & _ptr, - * so don't waste time setting them. - */ - if (_filbuf(stream) == EOF) - break; - } - if (stream->_nsl_cnt >= s) { - (void) memcpy((void*)dptr, stream->_nsl_ptr, (size_t)s); - stream->_nsl_ptr += s; - stream->_nsl_cnt -= s; - return (nitems); - } - } - return (size != 0 ? nitems - ((s + size - 1) / size) : 0); -} - -int -__nsl_fgetc(__NSL_FILE *stream) -{ - /* is it a readable stream */ - if (stream->_nsl_flag & __NSL_FILE_WRITE_ONLY) { - stream->_nsl_flag |= __NSL_FILE_ERR; - errno = EBADF; - return (0); - } - - if (stream->_nsl_cnt <= 0) { - if (_filbuf(stream) == EOF) - return (EOF); - } - --stream->_nsl_cnt; - return (*stream->_nsl_ptr++); -} - -int -__nsl_fflush(__NSL_FILE *stream) -{ - ssize_t n; - ssize_t num_wrote; - unsigned char *base; - - if (!(stream->_nsl_flag & __NSL_FILE_DIRTY)) { - return (0); - } - - base = stream->_nsl_base; - n = stream->_nsl_ptr - stream->_nsl_base; - - stream->_nsl_flag &= ~__NSL_FILE_DIRTY; - if (n > 0) { - while ((num_wrote = - write(stream->_nsl_file, base, (size_t)n)) != n) { - if (num_wrote <= 0) { - stream->_nsl_flag |= __NSL_FILE_ERR; - return (EOF); - } - n -= num_wrote; - base += num_wrote; - } - } - stream->_nsl_ptr = stream->_nsl_base; - stream->_nsl_cnt = sizeof (stream->_nsl_base); - return (0); -} - -int -__nsl_ungetc(int c, __NSL_FILE *stream) -{ - if (stream->_nsl_flag & __NSL_FILE_WRITE_ONLY) - return (EOF); - if (c == EOF) - return (EOF); - if (stream->_nsl_ptr <= stream->_nsl_base) - return (EOF); - stream->_nsl_flag &= ~(__NSL_FILE_EOF | __NSL_FILE_ERR); - *--stream->_nsl_ptr = c; - ++stream->_nsl_cnt; - return (c); -} - -__NSL_FILE * -__nsl_fdopen(int fildes, const char *mode) -{ - int flag; - __NSL_FILE *stream; - - if (mode == NULL) { - errno = EINVAL; - return (NULL); - } - switch (mode[0]) { - default: - errno = EINVAL; - return (NULL); - case 'r': - flag = 0; - break; - case 'w': - flag = __NSL_FILE_WRITE_ONLY; - break; - } - if (mode[1] != '\0') { - errno = EINVAL; - return (NULL); - } - - stream = (__NSL_FILE *)malloc(sizeof (__NSL_FILE)); - if (stream != NULL) { - stream->_nsl_file = fildes; - stream->_nsl_cnt = flag & __NSL_FILE_WRITE_ONLY ? - sizeof (stream->_nsl_base) : 0; - stream->_nsl_ptr = stream->_nsl_base; - stream->_nsl_flag = flag; - } - - return (stream); -} - -size_t -__nsl_fwrite(const void *ptr, size_t size, size_t nitems, - __NSL_FILE *stream) -{ - ssize_t s; - const unsigned char *dptr = (const unsigned char *)ptr; - - if (!(stream->_nsl_flag & __NSL_FILE_WRITE_ONLY)) - return (0); - - if (size < 1 || nitems < 1) - return (0); - - s = size * nitems; - - stream->_nsl_flag |= __NSL_FILE_DIRTY; - - while (s > 0) { - if (stream->_nsl_cnt < s) { - if (stream->_nsl_cnt > 0) { - (void) memcpy(stream->_nsl_ptr, (void *)dptr, - stream->_nsl_cnt); - dptr += stream->_nsl_cnt; - stream->_nsl_ptr += stream->_nsl_cnt; - s -= stream->_nsl_cnt; - stream->_nsl_cnt = 0; - } - if (__nsl_fflush(stream) == EOF) - break; - } - if (stream->_nsl_cnt >= s) { - (void) memcpy(stream->_nsl_ptr, (void *)dptr, s); - stream->_nsl_ptr += s; - stream->_nsl_cnt -= s; - - return (nitems); - } - } - - return (size != 0 ? nitems - ((s + size - 1) / size) : 0); -} - -int -__nsl_fputc(int c, __NSL_FILE *stream) -{ - if (!(stream->_nsl_flag & __NSL_FILE_WRITE_ONLY)) - return (EOF); - - if (stream->_nsl_cnt == 0) { - if (__nsl_fflush(stream) == EOF) - return (EOF); - } - (*stream->_nsl_ptr++) = (unsigned char)c; - --stream->_nsl_cnt; - - return ((unsigned char)c); -} |