1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1991-2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdlib.h> 30 #include <unistd.h> 31 #include <sys/stat.h> 32 33 #include <AudioRawPipe.h> 34 #include <libaudio.h> 35 #include <audio_hdr.h> 36 37 // class AudioPipe methods 38 39 // Constructor with file descriptor, mode, and optional name 40 AudioRawPipe:: 41 AudioRawPipe( 42 const int desc, // file descriptor 43 const FileAccess acc, // access mode 44 const AudioHdr& hdr_local, // header 45 const char *name_local, // name 46 const off_t off // offset 47 ):AudioPipe(desc, acc, name_local), offset(off) 48 { 49 isopened = FALSE; 50 setfd(desc); 51 SetHeader(hdr_local); 52 } 53 54 // The create routine for pipes writes a file header 55 AudioError AudioRawPipe:: 56 Create() 57 { 58 AudioError err; 59 60 // Was the header properly set? 61 err = GetHeader().Validate(); 62 if (err != AUDIO_SUCCESS) 63 return (RaiseError(err)); 64 65 // Open fd supplied by constructor 66 if (!isfdset() || opened()) { 67 return (RaiseError(AUDIO_ERR_NOEFFECT, Warning)); 68 } 69 70 // set flag for opened() test 71 isopened = TRUE; 72 73 // Set the actual output length to zero 74 setlength(0.); 75 76 return (AUDIO_SUCCESS); 77 } 78 79 // The open routine for raw pipes validates the header and 80 // init's the read pos to offset and sets the opened flag. 81 AudioError AudioRawPipe:: 82 Open() 83 { 84 AudioError err; 85 struct stat st; 86 87 // The constructor should have supplied a valid fd 88 // If fd is not open, or file header already decoded, skip it 89 if (!isfdset() || opened()) 90 return (RaiseError(AUDIO_ERR_NOEFFECT, Warning)); 91 92 // Stat the file, to see if it is a regular file 93 if (fstat(getfd(), &st) < 0) 94 return (RaiseError(AUDIO_UNIXERROR)); 95 96 // check validity of file header 97 err = GetHeader().Validate(); 98 if (err != AUDIO_SUCCESS) { 99 (void) close(getfd()); 100 setfd(-1); 101 return (err); 102 } 103 104 // Only trust the file size for regular files 105 if (S_ISREG(st.st_mode)) { 106 // for raw files - no hdr, so it's the whole file minus 107 // the offset. 108 setlength(GetHeader().Bytes_to_Time(st.st_size - offset)); 109 } else { 110 // don't know ... 111 setlength(AUDIO_UNKNOWN_TIME); 112 } 113 114 // set flag for opened() test 115 isopened = TRUE; 116 117 err = SetOffset(offset); 118 119 // reset logical position to 0.0, since this is, in effect, 120 // the beginning of the file. 121 SetReadPosition(0.0, Absolute); 122 123 return (err); 124 } 125 126 Boolean AudioRawPipe:: 127 opened() const 128 { 129 return (isopened); 130 } 131 132 AudioError AudioRawPipe:: 133 SetOffset(off_t val) 134 { 135 off_t setting = 0; 136 AudioError err; 137 138 // only read only files for now 139 if (GetAccess().Writeable()) { 140 return (AUDIO_ERR_NOEFFECT); 141 } 142 143 // only allow this if we haven't read anything yet (i.e. current 144 // position is 0). 145 if (ReadPosition() != 0.) { 146 return (AUDIO_ERR_NOEFFECT); 147 } 148 149 if ((err = seekread(GetHeader().Bytes_to_Time(val), setting)) 150 != AUDIO_SUCCESS) { 151 return (err); 152 } 153 154 // this should *never* happen 'cause seekread just sets setting 155 // to GetHeader().Time_to_Bytes.... 156 if (setting != val) { 157 // don't really know what error is apropos for this. 158 return (AUDIO_ERR_BADFRAME); 159 } 160 161 offset = val; 162 return (AUDIO_SUCCESS); 163 } 164 165 off_t AudioRawPipe:: 166 GetOffset() const 167 { 168 return (offset); 169 } 170