aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--include/util/io.h67
-rw-r--r--src/eval.cc4
-rw-r--r--src/handler.cc19
-rw-r--r--src/util/io.cc33
5 files changed, 109 insertions, 15 deletions
diff --git a/.gitignore b/.gitignore
index 9922c48..a716061 100644
--- a/.gitignore
+++ b/.gitignore
@@ -70,3 +70,4 @@ Testing/
include/test.h
src/test.cc
+test/
diff --git a/include/util/io.h b/include/util/io.h
index aaeac02..4f55fec 100644
--- a/include/util/io.h
+++ b/include/util/io.h
@@ -12,6 +12,7 @@
#include <iostream>
#include <vector>
#include <string>
+#include <type_traits>
#include "global.h"
@@ -23,16 +24,80 @@ namespace ov4
struct LogVoidify { void operator&(std::ostream&) const {} };
inline constexpr int DECIMAL = 10;
-inline constexpr int LENGTH = 32;
+inline constexpr int NUMBER_LENGTH = 70; // even enough for binary
+// async-signal-safe
void safe_print(const char *s, bool ignore_wrap = false);
+
+// async-signal-safe
void safe_print(int x);
+
+// async-signal-safe
void safe_debug(const char *s, bool ignore_wrap = false);
+
+// async-signal-safe
void safe_debug(int x);
+
+// async-signal-safe
bool isnum(const char *s);
+
+// async-signal-safe
void reverse(char *str, int length);
+
+// async-signal-safe
char *itoa(int num, char* str, int base);
+// async-signal-safe
+// remove '\n' from the string
+// when replacemen = '\0', '\n' is deleted (instead of really replacing by '\0' )
+void wrap_eliminator(char *s, char replacement = '\0');
+
+// async-signal-safe
+void _write_helper(const char *s);
+
+template <typename T>
+void _safe_output_handler(T x)
+{
+ int errno_old = errno;
+
+ if constexpr (std::is_same_v<T, int>) // int
+ {
+ char buffer[MAXLINE];
+ itoa(x, buffer, DECIMAL);
+ _write_helper(buffer);
+ }
+ else if constexpr (std::is_same_v<T, char*> || std::is_same_v<T, const char*>) // C-style string
+ {
+ _write_helper(x);
+ }
+ else // ???
+ {
+ static_assert(false, "_safe_output_handler: unsopported type");
+ }
+
+ errno = errno_old;
+}
+
+inline void safe_output()
+{
+ ; // empty
+}
+
+
+// async-signal-safe output function
+// example:
+// safe_output("string", 123, variable);
+template <typename T, typename ...T_arg>
+void safe_output(T x, T_arg ...arg)
+{
+ int errno_old = errno;
+
+ _safe_output_handler(x);
+ safe_output(arg...);
+
+ errno = errno_old;
+}
+
void usage(void);
void unix_error(const char *msg);
void app_error(const char *msg);
diff --git a/src/eval.cc b/src/eval.cc
index c4862d2..3b3a3ba 100644
--- a/src/eval.cc
+++ b/src/eval.cc
@@ -70,8 +70,8 @@ void eval(char *cmdline)
execve(cmd_c, argv, environ);
- safe_print(cmdline, true);
- safe_print(": Command not found\n");
+ wrap_eliminator(cmdline);
+ cout << cmdline << ": Command not found" << endl;
exit(-1); // if no command is found
}
diff --git a/src/handler.cc b/src/handler.cc
index 2e966f6..77512ec 100644
--- a/src/handler.cc
+++ b/src/handler.cc
@@ -72,11 +72,7 @@ void sigchld_handler([[maybe_unused]] int sig)
if (WIFSIGNALED(status) || WIFSTOPPED(status))
{
int jid = pid2jid(pid);
- safe_print("Job [");
- safe_print(jid);
- safe_print("] (");
- safe_print(pid);
- safe_print(") ");
+ safe_output("Job [", jid, "] (", pid, ") ");
if (!WIFSTOPPED(status) && WTERMSIG(status) == SIGINT)
safe_print("terminated");
else if (WIFSTOPPED(status))
@@ -93,17 +89,17 @@ void sigchld_handler([[maybe_unused]] int sig)
if (WIFSTOPPED(status))
{
- safe_debug("suspended pid: ");
- safe_debug(pid);
- safe_debug("\n");
+ // safe_debug("suspended pid: ");
+ // safe_debug(pid);
+ // safe_debug("\n");
+ safe_output("Process suspended PID: ", pid, "\n");
sigset_t prev_inner;
block_all(&prev_inner);
job_suspend(pid);
sigprocmask(SIG_SETMASK, &prev_inner, nullptr);
}
else {
- safe_debug("terminated pid: ");
- safe_debug(pid);
+ safe_output("Process terminated PID: ", pid, "\n");
sigset_t prev_inner;
block_all(&prev_inner);
deletejob(pid);
@@ -182,7 +178,8 @@ int block_handler(sigset_t *prev)
void sigquit_handler([[maybe_unused]] int sig)
{
- printf("Terminating after receipt of SIGQUIT signal\n");
+ //printf("Terminating after receipt of SIGQUIT signal\n");
+ safe_output("Terminating after receipt of SIGQUIT signal\n");
exit(1);
}
diff --git a/src/util/io.cc b/src/util/io.cc
index 1fe37e5..09479e6 100644
--- a/src/util/io.cc
+++ b/src/util/io.cc
@@ -22,7 +22,7 @@ void safe_print(const char *s, bool ignore_wrap)
void safe_print(int x)
{
int errno_old = errno;
- char msg[LENGTH];
+ char msg[NUMBER_LENGTH];
itoa(x, msg, DECIMAL);
safe_print(msg);
errno = errno_old;
@@ -110,6 +110,37 @@ char *itoa(int num, char* str, int base)
return str;
}
+void wrap_eliminator(char *s, char replacement)
+{
+ if (replacement == '\0')
+ {
+ char *r = s;
+ char *w = s;
+ while (*r) {
+ if (*r != '\n')
+ *w++ = *r;
+ r++;
+ }
+ *w = '\0';
+ return;
+ }
+ size_t len = strlen(s);
+ for (size_t i = 0; i < len; i++)
+ if (s[i] == '\n')
+ s[i] = replacement;
+}
+
+void write_helper(const char *s)
+{
+ int errno_old = errno;
+
+ size_t len = strlen(s);
+ for (size_t i = 0; i < len; i++)
+ write(STDIN_FILENO, &s[i], 1);
+
+ errno = errno_old;
+}
+
/*
* usage - print a help message
*/