Commit graph

455 commits

Author SHA1 Message Date
3c350af411 fix(debug): print messages to STDERR, to prevent redirection by pipes etc 2025-04-29 13:16:47 +02:00
Jérôme Guélen
5c53ebfa64 (fix) Quote removal on heredoc limiters 2025-04-28 21:37:31 +02:00
ab861fc5c0 tests(here-doc): ensure here docs work in many situations 2025-04-28 16:57:29 +02:00
aeb5105d97 tests(redir): ensure targets are expanded when no words are in the cmd 2025-04-28 16:28:04 +02:00
d4da91b62b fix(exec): do now swallow prompt and io on incorrect command followed by redirection 2025-04-28 16:07:08 +02:00
65c1eb9d84 fix(connec_cmd): handle nested connections correctly 2025-04-28 15:12:17 +02:00
92d647e33c feat(redirections): allow a command composed only of redirections 2025-04-28 14:44:20 +02:00
a9055b4c66 feat(redirection/group_cmd): handle redirections for group cmds 2025-04-28 13:01:08 +02:00
bd06d9f19c refactor(std_fds): allow for ability to store multiple std fds savesets 2025-04-28 12:49:13 +02:00
255a1382da fix(waitpid): remove spurious call & handle errors 2025-04-28 12:43:05 +02:00
505a96eeef refactor(redirections): make handle_redirections generic over cmd types 2025-04-28 12:43:05 +02:00
Jérôme Guélen
71eb07b4f5
(fix) Test was missing an EOF 2025-04-28 11:55:45 +02:00
Jérôme Guélen
32dd807c9d
(fix/enhancement): Added two tests for behaviour when not file corresponds 2025-04-28 11:50:36 +02:00
Jérôme Guélen
25ffc3fb6f
(fix): Proper behaviour for wildcards and proper test 2025-04-28 11:50:36 +02:00
Jérôme Guélen
e5952b3f43
Behaviour seems inconsistent 2025-04-28 11:50:32 +02:00
Jérôme Guélen
497f442d77
fix(expand-star): incomplete, committing to preserve 2025-04-28 11:48:13 +02:00
f0f19c3c0a fix(exec/and or): was exiting too soon 2025-04-25 18:03:12 +02:00
7a5e838fcf fix(debug): wrong indent for group_cmd 2025-04-25 17:53:40 +02:00
e1801652af fix(parsing/subshell): missing allocation for group cmd 2025-04-25 17:52:51 +02:00
9fcb34e1d5 feat(builtins/cd): on error, print path 2025-04-25 16:08:10 +02:00
29bbb5e572 fix(command_not_found): unset or empty PATH leads to No such file or directory error 2025-04-25 15:52:02 +02:00
c756d3783f tests(export): ensure export rejects invalid identifiers 2025-04-25 15:14:48 +02:00
c4be8693d1 tests(export): ensure export with extra = works 2025-04-25 15:10:05 +02:00
553783eb2d fix(tests): remove dependency on $HOME 2025-04-25 15:06:42 +02:00
f6ae16bbf8 tests(var_subst): ensure commands partially in variables work 2025-04-25 15:06:42 +02:00
a040ad5613 tests(export): ensure previous value of variable works correctly 2025-04-25 15:06:42 +02:00
Jérôme Guélen
29187f08da
tests(export/echo): ensure correct behaviour for single quotes in VAR 2025-04-25 15:01:54 +02:00
08baee41b6 tests(echo): ensure arguments in variables work 2025-04-25 14:40:09 +02:00
e5027323e1 fix(field_splitting): ensure no extraneous spaces appear
debug notes:
= 250  !! OK ===================================================================
export HOLA="bonjour "
echo $HOLA | cat -e
= out =
bonjour $

= err =
rc: 0

= refout =
bonjour$

