/*-1* Copyright (c) 2014 Pedro Souza <[email protected]>2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*25*/2627#include "lstd.h"28#include "math.h"2930#ifdef LOADER_VERIEXEC31#include <verify_file.h>32#endif3334FILE *35fopen(const char *filename, const char *mode)36{37struct stat st;38int fd, m, o;39FILE *f;4041if (mode == NULL)42return NULL;4344switch (*mode++) {45case 'r': /* open for reading */46m = O_RDONLY;47o = 0;48break;4950case 'w': /* open for writing */51m = O_WRONLY;52/* These are not actually implemented yet */53o = O_CREAT | O_TRUNC;54break;5556default: /* illegal mode */57return (NULL);58}5960if (*mode == '+')61m = O_RDWR;6263fd = open(filename, m | o);64if (fd < 0)65return NULL;6667f = malloc(sizeof(FILE));68if (f == NULL) {69close(fd);70return NULL;71}7273if (fstat(fd, &st) != 0) {74free(f);75close(fd);76return (NULL);77}7879#ifdef LOADER_VERIEXEC80/* only regular files and only reading makes sense */81if (S_ISREG(st.st_mode) && !(m & O_WRONLY)) {82if (verify_file(fd, filename, 0, VE_GUESS, __func__) < 0) {83free(f);84close(fd);85return (NULL);86}87}88#endif8990f->fd = fd;91f->offset = 0;92f->size = st.st_size;9394return (f);95}969798FILE *99freopen(const char *filename, const char *mode, FILE *stream)100{101fclose(stream);102return (fopen(filename, mode));103}104105size_t106fread(void *ptr, size_t size, size_t count, FILE *stream)107{108size_t r;109110if (stream == NULL)111return 0;112r = (size_t)read(stream->fd, ptr, size * count);113stream->offset += r;114115return (r);116}117118size_t119fwrite(const void *ptr, size_t size, size_t count, FILE *stream)120{121ssize_t w;122123if (stream == NULL || ptr == NULL)124return (0);125w = write(stream->fd, ptr, size * count);126if (w == -1)127return (0);128129stream->offset += w;130return ((size_t)w);131}132133int134fclose(FILE *stream)135{136if (stream == NULL)137return EOF;138close(stream->fd);139free(stream);140141return (0);142}143144int145ferror(FILE *stream)146{147148return (stream == NULL || stream->fd < 0);149}150151int152feof(FILE *stream)153{154155if (stream == NULL)156return 1;157158return (stream->offset >= stream->size);159}160161int162getc(FILE *stream)163{164char ch;165size_t r;166167if (stream == NULL)168return EOF;169r = read(stream->fd, &ch, 1);170if (r == 1)171return ch;172return EOF;173}174175DIR *176opendir(const char *name)177{178DIR *dp;179int fd;180181fd = open(name, O_RDONLY);182if (fd < 0)183return NULL;184dp = fdopendir(fd);185if (dp == NULL)186close(fd);187return dp;188}189190DIR *191fdopendir(int fd)192{193DIR *dp;194195dp = malloc(sizeof(*dp));196if (dp == NULL)197return NULL;198dp->fd = fd;199return dp;200}201202int203closedir(DIR *dp)204{205close(dp->fd);206dp->fd = -1;207free(dp);208return 0;209}210211void212luai_writestring(const char *s, int i)213{214215while (i-- > 0)216putchar(*s++);217}218219/*220* These routines from here on down are to implement the lua math221* library, but that's not presently included by default. They are222* little more than placeholders to allow compilation due to linkage223* issues with upstream Lua.224*/225226int64_t227lstd_pow(int64_t x, int64_t y)228{229int64_t rv = 1;230231if (y < 0)232return 0;233rv = x;234while (--y)235rv *= x;236237return rv;238}239240int64_t241lstd_floor(int64_t x)242{243244return (x);245}246247int64_t248lstd_fmod(int64_t a, int64_t b)249{250251return (a % b);252}253254/*255* This can't be implemented, so maybe it should just abort.256*/257int64_t258lstd_frexp(int64_t a, int *y)259{260*y = 0;261262return 0;263}264265266