1a23fd11yl/*
2a23fd11yl * CDDL HEADER START
3a23fd11yl *
4a23fd11yl * The contents of this file are subject to the terms of the
5a23fd11yl * Common Development and Distribution License (the "License").
6a23fd11yl * You may not use this file except in compliance with the License.
7a23fd11yl *
8a23fd11yl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9a23fd11yl * or http://www.opensolaris.org/os/licensing.
10a23fd11yl * See the License for the specific language governing permissions
11a23fd11yl * and limitations under the License.
12a23fd11yl *
13a23fd11yl * When distributing Covered Code, include this CDDL HEADER in each
14a23fd11yl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15a23fd11yl * If applicable, add the following below this CDDL HEADER, with the
16a23fd11yl * fields enclosed by brackets "[]" replaced with your own identifying
17a23fd11yl * information: Portions Copyright [yyyy] [name of copyright owner]
18a23fd11yl *
19a23fd11yl * CDDL HEADER END
20a23fd11yl */
21a23fd11yl
22a23fd11yl/*
230dc2366Venugopal Iyer * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24a23fd11yl * Use is subject to license terms.
25a23fd11yl */
26a23fd11yl
27a23fd11yl/*	Copyright (c) 1988 AT&T	*/
28a23fd11yl/*	  All Rights Reserved	*/
29a23fd11yl
30a23fd11yl#include "lint.h"
31a23fd11yl#include "file64.h"
32a23fd11yl#include "mtlib.h"
33a23fd11yl#include <sys/types.h>
34a23fd11yl#include <stdio.h>
35a23fd11yl#include <stdlib.h>
36a23fd11yl#include <thread.h>
37a23fd11yl#include <synch.h>
38a23fd11yl#include "stdiom.h"
39a23fd11yl
40a23fd11ylint
41a23fd11ylsetvbuf(FILE *iop, char *abuf, int type, size_t size)
42a23fd11yl{
43a23fd11yl
44a23fd11yl	Uchar	*buf = (Uchar *)abuf;
45a23fd11yl	Uchar *temp;
46a23fd11yl	int	sflag = iop->_flag & _IOMYBUF;
47a23fd11yl	rmutex_t *lk;
48a23fd11yl	int fd = _get_fd(iop);
49a23fd11yl
50a23fd11yl	FLOCKFILE(lk, iop);
51a23fd11yl	iop->_flag &= ~(_IOMYBUF | _IONBF | _IOLBF);
52a23fd11yl	switch (type) {
53a23fd11yl	/* note that the flags are the same as the possible values for type */
54a23fd11yl	case _IONBF:
55a23fd11yl		iop->_flag |= _IONBF;	 /* file is unbuffered */
56a23fd11yl		if (fd == 0 || fd == 1) {
57a23fd11yl			/* use special buffer for std{in,out} */
58a23fd11yl			buf = (fd == 0) ? _sibuf : _sobuf;
59a23fd11yl			size = BUFSIZ;
60a23fd11yl		} else if (fd >= 2 && fd < _NFILE) {
61a23fd11yl			buf = _smbuf[fd];
62a23fd11yl			size = _SMBFSZ - PUSHBACK;
63da14cebEric Cheng		} else {
64ba2e444seb			if ((buf = malloc(_SMBFSZ * sizeof (Uchar))) != NULL) {
65a23fd11yl				iop->_flag |= _IOMYBUF;
66a23fd11yl				size = _SMBFSZ - PUSHBACK;
67a23fd11yl			} else {
68a23fd11yl				FUNLOCKFILE(lk);
69a23fd11yl				return (EOF);
701939740Sherry Moore			}
71a23fd11yl		}
72a23fd11yl		break;
73a23fd11yl	case _IOLBF:
74a23fd11yl	case _IOFBF:
758347601yl		iop->_flag |= type;	/* buffer file */
767eced41xw		/*
777eced41xw		 * need at least an 8 character buffer for
787eced41xw		 * out_of_sync concerns.
797eced41xw		 */
807eced41xw		if (size <= _SMBFSZ) {
817eced41xw			size = BUFSIZ;
827eced41xw			buf = NULL;
837eced41xw		}
847eced41xw		if (buf == NULL) {
858347601yl			if ((buf = malloc(sizeof (Uchar) *
868347601yl			    (size + _SMBFSZ))) != NULL)
878347601yl				iop->_flag |= _IOMYBUF;
888347601yl			else {
898347601yl				FUNLOCKFILE(lk);
90a23fd11yl				return (EOF);
91da14cebEric Cheng			}
92da14cebEric Cheng		}
93da14cebEric Cheng		else
94da14cebEric Cheng			size -= _SMBFSZ;
95da14cebEric Cheng		break;
96da14cebEric Cheng	default:
97da14cebEric Cheng		FUNLOCKFILE(lk);
98da14cebEric Cheng		return (EOF);
99da14cebEric Cheng	}
100da14cebEric Cheng	if (iop->_base != NULL && sflag)
101da14cebEric Cheng		free((char *)iop->_base - PUSHBACK);
102da14cebEric Cheng	temp = buf + PUSHBACK;
103da14cebEric Cheng	iop->_base = temp;
104da14cebEric Cheng	_setbufend(iop, temp + size);
105da14cebEric Cheng	iop->_ptr = temp;
106da14cebEric Cheng	iop->_cnt = 0;
107da14cebEric Cheng	FUNLOCKFILE(lk);
108da14cebEric Cheng	return (0);
109da14cebEric Cheng}
110da14cebEric Cheng