++++++++++++++++++++++++++++++++++++++++++++++++++++
failed: quote removal before word splitting
++++++++++++++++++++++++++++++++++++++++++++++++++++
++++ test input:
export VAR="hello "
echo $VAR | cat -e
++++ Got output:
hello $
++++ But expected:
hello$

Problem is in post-processing:
parsed command
 ╰─ t_cmd
     ├─ t_cmd_type = FT_SIMPLE
     ├─ flags = 0
     ├─ line = 0
     ╰─ value
         ╰─ t_simple_cmd
             ├─ line = 0
             ├─ t_wordlist
             │   ├─ t_worddesc
             │   │   ├─ word   = [echo]
             │   │   ├─ marker = [    ]
             │   │   ├─ flags = 0
             │   │   ╰─ t_token_type = WORD_TOKEN
             │   ╰─ t_worddesc
             │       ├─ word   = [$VAR]
             │       ├─ marker = [    ]
             │       ├─ flags = 1
             │       ╰─ t_token_type = WORD_TOKEN
             ╰─ redirections = (empty redir list)
about to post-process
 ╰─ t_simple_cmd
     ├─ line = 0
     ├─ t_wordlist
     │   ├─ t_worddesc
     │   │   ├─ word   = [echo]
     │   │   ├─ marker = [    ]
     │   │   ├─ flags = 0
     │   │   ╰─ t_token_type = WORD_TOKEN
     │   ╰─ t_worddesc
     │       ├─ word   = [$VAR]
     │       ├─ marker = [    ]
     │       ├─ flags = 1
     │       ╰─ t_token_type = WORD_TOKEN
     ╰─ redirections = (empty redir list)
about to post-process
 ╰─ t_simple_cmd
     ├─ line = 0
     ├─ t_wordlist
     │   ├─ t_worddesc
     │   │   ├─ word   = [echo]
     │   │   ├─ marker = [    ]
     │   │   ├─ flags = 0
     │   │   ╰─ t_token_type = WORD_TOKEN
     │   ╰─ t_worddesc
     │       ├─ word   = [hello ]
     │       ├─ marker = [$$$$$$]
     │       ├─ flags = 1
     │       ╰─ t_token_type = WORD_TOKEN
     ╰─ redirections = (empty redir list)
about to post-process
 ╰─ t_simple_cmd
     ├─ line = 0
     ├─ t_wordlist
     │   ├─ t_worddesc
     │   │   ├─ word   = [echo]
     │   │   ├─ marker = [    ]
     │   │   ├─ flags = 0
     │   │   ╰─ t_token_type = WORD_TOKEN
     │   ├─ t_worddesc
     │   │   ├─ word   = [hello]
     │   │   ├─ marker = [$$$$$]
     │   │   ├─ flags = 1
     │   │   ╰─ t_token_type = WORD_TOKEN
     │   ╰─ t_worddesc <---- WHAT IS THIS DOING HERE???
     │       ├─ word   = []
     │       ├─ marker = []
     │       ├─ flags = 1
     │       ╰─ t_token_type = WORD_TOKEN
     ╰─ redirections = (empty redir list)
about to post-process
 ╰─ t_simple_cmd
     ├─ line = 0
     ├─ t_wordlist
     │   ├─ t_worddesc
     │   │   ├─ word   = [echo]
     │   │   ├─ marker = [    ]
     │   │   ├─ flags = 0
     │   │   ╰─ t_token_type = WORD_TOKEN
     │   ├─ t_worddesc
     │   │   ├─ word   = [hello]
     │   │   ├─ marker = [$$$$$]
     │   │   ├─ flags = 1
     │   │   ╰─ t_token_type = WORD_TOKEN
     │   ╰─ t_worddesc
     │       ├─ word   = []
     │       ├─ marker = []
     │       ├─ flags = 1
     │       ╰─ t_token_type = WORD_TOKEN
     ╰─ redirections = (empty redir list)
