Home | History | Annotate | Line # | Download | only in lib
      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