PatchworkOS  3984a1d
A non-POSIX operating system.
Loading...
Searching...
No Matches
interactive.c
Go to the documentation of this file.
1#include "interactive.h"
2#include "ansi.h"
3#include "history.h"
4#include "pipeline.h"
5
6#include <errno.h>
7#include <signal.h>
8#include <stdatomic.h>
9#include <stdbool.h>
10#include <stdio.h>
11#include <string.h>
12#include <sys/defs.h>
13#include <sys/io.h>
14#include <sys/kbd.h>
15#include <sys/proc.h>
16#include <threads.h>
17
18static ansi_t ansi;
20static char buffer[MAX_PATH];
22
24{
25 UNUSED(sig);
26
27 // Do nothing, only child processes should be interrupted.
28}
29
30static void interactive_prompt(void)
31{
32 char cwd[MAX_PATH] = {0};
33 if (readfile("/proc/self/cwd", cwd, MAX_PATH - 1, 0) == ERR)
34 {
35 strcpy(cwd, "?");
36 }
37 printf("\n\033[32m%s\n\033[92m>\033[m ", cwd);
39}
40
41static void interactive_execute(void)
42{
43 if (pos == 0)
44 {
46 return;
47 }
48
50
53 {
55 return;
56 }
57
60
61 if (strlen(pipeline.status) > 0 && strcmp(pipeline.status, "0") != 0 && strcmp(pipeline.status, "-1") != 0)
62 {
63 int status;
64 if (sscanf(pipeline.status, "%d", &status) == 1)
65 {
66 if (status > 0 && status < EMAX)
67 {
68 printf("shell: %s\n", strerror(status));
69 }
70 else if (status < 0 && -status > 0 && -status < EMAX)
71 {
72 printf("shell: %s\n", strerror(-status));
73 }
74 else
75 {
76 printf("shell: %llu\n", status);
77 }
78 }
79 else
80 {
81 printf("shell: %s\n", pipeline.status);
82 }
83 }
84
86
88}
89
91{
92 if (result->type == ANSI_PRINTABLE)
93 {
94 if (pos >= MAX_PATH - 1)
95 {
96 return;
97 }
98 memmove(&buffer[pos + 1], &buffer[pos], MAX_PATH - pos - 1);
99 buffer[pos++] = result->printable;
100 printf("%c\033[s%s\033[u", result->printable, &buffer[pos]);
101 fflush(stdout);
102 return;
103 }
104
105 switch (result->type)
106 {
107 case ANSI_BACKSPACE:
108 if (pos == 0)
109 {
110 break;
111 }
112 memmove(&buffer[pos - 1], &buffer[pos], MAX_PATH - pos + 1);
113 buffer[MAX_PATH - 1] = '\0';
114 pos--;
115 // Move left, save cursor, print rest of line, clear to end, restore cursor
116 printf("\033[1D\033[s%s\033[K\033[u", &buffer[pos]);
117 fflush(stdout);
118 break;
119 case ANSI_NEWLINE:
120 printf("\n");
122 printf("\033[0m\033[?25h"); // Reset colors and cursor
123 fflush(stdout);
125 pos = 0;
126 break;
127 case ANSI_TAB:
128 /// @todo Implement tab completion
129 break;
130 case ANSI_ARROW_UP:
131 {
132 const char* previous = history_previous(&history);
133 if (previous == NULL)
134 {
135 break;
136 }
137 while (pos > 0) // Cant use \r because of prompt
138 {
139 pos--;
140 printf("\033[D");
141 }
143 buffer[MAX_PATH - 1] = '\0';
144 pos = strlen(buffer);
145 printf("\033[K%s", buffer);
146 fflush(stdout);
147 }
148 break;
149 case ANSI_ARROW_DOWN:
150 {
151 const char* next = history_next(&history);
152 while (pos > 0) // Cant use \r because of prompt
153 {
154 pos--;
155 printf("\033[D");
156 }
157 printf("\033[K");
158 if (next == NULL)
159 {
161 pos = 0;
162 fflush(stdout);
163 break;
164 }
166 buffer[MAX_PATH - 1] = '\0';
167 pos = strlen(buffer);
168 printf("%s", buffer);
169 fflush(stdout);
170 }
171 break;
172 case ANSI_ARROW_RIGHT:
173 if (pos < strlen(buffer))
174 {
175 pos++;
176 printf("\033[C");
177 fflush(stdout);
178 }
179 break;
180 case ANSI_ARROW_LEFT:
181 if (pos > 0)
182 {
183 pos--;
184 printf("\033[D");
185 fflush(stdout);
186 }
187 break;
188 case ANSI_HOME:
189 while (pos > 0)
190 {
191 pos--;
192 printf("\033[D");
193 }
194 fflush(stdout);
195 break;
196 case ANSI_END:
197 while (pos < strlen(buffer))
198 {
199 pos++;
200 printf("\033[C");
201 }
202 fflush(stdout);
203 break;
204 case ANSI_CTRL_C:
205 break;
206 default:
207 break;
208 }
209}
210
211static void interactive_handle_input(const char* input, uint64_t length)
212{
213 for (uint64_t i = 0; i < length; i++)
214 {
215 ansi_result_t result;
216 if (ansi_parse(&ansi, input[i], &result) == ERR)
217 {
218 continue;
219 }
220
221 if (result.type == ANSI_STILL_PARSING)
222 {
223 continue;
224 }
225
227 }
228}
229
231{
233 {
234 _exit(F("shell: failed to set SIGINT handler (%s)\n", strerror(errno)));
235 }
236
237 printf("Welcome to the PatchworkOS Shell!\n");
238 printf("Type \033[92mhelp\033[m for information on how to use the shell.\n");
239
241
242 ansi_init(&ansi);
245 pos = 0;
246
247 while (true)
248 {
249 char buffer[MAX_PATH];
251 if (readCount == ERR)
252 {
253 printf("shell: failed to read input (%s)\n", strerror(errno));
255 }
256
258 }
259}
#define MAX_PATH
Maximum length of filepaths.
Definition MAX_PATH.h:11
void ansi_init(ansi_t *ansi)
Definition ansi.c:6
uint64_t ansi_parse(ansi_t *ansi, char input, ansi_result_t *result)
Definition ansi.c:11
int64_t y
Definition main.c:153
#define EMAX
Maximum value for all error codes (not inclusive)
Definition errno.h:692
#define errno
Error number variable.
Definition errno.h:27
#define SIG_ERR
Definition signal.h:33
#define SIGINT
Definition signal.h:27
_PUBLIC sighandler_t signal(int sig, sighandler_t func)
Definition signal.c:5
#define UNUSED(x)
Mark a variable as unused.
Definition defs.h:100
#define F(format,...)
Allocates a formatted string on the stack.
Definition io.h:66
size_t readfile(const char *path, void *buffer, size_t count, size_t offset)
Wrapper for reading a file directly using a path.
Definition readfile.c:3
size_t read(fd_t fd, void *buffer, size_t count)
System call for reading from files.
Definition read.c:8
#define STDOUT_FILENO
Standard output file descriptor.
Definition io.h:35
#define STDERR_FILENO
Standard error file descriptor.
Definition io.h:36
#define RETRY_EINTR(expr)
Macro to automatically retry a function that returns an integer if it errors and errno == EINTR.
Definition io.h:601
#define STDIN_FILENO
Standard input file descriptor.
Definition io.h:34
_NORETURN void _exit(const char *status)
System call that handles pending notes for the current thread.
Definition _exit.c:7
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
const char * history_previous(history_t *history)
Definition history.c:60
void history_push(history_t *history, const char *entry)
Definition history.c:20
void history_init(history_t *history)
Definition history.c:6
const char * history_next(history_t *history)
Definition history.c:48
static history_t history
Definition interactive.c:19
static ansi_t ansi
Definition interactive.c:18
static uint64_t pos
Definition interactive.c:21
static void interactive_execute(void)
Definition interactive.c:41
void interactive_shell(void)
static void interactive_handle_ansi(ansi_result_t *result)
Definition interactive.c:90
static void interactive_handle_input(const char *input, uint64_t length)
static void interactive_sigint_handler(int sig)
Definition interactive.c:23
static void interactive_prompt(void)
Definition interactive.c:30
static char buffer[MAX_PATH]
Definition interactive.c:20
void pipeline_deinit(pipeline_t *pipeline)
Definition pipeline.c:264
void pipeline_wait(pipeline_t *pipeline)
Definition pipeline.c:435
uint64_t pipeline_init(pipeline_t *pipeline, const char *cmdline, fd_t stdin, fd_t stdout, fd_t stderr)
Definition pipeline.c:13
void pipeline_execute(pipeline_t *pipeline)
Definition pipeline.c:427
@ ANSI_BACKSPACE
Definition ansi.h:20
@ ANSI_CTRL_C
Definition ansi.h:32
@ ANSI_HOME
Definition ansi.h:29
@ ANSI_ARROW_DOWN
Definition ansi.h:24
@ ANSI_NEWLINE
Definition ansi.h:21
@ ANSI_END
Definition ansi.h:30
@ ANSI_TAB
Definition ansi.h:22
@ ANSI_STILL_PARSING
Definition ansi.h:18
@ ANSI_PRINTABLE
Definition ansi.h:19
@ ANSI_ARROW_UP
Definition ansi.h:23
@ ANSI_ARROW_RIGHT
Definition ansi.h:26
@ ANSI_ARROW_LEFT
Definition ansi.h:25
static atomic_long next
Definition main.c:12
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
_PUBLIC int sscanf(const char *_RESTRICT s, const char *_RESTRICT format,...)
Definition sscanf.c:4
_PUBLIC int fflush(FILE *stream)
Definition fflush.c:5
_PUBLIC int printf(const char *_RESTRICT format,...)
Definition printf.c:3
FILE * stdout
Definition std_streams.c:18
_PUBLIC _NORETURN void exit(int status)
Definition exit.c:7
#define EXIT_FAILURE
Definition stdlib.h:47
_PUBLIC char * strerror(int errnum)
Definition strerror.c:6
_PUBLIC void * memmove(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
_PUBLIC char * strncpy(char *_RESTRICT s1, const char *_RESTRICT s2, size_t n)
Definition strncpy.c:3
_PUBLIC size_t strlen(const char *s)
Definition strlen.c:3
_PUBLIC char * strcpy(char *_RESTRICT s1, const char *_RESTRICT s2)
Definition strcpy.c:3
_PUBLIC int strcmp(const char *s1, const char *s2)
Definition strcmp.c:3
_PUBLIC void * memset(void *s, int c, size_t n)
Definition memset.c:4
char printable
Definition ansi.h:38
ansi_result_type_t type
Definition ansi.h:37
Definition ansi.h:9