aboutsummaryrefslogtreecommitdiff
path: root/stand
diff options
context:
space:
mode:
Diffstat (limited to 'stand')
-rw-r--r--stand/liblua/lstd.c40
-rw-r--r--stand/liblua/lstd.h1
-rw-r--r--stand/liblua/lutils.c73
-rw-r--r--stand/libsa/stand.h3
4 files changed, 110 insertions, 7 deletions
diff --git a/stand/liblua/lstd.c b/stand/liblua/lstd.c
index b00abf203562..c71232ee1024 100644
--- a/stand/liblua/lstd.c
+++ b/stand/liblua/lstd.c
@@ -35,13 +35,32 @@ FILE *
fopen(const char *filename, const char *mode)
{
struct stat st;
- int fd;
+ int fd, m, o;
FILE *f;
- if (mode == NULL || mode[0] != 'r')
+ if (mode == NULL)
return NULL;
- fd = open(filename, O_RDONLY);
+ switch (*mode++) {
+ case 'r': /* open for reading */
+ m = O_RDONLY;
+ o = 0;
+ break;
+
+ case 'w': /* open for writing */
+ m = O_WRONLY;
+ /* These are not actually implemented yet */
+ o = O_CREAT | O_TRUNC;
+ break;
+
+ default: /* illegal mode */
+ return (NULL);
+ }
+
+ if (*mode == '+')
+ m = O_RDWR;
+
+ fd = open(filename, m | o);
if (fd < 0)
return NULL;
@@ -85,6 +104,21 @@ fread(void *ptr, size_t size, size_t count, FILE *stream)
return (r);
}
+size_t
+fwrite(const void *ptr, size_t size, size_t count, FILE *stream)
+{
+ ssize_t w;
+
+ if (stream == NULL || ptr == NULL)
+ return (0);
+ w = write(stream->fd, ptr, size * count);
+ if (w == -1)
+ return (0);
+
+ stream->offset += w;
+ return ((size_t)w);
+}
+
int
fclose(FILE *stream)
{
diff --git a/stand/liblua/lstd.h b/stand/liblua/lstd.h
index 5e47cff1d0c1..6f9eec2b40b9 100644
--- a/stand/liblua/lstd.h
+++ b/stand/liblua/lstd.h
@@ -51,6 +51,7 @@ typedef struct DIR
FILE *fopen(const char *filename, const char *mode);
FILE *freopen( const char *filename, const char *mode, FILE *stream);
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
+size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
int fclose(FILE *stream);
int ferror(FILE *stream);
int feof(FILE *stream);
diff --git a/stand/liblua/lutils.c b/stand/liblua/lutils.c
index 3b30520d92b8..38392b039688 100644
--- a/stand/liblua/lutils.c
+++ b/stand/liblua/lutils.c
@@ -165,15 +165,24 @@ lua_printc(lua_State *L)
static int
lua_openfile(lua_State *L)
{
- const char *str;
+ const char *mode, *str;
+ int nargs;
- if (lua_gettop(L) != 1) {
+ nargs = lua_gettop(L);
+ if (nargs < 1 || nargs > 2) {
lua_pushnil(L);
return 1;
}
str = lua_tostring(L, 1);
-
- FILE * f = fopen(str, "r");
+ mode = "r";
+ if (nargs > 1) {
+ mode = lua_tostring(L, 2);
+ if (mode == NULL) {
+ lua_pushnil(L);
+ return 1;
+ }
+ }
+ FILE * f = fopen(str, mode);
if (f != NULL) {
FILE ** ptr = (FILE**)lua_newuserdata(L, sizeof(FILE**));
*ptr = f;
@@ -237,6 +246,61 @@ lua_readfile(lua_State *L)
return 2;
}
+/*
+ * Implements io.write(file, ...)
+ * Any number of string and number arguments may be passed to it,
+ * and it will return the number of bytes written, or nil, an error string, and
+ * the errno.
+ */
+static int
+lua_writefile(lua_State *L)
+{
+ FILE **f;
+ const char *buf;
+ int i, nargs;
+ size_t bufsz, w, wrsz;
+
+ buf = NULL;
+ bufsz = 0;
+ w = 0;
+ wrsz = 0;
+ nargs = lua_gettop(L);
+ if (nargs < 2) {
+ errno = EINVAL;
+ return luaL_fileresult(L, 0, NULL);
+ }
+
+ f = (FILE**)lua_touserdata(L, 1);
+
+ if (f == NULL || *f == NULL) {
+ errno = EINVAL;
+ return luaL_fileresult(L, 0, NULL);
+ }
+
+ /* Do a validation pass first */
+ for (i = 0; i < nargs - 1; i++) {
+ /*
+ * With Lua's API, lua_isstring really checks if the argument
+ * is a string or a number. The latter will be implicitly
+ * converted to a string by our later call to lua_tolstring.
+ */
+ if (!lua_isstring(L, i + 2)) {
+ errno = EINVAL;
+ return luaL_fileresult(L, 0, NULL);
+ }
+ }
+ for (i = 0; i < nargs - 1; i++) {
+ /* We've already validated; there's no chance of failure */
+ buf = lua_tolstring(L, i + 2, &bufsz);
+ wrsz = fwrite(buf, 1, bufsz, *f);
+ if (wrsz < bufsz)
+ return luaL_fileresult(L, 0, NULL);
+ w += wrsz;
+ }
+ lua_pushinteger(L, w);
+ return 1;
+}
+
#define REG_SIMPLE(n) { #n, lua_ ## n }
static const struct luaL_Reg loaderlib[] = {
REG_SIMPLE(delay),
@@ -257,6 +321,7 @@ static const struct luaL_Reg iolib[] = {
REG_SIMPLE(ischar),
{ "open", lua_openfile },
{ "read", lua_readfile },
+ { "write", lua_writefile },
{ NULL, NULL },
};
#undef REG_SIMPLE
diff --git a/stand/libsa/stand.h b/stand/libsa/stand.h
index 614eaa65f67f..677aff5a1fdb 100644
--- a/stand/libsa/stand.h
+++ b/stand/libsa/stand.h
@@ -286,6 +286,9 @@ extern int open(const char *, int);
#define O_RDONLY 0x0
#define O_WRONLY 0x1
#define O_RDWR 0x2
+/* NOT IMPLEMENTED */
+#define O_CREAT 0x0200 /* create if nonexistent */
+#define O_TRUNC 0x0400 /* truncate to zero length */
extern int close(int);
extern void closeall(void);
extern ssize_t read(int, void *, size_t);