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 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; 96a7ec597cSGregory Neil Shapiro #endif /* O_BINARY */ 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: 12140266059SGregory Neil Shapiro ** Updates internal offset into file. 12240266059SGregory Neil Shapiro */ 12340266059SGregory Neil Shapiro 12440266059SGregory Neil Shapiro ssize_t 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 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 ** 16540266059SGregory Neil Shapiro ** Parmeters: 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 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 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 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 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 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 /* 320*da7d7b9cSGregory 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 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 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; 436a7ec597cSGregory Neil Shapiro #endif /* O_BINARY */ 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 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