xref: /freebsd/stand/liblua/lstd.c (revision 3e15b01d6914c927e37d1699645783acf286655c)
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