about to execute
 ╰─ t_simple_cmd
     ├─ line = 0
     ├─ t_wordlist
     │   ├─ t_worddesc
     │   │   ├─ word   = [echo]
     │   │   ├─ marker = [(null)]
     │   │   ├─ flags = 0
     │   │   ╰─ t_token_type = WORD_TOKEN
     │   ├─ t_worddesc
     │   │   ├─ word   = [hello]
     │   │   ├─ marker = [(null)]
     │   │   ├─ flags = 1
     │   │   ╰─ t_token_type = WORD_TOKEN
     │   ╰─ t_worddesc
     │       ├─ word   = []
     │       ├─ marker = [(null)]
     │       ├─ flags = 1
     │       ╰─ t_token_type = WORD_TOKEN
     ╰─ redirections = (empty redir list)

Problem seems to be in field splitting
2025-04-25 14:32:16 +02:00
588b016f69 tests(export): ensure variable substitution in variable names works 2025-04-25 13:41:43 +02:00
45869f1154 tests(export): ensure @ is accepted in variable values 2025-04-25 13:36:28 +02:00
297d68e73c tests(parsing): ensure unmatched ) are correctly reported 2025-04-25 13:33:09 +02:00
0c9dcd944e fix(parsing): report unclosed ( error 2025-04-25 13:19:44 +02:00
527a624765 fix(exec): return code 126 when command is found but permission denied 2025-04-25 12:40:34 +02:00
9d37d07589 fix(get_command_path): leak when path unset and calling file present in current dir
$ touch cat
$ unset PATH
$ cat
m==75845== Memcheck, a memory error detector
==75845== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==75845== Using Valgrind-3.23.0 and LibVEX; rerun with -h for copyright info
==75845== Command: ./minishell
==75845==
==75846== Memcheck, a memory error detector
==75846== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==75846== Using Valgrind-3.23.0 and LibVEX; rerun with -h for copyright info
==75846== Command: /nix/store/6wgd8c9vq93mqxzc7jhkl86mv6qbc360-coreutils-9.5/bin/touch cat
==75846==
==75846==
==75846== FILE DESCRIPTORS: 0 open (0 std) at exit.
==75846==
==75846== HEAP SUMMARY:
==75846==     in use at exit: 0 bytes in 0 blocks
==75846==   total heap usage: 46 allocs, 46 frees, 8,126 bytes allocated
==75846==
==75846== All heap blocks were freed -- no leaks are possible
==75846==
==75846== For lists of detected and suppressed errors, rerun with: -s
==75846== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
minishell: cat: Permission denied
==75849==
==75849== FILE DESCRIPTORS: 3 open (3 std) at exit.
==75849==
==75849== HEAP SUMMARY:
==75849==     in use at exit: 4,181 bytes in 12 blocks
==75849==   total heap usage: 982 allocs, 970 frees, 122,299 bytes allocated
==75849==
==75849== 8 bytes in 1 blocks are definitely lost in loss record 1 of 9
==75849==    at 0x48467D9: malloc (in /nix/store/phbnjdfmy3v4ak9xf211y2336mv5kx9s-valgrind-3.23.0/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==75849==    by 0x113C22: ft_calloc (ft_calloc.c:28)
==75849==    by 0x112399: get_paths_array (src/subst/simple_filename_exp.c:37)
==75849==    by 0x1121EE: filepath_from_env (src/subst/simple_filename_exp.c:144)
==75849==    by 0x1121C0: get_cmdpath (src/subst/simple_filename_exp.c:184)
==75849==    by 0x10CD97: exec_external_cmd (src/executing/simple_cmd/simple_cmd_execute.c:67)
==75849==    by 0x10CC58: simple_cmd_execute (src/executing/simple_cmd/simple_cmd_execute.c:94)
==75849==    by 0x10B12C: cmd_execute (src/executing/cmd/cmd_execute.c:23)
==75849==    by 0x10A4FD: execute_command (src/minishell.c:37)
==75849==    by 0x10A3B2: main (src/minishell.c:90)
==75849==
==75849== 24 bytes in 1 blocks are still reachable in loss record 6 of 9
==75849==    at 0x48467D9: malloc (in /nix/store/phbnjdfmy3v4ak9xf211y2336mv5kx9s-valgrind-3.23.0/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==75849==    by 0x113C22: ft_calloc (ft_calloc.c:28)
==75849==    by 0x10D4A9: cmd_create (src/parser/cmd/cmd.c:20)
==75849==    by 0x10F6A1: simple_cmd_create (src/parser/simple_cmd/simple_cmd_parse.c:24)
==75849==    by 0x10F4E4: minishell_simple_cmd_parse (src/parser/simple_cmd/simple_cmd_parse.c:38)
==75849==    by 0x10E078: minishell_group_or_simple_parse (src/parser/group_cmd/group_cmd_parse.c:53)
==75849==    by 0x10E4AC: minishell_pipeline_parse (src/parser/pipeline/pipeline_parse.c:26)
==75849==    by 0x10D93C: minishell_cmds_parse (src/parser/cmd/cmds_parse.c:30)
==75849==    by 0x1139D5: minishell_parse (src/parser/cmd_parsing.c:67)
==75849==    by 0x10A38B: main (src/minishell.c:87)
==75849==
==75849== LEAK SUMMARY:
==75849==    definitely lost: 8 bytes in 1 blocks
==75849==    indirectly lost: 0 bytes in 0 blocks
==75849==      possibly lost: 0 bytes in 0 blocks
==75849==    still reachable: 24 bytes in 1 blocks
==75849==         suppressed: 4,149 bytes in 10 blocks
==75849==
==75849== For lists of detected and suppressed errors, rerun with: -s
==75849== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
126
==75845==
==75845== FILE DESCRIPTORS: 3 open (3 std) at exit.
==75845==
==75845== HEAP SUMMARY:
==75845==     in use at exit: 4,201 bytes in 14 blocks
==75845==   total heap usage: 844 allocs, 830 frees, 72,248 bytes allocated
==75845==
==75845== 8 bytes in 1 blocks are definitely lost in loss record 1 of 8
==75845==    at 0x48467D9: malloc (in /nix/store/phbnjdfmy3v4ak9xf211y2336mv5kx9s-valgrind-3.23.0/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==75845==    by 0x113C22: ft_calloc (ft_calloc.c:28)
==75845==    by 0x112399: get_paths_array (src/subst/simple_filename_exp.c:37)
==75845==    by 0x1121EE: filepath_from_env (src/subst/simple_filename_exp.c:144)
==75845==    by 0x1121C0: get_cmdpath (src/subst/simple_filename_exp.c:184)
==75845==    by 0x10CD97: exec_external_cmd (src/executing/simple_cmd/simple_cmd_execute.c:67)
==75845==    by 0x10CC58: simple_cmd_execute (src/executing/simple_cmd/simple_cmd_execute.c:94)
==75845==    by 0x10B12C: cmd_execute (src/executing/cmd/cmd_execute.c:23)
==75845==    by 0x10A4FD: execute_command (src/minishell.c:37)
==75845==    by 0x10A3B2: main (src/minishell.c:90)
==75845==
==75845== LEAK SUMMARY:
==75845==    definitely lost: 8 bytes in 1 blocks
==75845==    indirectly lost: 0 bytes in 0 blocks
==75845==      possibly lost: 0 bytes in 0 blocks
==75845==    still reachable: 0 bytes in 0 blocks
==75845==         suppressed: 4,193 bytes in 13 blocks
==75845==
==75845== For lists of detected and suppressed errors, rerun with: -s
==75845== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)inishell: cat: Permission denied
2025-04-24 18:03:25 +02:00
Jérôme Guélen
a86616f910
(enhancement) Printing an error on unclosed quote and corrected a typo. 2025-04-24 17:20:04 +02:00
Jérôme Guélen
3b5df9ec10
(fix) Dealing with signals correctly from the start 2025-04-24 14:28:07 +02:00
5fb054d403 fix(redirection): restore std fds on redirection error
debug notes:
$ cat << eof > /root/outfile
hello
eof
minishell: open: Permission denied
minishell: hello: command not found
==42382==
==42382== FILE DESCRIPTORS: 9 open (3 std) at exit.
==42382== Open file descriptor 8: /dev/pts/3
==42382==    at 0x49A8C1B: dup (in /nix/store/nqb2ns2d1lahnd5ncwmn6k84qfd7vx2k-glibc-2.40-36/lib/libc.so.6)
==42382==    by 0x10C9CC: handle_redirections (src/executing/simple_cmd/handle_redirections.c:65)
==42382==    by 0x10CBF6: simple_cmd_execute (src/executing/simple_cmd/simple_cmd_execute.c:91)
==42382==    by 0x10B10C: cmd_execute (src/executing/cmd/cmd_execute.c:23)
==42382==    by 0x10A4DD: execute_command (src/minishell.c:37)
==42382==    by 0x10A3A2: main (src/minishell.c:89)
==42382==
==42382== Open file descriptor 7: /dev/pts/3
==42382==    at 0x49A8C1B: dup (in /nix/store/nqb2ns2d1lahnd5ncwmn6k84qfd7vx2k-glibc-2.40-36/lib/libc.so.6)
==42382==    by 0x10C9B9: handle_redirections (src/executing/simple_cmd/handle_redirections.c:64)
==42382==    by 0x10CBF6: simple_cmd_execute (src/executing/simple_cmd/simple_cmd_execute.c:91)
==42382==    by 0x10B10C: cmd_execute (src/executing/cmd/cmd_execute.c:23)
==42382==    by 0x10A4DD: execute_command (src/minishell.c:37)
==42382==    by 0x10A3A2: main (src/minishell.c:89)
==42382==
==42382== Open file descriptor 6: /dev/pts/3
==42382==    at 0x49A8C1B: dup (in /nix/store/nqb2ns2d1lahnd5ncwmn6k84qfd7vx2k-glibc-2.40-36/lib/libc.so.6)
==42382==    by 0x10C9CC: handle_redirections (src/executing/simple_cmd/handle_redirections.c:65)
==42382==    by 0x10CBF6: simple_cmd_execute (src/executing/simple_cmd/simple_cmd_execute.c:91)
==42382==    by 0x10B10C: cmd_execute (src/executing/cmd/cmd_execute.c:23)
==42382==    by 0x10A4DD: execute_command (src/minishell.c:37)
==42382==    by 0x10A3A2: main (src/minishell.c:89)
==42382==
==42382== Open file descriptor 5: /dev/pts/3
==42382==    at 0x49A8C1B: dup (in /nix/store/nqb2ns2d1lahnd5ncwmn6k84qfd7vx2k-glibc-2.40-36/lib/libc.so.6)
==42382==    by 0x10C9B9: handle_redirections (src/executing/simple_cmd/handle_redirections.c:64)
==42382==    by 0x10CBF6: simple_cmd_execute (src/executing/simple_cmd/simple_cmd_execute.c:91)
==42382==    by 0x10B10C: cmd_execute (src/executing/cmd/cmd_execute.c:23)
==42382==    by 0x10A4DD: execute_command (src/minishell.c:37)
==42382==    by 0x10A3A2: main (src/minishell.c:89)
==42382==
==42382== Open file descriptor 4: /dev/pts/3
==42382==    at 0x49A8C1B: dup (in /nix/store/nqb2ns2d1lahnd5ncwmn6k84qfd7vx2k-glibc-2.40-36/lib/libc.so.6)
==42382==    by 0x10C9A6: handle_redirections (src/executing/simple_cmd/handle_redirections.c:63)
==42382==    by 0x10CBF6: simple_cmd_execute (src/executing/simple_cmd/simple_cmd_execute.c:91)
==42382==    by 0x10B10C: cmd_execute (src/executing/cmd/cmd_execute.c:23)
==42382==    by 0x10A4DD: execute_command (src/minishell.c:37)
==42382==    by 0x10A3A2: main (src/minishell.c:89)
==42382==
==42382== Open file descriptor 3: /tmp/minishell_here_doc_78Ak8J9TeVu (deleted)
==42382==    at 0x49A8C1B: dup (in /nix/store/nqb2ns2d1lahnd5ncwmn6k84qfd7vx2k-glibc-2.40-36/lib/libc.so.6)
==42382==    by 0x10C9A6: handle_redirections (src/executing/simple_cmd/handle_redirections.c:63)
==42382==    by 0x10CBF6: simple_cmd_execute (src/executing/simple_cmd/simple_cmd_execute.c:91)
==42382==    by 0x10B10C: cmd_execute (src/executing/cmd/cmd_execute.c:23)
==42382==    by 0x10A4DD: execute_command (src/minishell.c:37)
==42382==    by 0x10A3A2: main (src/minishell.c:89)
2025-04-24 13:47:54 +02:00
9db47dc96d feat(redirection): print path of redirection target on redirection error 2025-04-24 13:42:31 +02:00
b6e97ac2c7 fix(debug): redirectee prints both variants of an enum 2025-04-24 13:34:39 +02:00
3f08189aae fix(parsing/redirect): sometimes do not take a redirection into account
debug notes:

++++++++++++++++++++++++++++++++++++++++++++++++++++
failed: ambiguous redirect
++++++++++++++++++++++++++++++++++++++++++++++++++++
++++ test input:
export target="outfile1 outfile2"
echo hello > $target
echo $?
echo hi >> $target
echo $?
cat < $target
echo $?
ls
echo $?
++++ Got output:
hello
0
hi
0
echo $?
ls
echo $?
++++ But expected:
minishell: $target: ambiguous redirect
1
minishell: $target: ambiguous redirect
1
minishell: $target: ambiguous redirect
1
0

Reproduced this with rr record --cahos, see
/home/khais/.local/share/rr/minishell-48

$ export target="outfile1 outfile2"
$ echo hi > $target
hi

Break in simple_cmd_execute, second command has no redirections when it should
have some, presumably this comes from some uninitialized memory somewhere.
2025-04-24 13:26:40 +02:00
8d60113351 feat(postprocess/redir): remove quotes in redirection targets 2025-04-24 12:45:00 +02:00
ac198727e9 feat(postprocess): show error when post-processing failure occurs 2025-04-24 12:45:00 +02:00
2180909285 fix(expansion/wildcard): do not remove quotes twice on non-pattern strings
There is still an issue with removing too many quotes when expanding variables
(see #138). This will be tackled in a later PR.
2025-04-24 12:45:00 +02:00
aca85c3583 fix(expansion/redirection): prevent infinite loop of redir list pointing to itself
also add a hard limit of OVER 9000! iterations for the problematic loop
2025-04-24 12:45:00 +02:00
bf26afce2b fix(debug): correctly print here_doc_eof in redirect debug 2025-04-24 12:45:00 +02:00
38ffac7fc3 feat(redir): expand wildcards in targets and handle ambiguous redirects 2025-04-24 12:45:00 +02:00
920ad586e1 refactor(redirect): ambiguous redirect message to own file 2025-04-24 12:45:00 +02:00
2dd20b21bc feat(redir): fieldsplit redir target, and handle ambiguous redirects 2025-04-24 12:44:33 +02:00
5de82f2940 feat(debug): add function to easily treeprint a redirect 2025-04-21 11:00:14 +02:00