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 #include <stdlib.h> 28 #include <unistd.h> 29 #include <sys/stat.h> 30 31 #include <AudioRawPipe.h> 32 #include <libaudio.h> 33 #include <audio_hdr.h> 34 35 // class AudioPipe methods 36 37 // Constructor with file descriptor, mode, and optional name 38 AudioRawPipe:: 39 AudioRawPipe( 40 const int desc, // file descriptor 41 const FileAccess acc, // access mode 42 const AudioHdr& hdr_local, // header 43 const char *name_local, // name 44 const off_t off // offset 45 ):AudioPipe(desc, acc, name_local), offset(off) 46 { 47 isopened = FALSE; 48 setfd(desc); 49 SetHeader(hdr_local); 50 } 51 52 // The create routine for pipes writes a file header 53 AudioError AudioRawPipe:: 54 Create() 55 { 56 AudioError err; 57 58 // Was the header properly set? 59 err = GetHeader().Validate(); 60 if (err != AUDIO_SUCCESS) 61 return (RaiseError(err)); 62 63 // Open fd supplied by constructor 64 if (!isfdset() || opened()) { 65 return (RaiseError(AUDIO_ERR_NOEFFECT, Warning)); 66 } 67 68 // set flag for opened() test 69 isopened = TRUE; 70 71 // Set the actual output length to zero 72 setlength(0.); 73 74 return (AUDIO_SUCCESS); 75 } 76 77 // The open routine for raw pipes validates the header and 78 // init's the read pos to offset and sets the opened flag. 79 AudioError AudioRawPipe:: 80 Open() 81 { 82 AudioError err; 83 struct stat st; 84 85 // The constructor should have supplied a valid fd 86 // If fd is not open, or file header already decoded, skip it 87 if (!isfdset() || opened()) 88 return (RaiseError(AUDIO_ERR_NOEFFECT, Warning)); 89 90 // Stat the file, to see if it is a regular file 91 if (fstat(getfd(), &st) < 0) 92 return (RaiseError(AUDIO_UNIXERROR)); 93 94 // check validity of file header 95 err = GetHeader().Validate(); 96 if (err != AUDIO_SUCCESS) { 97 (void) close(getfd()); 98 setfd(-1); 99 return (err); 100 } 101 102 // Only trust the file size for regular files 103 if (S_ISREG(st.st_mode)) { 104 // for raw files - no hdr, so it's the whole file minus 105 // the offset. 106 setlength(GetHeader().Bytes_to_Time(st.st_size - offset)); 107 } else { 108 // don't know ... 109 setlength(AUDIO_UNKNOWN_TIME); 110 } 111 112 // set flag for opened() test 113 isopened = TRUE; 114 115 err = SetOffset(offset); 116 117 // reset logical position to 0.0, since this is, in effect, 118 // the beginning of the file. 119 SetReadPosition(0.0, Absolute); 120 121 return (err); 122 } 123 124 Boolean AudioRawPipe:: 125 opened() const 126 { 127 return (isopened); 128 } 129 130 AudioError AudioRawPipe:: 131 SetOffset(off_t val) 132 { 133 off_t setting = 0; 134 AudioError err; 135 136 // only read only files for now 137 if (GetAccess().Writeable()) { 138 return (AUDIO_ERR_NOEFFECT); 139 } 140 141 // only allow this if we haven't read anything yet (i.e. current 142 // position is 0). 143 if (ReadPosition() != 0.) { 144 return (AUDIO_ERR_NOEFFECT); 145 } 146 147 if ((err = seekread(GetHeader().Bytes_to_Time(val), setting)) 148 != AUDIO_SUCCESS) { 149 return (err); 150 } 151 152 // this should *never* happen 'cause seekread just sets setting 153 // to GetHeader().Time_to_Bytes.... 154 if (setting != val) { 155 // don't really know what error is apropos for this. 156 return (AUDIO_ERR_BADFRAME); 157 } 158 159 offset = val; 160 return (AUDIO_SUCCESS); 161 } 162 163 off_t AudioRawPipe:: 164 GetOffset() const 165 { 166 return (offset); 167 } 168