17cafeaa1SWarner Losh /*- 27cafeaa1SWarner Losh * Copyright (c) 2014 Pedro Souza <pedrosouza@freebsd.org> 37cafeaa1SWarner Losh * All rights reserved. 47cafeaa1SWarner Losh * 57cafeaa1SWarner Losh * Redistribution and use in source and binary forms, with or without 67cafeaa1SWarner Losh * modification, are permitted provided that the following conditions 77cafeaa1SWarner Losh * are met: 87cafeaa1SWarner Losh * 1. Redistributions of source code must retain the above copyright 97cafeaa1SWarner Losh * notice, this list of conditions and the following disclaimer. 107cafeaa1SWarner Losh * 2. Redistributions in binary form must reproduce the above copyright 117cafeaa1SWarner Losh * notice, this list of conditions and the following disclaimer in the 127cafeaa1SWarner Losh * documentation and/or other materials provided with the distribution. 137cafeaa1SWarner Losh * 147cafeaa1SWarner Losh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 157cafeaa1SWarner Losh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 167cafeaa1SWarner Losh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 177cafeaa1SWarner Losh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 187cafeaa1SWarner Losh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 197cafeaa1SWarner Losh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 207cafeaa1SWarner Losh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 217cafeaa1SWarner Losh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 227cafeaa1SWarner Losh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 237cafeaa1SWarner Losh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 247cafeaa1SWarner Losh * SUCH DAMAGE. 257cafeaa1SWarner Losh * 267cafeaa1SWarner Losh */ 277cafeaa1SWarner Losh 287cafeaa1SWarner Losh #include <sys/cdefs.h> 297cafeaa1SWarner Losh __FBSDID("$FreeBSD$"); 307cafeaa1SWarner Losh 317cafeaa1SWarner Losh #include "lstd.h" 327cafeaa1SWarner Losh #include "math.h" 337cafeaa1SWarner Losh 34*8df8b2d3SSimon J. Gerraty #ifdef LOADER_VERIEXEC 35*8df8b2d3SSimon J. Gerraty #include <verify_file.h> 36*8df8b2d3SSimon J. Gerraty #endif 37*8df8b2d3SSimon J. Gerraty 387cafeaa1SWarner Losh FILE * 397cafeaa1SWarner Losh fopen(const char *filename, const char *mode) 407cafeaa1SWarner Losh { 417cafeaa1SWarner Losh struct stat st; 4282c85a42SKyle Evans int fd, m, o; 437cafeaa1SWarner Losh FILE *f; 447cafeaa1SWarner Losh 4582c85a42SKyle Evans if (mode == NULL) 467cafeaa1SWarner Losh return NULL; 477cafeaa1SWarner Losh 4882c85a42SKyle Evans switch (*mode++) { 4982c85a42SKyle Evans case 'r': /* open for reading */ 5082c85a42SKyle Evans m = O_RDONLY; 5182c85a42SKyle Evans o = 0; 5282c85a42SKyle Evans break; 5382c85a42SKyle Evans 5482c85a42SKyle Evans case 'w': /* open for writing */ 5582c85a42SKyle Evans m = O_WRONLY; 5682c85a42SKyle Evans /* These are not actually implemented yet */ 5782c85a42SKyle Evans o = O_CREAT | O_TRUNC; 5882c85a42SKyle Evans break; 5982c85a42SKyle Evans 6082c85a42SKyle Evans default: /* illegal mode */ 6182c85a42SKyle Evans return (NULL); 6282c85a42SKyle Evans } 6382c85a42SKyle Evans 6482c85a42SKyle Evans if (*mode == '+') 6582c85a42SKyle Evans m = O_RDWR; 6682c85a42SKyle Evans 6782c85a42SKyle Evans fd = open(filename, m | o); 687cafeaa1SWarner Losh if (fd < 0) 697cafeaa1SWarner Losh return NULL; 707cafeaa1SWarner Losh 717cafeaa1SWarner Losh f = malloc(sizeof(FILE)); 727cafeaa1SWarner Losh if (f == NULL) { 737cafeaa1SWarner Losh close(fd); 747cafeaa1SWarner Losh return NULL; 757cafeaa1SWarner Losh } 767cafeaa1SWarner Losh 777cafeaa1SWarner Losh if (fstat(fd, &st) != 0) { 787cafeaa1SWarner Losh free(f); 797cafeaa1SWarner Losh close(fd); 807cafeaa1SWarner Losh return (NULL); 817cafeaa1SWarner Losh } 827cafeaa1SWarner Losh 83*8df8b2d3SSimon J. Gerraty #ifdef LOADER_VERIEXEC 84*8df8b2d3SSimon J. Gerraty /* only regular files and only reading makes sense */ 85*8df8b2d3SSimon J. Gerraty if (S_ISREG(st.st_mode) && !(m & O_WRONLY)) { 86*8df8b2d3SSimon J. Gerraty if (verify_file(fd, filename, 0, VE_GUESS) < 0) { 87*8df8b2d3SSimon J. Gerraty free(f); 88*8df8b2d3SSimon J. Gerraty close(fd); 89*8df8b2d3SSimon J. Gerraty return (NULL); 90*8df8b2d3SSimon J. Gerraty } 91*8df8b2d3SSimon J. Gerraty } 92*8df8b2d3SSimon J. Gerraty #endif 93*8df8b2d3SSimon J. Gerraty 947cafeaa1SWarner Losh f->fd = fd; 957cafeaa1SWarner Losh f->offset = 0; 967cafeaa1SWarner Losh f->size = st.st_size; 977cafeaa1SWarner Losh 987cafeaa1SWarner Losh return (f); 997cafeaa1SWarner Losh } 1007cafeaa1SWarner Losh 1017cafeaa1SWarner Losh 1027cafeaa1SWarner Losh FILE * 1037cafeaa1SWarner Losh freopen(const char *filename, const char *mode, FILE *stream) 1047cafeaa1SWarner Losh { 1057cafeaa1SWarner Losh fclose(stream); 1067cafeaa1SWarner Losh return (fopen(filename, mode)); 1077cafeaa1SWarner Losh } 1087cafeaa1SWarner Losh 1097cafeaa1SWarner Losh size_t 1107cafeaa1SWarner Losh fread(void *ptr, size_t size, size_t count, FILE *stream) 1117cafeaa1SWarner Losh { 1127cafeaa1SWarner Losh size_t r; 1137cafeaa1SWarner Losh 1147cafeaa1SWarner Losh if (stream == NULL) 1157cafeaa1SWarner Losh return 0; 1167cafeaa1SWarner Losh r = (size_t)read(stream->fd, ptr, size * count); 1177cafeaa1SWarner Losh stream->offset += r; 1187cafeaa1SWarner Losh 1197cafeaa1SWarner Losh return (r); 1207cafeaa1SWarner Losh } 1217cafeaa1SWarner Losh 12282c85a42SKyle Evans size_t 12382c85a42SKyle Evans fwrite(const void *ptr, size_t size, size_t count, FILE *stream) 12482c85a42SKyle Evans { 12582c85a42SKyle Evans ssize_t w; 12682c85a42SKyle Evans 12782c85a42SKyle Evans if (stream == NULL || ptr == NULL) 12882c85a42SKyle Evans return (0); 12982c85a42SKyle Evans w = write(stream->fd, ptr, size * count); 13082c85a42SKyle Evans if (w == -1) 13182c85a42SKyle Evans return (0); 13282c85a42SKyle Evans 13382c85a42SKyle Evans stream->offset += w; 13482c85a42SKyle Evans return ((size_t)w); 13582c85a42SKyle Evans } 13682c85a42SKyle Evans 1377cafeaa1SWarner Losh int 1387cafeaa1SWarner Losh fclose(FILE *stream) 1397cafeaa1SWarner Losh { 1407cafeaa1SWarner Losh if (stream == NULL) 1417cafeaa1SWarner Losh return EOF; 1427cafeaa1SWarner Losh close(stream->fd); 1437cafeaa1SWarner Losh free(stream); 1447cafeaa1SWarner Losh 1457cafeaa1SWarner Losh return (0); 1467cafeaa1SWarner Losh } 1477cafeaa1SWarner Losh 1487cafeaa1SWarner Losh int 1497cafeaa1SWarner Losh ferror(FILE *stream) 1507cafeaa1SWarner Losh { 1517cafeaa1SWarner Losh 1527cafeaa1SWarner Losh return (stream == NULL || stream->fd < 0); 1537cafeaa1SWarner Losh } 1547cafeaa1SWarner Losh 1557cafeaa1SWarner Losh int 1567cafeaa1SWarner Losh feof(FILE *stream) 1577cafeaa1SWarner Losh { 1587cafeaa1SWarner Losh 1597cafeaa1SWarner Losh if (stream == NULL) 1607cafeaa1SWarner Losh return 1; 1617cafeaa1SWarner Losh 1627cafeaa1SWarner Losh return (stream->offset >= stream->size); 1637cafeaa1SWarner Losh } 1647cafeaa1SWarner Losh 1657cafeaa1SWarner Losh int 1667cafeaa1SWarner Losh getc(FILE *stream) 1677cafeaa1SWarner Losh { 1687cafeaa1SWarner Losh char ch; 1697cafeaa1SWarner Losh size_t r; 1707cafeaa1SWarner Losh 1717cafeaa1SWarner Losh if (stream == NULL) 1727cafeaa1SWarner Losh return EOF; 1737cafeaa1SWarner Losh r = read(stream->fd, &ch, 1); 1747cafeaa1SWarner Losh if (r == 1) 1757cafeaa1SWarner Losh return ch; 1767cafeaa1SWarner Losh return EOF; 1777cafeaa1SWarner Losh } 1787cafeaa1SWarner Losh 179b216e997SConrad Meyer DIR * 180b216e997SConrad Meyer opendir(const char *name) 181b216e997SConrad Meyer { 182b216e997SConrad Meyer DIR *dp; 183b216e997SConrad Meyer int fd; 184b216e997SConrad Meyer 185b216e997SConrad Meyer fd = open(name, O_RDONLY); 186b216e997SConrad Meyer if (fd < 0) 187b216e997SConrad Meyer return NULL; 188b216e997SConrad Meyer dp = fdopendir(fd); 189b216e997SConrad Meyer if (dp == NULL) 190b216e997SConrad Meyer close(fd); 191b216e997SConrad Meyer return dp; 192b216e997SConrad Meyer } 193b216e997SConrad Meyer 194b216e997SConrad Meyer DIR * 195b216e997SConrad Meyer fdopendir(int fd) 196b216e997SConrad Meyer { 197b216e997SConrad Meyer DIR *dp; 198b216e997SConrad Meyer 199b216e997SConrad Meyer dp = malloc(sizeof(*dp)); 200b216e997SConrad Meyer if (dp == NULL) 201b216e997SConrad Meyer return NULL; 202b216e997SConrad Meyer dp->fd = fd; 203b216e997SConrad Meyer return dp; 204b216e997SConrad Meyer } 205b216e997SConrad Meyer 206b216e997SConrad Meyer int 207b216e997SConrad Meyer closedir(DIR *dp) 208b216e997SConrad Meyer { 209b216e997SConrad Meyer close(dp->fd); 210b216e997SConrad Meyer dp->fd = -1; 211b216e997SConrad Meyer free(dp); 212b216e997SConrad Meyer return 0; 213b216e997SConrad Meyer } 214b216e997SConrad Meyer 2157cafeaa1SWarner Losh void 2167cafeaa1SWarner Losh luai_writestring(const char *s, int i) 2177cafeaa1SWarner Losh { 2187cafeaa1SWarner Losh 2197cafeaa1SWarner Losh while (i-- > 0) 2207cafeaa1SWarner Losh putchar(*s++); 2217cafeaa1SWarner Losh } 2227cafeaa1SWarner Losh 2237cafeaa1SWarner Losh /* 2247cafeaa1SWarner Losh * These routines from here on down are to implement the lua math 2257cafeaa1SWarner Losh * library, but that's not presently included by default. They are 2267cafeaa1SWarner Losh * little more than placeholders to allow compilation due to linkage 2277cafeaa1SWarner Losh * issues with upstream Lua. 2287cafeaa1SWarner Losh */ 2297cafeaa1SWarner Losh 2307cafeaa1SWarner Losh int64_t 2317cafeaa1SWarner Losh lstd_pow(int64_t x, int64_t y) 2327cafeaa1SWarner Losh { 2337cafeaa1SWarner Losh int64_t rv = 1; 2347cafeaa1SWarner Losh 2357cafeaa1SWarner Losh if (y < 0) 2367cafeaa1SWarner Losh return 0; 2377cafeaa1SWarner Losh rv = x; 2387cafeaa1SWarner Losh while (--y) 2397cafeaa1SWarner Losh rv *= x; 2407cafeaa1SWarner Losh 2417cafeaa1SWarner Losh return rv; 2427cafeaa1SWarner Losh } 2437cafeaa1SWarner Losh 2447cafeaa1SWarner Losh int64_t 2457cafeaa1SWarner Losh lstd_floor(int64_t x) 2467cafeaa1SWarner Losh { 2477cafeaa1SWarner Losh 2487cafeaa1SWarner Losh return (x); 2497cafeaa1SWarner Losh } 2507cafeaa1SWarner Losh 2517cafeaa1SWarner Losh int64_t 2527cafeaa1SWarner Losh lstd_fmod(int64_t a, int64_t b) 2537cafeaa1SWarner Losh { 2547cafeaa1SWarner Losh 2557cafeaa1SWarner Losh return (a % b); 2567cafeaa1SWarner Losh } 2577cafeaa1SWarner Losh 2587cafeaa1SWarner Losh /* 2597cafeaa1SWarner Losh * This can't be implemented, so maybe it should just abort. 2607cafeaa1SWarner Losh */ 2617cafeaa1SWarner Losh int64_t 2627cafeaa1SWarner Losh lstd_frexp(int64_t a, int *y) 2637cafeaa1SWarner Losh { 2647cafeaa1SWarner Losh *y = 0; 2657cafeaa1SWarner Losh 2667cafeaa1SWarner Losh return 0; 2677cafeaa1SWarner Losh } 268