xref: /freebsd/contrib/sendmail/libsm/stdio.c (revision d39bd2c1388b520fcba9abed1932acacead60fba)
140266059SGregory Neil Shapiro /*
25dd76dd0SGregory Neil Shapiro  * Copyright (c) 2000-2005 Proofpoint, Inc. and its suppliers.
340266059SGregory Neil Shapiro  *      All rights reserved.
440266059SGregory Neil Shapiro  * Copyright (c) 1990, 1993
540266059SGregory Neil Shapiro  *	The Regents of the University of California.  All rights reserved.
640266059SGregory Neil Shapiro  *
740266059SGregory Neil Shapiro  * This code is derived from software contributed to Berkeley by
840266059SGregory Neil Shapiro  * Chris Torek.
940266059SGregory Neil Shapiro  *
1040266059SGregory Neil Shapiro  * By using this file, you agree to the terms and conditions set
1140266059SGregory Neil Shapiro  * forth in the LICENSE file which can be found at the top level of
1240266059SGregory Neil Shapiro  * the sendmail distribution.
1340266059SGregory Neil Shapiro  */
1440266059SGregory Neil Shapiro 
1540266059SGregory Neil Shapiro #include <sm/gen.h>
164313cc83SGregory Neil Shapiro SM_RCSID("@(#)$Id: stdio.c,v 1.72 2013-11-22 20:51:43 ca Exp $")
1740266059SGregory Neil Shapiro #include <unistd.h>
1840266059SGregory Neil Shapiro #include <errno.h>
1940266059SGregory Neil Shapiro #include <fcntl.h>
2040266059SGregory Neil Shapiro #include <string.h>	/* FreeBSD: FD_ZERO needs <string.h> */
2140266059SGregory Neil Shapiro #include <sys/stat.h>
224e4196cbSGregory Neil Shapiro #include <sm/time.h>
2340266059SGregory Neil Shapiro #include <sm/heap.h>
2440266059SGregory Neil Shapiro #include <sm/assert.h>
2540266059SGregory Neil Shapiro #include <sm/varargs.h>
2640266059SGregory Neil Shapiro #include <sm/io.h>
2740266059SGregory Neil Shapiro #include <sm/setjmp.h>
2840266059SGregory Neil Shapiro #include <sm/conf.h>
2913bd1963SGregory Neil Shapiro #include <sm/fdset.h>
3040266059SGregory Neil Shapiro #include "local.h"
3140266059SGregory Neil Shapiro 
32b6bacd31SGregory Neil Shapiro static int	sm_stdsetmode __P((SM_FILE_T *, const int *));
33b6bacd31SGregory Neil Shapiro static int	sm_stdgetmode __P((SM_FILE_T *, int *));
34b6bacd31SGregory Neil Shapiro 
3540266059SGregory Neil Shapiro /*
3640266059SGregory Neil Shapiro **  Overall:
3740266059SGregory Neil Shapiro **  Small standard I/O/seek/close functions.
3840266059SGregory Neil Shapiro **  These maintain the `known seek offset' for seek optimization.
3940266059SGregory Neil Shapiro */
4040266059SGregory Neil Shapiro 
4140266059SGregory Neil Shapiro /*
4240266059SGregory Neil Shapiro **  SM_STDOPEN -- open a file with stdio behavior
4340266059SGregory Neil Shapiro **
4440266059SGregory Neil Shapiro **  Not associated with the system's stdio in libc.
4540266059SGregory Neil Shapiro **
4640266059SGregory Neil Shapiro **	Parameters:
4740266059SGregory Neil Shapiro **		fp -- file pointer to be associated with the open
4840266059SGregory Neil Shapiro **		info -- pathname of the file to be opened
4940266059SGregory Neil Shapiro **		flags -- indicates type of access methods
5040266059SGregory Neil Shapiro **		rpool -- ignored
5140266059SGregory Neil Shapiro **
5240266059SGregory Neil Shapiro **	Returns:
5340266059SGregory Neil Shapiro **		Failure: -1 and set errno
5440266059SGregory Neil Shapiro **		Success: 0 or greater (fd of file from open(2)).
5540266059SGregory Neil Shapiro **
5640266059SGregory Neil Shapiro */
5740266059SGregory Neil Shapiro 
5840266059SGregory Neil Shapiro /* ARGSUSED3 */
5940266059SGregory Neil Shapiro int
sm_stdopen(fp,info,flags,rpool)6040266059SGregory Neil Shapiro sm_stdopen(fp, info, flags, rpool)
6140266059SGregory Neil Shapiro 	SM_FILE_T *fp;
6240266059SGregory Neil Shapiro 	const void *info;
6340266059SGregory Neil Shapiro 	int flags;
6440266059SGregory Neil Shapiro 	const void *rpool;
6540266059SGregory Neil Shapiro {
6640266059SGregory Neil Shapiro 	char *path = (char *) info;
6740266059SGregory Neil Shapiro 	int oflags;
6840266059SGregory Neil Shapiro 
69a7ec597cSGregory Neil Shapiro 	switch (SM_IO_MODE(flags))
7040266059SGregory Neil Shapiro 	{
7140266059SGregory Neil Shapiro 	  case SM_IO_RDWR:
7240266059SGregory Neil Shapiro 		oflags = O_RDWR;
7340266059SGregory Neil Shapiro 		break;
7440266059SGregory Neil Shapiro 	  case SM_IO_RDWRTR:
7540266059SGregory Neil Shapiro 		oflags = O_RDWR | O_CREAT | O_TRUNC;
7640266059SGregory Neil Shapiro 		break;
7740266059SGregory Neil Shapiro 	  case SM_IO_RDONLY:
7840266059SGregory Neil Shapiro 		oflags = O_RDONLY;
7940266059SGregory Neil Shapiro 		break;
8040266059SGregory Neil Shapiro 	  case SM_IO_WRONLY:
8140266059SGregory Neil Shapiro 		oflags = O_WRONLY | O_CREAT | O_TRUNC;
8240266059SGregory Neil Shapiro 		break;
8340266059SGregory Neil Shapiro 	  case SM_IO_APPEND:
8440266059SGregory Neil Shapiro 		oflags = O_APPEND | O_WRONLY | O_CREAT;
8540266059SGregory Neil Shapiro 		break;
8640266059SGregory Neil Shapiro 	  case SM_IO_APPENDRW:
8740266059SGregory Neil Shapiro 		oflags = O_APPEND | O_RDWR | O_CREAT;
8840266059SGregory Neil Shapiro 		break;
8940266059SGregory Neil Shapiro 	  default:
9040266059SGregory Neil Shapiro 		errno = EINVAL;
9140266059SGregory Neil Shapiro 		return -1;
9240266059SGregory Neil Shapiro 	}
93a7ec597cSGregory Neil Shapiro #ifdef O_BINARY
94a7ec597cSGregory Neil Shapiro 	if (SM_IS_BINARY(flags))
95a7ec597cSGregory Neil Shapiro 		oflags |= O_BINARY;
965b0945b5SGregory Neil Shapiro #endif
9740266059SGregory Neil Shapiro 	fp->f_file = open(path, oflags,
9840266059SGregory Neil Shapiro 			  S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
9940266059SGregory Neil Shapiro 	if (fp->f_file < 0)
10040266059SGregory Neil Shapiro 		return -1; /* errno set by open() */
10140266059SGregory Neil Shapiro 
10240266059SGregory Neil Shapiro 	if (oflags & O_APPEND)
10340266059SGregory Neil Shapiro 		(void) (*fp->f_seek)((void *)fp, (off_t)0, SEEK_END);
10440266059SGregory Neil Shapiro 
10540266059SGregory Neil Shapiro 	return fp->f_file;
10640266059SGregory Neil Shapiro }
10740266059SGregory Neil Shapiro 
10840266059SGregory Neil Shapiro /*
10940266059SGregory Neil Shapiro **  SM_STDREAD -- read from the file
11040266059SGregory Neil Shapiro **
11140266059SGregory Neil Shapiro **	Parameters:
11240266059SGregory Neil Shapiro **		fp -- file pointer to read from
11340266059SGregory Neil Shapiro **		buf -- location to place read data
11440266059SGregory Neil Shapiro **		n -- number of bytes to read
11540266059SGregory Neil Shapiro **
11640266059SGregory Neil Shapiro **	Returns:
11740266059SGregory Neil Shapiro **		Failure: -1 and sets errno
11840266059SGregory Neil Shapiro **		Success: number of bytes read
11940266059SGregory Neil Shapiro **
12040266059SGregory Neil Shapiro **	Side Effects:
1215b0945b5SGregory Neil Shapiro **		Updates internal offset for file.
12240266059SGregory Neil Shapiro */
12340266059SGregory Neil Shapiro 
12440266059SGregory Neil Shapiro ssize_t
sm_stdread(fp,buf,n)12540266059SGregory Neil Shapiro sm_stdread(fp, buf, n)
12640266059SGregory Neil Shapiro 	SM_FILE_T *fp;
12740266059SGregory Neil Shapiro 	char *buf;
12840266059SGregory Neil Shapiro 	size_t n;
12940266059SGregory Neil Shapiro {
13040266059SGregory Neil Shapiro 	register int ret;
13140266059SGregory Neil Shapiro 
13240266059SGregory Neil Shapiro 	ret = read(fp->f_file, buf, n);
13340266059SGregory Neil Shapiro 
13440266059SGregory Neil Shapiro 	/* if the read succeeded, update the current offset */
13540266059SGregory Neil Shapiro 	if (ret > 0)
13640266059SGregory Neil Shapiro 		fp->f_lseekoff += ret;
13740266059SGregory Neil Shapiro 	return ret;
13840266059SGregory Neil Shapiro }
13940266059SGregory Neil Shapiro 
14040266059SGregory Neil Shapiro /*
14140266059SGregory Neil Shapiro **  SM_STDWRITE -- write to the file
14240266059SGregory Neil Shapiro **
14340266059SGregory Neil Shapiro **	Parameters:
14440266059SGregory Neil Shapiro **		fp -- file pointer ro write to
14540266059SGregory Neil Shapiro **		buf -- location of data to be written
14640266059SGregory Neil Shapiro **		n - number of bytes to write
14740266059SGregory Neil Shapiro **
14840266059SGregory Neil Shapiro **	Returns:
14940266059SGregory Neil Shapiro **		Failure: -1 and sets errno
15040266059SGregory Neil Shapiro **		Success: number of bytes written
15140266059SGregory Neil Shapiro */
15240266059SGregory Neil Shapiro 
15340266059SGregory Neil Shapiro ssize_t
sm_stdwrite(fp,buf,n)15440266059SGregory Neil Shapiro sm_stdwrite(fp, buf, n)
15540266059SGregory Neil Shapiro 	SM_FILE_T *fp;
15640266059SGregory Neil Shapiro 	char const *buf;
15740266059SGregory Neil Shapiro 	size_t n;
15840266059SGregory Neil Shapiro {
15940266059SGregory Neil Shapiro 	return write(fp->f_file, buf, n);
16040266059SGregory Neil Shapiro }
16140266059SGregory Neil Shapiro 
16240266059SGregory Neil Shapiro /*
16340266059SGregory Neil Shapiro **  SM_STDSEEK -- set the file offset position
16440266059SGregory Neil Shapiro **
165*d39bd2c1SGregory Neil Shapiro **	Parameters:
16640266059SGregory Neil Shapiro **		fp -- file pointer to position
16740266059SGregory Neil Shapiro **		offset -- how far to position from "base" (set by 'whence')
16840266059SGregory Neil Shapiro **		whence -- indicates where the "base" of the 'offset' to start
16940266059SGregory Neil Shapiro **
17040266059SGregory Neil Shapiro **	Results:
17140266059SGregory Neil Shapiro **		Failure: -1 and sets errno
17240266059SGregory Neil Shapiro **		Success: the current offset
17340266059SGregory Neil Shapiro **
17440266059SGregory Neil Shapiro **	Side Effects:
17540266059SGregory Neil Shapiro **		Updates the internal value of the offset.
17640266059SGregory Neil Shapiro */
17740266059SGregory Neil Shapiro 
17840266059SGregory Neil Shapiro off_t
sm_stdseek(fp,offset,whence)17940266059SGregory Neil Shapiro sm_stdseek(fp, offset, whence)
18040266059SGregory Neil Shapiro 	SM_FILE_T *fp;
18140266059SGregory Neil Shapiro 	off_t offset;
18240266059SGregory Neil Shapiro 	int whence;
18340266059SGregory Neil Shapiro {
18440266059SGregory Neil Shapiro 	register off_t ret;
18540266059SGregory Neil Shapiro 
18640266059SGregory Neil Shapiro 	ret = lseek(fp->f_file, (off_t) offset, whence);
18740266059SGregory Neil Shapiro 	if (ret != (off_t) -1)
18840266059SGregory Neil Shapiro 		fp->f_lseekoff = ret;
18940266059SGregory Neil Shapiro 	return ret;
19040266059SGregory Neil Shapiro }
19140266059SGregory Neil Shapiro 
19240266059SGregory Neil Shapiro /*
19340266059SGregory Neil Shapiro **  SM_STDCLOSE -- close the file
19440266059SGregory Neil Shapiro **
19540266059SGregory Neil Shapiro **	Parameters:
19640266059SGregory Neil Shapiro **		fp -- the file pointer to close
19740266059SGregory Neil Shapiro **
19840266059SGregory Neil Shapiro **	Returns:
19940266059SGregory Neil Shapiro **		Success: 0 (zero)
20040266059SGregory Neil Shapiro **		Failure: -1 and sets errno
20140266059SGregory Neil Shapiro */
20240266059SGregory Neil Shapiro 
20340266059SGregory Neil Shapiro int
sm_stdclose(fp)20440266059SGregory Neil Shapiro sm_stdclose(fp)
20540266059SGregory Neil Shapiro 	SM_FILE_T *fp;
20640266059SGregory Neil Shapiro {
20740266059SGregory Neil Shapiro 	return close(fp->f_file);
20840266059SGregory Neil Shapiro }
20940266059SGregory Neil Shapiro 
21040266059SGregory Neil Shapiro /*
21140266059SGregory Neil Shapiro **  SM_STDSETMODE -- set the access mode for the file
21240266059SGregory Neil Shapiro **
21340266059SGregory Neil Shapiro **  Called by sm_stdsetinfo().
21440266059SGregory Neil Shapiro **
21540266059SGregory Neil Shapiro **	Parameters:
21640266059SGregory Neil Shapiro **		fp -- file pointer
21740266059SGregory Neil Shapiro **		mode -- new mode to set the file access to
21840266059SGregory Neil Shapiro **
21940266059SGregory Neil Shapiro **	Results:
22040266059SGregory Neil Shapiro **		Success: 0 (zero);
22140266059SGregory Neil Shapiro **		Failure: -1 and sets errno
22240266059SGregory Neil Shapiro */
22340266059SGregory Neil Shapiro 
2244e4196cbSGregory Neil Shapiro static int
sm_stdsetmode(fp,mode)22540266059SGregory Neil Shapiro sm_stdsetmode(fp, mode)
22640266059SGregory Neil Shapiro 	SM_FILE_T *fp;
22740266059SGregory Neil Shapiro 	const int *mode;
22840266059SGregory Neil Shapiro {
22940266059SGregory Neil Shapiro 	int flags = 0;
23040266059SGregory Neil Shapiro 
231a7ec597cSGregory Neil Shapiro 	switch (SM_IO_MODE(*mode))
23240266059SGregory Neil Shapiro 	{
23340266059SGregory Neil Shapiro 	  case SM_IO_RDWR:
23440266059SGregory Neil Shapiro 		flags |= SMRW;
23540266059SGregory Neil Shapiro 		break;
23640266059SGregory Neil Shapiro 	  case SM_IO_RDONLY:
23740266059SGregory Neil Shapiro 		flags |= SMRD;
23840266059SGregory Neil Shapiro 		break;
23940266059SGregory Neil Shapiro 	  case SM_IO_WRONLY:
24040266059SGregory Neil Shapiro 		flags |= SMWR;
24140266059SGregory Neil Shapiro 		break;
24240266059SGregory Neil Shapiro 	  case SM_IO_APPEND:
24340266059SGregory Neil Shapiro 	  default:
24440266059SGregory Neil Shapiro 		errno = EINVAL;
24540266059SGregory Neil Shapiro 		return -1;
24640266059SGregory Neil Shapiro 	}
24740266059SGregory Neil Shapiro 	fp->f_flags = fp->f_flags & ~SMMODEMASK;
24840266059SGregory Neil Shapiro 	fp->f_flags |= flags;
24940266059SGregory Neil Shapiro 	return 0;
25040266059SGregory Neil Shapiro }
25140266059SGregory Neil Shapiro 
25240266059SGregory Neil Shapiro /*
25340266059SGregory Neil Shapiro **  SM_STDGETMODE -- for getinfo determine open mode
25440266059SGregory Neil Shapiro **
25540266059SGregory Neil Shapiro **  Called by sm_stdgetinfo().
25640266059SGregory Neil Shapiro **
25740266059SGregory Neil Shapiro **	Parameters:
25840266059SGregory Neil Shapiro **		fp -- the file mode being determined
25940266059SGregory Neil Shapiro **		mode -- internal mode to map to external value
26040266059SGregory Neil Shapiro **
26140266059SGregory Neil Shapiro **	Results:
26240266059SGregory Neil Shapiro **		Failure: -1 and sets errno
26340266059SGregory Neil Shapiro **		Success: external mode value
26440266059SGregory Neil Shapiro */
26540266059SGregory Neil Shapiro 
266b6bacd31SGregory Neil Shapiro static int
sm_stdgetmode(fp,mode)26740266059SGregory Neil Shapiro sm_stdgetmode(fp, mode)
26840266059SGregory Neil Shapiro 	SM_FILE_T *fp;
26940266059SGregory Neil Shapiro 	int *mode;
27040266059SGregory Neil Shapiro {
27140266059SGregory Neil Shapiro 	switch (fp->f_flags & SMMODEMASK)
27240266059SGregory Neil Shapiro 	{
27340266059SGregory Neil Shapiro 	  case SMRW:
27440266059SGregory Neil Shapiro 		*mode = SM_IO_RDWR;
27540266059SGregory Neil Shapiro 		break;
27640266059SGregory Neil Shapiro 	  case SMRD:
27740266059SGregory Neil Shapiro 		*mode = SM_IO_RDONLY;
27840266059SGregory Neil Shapiro 		break;
27940266059SGregory Neil Shapiro 	  case SMWR:
28040266059SGregory Neil Shapiro 		*mode = SM_IO_WRONLY;
28140266059SGregory Neil Shapiro 		break;
28240266059SGregory Neil Shapiro 	  default:
28340266059SGregory Neil Shapiro 		errno = EINVAL;
28440266059SGregory Neil Shapiro 		return -1;
28540266059SGregory Neil Shapiro 	}
28640266059SGregory Neil Shapiro 	return 0;
28740266059SGregory Neil Shapiro }
28840266059SGregory Neil Shapiro 
28940266059SGregory Neil Shapiro /*
29040266059SGregory Neil Shapiro **  SM_STDSETINFO -- set/modify information for a file
29140266059SGregory Neil Shapiro **
29240266059SGregory Neil Shapiro **	Parameters:
29340266059SGregory Neil Shapiro **		fp -- file to set info for
29440266059SGregory Neil Shapiro **		what -- type of info to set
29540266059SGregory Neil Shapiro **		valp -- location of data used for setting
29640266059SGregory Neil Shapiro **
29740266059SGregory Neil Shapiro **	Returns:
29840266059SGregory Neil Shapiro **		Failure: -1 and sets errno
29940266059SGregory Neil Shapiro **		Success: >=0
30040266059SGregory Neil Shapiro */
30140266059SGregory Neil Shapiro 
30240266059SGregory Neil Shapiro int
sm_stdsetinfo(fp,what,valp)30340266059SGregory Neil Shapiro sm_stdsetinfo(fp, what, valp)
30440266059SGregory Neil Shapiro 	SM_FILE_T *fp;
30540266059SGregory Neil Shapiro 	int what;
30640266059SGregory Neil Shapiro 	void *valp;
30740266059SGregory Neil Shapiro {
30840266059SGregory Neil Shapiro 	switch (what)
30940266059SGregory Neil Shapiro 	{
31040266059SGregory Neil Shapiro 	  case SM_IO_WHAT_MODE:
31140266059SGregory Neil Shapiro 		return sm_stdsetmode(fp, (const int *)valp);
31240266059SGregory Neil Shapiro 
31340266059SGregory Neil Shapiro 	  default:
31440266059SGregory Neil Shapiro 		errno = EINVAL;
31540266059SGregory Neil Shapiro 		return -1;
31640266059SGregory Neil Shapiro 	}
31740266059SGregory Neil Shapiro }
31840266059SGregory Neil Shapiro 
31940266059SGregory Neil Shapiro /*
320da7d7b9cSGregory Neil Shapiro **  SM_STDGETINFO -- get information about the open file
32140266059SGregory Neil Shapiro **
32240266059SGregory Neil Shapiro **	Parameters:
32340266059SGregory Neil Shapiro **		fp -- file to get info for
32440266059SGregory Neil Shapiro **		what -- type of info to get
32540266059SGregory Neil Shapiro **		valp -- location to place found info
32640266059SGregory Neil Shapiro **
32740266059SGregory Neil Shapiro **	Returns:
32840266059SGregory Neil Shapiro **		Success: may or may not place info in 'valp' depending
32940266059SGregory Neil Shapiro **			on 'what' value, and returns values >=0. Return
33040266059SGregory Neil Shapiro **			value may be the obtained info
33140266059SGregory Neil Shapiro **		Failure: -1 and sets errno
33240266059SGregory Neil Shapiro */
33340266059SGregory Neil Shapiro 
33440266059SGregory Neil Shapiro int
sm_stdgetinfo(fp,what,valp)33540266059SGregory Neil Shapiro sm_stdgetinfo(fp, what, valp)
33640266059SGregory Neil Shapiro 	SM_FILE_T *fp;
33740266059SGregory Neil Shapiro 	int what;
33840266059SGregory Neil Shapiro 	void *valp;
33940266059SGregory Neil Shapiro {
34040266059SGregory Neil Shapiro 	switch (what)
34140266059SGregory Neil Shapiro 	{
34240266059SGregory Neil Shapiro 	  case SM_IO_WHAT_MODE:
34340266059SGregory Neil Shapiro 		return sm_stdgetmode(fp, (int *)valp);
34440266059SGregory Neil Shapiro 
34540266059SGregory Neil Shapiro 	  case SM_IO_WHAT_FD:
34640266059SGregory Neil Shapiro 		return fp->f_file;
34740266059SGregory Neil Shapiro 
348605302a5SGregory Neil Shapiro 	  case SM_IO_WHAT_SIZE:
349605302a5SGregory Neil Shapiro 	  {
350605302a5SGregory Neil Shapiro 		  struct stat st;
351605302a5SGregory Neil Shapiro 
352605302a5SGregory Neil Shapiro 		  if (fstat(fp->f_file, &st) == 0)
353605302a5SGregory Neil Shapiro 			  return st.st_size;
354605302a5SGregory Neil Shapiro 		  else
355605302a5SGregory Neil Shapiro 			  return -1;
356605302a5SGregory Neil Shapiro 	  }
357605302a5SGregory Neil Shapiro 
35840266059SGregory Neil Shapiro 	  case SM_IO_IS_READABLE:
35940266059SGregory Neil Shapiro 	  {
36040266059SGregory Neil Shapiro 		  fd_set readfds;
36140266059SGregory Neil Shapiro 		  struct timeval timeout;
36240266059SGregory Neil Shapiro 
36313bd1963SGregory Neil Shapiro 		  if (SM_FD_SETSIZE > 0 && fp->f_file >= SM_FD_SETSIZE)
36413bd1963SGregory Neil Shapiro 		  {
36513bd1963SGregory Neil Shapiro 			  errno = EINVAL;
36613bd1963SGregory Neil Shapiro 			  return -1;
36713bd1963SGregory Neil Shapiro 		  }
36840266059SGregory Neil Shapiro 		  FD_ZERO(&readfds);
36940266059SGregory Neil Shapiro 		  SM_FD_SET(fp->f_file, &readfds);
37040266059SGregory Neil Shapiro 		  timeout.tv_sec = 0;
37140266059SGregory Neil Shapiro 		  timeout.tv_usec = 0;
372605302a5SGregory Neil Shapiro 		  if (select(fp->f_file + 1, FDSET_CAST &readfds,
373605302a5SGregory Neil Shapiro 			     NULL, NULL, &timeout) > 0 &&
37440266059SGregory Neil Shapiro 		      SM_FD_ISSET(fp->f_file, &readfds))
37540266059SGregory Neil Shapiro 			  return 1;
37640266059SGregory Neil Shapiro 		  return 0;
37740266059SGregory Neil Shapiro 	  }
37840266059SGregory Neil Shapiro 
37940266059SGregory Neil Shapiro 	  default:
38040266059SGregory Neil Shapiro 		errno = EINVAL;
38140266059SGregory Neil Shapiro 		return -1;
38240266059SGregory Neil Shapiro 	}
38340266059SGregory Neil Shapiro }
38440266059SGregory Neil Shapiro 
38540266059SGregory Neil Shapiro /*
386605302a5SGregory Neil Shapiro **  SM_STDFDOPEN -- open file by primitive 'fd' rather than pathname
38740266059SGregory Neil Shapiro **
38840266059SGregory Neil Shapiro **	I/O function to handle fdopen() stdio equivalence. The rest of
38940266059SGregory Neil Shapiro **	the functions are the same as the sm_stdopen() above.
39040266059SGregory Neil Shapiro **
39140266059SGregory Neil Shapiro **	Parameters:
39240266059SGregory Neil Shapiro **		fp -- the file pointer to be associated with the open
393605302a5SGregory Neil Shapiro **		name -- the primitive file descriptor for association
39440266059SGregory Neil Shapiro **		flags -- indicates type of access methods
39540266059SGregory Neil Shapiro **		rpool -- ignored
39640266059SGregory Neil Shapiro **
39740266059SGregory Neil Shapiro **	Results:
398605302a5SGregory Neil Shapiro **		Success: primitive file descriptor value
39940266059SGregory Neil Shapiro **		Failure: -1 and sets errno
40040266059SGregory Neil Shapiro */
40140266059SGregory Neil Shapiro 
40240266059SGregory Neil Shapiro /* ARGSUSED3 */
40340266059SGregory Neil Shapiro int
sm_stdfdopen(fp,info,flags,rpool)40440266059SGregory Neil Shapiro sm_stdfdopen(fp, info, flags, rpool)
40540266059SGregory Neil Shapiro 	SM_FILE_T *fp;
40640266059SGregory Neil Shapiro 	const void *info;
40740266059SGregory Neil Shapiro 	int flags;
40840266059SGregory Neil Shapiro 	const void *rpool;
40940266059SGregory Neil Shapiro {
41040266059SGregory Neil Shapiro 	int oflags, tmp, fdflags, fd = *((int *) info);
41140266059SGregory Neil Shapiro 
412a7ec597cSGregory Neil Shapiro 	switch (SM_IO_MODE(flags))
41340266059SGregory Neil Shapiro 	{
41440266059SGregory Neil Shapiro 	  case SM_IO_RDWR:
41540266059SGregory Neil Shapiro 		oflags = O_RDWR | O_CREAT;
41640266059SGregory Neil Shapiro 		break;
41740266059SGregory Neil Shapiro 	  case SM_IO_RDONLY:
41840266059SGregory Neil Shapiro 		oflags = O_RDONLY;
41940266059SGregory Neil Shapiro 		break;
42040266059SGregory Neil Shapiro 	  case SM_IO_WRONLY:
42140266059SGregory Neil Shapiro 		oflags = O_WRONLY | O_CREAT | O_TRUNC;
42240266059SGregory Neil Shapiro 		break;
42340266059SGregory Neil Shapiro 	  case SM_IO_APPEND:
42440266059SGregory Neil Shapiro 		oflags = O_APPEND | O_WRONLY | O_CREAT;
42540266059SGregory Neil Shapiro 		break;
42640266059SGregory Neil Shapiro 	  case SM_IO_APPENDRW:
42740266059SGregory Neil Shapiro 		oflags = O_APPEND | O_RDWR | O_CREAT;
42840266059SGregory Neil Shapiro 		break;
42940266059SGregory Neil Shapiro 	  default:
43040266059SGregory Neil Shapiro 		errno = EINVAL;
43140266059SGregory Neil Shapiro 		return -1;
43240266059SGregory Neil Shapiro 	}
433a7ec597cSGregory Neil Shapiro #ifdef O_BINARY
434a7ec597cSGregory Neil Shapiro 	if (SM_IS_BINARY(flags))
435a7ec597cSGregory Neil Shapiro 		oflags |= O_BINARY;
4365b0945b5SGregory Neil Shapiro #endif
43740266059SGregory Neil Shapiro 
43840266059SGregory Neil Shapiro 	/* Make sure the mode the user wants is a subset of the actual mode. */
43940266059SGregory Neil Shapiro 	if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0)
44040266059SGregory Neil Shapiro 		return -1;
44140266059SGregory Neil Shapiro 	tmp = fdflags & O_ACCMODE;
44240266059SGregory Neil Shapiro 	if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE)))
44340266059SGregory Neil Shapiro 	{
44440266059SGregory Neil Shapiro 		errno = EINVAL;
44540266059SGregory Neil Shapiro 		return -1;
44640266059SGregory Neil Shapiro 	}
44740266059SGregory Neil Shapiro 	fp->f_file = fd;
44840266059SGregory Neil Shapiro 	if (oflags & O_APPEND)
44940266059SGregory Neil Shapiro 		(void) (*fp->f_seek)(fp, (off_t)0, SEEK_END);
45040266059SGregory Neil Shapiro 	return fp->f_file;
45140266059SGregory Neil Shapiro }
45240266059SGregory Neil Shapiro 
45340266059SGregory Neil Shapiro /*
45440266059SGregory Neil Shapiro **  SM_IO_FOPEN -- open a file
45540266059SGregory Neil Shapiro **
45640266059SGregory Neil Shapiro **	Same interface and semantics as the open() system call,
45740266059SGregory Neil Shapiro **	except that it returns SM_FILE_T* instead of a file descriptor.
45840266059SGregory Neil Shapiro **
45940266059SGregory Neil Shapiro **	Parameters:
46040266059SGregory Neil Shapiro **		pathname -- path of file to open
46140266059SGregory Neil Shapiro **		flags -- flags controlling the open
46240266059SGregory Neil Shapiro **		...  -- option "mode" for opening the file
46340266059SGregory Neil Shapiro **
46440266059SGregory Neil Shapiro **	Returns:
46540266059SGregory Neil Shapiro **		Raises an exception on heap exhaustion.
46640266059SGregory Neil Shapiro **		Returns NULL and sets errno if open() fails.
46740266059SGregory Neil Shapiro **		Returns an SM_FILE_T pointer on success.
46840266059SGregory Neil Shapiro */
46940266059SGregory Neil Shapiro 
47040266059SGregory Neil Shapiro SM_FILE_T *
47140266059SGregory Neil Shapiro #if SM_VA_STD
sm_io_fopen(char * pathname,int flags,...)47240266059SGregory Neil Shapiro sm_io_fopen(char *pathname, int flags, ...)
47340266059SGregory Neil Shapiro #else /* SM_VA_STD */
47440266059SGregory Neil Shapiro sm_io_fopen(pathname, flags, va_alist)
47540266059SGregory Neil Shapiro 	char *pathname;
47640266059SGregory Neil Shapiro 	int flags;
47740266059SGregory Neil Shapiro 	va_dcl
47840266059SGregory Neil Shapiro #endif /* SM_VA_STD */
47940266059SGregory Neil Shapiro {
48040266059SGregory Neil Shapiro 	MODE_T mode;
48140266059SGregory Neil Shapiro 	SM_FILE_T *fp;
48240266059SGregory Neil Shapiro 	int ioflags;
48340266059SGregory Neil Shapiro 
48440266059SGregory Neil Shapiro 	if (flags & O_CREAT)
48540266059SGregory Neil Shapiro 	{
48640266059SGregory Neil Shapiro 		SM_VA_LOCAL_DECL
48740266059SGregory Neil Shapiro 
48840266059SGregory Neil Shapiro 		SM_VA_START(ap, flags);
48940266059SGregory Neil Shapiro 		mode = (MODE_T) SM_VA_ARG(ap, int);
49040266059SGregory Neil Shapiro 		SM_VA_END(ap);
49140266059SGregory Neil Shapiro 	}
49240266059SGregory Neil Shapiro 	else
49340266059SGregory Neil Shapiro 		mode = 0;
49440266059SGregory Neil Shapiro 
49540266059SGregory Neil Shapiro 	switch (flags & O_ACCMODE)
49640266059SGregory Neil Shapiro 	{
49740266059SGregory Neil Shapiro 	  case O_RDONLY:
49840266059SGregory Neil Shapiro 		ioflags = SMRD;
49940266059SGregory Neil Shapiro 		break;
50040266059SGregory Neil Shapiro 	  case O_WRONLY:
50140266059SGregory Neil Shapiro 		ioflags = SMWR;
50240266059SGregory Neil Shapiro 		break;
50340266059SGregory Neil Shapiro 	  case O_RDWR:
50440266059SGregory Neil Shapiro 		ioflags = SMRW;
50540266059SGregory Neil Shapiro 		break;
50640266059SGregory Neil Shapiro 	  default:
50740266059SGregory Neil Shapiro 		sm_abort("sm_io_fopen: bad flags 0%o", flags);
50840266059SGregory Neil Shapiro 	}
50940266059SGregory Neil Shapiro 
51040266059SGregory Neil Shapiro 	fp = sm_fp(SmFtStdio, ioflags, NULL);
51140266059SGregory Neil Shapiro 	fp->f_file = open(pathname, flags, mode);
51240266059SGregory Neil Shapiro 	if (fp->f_file == -1)
51340266059SGregory Neil Shapiro 	{
51440266059SGregory Neil Shapiro 		fp->f_flags = 0;
51540266059SGregory Neil Shapiro 		fp->sm_magic = NULL;
51640266059SGregory Neil Shapiro 		return NULL;
51740266059SGregory Neil Shapiro 	}
51840266059SGregory Neil Shapiro 	return fp;
51940266059SGregory Neil Shapiro }
520