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 "lstd.h"
297cafeaa1SWarner Losh #include "math.h"
307cafeaa1SWarner Losh
318df8b2d3SSimon J. Gerraty #ifdef LOADER_VERIEXEC
328df8b2d3SSimon J. Gerraty #include <verify_file.h>
338df8b2d3SSimon J. Gerraty #endif
348df8b2d3SSimon J. Gerraty
357cafeaa1SWarner Losh FILE *
fopen(const char * filename,const char * mode)367cafeaa1SWarner Losh fopen(const char *filename, const char *mode)
377cafeaa1SWarner Losh {
387cafeaa1SWarner Losh struct stat st;
3982c85a42SKyle Evans int fd, m, o;
407cafeaa1SWarner Losh FILE *f;
417cafeaa1SWarner Losh
4282c85a42SKyle Evans if (mode == NULL)
437cafeaa1SWarner Losh return NULL;
447cafeaa1SWarner Losh
4582c85a42SKyle Evans switch (*mode++) {
4682c85a42SKyle Evans case 'r': /* open for reading */
4782c85a42SKyle Evans m = O_RDONLY;
4882c85a42SKyle Evans o = 0;
4982c85a42SKyle Evans break;
5082c85a42SKyle Evans
5182c85a42SKyle Evans case 'w': /* open for writing */
5282c85a42SKyle Evans m = O_WRONLY;
5382c85a42SKyle Evans /* These are not actually implemented yet */
5482c85a42SKyle Evans o = O_CREAT | O_TRUNC;
5582c85a42SKyle Evans break;
5682c85a42SKyle Evans
5782c85a42SKyle Evans default: /* illegal mode */
5882c85a42SKyle Evans return (NULL);
5982c85a42SKyle Evans }
6082c85a42SKyle Evans
6182c85a42SKyle Evans if (*mode == '+')
6282c85a42SKyle Evans m = O_RDWR;
6382c85a42SKyle Evans
6482c85a42SKyle Evans fd = open(filename, m | o);
657cafeaa1SWarner Losh if (fd < 0)
667cafeaa1SWarner Losh return NULL;
677cafeaa1SWarner Losh
687cafeaa1SWarner Losh f = malloc(sizeof(FILE));
697cafeaa1SWarner Losh if (f == NULL) {
707cafeaa1SWarner Losh close(fd);
717cafeaa1SWarner Losh return NULL;
727cafeaa1SWarner Losh }
737cafeaa1SWarner Losh
747cafeaa1SWarner Losh if (fstat(fd, &st) != 0) {
757cafeaa1SWarner Losh free(f);
767cafeaa1SWarner Losh close(fd);
777cafeaa1SWarner Losh return (NULL);
787cafeaa1SWarner Losh }
797cafeaa1SWarner Losh
808df8b2d3SSimon J. Gerraty #ifdef LOADER_VERIEXEC
818df8b2d3SSimon J. Gerraty /* only regular files and only reading makes sense */
828df8b2d3SSimon J. Gerraty if (S_ISREG(st.st_mode) && !(m & O_WRONLY)) {
83*212e103fSSimon J. Gerraty if (verify_file(fd, filename, 0, VE_GUESS, __func__) < 0) {
848df8b2d3SSimon J. Gerraty free(f);
858df8b2d3SSimon J. Gerraty close(fd);
868df8b2d3SSimon J. Gerraty return (NULL);
878df8b2d3SSimon J. Gerraty }
888df8b2d3SSimon J. Gerraty }
898df8b2d3SSimon J. Gerraty #endif
908df8b2d3SSimon J. Gerraty
917cafeaa1SWarner Losh f->fd = fd;
927cafeaa1SWarner Losh f->offset = 0;
937cafeaa1SWarner Losh f->size = st.st_size;
947cafeaa1SWarner Losh
957cafeaa1SWarner Losh return (f);
967cafeaa1SWarner Losh }
977cafeaa1SWarner Losh
987cafeaa1SWarner Losh
997cafeaa1SWarner Losh FILE *
freopen(const char * filename,const char * mode,FILE * stream)1007cafeaa1SWarner Losh freopen(const char *filename, const char *mode, FILE *stream)
1017cafeaa1SWarner Losh {
1027cafeaa1SWarner Losh fclose(stream);
1037cafeaa1SWarner Losh return (fopen(filename, mode));
1047cafeaa1SWarner Losh }
1057cafeaa1SWarner Losh
1067cafeaa1SWarner Losh size_t
fread(void * ptr,size_t size,size_t count,FILE * stream)1077cafeaa1SWarner Losh fread(void *ptr, size_t size, size_t count, FILE *stream)
1087cafeaa1SWarner Losh {
1097cafeaa1SWarner Losh size_t r;
1107cafeaa1SWarner Losh
1117cafeaa1SWarner Losh if (stream == NULL)
1127cafeaa1SWarner Losh return 0;
1137cafeaa1SWarner Losh r = (size_t)read(stream->fd, ptr, size * count);
1147cafeaa1SWarner Losh stream->offset += r;
1157cafeaa1SWarner Losh
1167cafeaa1SWarner Losh return (r);
1177cafeaa1SWarner Losh }
1187cafeaa1SWarner Losh
11982c85a42SKyle Evans size_t
fwrite(const void * ptr,size_t size,size_t count,FILE * stream)12082c85a42SKyle Evans fwrite(const void *ptr, size_t size, size_t count, FILE *stream)
12182c85a42SKyle Evans {
12282c85a42SKyle Evans ssize_t w;
12382c85a42SKyle Evans
12482c85a42SKyle Evans if (stream == NULL || ptr == NULL)
12582c85a42SKyle Evans return (0);
12682c85a42SKyle Evans w = write(stream->fd, ptr, size * count);
12782c85a42SKyle Evans if (w == -1)
12882c85a42SKyle Evans return (0);
12982c85a42SKyle Evans
13082c85a42SKyle Evans stream->offset += w;
13182c85a42SKyle Evans return ((size_t)w);
13282c85a42SKyle Evans }
13382c85a42SKyle Evans
1347cafeaa1SWarner Losh int
fclose(FILE * stream)1357cafeaa1SWarner Losh fclose(FILE *stream)
1367cafeaa1SWarner Losh {
1377cafeaa1SWarner Losh if (stream == NULL)
1387cafeaa1SWarner Losh return EOF;
1397cafeaa1SWarner Losh close(stream->fd);
1407cafeaa1SWarner Losh free(stream);
1417cafeaa1SWarner Losh
1427cafeaa1SWarner Losh return (0);
1437cafeaa1SWarner Losh }
1447cafeaa1SWarner Losh
1457cafeaa1SWarner Losh int
ferror(FILE * stream)1467cafeaa1SWarner Losh ferror(FILE *stream)
1477cafeaa1SWarner Losh {
1487cafeaa1SWarner Losh
1497cafeaa1SWarner Losh return (stream == NULL || stream->fd < 0);
1507cafeaa1SWarner Losh }
1517cafeaa1SWarner Losh
1527cafeaa1SWarner Losh int
feof(FILE * stream)1537cafeaa1SWarner Losh feof(FILE *stream)
1547cafeaa1SWarner Losh {
1557cafeaa1SWarner Losh
1567cafeaa1SWarner Losh if (stream == NULL)
1577cafeaa1SWarner Losh return 1;
1587cafeaa1SWarner Losh
1597cafeaa1SWarner Losh return (stream->offset >= stream->size);
1607cafeaa1SWarner Losh }
1617cafeaa1SWarner Losh
1627cafeaa1SWarner Losh int
getc(FILE * stream)1637cafeaa1SWarner Losh getc(FILE *stream)
1647cafeaa1SWarner Losh {
1657cafeaa1SWarner Losh char ch;
1667cafeaa1SWarner Losh size_t r;
1677cafeaa1SWarner Losh
1687cafeaa1SWarner Losh if (stream == NULL)
1697cafeaa1SWarner Losh return EOF;
1707cafeaa1SWarner Losh r = read(stream->fd, &ch, 1);
1717cafeaa1SWarner Losh if (r == 1)
1727cafeaa1SWarner Losh return ch;
1737cafeaa1SWarner Losh return EOF;
1747cafeaa1SWarner Losh }
1757cafeaa1SWarner Losh
176b216e997SConrad Meyer DIR *
opendir(const char * name)177b216e997SConrad Meyer opendir(const char *name)
178b216e997SConrad Meyer {
179b216e997SConrad Meyer DIR *dp;
180b216e997SConrad Meyer int fd;
181b216e997SConrad Meyer
182b216e997SConrad Meyer fd = open(name, O_RDONLY);
183b216e997SConrad Meyer if (fd < 0)
184b216e997SConrad Meyer return NULL;
185b216e997SConrad Meyer dp = fdopendir(fd);
186b216e997SConrad Meyer if (dp == NULL)
187b216e997SConrad Meyer close(fd);
188b216e997SConrad Meyer return dp;
189b216e997SConrad Meyer }
190b216e997SConrad Meyer
191b216e997SConrad Meyer DIR *
fdopendir(int fd)192b216e997SConrad Meyer fdopendir(int fd)
193b216e997SConrad Meyer {
194b216e997SConrad Meyer DIR *dp;
195b216e997SConrad Meyer
196b216e997SConrad Meyer dp = malloc(sizeof(*dp));
197b216e997SConrad Meyer if (dp == NULL)
198b216e997SConrad Meyer return NULL;
199b216e997SConrad Meyer dp->fd = fd;
200b216e997SConrad Meyer return dp;
201b216e997SConrad Meyer }
202b216e997SConrad Meyer
203b216e997SConrad Meyer int
closedir(DIR * dp)204b216e997SConrad Meyer closedir(DIR *dp)
205b216e997SConrad Meyer {
206b216e997SConrad Meyer close(dp->fd);
207b216e997SConrad Meyer dp->fd = -1;
208b216e997SConrad Meyer free(dp);
209b216e997SConrad Meyer return 0;
210b216e997SConrad Meyer }
211b216e997SConrad Meyer
2127cafeaa1SWarner Losh void
luai_writestring(const char * s,int i)2137cafeaa1SWarner Losh luai_writestring(const char *s, int i)
2147cafeaa1SWarner Losh {
2157cafeaa1SWarner Losh
2167cafeaa1SWarner Losh while (i-- > 0)
2177cafeaa1SWarner Losh putchar(*s++);
2187cafeaa1SWarner Losh }
2197cafeaa1SWarner Losh
2207cafeaa1SWarner Losh /*
2217cafeaa1SWarner Losh * These routines from here on down are to implement the lua math
2227cafeaa1SWarner Losh * library, but that's not presently included by default. They are
2237cafeaa1SWarner Losh * little more than placeholders to allow compilation due to linkage
2247cafeaa1SWarner Losh * issues with upstream Lua.
2257cafeaa1SWarner Losh */
2267cafeaa1SWarner Losh
2277cafeaa1SWarner Losh int64_t
lstd_pow(int64_t x,int64_t y)2287cafeaa1SWarner Losh lstd_pow(int64_t x, int64_t y)
2297cafeaa1SWarner Losh {
2307cafeaa1SWarner Losh int64_t rv = 1;
2317cafeaa1SWarner Losh
2327cafeaa1SWarner Losh if (y < 0)
2337cafeaa1SWarner Losh return 0;
2347cafeaa1SWarner Losh rv = x;
2357cafeaa1SWarner Losh while (--y)
2367cafeaa1SWarner Losh rv *= x;
2377cafeaa1SWarner Losh
2387cafeaa1SWarner Losh return rv;
2397cafeaa1SWarner Losh }
2407cafeaa1SWarner Losh
2417cafeaa1SWarner Losh int64_t
lstd_floor(int64_t x)2427cafeaa1SWarner Losh lstd_floor(int64_t x)
2437cafeaa1SWarner Losh {
2447cafeaa1SWarner Losh
2457cafeaa1SWarner Losh return (x);
2467cafeaa1SWarner Losh }
2477cafeaa1SWarner Losh
2487cafeaa1SWarner Losh int64_t
lstd_fmod(int64_t a,int64_t b)2497cafeaa1SWarner Losh lstd_fmod(int64_t a, int64_t b)
2507cafeaa1SWarner Losh {
2517cafeaa1SWarner Losh
2527cafeaa1SWarner Losh return (a % b);
2537cafeaa1SWarner Losh }
2547cafeaa1SWarner Losh
2557cafeaa1SWarner Losh /*
2567cafeaa1SWarner Losh * This can't be implemented, so maybe it should just abort.
2577cafeaa1SWarner Losh */
2587cafeaa1SWarner Losh int64_t
lstd_frexp(int64_t a,int * y)2597cafeaa1SWarner Losh lstd_frexp(int64_t a, int *y)
2607cafeaa1SWarner Losh {
2617cafeaa1SWarner Losh *y = 0;
2627cafeaa1SWarner Losh
2637cafeaa1SWarner Losh return 0;
2647cafeaa1SWarner Losh }
265