aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lua_api.c63
-rw-r--r--src/lua_api.h27
-rw-r--r--src/lush.c42
-rw-r--r--src/lush.h13
4 files changed, 128 insertions, 17 deletions
diff --git a/src/lua_api.c b/src/lua_api.c
new file mode 100644
index 0000000..becd2b7
--- /dev/null
+++ b/src/lua_api.c
@@ -0,0 +1,63 @@
+/*
+Copyright (c) 2024, Lance Borden
+All rights reserved.
+
+This software is licensed under the BSD 3-Clause License.
+You may obtain a copy of the license at:
+https://opensource.org/licenses/BSD-3-Clause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted under the conditions stated in the BSD 3-Clause
+License.
+
+THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTIES,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+*/
+
+#include "lua_api.h"
+#include "lush.h"
+#include <lauxlib.h>
+#include <lua.h>
+#include <lualib.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+// -- script execution --
+void lua_load_script(lua_State *L, const char *script) {
+ if (luaL_dofile(L, script) != LUA_OK) {
+ printf("[C] Error reading script\n");
+ luaL_error(L, "Error: %s\n", lua_tostring(L, -1));
+ }
+}
+
+// -- C funtions --
+static void execute_command(lua_State *L, const char *line) {
+ int status = 0;
+ char **commands = lush_split_pipes((char *)line);
+ char ***args = lush_split_args(commands, &status);
+ if (status == -1) {
+ fprintf(stderr, "lush: Expected end of quoted string\n");
+ } else if (lush_run(L, args, status) == 0) {
+ exit(1);
+ }
+
+ for (int i = 0; args[i]; i++) {
+ free(args[i]);
+ }
+ free(args);
+ free(commands);
+}
+
+// -- Lua wrappers --
+static int l_execute_command(lua_State *L) {
+ const char *command = luaL_checkstring(L, 1);
+ execute_command(L, command);
+ return 0;
+}
+
+// -- register Lua functions --
+
+void lua_register_api(lua_State *L) {
+ lua_register(L, "exec", l_execute_command);
+}
diff --git a/src/lua_api.h b/src/lua_api.h
new file mode 100644
index 0000000..915b4ab
--- /dev/null
+++ b/src/lua_api.h
@@ -0,0 +1,27 @@
+/*
+Copyright (c) 2024, Lance Borden
+All rights reserved.
+
+This software is licensed under the BSD 3-Clause License.
+You may obtain a copy of the license at:
+https://opensource.org/licenses/BSD-3-Clause
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted under the conditions stated in the BSD 3-Clause
+License.
+
+THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTIES,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+*/
+
+#ifndef LUA_API_H
+#define LUA_API_H
+
+#include <lua.h>
+
+void lua_load_script(lua_State *L, const char *script);
+void lua_register_api(lua_State *L);
+
+#endif
+
diff --git a/src/lush.c b/src/lush.c
index 542aaf4..0b1c21b 100644
--- a/src/lush.c
+++ b/src/lush.c
@@ -17,6 +17,10 @@ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#include "lush.h"
#include "help.h"
+#include "lauxlib.h"
+#include "lua.h"
+#include "lua_api.h"
+#include "lualib.h"
#include <bits/time.h>
#include <linux/limits.h>
#include <pwd.h>
@@ -34,14 +38,14 @@ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#define BUFFER_SIZE 1024
// -- builtin functions --
-char *builtin_strs[] = {"cd", "help", "exit", "time"};
+char *builtin_strs[] = {"cd", "help", "exit", "time", "lush"};
-int (*builtin_func[])(char ***) = {&lush_cd, &lush_help, &lush_exit,
- &lush_time};
+int (*builtin_func[])(lua_State *, char ***) = {
+ &lush_cd, &lush_help, &lush_exit, &lush_time, &lush_lush};
int lush_num_builtins() { return sizeof(builtin_strs) / sizeof(char *); }
-int lush_cd(char ***args) {
+int lush_cd(lua_State *L, char ***args) {
uid_t uid = getuid();
struct passwd *pw = getpwuid(uid);
if (!pw) {
@@ -75,7 +79,7 @@ int lush_cd(char ***args) {
return 1;
}
-int lush_help(char ***args) {
+int lush_help(lua_State *L, char ***args) {
printf("%s\n", lush_get_help_text());
#ifdef LUSH_VERSION
printf("Lunar Shell, version %s\n", LUSH_VERSION);
@@ -89,9 +93,9 @@ int lush_help(char ***args) {
return 1;
}
-int lush_exit(char ***args) { return 0; }
+int lush_exit(lua_State *L, char ***args) { return 0; }
-int lush_time(char ***args) {
+int lush_time(lua_State *L, char ***args) {
// advance past time command
args[0]++;
@@ -106,7 +110,7 @@ int lush_time(char ***args) {
double elapsed_time;
clock_gettime(CLOCK_MONOTONIC, &start);
- int rc = lush_run(args, i);
+ int rc = lush_run(L, args, i);
clock_gettime(CLOCK_MONOTONIC, &end);
elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0 +
@@ -118,6 +122,16 @@ int lush_time(char ***args) {
return rc;
}
+int lush_lush(lua_State *L, char ***args) {
+ // run the lua file given
+ args[0]++;
+ lua_load_script(L, *args[0]);
+
+ // return pointer back for free()
+ args[0]--;
+ return 1;
+}
+
// -- shell utility --
// -- static helpers for input --
@@ -423,7 +437,7 @@ void lush_execute_command(char **args, int input_fd, int output_fd) {
}
}
-int lush_run(char ***commands, int num_commands) {
+int lush_run(lua_State *L, char ***commands, int num_commands) {
if (commands[0][0] == NULL) {
// no command given
return 1;
@@ -432,7 +446,7 @@ int lush_run(char ***commands, int num_commands) {
// check shell builtins
for (int i = 0; i < lush_num_builtins(); i++) {
if (strcmp(commands[0][0], builtin_strs[i]) == 0) {
- return ((*builtin_func[i])(commands));
+ return ((*builtin_func[i])(L, commands));
}
}
@@ -440,6 +454,9 @@ int lush_run(char ***commands, int num_commands) {
}
int main() {
+ lua_State *L = luaL_newstate();
+ luaL_openlibs(L);
+ lua_register_api(L);
// eat ^C in main
struct sigaction sa;
sa.sa_handler = SIG_IGN;
@@ -452,16 +469,16 @@ int main() {
// Prompt
print_prompt();
char *line = lush_read_line();
+ printf("\n");
if (line == NULL || strlen(line) == 0) {
free(line);
continue;
}
- printf("\n");
char **commands = lush_split_pipes(line);
char ***args = lush_split_args(commands, &status);
if (status == -1) {
fprintf(stderr, "lush: Expected end of quoted string\n");
- } else if (lush_run(args, status) == 0) {
+ } else if (lush_run(L, args, status) == 0) {
exit(1);
}
@@ -472,4 +489,5 @@ int main() {
free(commands);
free(line);
}
+ lua_close(L);
}
diff --git a/src/lush.h b/src/lush.h
index 65846b0..ef60692 100644
--- a/src/lush.h
+++ b/src/lush.h
@@ -18,14 +18,17 @@ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#ifndef LUSH_H
#define LUSH_H
-int lush_cd(char ***args);
-int lush_help(char ***args);
-int lush_exit(char ***args);
-int lush_time(char ***args);
+#include <lua.h>
+
+int lush_cd(lua_State *L, char ***args);
+int lush_help(lua_State *L, char ***args);
+int lush_exit(lua_State *L, char ***args);
+int lush_time(lua_State *L, char ***args);
+int lush_lush(lua_State *L, char ***args);
int lush_num_builtins();
-int lush_run(char ***commands, int num_commands);
+int lush_run(lua_State *L, char ***commands, int num_commands);
char *lush_read_line();
char **lush_split_pipes(char *line);