1//#include <_syslist.h> 2 3#include <sys/types.h> /* for off_t */ 4 5/* defined in barrelfish/debug.h */ 6void debug_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); 7 8/* Some targets provides their own versions of this functions. Those 9 targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS. */ 10 11typedef int fsopen_fn_t(const char *, int); 12typedef int fsread_fn_t(int, void *buf, size_t); 13typedef int fswrite_fn_t(int, const void *, size_t); 14typedef int fsclose_fn_t(int); 15typedef off_t fslseek_fn_t(int, off_t, int); 16 17#define FAIL_FN() \ 18do { \ 19 debug_printf("***** %s:%s() called. Something is probably wrong! Maybe " \ 20 "you forgot to call vfs_init().\n", __FILE__,__FUNCTION__); \ 21 return -1; \ 22} while (0) 23 24static int open_fail(const char *pathname, int flags) { FAIL_FN(); } 25static int read_fail(int fd, void *buf, size_t len) { FAIL_FN(); } 26static int write_fail(int fd, const void *buf, size_t len) { FAIL_FN(); } 27static int close_fail(int fd) { FAIL_FN(); } 28static off_t lseek_fail(int fd, off_t off, int whence) { FAIL_FN(); } 29 30static struct { 31 fsopen_fn_t *open; 32 fsread_fn_t *read; 33 fswrite_fn_t *write; 34 fsclose_fn_t *close; 35 fslseek_fn_t *lseek; 36} fs_ops = { 37 .open = open_fail, 38 .read = read_fail, 39 .write = write_fail, 40 .close = close_fail, 41 .lseek = lseek_fail 42}; 43 44void 45newlib_register_fsops__(fsopen_fn_t *open_fn, 46 fsread_fn_t *read_fn, 47 fswrite_fn_t *write_fn, 48 fsclose_fn_t *close_fn, 49 fslseek_fn_t *lseek_fn) 50{ 51 fs_ops.open = open_fn ? open_fn : open_fail; 52 fs_ops.read = read_fn ? read_fn : read_fail; 53 fs_ops.write = write_fn ? write_fn : write_fail; 54 fs_ops.close = close_fn ? close_fn : close_fail; 55 fs_ops.lseek = lseek_fn ? lseek_fn : lseek_fail; 56} 57 58 59#ifdef _REENT_ONLY 60#ifndef REENTRANT_SYSCALLS_PROVIDED 61#define REENTRANT_SYSCALLS_PROVIDED 62#endif 63#endif 64 65#ifndef REENTRANT_SYSCALLS_PROVIDED 66 67/* We use the errno variable used by the system dependent layer. */ 68#undef errno 69extern int errno; 70 71ssize_t 72static xwrite(int fd, const void *buf, size_t count) 73{ 74 return fs_ops.write(fd, buf, count); 75} 76 77_ssize_t 78_DEFUN (_write_r, (ptr, fd, buf, cnt), 79 struct _reent *ptr _AND 80 int fd _AND 81 _CONST _PTR buf _AND 82 size_t cnt) 83{ 84 _ssize_t ret; 85 86 errno = 0; 87 if ((ret = (_ssize_t)xwrite (fd, buf, cnt)) == -1 && errno != 0) 88 ptr->_errno = errno; 89 return ret; 90} 91 92static ssize_t 93xread(int fd, void *buf, size_t count) 94{ 95 return fs_ops.read(fd, buf, count); 96} 97 98_ssize_t 99_DEFUN (_read_r, (ptr, fd, buf, cnt), 100 struct _reent *ptr _AND 101 int fd _AND 102 _PTR buf _AND 103 size_t cnt) 104{ 105 _ssize_t ret; 106 107 108 errno = 0; 109 if ((ret = (_ssize_t)xread (fd, buf, cnt)) == -1 && errno != 0) 110 ptr->_errno = errno; 111 return ret; 112} 113 114 115static int 116xclose(int fd) 117{ 118 return fs_ops.close(fd); 119} 120 121int 122_DEFUN(_close_r, (ptr, fd), 123 struct _reent *ptr _AND 124 int fd) 125{ 126 int ret; 127 128 errno = 0; 129 if ((ret = xclose (fd)) == -1 && errno != 0) 130 ptr->_errno = errno; 131 return ret; 132} 133 134 135static int 136xopen(const char *pathname, int flags, ...) 137{ 138 return fs_ops.open(pathname, flags); 139} 140 141int 142_DEFUN (_open_r, (ptr, file, flags, mode), 143 struct _reent *ptr _AND 144 _CONST char *file _AND 145 int flags _AND 146 int mode) 147{ 148 int ret; 149 150 errno = 0; 151 if ((ret = xopen (file, flags, mode)) == -1 && errno != 0) 152 ptr->_errno = errno; 153 return ret; 154} 155 156static off_t 157xlseek(int fd, off_t offset, int whence) 158{ 159 return fs_ops.lseek(fd, offset, whence); 160} 161 162_off_t 163_DEFUN (_lseek_r, (ptr, fd, pos, whence), 164 struct _reent *ptr _AND 165 int fd _AND 166 _off_t pos _AND 167 int whence) 168{ 169 _off_t ret; 170 171 errno = 0; 172 if ((ret = xlseek (fd, pos, whence)) == (_off_t) -1 && errno != 0) 173 ptr->_errno = errno; 174 return ret; 175} 176 177/* we don't provide an fstat function. It's only use seems to be in: 178 * stdio/makebuf.c:59, which we don't really care about. Programs can use libvfs 179 * or libposixcompat for this functionality */ 180static off_t 181xfstat(int fd, void *stat) 182{ 183 return -1; 184} 185 186int 187_fstat_r (struct _reent *ptr, int fd, struct stat *pstat) 188{ 189 int ret; 190 191 errno = 0; 192 if ((ret = xfstat (fd, pstat)) == -1 && errno != 0) 193 ptr->_errno = errno; 194 return ret; 195} 196 197#endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */ 198