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