1/* $NetBSD: riscosfile.c,v 1.3 2005/12/11 12:16:08 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 35struct riscosfile { 36 int file; 37}; 38 39int 40riscos_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 76int 77riscos_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 93int 94riscos_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 113int 114riscos_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 133int 134riscos_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 155off_t 156riscos_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 191err: 192 errno = riscos_errno(error); 193 return -1; 194} 195#endif 196