Skip to content

Commit 60a1b8a

Browse files
committed
Fix bugs, add .nushrc support, beautify prompt
- Fix char overflow in read_command (pointer_length -> size_t) - Fix out-of-bounds read on empty PATH components - Use _exit() instead of exit() in child after fork - Add bounds check on symtab stack overflow - Fix add_to_buf write-before-check and realloc failure corruption - Fix include guard BACKEND_H -> EXECUTOR_H - Stop redefining EOF from stdio (use SRC_EOF) - Remove dead variable in source.c - Replace deprecated cuserid with getpwuid(getuid()) - Add .nushrc loading on startup - Beautify prompt: user@hostname:path $ with colors and ~ substitution
1 parent 534eb0a commit 60a1b8a

10 files changed

Lines changed: 145 additions & 33 deletions

File tree

src/executor.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ char *search_path(char *file)
3737
strncpy(path, p, p2-p);
3838
path[p2-p] = '\0';
3939

40-
if(p2[-1] != '/')
40+
if(p2 > p && p2[-1] != '/')
4141
{
4242
strcat(path, "/");
4343
}
@@ -170,15 +170,15 @@ int do_simple_command(struct node_s *node)
170170
fprintf(stderr, "Error: Failed to execute command: %s\n", strerror(errno));
171171
if(errno == ENOEXEC)
172172
{
173-
exit(126);
173+
_exit(126);
174174
}
175175
else if(errno == ENOENT)
176176
{
177-
exit(127);
177+
_exit(127);
178178
}
179179
else
180180
{
181-
exit(EXIT_FAILURE);
181+
_exit(EXIT_FAILURE);
182182
}
183183
}
184184
else if(child_pid < 0)

src/executor.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
#ifndef BACKEND_H
2-
#define BACKEND_H
1+
#ifndef EXECUTOR_H
2+
#define EXECUTOR_H
33

44
#include "node.h"
55

src/initsh.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
13
#include <string.h>
24
#include "shell.h"
5+
#include "source.h"
36
#include "symtab/symtab.h"
47

58
extern char **environ;
@@ -41,4 +44,55 @@ void initsh(void)
4144

4245
entry = add_to_symtab("PS2");
4346
symtab_entry_setval(entry, "> ");
47+
48+
load_rc_file();
49+
}
50+
51+
void load_rc_file(void)
52+
{
53+
char *home = getenv("HOME");
54+
if(!home) return;
55+
56+
size_t path_len = strlen(home) + 9;
57+
char path[path_len];
58+
strcpy(path, home);
59+
strcat(path, "/.nushrc");
60+
61+
FILE *fp = fopen(path, "r");
62+
if(!fp) return;
63+
64+
fseek(fp, 0, SEEK_END);
65+
long fsize = ftell(fp);
66+
if(fsize <= 0)
67+
{
68+
fclose(fp);
69+
return;
70+
}
71+
fseek(fp, 0, SEEK_SET);
72+
73+
char *buffer = malloc(fsize + 1);
74+
if(!buffer)
75+
{
76+
fclose(fp);
77+
return;
78+
}
79+
80+
size_t nread = fread(buffer, 1, fsize, fp);
81+
fclose(fp);
82+
83+
if(nread == 0)
84+
{
85+
free(buffer);
86+
return;
87+
}
88+
89+
buffer[nread] = '\0';
90+
91+
struct source_s src;
92+
src.buffer = buffer;
93+
src.buffer_size = nread;
94+
src.cursor_position = INIT_SRC_POS;
95+
96+
parse_and_execute(&src);
97+
free(buffer);
4498
}

