1 /* $NetBSD: riscosfile.c,v 1.4 2006/01/25 18:28:25 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 2001 Ben Harris 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <lib/libsa/stand.h> 31 #include <riscoscalls.h> 32 #include <riscosfile.h> 33 #include <sys/stat.h> 34 35 struct riscosfile { 36 int file; 37 }; 38 39 int 40 riscos_open(const char *path, struct open_file *f) 41 { 42 struct riscosfile *rf; 43 os_error *error; 44 int flags; 45 46 rf = (struct riscosfile *) alloc(sizeof(*rf)); 47 if (!rf) 48 return -1; 49 50 switch (f->f_flags & (F_READ | F_WRITE)) { 51 case F_READ: 52 flags = OSFind_Openin; 53 break; 54 case F_WRITE: 55 flags = OSFind_Openout; 56 break; 57 case F_READ | F_WRITE: 58 flags = OSFind_Openup; 59 break; 60 default: 61 /* Erm... */ 62 return EINVAL; 63 } 64 65 error = xosfind_open(flags | osfind_ERROR_IF_DIR | 66 osfind_ERROR_IF_ABSENT, path, NULL, &rf->file); 67 if (error) { 68 dealloc(rf, sizeof(*rf)); 69 return riscos_errno(error); 70 } 71 f->f_fsdata = rf; 72 return 0; 73 } 74 75 #ifndef LIBSA_NO_FS_CLOSE 76 int 77 riscos_close(struct open_file *f) 78 { 79 struct riscosfile *rf; 80 struct os_error *error; 81 int err = 0; 82 83 rf = f->f_fsdata; 84 85 error = xosfind_close(rf->file); 86 if (error) 87 err = riscos_errno(error); 88 dealloc(rf, sizeof(*rf)); 89 return err; 90 } 91 #endif 92 93 int 94 riscos_read(struct open_file *f, void *buf, size_t size, size_t *residp) 95 { 96 struct riscosfile *rf; 97 int resid; 98 os_error *error; 99 100 rf = f->f_fsdata; 101 102 #ifndef LIBSA_NO_TWIDDLE 103 twiddle(); 104 #endif 105 error = xosgbpb_read(rf->file, buf, size, &resid); 106 *residp = resid; 107 if (error) 108 return riscos_errno(error); 109 return 0; 110 } 111 112 #ifndef LIBSA_NO_FS_WRITE 113 int 114 riscos_write(struct open_file *f, void *buf, size_t size, size_t *residp) 115 { 116 struct riscosfile *rf; 117 int resid; 118 os_error *error; 119 120 rf = f->f_fsdata; 121 122 #ifndef LIBSA_NO_TWIDDLE 123 twiddle(); 124 #endif 125 error = xosgbpb_write(rf->file, buf, size, &resid); 126 *residp = resid; 127 if (error) 128 return riscos_errno(error); 129 return 0; 130 } 131 #endif 132 133 int 134 riscos_stat(struct open_file *f, struct stat *sb) 135 { 136 struct riscosfile *rf; 137 os_error *error; 138 int extent; 139 140 rf = f->f_fsdata; 141 142 error = xosargs_read_ext(rf->file, &extent); 143 if (error) 144 return riscos_errno(error); 145 146 sb->st_mode = S_IFREG | 0444; 147 sb->st_nlink = 1; 148 sb->st_uid = 0; 149 sb->st_gid = 0; 150 sb->st_size = extent; 151 return 0; 152 } 153 154 #ifndef LIBSA_NO_FS_SEEK 155 off_t 156 riscos_seek(struct open_file *f, off_t offset, int where) 157 { 158 struct riscosfile *rf; 159 int base, result; 160 os_error *error; 161 162 rf = f->f_fsdata; 163 164 switch (where) { 165 case SEEK_SET: 166 base = 0; 167 break; 168 case SEEK_CUR: 169 error = xosargs_read_ptr(rf->file, &base); 170 if (error) 171 goto err; 172 break; 173 case SEEK_END: 174 error = xosargs_read_ext(rf->file, &base); 175 if (error) 176 goto err; 177 break; 178 default: 179 errno = EOFFSET; 180 return -1; 181 } 182 offset = base + offset; 183 error = xosargs_set_ptr(rf->file, offset); 184 if (error) 185 goto err; 186 error = xosargs_read_ptr(rf->file, &result); 187 if (error) 188 goto err; 189 return result; 190 191 err: 192 errno = riscos_errno(error); 193 return -1; 194 } 195 #endif 196