src/main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ char *read_command(void)
5151
{
5252
char buffer[1024];
5353
char *pointer = NULL;
54-
char pointer_length = 0;
54+
size_t pointer_length = 0;
5555

5656
while(fgets(buffer, 1024, stdin))
5757
{
58-
int buffer_length = strlen(buffer);
58+
size_t buffer_length = strlen(buffer);
5959

6060
if(!pointer)
6161
{

src/prompt.c

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,91 @@
11
#include <stdio.h>
2-
#include "shell.h"
2+
#include <stdlib.h>
3+
#include <string.h>
34
#include <unistd.h>
45
#include <limits.h>
6+
#include <pwd.h>
7+
#include "shell.h"
58
#include "symtab/symtab.h"
69

7-
#define CYN "\x1B[36m"
8-
#define WHT "\x1B[37m"
10+
#define GRN "\x1B[32m"
11+
#define BLU "\x1B[34m"
912
#define RESET "\x1B[0m"
1013

14+
static void get_user_name(char *buf, size_t size)
15+
{
16+
struct passwd *pw = getpwuid(getuid());
17+
if(pw && pw->pw_name)
18+
{
19+
strncpy(buf, pw->pw_name, size - 1);
20+
buf[size - 1] = '\0';
21+
}
22+
else
23+
{
24+
buf[0] = '\0';
25+
}
26+
}
27+
28+
static char *display_path(char *cwd)
29+
{
30+
char *home = getenv("HOME");
31+
if(!home) return cwd;
32+
33+
size_t hlen = strlen(home);
34+
if(strncmp(cwd, home, hlen) == 0)
35+
{
36+
if(cwd[hlen] == '\0' || cwd[hlen] == '/')
37+
{
38+
static char buf[PATH_MAX];
39+
buf[0] = '~';
40+
strcpy(buf + 1, cwd + hlen);
41+
return buf;
42+
}
43+
}
44+
return cwd;
45+
}
46+
1147
void print_prompt1(void)
1248
{
1349
struct symtab_entry_s *entry = get_symtab_entry("PS1");
1450
char user[PATH_MAX];
1551
char cwd[PATH_MAX];
16-
cuserid(user);
17-
getcwd(cwd, sizeof(cwd));
52+
char hostname[256];
53+
54+
get_user_name(user, sizeof(user));
55+
gethostname(hostname, sizeof(hostname));
56+
hostname[sizeof(hostname) - 1] = '\0';
57+
58+
if(!getcwd(cwd, sizeof(cwd)))
59+
{
60+
cwd[0] = '\0';
61+
}
62+
63+
fprintf(stderr, GRN "%s@%s" RESET ":" BLU "%s" RESET, user, hostname, display_path(cwd));
64+
1865
if(entry && entry->val)
1966
{
20-
fprintf(stderr,CYN "NUSH@%s>" WHT "%s" CYN "%s" RESET,user,cwd,entry->val);
67+
fprintf(stderr, " " GRN "%s" RESET, entry->val);
2168
}
2269
else
2370
{
24-
fprintf(stderr, CYN "NUSH@%s>" WHT "%s" CYN "$ " RESET,user,cwd);
71+
fprintf(stderr, " " GRN "$" RESET " ");
2572
}
2673
}
2774

2875
void print_prompt2(void)
2976
{
3077
char user[PATH_MAX];
3178
char cwd[PATH_MAX];
32-
cuserid(user);
33-
getcwd(cwd, sizeof(cwd));
34-
fprintf(stderr,CYN "NUSH@%s>" WHT "%s" CYN "> " RESET,user,cwd);
79+
char hostname[256];
80+
81+
get_user_name(user, sizeof(user));
82+
gethostname(hostname, sizeof(hostname));
83+
hostname[sizeof(hostname) - 1] = '\0';
84+
85+
if(!getcwd(cwd, sizeof(cwd)))
86+
{
87+
cwd[0] = '\0';
88+
}
89+
90+
fprintf(stderr, GRN "%s@%s" RESET ":" BLU "%s" RESET " " GRN ">" RESET " ", user, hostname, display_path(cwd));
3591
}

src/scanner.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,9 @@ struct token_s eof_token =
1818

1919
void add_to_buf(char c)
2020
{
21-
tok_buf[tok_bufindex++] = c;
22-
23-
if(tok_bufindex >= tok_bufsize)
21+
if(tok_bufindex + 1 >= tok_bufsize)
2422
{
25-
char *tmp = realloc(tok_buf, tok_bufsize*2);
23+
char *tmp = realloc(tok_buf, tok_bufsize * 2);
2624

2725
if(!tmp)
2826
{
@@ -33,6 +31,8 @@ void add_to_buf(char c)
3331
tok_buf = tmp;
3432
tok_bufsize *= 2;
3533
}
34+
35+
tok_buf[tok_bufindex++] = c;
3636
}
3737

3838

@@ -99,7 +99,7 @@ struct token_s *tokenize(struct source_s *src)
9999

100100
char nc = next_character(src);
101101

102-
if(nc == ERRCHAR || nc == EOF)
102+
if(nc == ERRCHAR || nc == SRC_EOF)
103103
{
104104
return &eof_token;
105105
}
@@ -138,7 +138,7 @@ struct token_s *tokenize(struct source_s *src)
138138
break;
139139
}
140140

141-
} while((nc = next_character(src)) != EOF);
141+
} while((nc = next_character(src)) != SRC_EOF);
142142

143143
if(tok_bufindex == 0)
144144
{

src/shell.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ char *read_command(void);
1111
int parse_and_execute(struct source_s *src);
1212

1313
void initsh(void);
14+
void load_rc_file(void);
1415

1516
int dump(int argc, char **argv);
1617

src/source.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,15 @@ char next_character(struct source_s *src)
2121
return ERRCHAR;
2222
}
2323

24-
char c1 = 0;
2524
if(src->cursor_position == INIT_SRC_POS)
2625
{
2726
src->cursor_position = -1;
2827
}
29-
else
30-
{
31-
c1 = src->buffer[src->cursor_position];
32-
}
3328

3429
if(++src->cursor_position >= src->buffer_size)
3530
{
3631
src->cursor_position = src->buffer_size;
37-
return EOF;
32+
return SRC_EOF;
3833
}
3934

4035
return src->buffer[src->cursor_position];
@@ -59,7 +54,7 @@ char peek_character(struct source_s *src)
5954

6055
if(pos >= src->buffer_size)
6156
{
62-
return EOF;
57+
return SRC_EOF;
6358
}
6459

6560
return src->buffer[pos];
@@ -75,7 +70,7 @@ void skip_white_spaces(struct source_s *src)
7570
return;
7671
}
7772

78-
while(((c = peek_character(src)) != EOF) && (c == ' ' || c == '\t'))
73+
while(((c = peek_character(src)) != SRC_EOF) && (c == ' ' || c == '\t'))
7974
{
8075
next_character(src);
8176
}

src/source.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef SOURCE_H
22
#define SOURCE_H
33

4-
#define EOF (-1)
4+
#define SRC_EOF (-1)
55
#define ERRCHAR ( 0)
66

77
#define INIT_SRC_POS (-2)

src/symtab/symtab.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,12 @@ void symtab_entry_setval(struct symtab_entry_s *entry, char *val)
268268

269269
void symtab_stack_add(struct symtab_s *symtab)
270270
{
271+
if(symtab_stack.symtab_count >= MAX_SYMTAB)
272+
{
273+
fprintf(stderr, "fatal error: symbol table stack overflow\n");
274+
exit(EXIT_FAILURE);
275+
}
276+
271277
symtab_stack.symtab_list[symtab_stack.symtab_count++] = symtab;
272278
symtab_stack.local_symtab = symtab;
273279
}

0 commit comments

Comments
 (0)