237 Commits

Author SHA1 Message Date
12dc548a4e Update README.md 2024-10-17 07:34:10 +02:00
bd18752fdc Create README.md 2024-10-17 07:33:46 +02:00
ded1b802b2 kill me 2024-05-22 13:53:49 +02:00
1731f820ee Merge branch 'main' of github.com:mdev9/minishell 2024-05-16 13:22:35 +02:00
b8fade86a0 the most important thing to fix 2024-05-16 13:22:28 +02:00
6d40826c51 fixed big error 2024-05-16 13:21:04 +02:00
f5532679bc fixed minishell 2024-05-16 13:14:30 +02:00
2c8feb6c18 removed useless file 2024-05-15 17:21:53 +02:00
956aa0e1e7 norm 2024-05-08 12:32:20 +02:00
d1681dafe3 fix is_var 2024-05-08 11:57:49 +02:00
e986d8692b fix des trucs 2024-05-07 17:43:00 +02:00
01496f0587 fix cat < missing | cat mais ça a probablement cassé autre chose 2024-05-07 12:37:36 +02:00
e1831b18fa fix error code 2024-05-06 16:41:37 +02:00
0af303d895 fix infinite loop 2024-05-06 16:29:27 +02:00
3d2adaf520 fix norme 2024-05-06 16:17:54 +02:00
923da71a49 AAAAAAAAAAA 2024-05-06 15:23:30 +02:00
444b84c541 fixed hell 2024-05-06 14:29:15 +02:00
855ba3f6f2 fixed stuff 2024-05-06 14:18:40 +02:00
60d6e50ab9 fix un truc 2024-05-06 13:42:47 +02:00
231f1a8002 updated tood 2024-05-06 13:20:23 +02:00
398e4b5928 fix too long path 2024-05-06 13:19:17 +02:00
b65c07d430 fix infinit loop when redirection to ( 2024-05-06 11:15:44 +02:00
ab5ef04911 c'est mieux quand ça compile 2024-05-06 11:00:51 +02:00
6cfc2beff4 norme 2024-05-06 10:58:42 +02:00
57ad83c2aa fix "$" 2024-05-06 10:56:13 +02:00
8513bd3bdd merge avec moi meme 2024-05-06 10:29:41 +02:00
d3e5d459cb fix fds ouverts 2024-05-06 10:28:30 +02:00
28efa75b39 fix autre invalid read 2024-05-05 20:38:05 +02:00
43e4d054b5 fix exit when variable on input redirection and invalid read 2024-05-05 20:26:52 +02:00
b45a04e622 fix exit quand output ambiguous redirect 2024-05-05 20:07:53 +02:00
257e4829ba j'ai remis le is_var, je sais pas a quoi il sert mais mtn il marche (peut-être) 2024-05-04 18:32:37 +02:00
ef3915c640 AAAAAAAAAAAAAAAAAAAAAAAAAAA j'ai pas les variables d'environnement 2024-05-04 14:33:30 +02:00
fb0ebc2398 fix unset all -> export a 2024-05-03 15:06:27 +02:00
b7658d02ec fix export a= ->a="" 2024-05-03 14:30:50 +02:00
bdfff1360a fixed some errors 2024-05-03 14:14:12 +02:00
032bfb976e fix des trucs 2024-05-03 13:03:41 +02:00
2d5449ed3d fix $""coucou 2024-05-03 12:56:07 +02:00
6e93081fcb j'aime pas minishell 2024-05-03 11:18:49 +02:00
2d11d1493a Merge branch 'main' of github.com:mdev9/minishell 2024-05-03 08:49:16 +02:00
b1c3e53509 fix leak 2024-05-03 08:49:04 +02:00
9e2f926ca8 fixed command not found stopping execution 2024-05-03 08:42:53 +02:00
e75099562e fix leak when (()) 2024-05-03 08:14:33 +02:00
f661232c77 fixed all problems 2024-04-30 14:50:58 +02:00
f67d334503 fixed closing all pipe fds 2024-04-30 14:05:25 +02:00
df6bef58dc todo 2024-04-29 22:17:20 +02:00
992f02cded fix quelques trucs 2024-04-29 22:12:46 +02:00
0bad8c3cdb fix echo 2024-04-29 21:43:50 +02:00
245b7b2526 todo 2024-04-29 19:41:15 +02:00
efd8838ee0 free trop tot quand il y a une syntax error 2024-04-29 13:22:18 +02:00
03e108b625 rl_clear_history() 2024-04-29 13:01:14 +02:00
d05e304475 added libft 2024-04-29 12:38:11 +02:00
e9f9ede1f1 fixed wildcards and makefile 2024-04-29 11:15:54 +02:00
bb0a62342e ambigous redirect stops execution 2024-04-28 14:54:32 +02:00
97d5c24662 yes 2024-04-26 19:00:57 +02:00
56ff115753 fixed wildcards 2024-04-26 17:41:04 +02:00
a7f8b264b7 rm bonus 2024-04-26 16:08:33 +02:00
6c58f1d26c fix export ="" 2024-04-26 16:07:25 +02:00
ee49511eaf fixed header 2024-04-26 15:50:46 +02:00
344c40df46 fixed 2024-04-26 15:47:34 +02:00
2290d638b6 fixed wildcards 2024-04-26 15:45:28 +02:00
6012037886 wildcards 2024-04-26 15:34:05 +02:00
5eff48d14b invalid free 2024-04-26 15:28:08 +02:00
8a6378aa9c val.supp 2024-04-26 15:24:19 +02:00
1c8694e688 Merge branch 'main' of github.com:mdev9/minishell 2024-04-26 15:08:01 +02:00
69467e0446 tres important 2024-04-26 15:07:50 +02:00
e7ab260a3b norme 2024-04-26 14:52:59 +02:00
744ab7728d AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 2024-04-26 14:46:08 +02:00
f3d01b28f0 Merge branch 'main' of github.com:mdev9/minishell 2024-04-26 13:47:34 +02:00
517f94fe48 () (()) 2024-04-26 13:47:08 +02:00
7b5df4fa3a fixed some minor issues 2024-04-26 13:27:27 +02:00
6310a99dcb merge 2024-04-26 11:09:51 +02:00
0a2ec43f41 signaux here_doc 2024-04-26 11:07:30 +02:00
c3a0786da1 normed 2024-04-26 10:54:32 +02:00
40a5533c5f nfs 2024-04-26 10:38:01 +02:00
390937d195 stop quand here_doc fail 2024-04-26 10:36:57 +02:00
6de6904a67 Merge branch 'bonus' of github.com:mdev9/minishell into bonus 2024-04-26 10:18:36 +02:00
36f7bfd64d chepa 2024-04-25 19:20:46 +02:00
24f44c27e7 fixed and broke export 2024-04-25 19:03:02 +02:00
1366c49e99 Merge branch 'bonus' of github.com:mdev9/minishell into bonus 2024-04-25 18:41:09 +02:00
2af75c9497 heredoc ctrl+C 2024-04-25 18:41:02 +02:00
df02363087 removed minishell bonus 2024-04-25 18:24:24 +02:00
b8ceec5d95 fixed export with multiple variable definitions and exit long long exit code overflows 2024-04-25 18:21:28 +02:00
15f8e10829 merge 2024-04-25 13:52:01 +02:00
fe095d4b1f glhf pour les conflits 2024-04-25 13:50:19 +02:00
bee12290d5 fixed syntax error error code and exit too big 2024-04-25 13:45:13 +02:00
7f85951e43 fix ************************************* 2024-04-25 10:38:02 +02:00
26cf503126 norme 2024-04-24 21:31:37 +02:00
ae81e8dc45 ça marche bien ! 2024-04-24 21:27:16 +02:00
6b4a3dd857 fixed ambiguous commands 2024-04-24 21:14:54 +02:00
7cb969caba fixed wildcards 2024-04-24 20:40:29 +02:00
86653bb3a0 swp 2024-04-24 19:21:58 +02:00
1cd1e9562f merge 2024-04-24 19:20:42 +02:00
5810e1c970 echoctl 2024-04-24 19:17:24 +02:00
080f05d4f7 updated todo_list 2024-04-24 19:07:28 +02:00
93e4d43283 fixed echo and updated todo_list 2024-04-24 18:43:25 +02:00
52174b8737 Fuck it, YOLO! 2024-04-24 18:11:37 +02:00
59ce849e26 swp 2024-04-24 16:29:00 +02:00
2cbb079036 echoctl et 2024-04-24 15:40:45 +02:00
2f3132a2c3 patate douce 2024-04-24 15:07:12 +02:00
3a55a9f6ec ct kc 2024-04-24 14:42:39 +02:00
4a901bbdb2 merge 2024-04-24 14:07:41 +02:00
79e440d6b6 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 2024-04-24 14:07:14 +02:00
6a05ea29a2 normed 2024-04-24 14:06:52 +02:00
285a99b6a9 fixed norme on output_redirections and updated todo_list 2024-04-24 13:29:38 +02:00
6977ae4f71 merge 2024-04-24 13:07:36 +02:00
2cea45c05d shlvl 2024-04-24 13:06:26 +02:00
20037a4609 organised functions into multiple files and did some more norming 2024-04-24 11:06:03 +02:00
ab5190ee8f fixed norme 2024-04-24 10:45:19 +02:00
8becb3f468 fixed double here_doc 2024-04-24 10:32:29 +02:00
202c5e8811 ça marche bien ! 2024-04-23 20:07:21 +02:00
7044aab736 fix merge 2024-04-23 19:56:19 +02:00
3c5ad3ad89 cd - et oldpwd pwd 2024-04-23 19:54:44 +02:00
006be64ff5 fixed cd builtin 2024-04-23 19:07:56 +02:00
529b7b0ef1 fixed todolist conflict 2024-04-23 18:56:01 +02:00
471a417bf9 patate 2024-04-23 18:51:39 +02:00
e5b705ff64 compiles now 2024-04-23 17:08:08 +02:00
2d8624d221 des trucs 2024-04-23 17:03:30 +02:00
905bbc659b fprintf->ft_printf_fd 2024-04-23 16:42:13 +02:00
b7755111f6 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 2024-04-23 16:35:34 +02:00
b2ff5bcf22 Merge branch 'bonus' of github.com:mdev9/minishell into bonus 2024-04-23 16:03:10 +02:00
7a032b41b1 parentheses 2024-04-23 16:03:01 +02:00
33a37e4711 removed useless files 2024-04-23 13:29:39 +02:00
3cf92d0495 builtin export redirection 2024-04-23 13:22:03 +02:00
3fac53244f preped export redirections 2024-04-23 11:16:39 +02:00
e5de3364e7 redirections cassés 2024-04-22 23:07:06 +02:00
a8fa757432 export sort 2024-04-22 23:06:14 +02:00
67e514d5f9 useless fix (normed infinite loop) 2024-04-22 20:04:28 +02:00
e4df4a5655 did some slight norming (200 lines of norminette and i'm not even done yet... :c) 2024-04-22 19:56:22 +02:00
642a9ab232 fixed leaks and some redirection errors 2024-04-22 19:19:55 +02:00
3cfeeb348a minishell| minishell 2024-04-22 18:40:15 +02:00
a56cd5cc81 erreur parsing 2024-04-22 18:32:11 +02:00
4304a4aaad input redirection 2024-04-22 17:03:26 +02:00
3bd4113489 enorme fix 2024-04-22 16:47:50 +02:00
d35e48eb4f fix $ en fin de chaine 2024-04-22 16:43:50 +02:00
f37b0cf8bc input redirection 2024-04-22 16:37:57 +02:00
9f14d1c1b6 fixed some errors 2024-04-22 15:40:06 +02:00
901ff34b7c fixed builtins in piiiiiiiiiiiiiiiiiiiiipes 2024-04-22 13:38:56 +02:00
30fafc49b0 working on builtin execution in pipes 2024-04-22 12:48:06 +02:00
a8b65c820b end blink async 2024-04-21 23:59:08 +02:00
51934faa06 export et autre 2024-04-21 23:54:15 +02:00
a42ddc1955 here doc repaired and makefile exec.c 2024-04-19 20:51:24 +02:00
e2898b8128 signaux et d'autres trucs mais flemme de le marque ducoup je mets un message de commit plus long pour le dire 2024-04-19 20:10:10 +02:00
dfa81cd19c fix export 2024-04-19 19:55:49 +02:00
27d38f5068 fixed exit | exit 2024-04-19 19:38:06 +02:00
af73eddc64 leaks are no more (for real this time) 2024-04-19 18:53:19 +02:00
a95e4bcbff gros fix 2024-04-19 17:59:51 +02:00
ff1406b93e signaled message 2024-04-19 17:57:44 +02:00
73e576f109 fix and , or 2024-04-19 14:55:01 +02:00
7d696f952f merge 2024-04-19 13:51:18 +02:00
e240f0e1f1 AAAAAAAAAAAAAAAAAAA 2024-04-19 13:50:11 +02:00
70a7bde82f fixed priorities and return codes 2024-04-19 13:46:57 +02:00
700a63c6c8 parsing redirection au millieu d'une commande 2024-04-19 11:17:53 +02:00
302eb2a17b important changes 2024-04-18 23:19:10 +02:00
4585ef9054 merge 2024-04-18 23:06:31 +02:00
8e803ae4cf makefile anti fun pour marijn 2024-04-18 23:05:12 +02:00
fb62d4ceed i think i never speedran the norm like this before 2024-04-18 21:50:23 +02:00
5da5968deb works now (in my dreams) 2024-04-18 18:31:01 +02:00
9053276342 ft_printfd_fd -> fprintf 2024-04-18 17:57:17 +02:00
be46825893 added prints 2024-04-18 17:41:25 +02:00
6fb0af3d17 in et out type reparé( peut-être) 2024-04-17 19:03:34 +02:00
9da2f11ea0 todo 2024-04-17 17:45:33 +02:00
3dcb4e55d7 wildcard sort 2024-04-17 10:49:51 +02:00
483d6579d6 wildcards (mieux) 2024-04-16 09:35:04 +02:00
dd581557de merge 2024-04-15 18:59:10 +02:00
5ab0c197ce wildcards 2024-04-15 18:55:52 +02:00
c1c97e1666 debugging output redirections 2024-04-15 17:14:09 +02:00
95d9c986f2 didnt do much 2024-04-15 12:46:50 +02:00
2862f6bab5 it's really broken 2024-04-13 21:25:38 +02:00
6ea24e899f reput fds into arrays 2024-04-13 13:44:56 +02:00
90e569f231 c'est encore cassé mais un peut moins 2024-04-13 13:22:20 +02:00
51fff7aefd ckc 2024-04-13 12:42:16 +02:00
3a7bbac5cb chepa 2024-04-07 18:04:13 +02:00
2bfd801ba3 ckc 2024-04-06 19:24:34 +02:00
2a4c52f370 encore mieux 2024-04-06 18:46:43 +02:00
6bb41cb5bb amelioration du makefile 2024-04-06 18:37:47 +02:00
4373c0da3d whatthecommit.com’s server IP address could not be found. 2024-04-03 22:07:09 +02:00
babcc2ebdf l'execution marche (un petit peu) ( je crois) 2024-04-03 17:47:21 +02:00
4c9941a5d6 output redirections 2024-04-03 01:29:50 +02:00
c9bd04d42c des trucs 2024-04-02 17:55:30 +02:00
b4c9665dd3 chepa, des trucs, regarde le commit si tu veut savoir 2024-04-02 16:15:49 +02:00
0ebdfd7d34 glhf marijn 2024-04-02 13:51:57 +02:00
a1fa344ef0 Merge branch 'bonus' of github.com:mdev9/minishell into bonus 2024-04-02 13:45:11 +02:00
d68e163595 infinite loop 2024-04-02 13:45:06 +02:00
cbbe866ff4 fixed redirections types handling 2024-04-02 13:44:32 +02:00
eb97119a2f debug 2024-04-02 13:34:20 +02:00
99054a5237 compiles 2024-04-02 13:32:44 +02:00
2473775fa5 AAAA 2024-04-02 13:06:36 +02:00
5580852791 wip (ça compile pas) 2024-04-02 12:32:18 +02:00
68469542ff conflit 2024-04-01 22:06:51 +02:00
fde70abd2b c kc 2024-04-01 21:40:55 +02:00
dc73084ede working on fixing pipes 2024-04-01 21:39:33 +02:00
7d1fba69a9 modified cmds to tokens 2024-04-01 13:59:34 +02:00
e05465348d wip 2024-04-01 11:17:12 +02:00
bd6fba08fe working on bonus execution 2024-03-30 18:58:39 +01:00
eda077e34b parenthese a la fin des arguments de type parenthesis 2024-03-30 16:45:30 +01:00
43936f2cd4 parsing 2024-03-29 18:44:13 +01:00
7e6f3d8a72 no infinite loop 2024-03-29 16:47:23 +01:00
2a06dc1fac compiles now 2024-03-29 16:20:18 +01:00
25a7368c4c parsing bonus (pas complet) 2024-03-29 16:06:12 +01:00
d07a954adf bonus 2024-03-28 14:44:58 +01:00
db934be785 tout tout tout debus parsing bonus 2024-03-27 20:09:04 +01:00
157bb8a1ac yo recipes 2024-03-27 18:29:11 +01:00
eae8f96645 norm ok + compile 2024-03-27 17:34:43 +01:00
ffbbd564f9 norm ok 2024-03-27 17:22:11 +01:00
a9fde3bad1 t_cmd => t_token (parce que c'est plus logique aussi) 2024-03-27 16:23:09 +01:00
7ea57084dd cmd->token to cmd->value parce que c'est plus logique 2024-03-27 15:02:11 +01:00
dad89c923e changement signaux et reactivation du echoctl quand exit 2024-03-27 14:30:32 +01:00
ca90a5f692 fix echo 2024-03-26 14:53:45 +01:00
1acbb38932 exit quand ctrl+c 2024-03-26 14:07:18 +01:00
39d736ac38 fix export variables vides 2024-03-26 14:00:51 +01:00
d767ea3f10 fixed broken redirects from norming, working on broken echo command 2024-03-26 09:22:12 +01:00
0fb72c0c2c fixed echo bt and did some norming 2024-03-26 09:12:32 +01:00
c5b6f8f53e signaux 2024-03-25 20:41:05 +01:00
50dd393b36 here doc sigint 2024-03-25 19:15:34 +01:00
6ffeebf87b here doc variable d'environnement 2024-03-25 18:16:48 +01:00
a7ce98266c Merge branch 'main' of github.com:mdev9/minishell 2024-03-25 13:50:25 +01:00
5a3bbfa236 fixed the unfixable bug 2024-03-25 13:50:20 +01:00
1e6df9ea62 Merge branch 'main' of github.com:mdev9/minishell 2024-03-25 13:31:05 +01:00
a140be4c3e fix env vide 2024-03-25 13:30:55 +01:00
6e0afd2499 fixed some leaks 2024-03-25 13:18:25 +01:00
1f567bd6ce fixed here_doc but lots of leaks 2024-03-25 13:03:23 +01:00
eb5f2bd32e hééééhééééééhééhéééhéééééhéééhé 2024-03-25 12:42:23 +01:00
b25a87953b working on here_doc 2024-03-24 19:28:02 +01:00
a58366f827 can't figure out why it returns wrong value 2024-03-24 10:00:09 +01:00
bedf72b553 Added translation. 2024-03-23 19:46:08 +01:00
aed056ae87 fixed some norme 2024-03-23 19:26:10 +01:00
19bf6c24ff herpderp (redux) 2024-03-23 19:18:32 +01:00
0b81c8e3b0 fixed open fd 2024-03-23 18:15:33 +01:00
d4a95a0d76 stopped caring 20 commits ago 2024-03-23 18:07:17 +01:00
568df14b4a wip 2024-03-23 10:35:39 +01:00
7b6c75b5c3 debut signal 2024-03-22 20:12:25 +01:00
2718546387 Merge branch 'main' of github.com:mdev9/minishell 2024-03-22 14:01:35 +01:00
d6d99aefba export et autres problemes 2024-03-22 14:01:16 +01:00
afbcb6b7ba removed swap file 2024-03-21 16:51:56 +01:00
5677edfce1 chepa 2024-03-21 16:45:30 +01:00
4011934434 removed path from non existant commands 2024-03-21 16:42:41 +01:00
02cb28b60a protection malloc parsing et condition pour empecher les arguments vides 2024-03-20 18:48:25 +01:00
53 changed files with 2315 additions and 1085 deletions

59
.gitignore vendored
View File

@ -1,59 +0,0 @@
# Prerequisites
*.d
minishell
.minishellrc
objs/
.tmp*
out
minishell_tester/
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf

View File

@ -6,7 +6,7 @@
# By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2023/07/28 00:35:01 by tomoron #+# #+# #
# Updated: 2024/03/05 19:11:56 by marde-vr ### ########.fr #
# Updated: 2024/05/22 13:50:22 by tomoron ### ########.fr #
# #
# **************************************************************************** #
@ -15,28 +15,40 @@ SRCS_RAW = main.c\
lst_cmd.c\
cd.c\
lst_env.c\
exec.c\
lst_token.c\
exit.c\
is_fd_open.c\
echo.c\
alias.c\
unalias.c\
pwd.c\
env.c\
parsing.c\
debug.c\
env_to_char_tab.c\
env_utils.c\
parsing_var.c\
handle_alias.c\
lst_alias.c\
minishellrc.c\
path.c\
here_doc.c\
here_doc_utils.c\
export.c\
input_redirections.c\
redirection_utils.c\
sort_wildcard_list.c\
output_redirections.c\
builtins.c\
variable_expantion.c\
wildcards.c\
commands.c\
pipe.c\
utils.c
utils.c\
utils_bonus.c\
signal_handler.c\
parsing_bonus.c\
exec_bonus.c\
exec_utils.c\
get_len_bonus.c\
check_syntax.c\
check_syntax_utils.c\
parsing_utils.c\
unset.c\
free.c
OBJS_DIR = objs/
SRCS_DIR = srcs/
@ -51,29 +63,42 @@ all:
@$(MAKE) --no-print-directory -j $(NAME)
$(NAME) : $(LIBFT) $(OBJS)
$(CC) $(FLAGS) $(OBJS) $(LIBFT) -lreadline -o $(NAME)
@$(CC) $(FLAGS) $(OBJS) $(LIBFT) -lreadline -o $(NAME)
@echo project ready
@if [ ! $(USER) = "marde-vr" ];then\
timeout 2 bash -c 'while :; do r=$$(echo "scale=2;($$RANDOM / 16384) + 0.01" | bc -l);g=$$(echo "scale=2;($$RANDOM / 16384) + 0.01" | bc -l); b=$$(echo "scale=2;($$RANDOM / 16384) + 0.01" | bc -l);xrandr --output "HDMI-1-2" --gamma $$r:$$g:$$b;sleep 0.05;done' || true && xrandr --output HDMI-1-2 --brightness 1&\
fi
$(LIBFT):
make --no-print-directory -j -C ./libft
@echo compiling libft...
@make --no-print-directory -j -C ./libft
@echo done
$(OBJS_DIR):
mkdir -p $(OBJS_DIR)
@mkdir -p $(OBJS_DIR)
$(OBJS_DIR)%.o : $(SRCS_DIR)%.c | $(OBJS_DIR)
$(CC) $(FLAGS) -c $< -o $@
@$(CC) $(FLAGS) -c $< -o $@
clean:
rm -rf $(OBJS_DIR)
make --no-print-directory -C ./libft fclean
@if [ ! $(USER) = "marde-vr" ];then\
bash -c 'gamma=1;while (( $$(echo "$$gamma > 0" | bc -l) )); do gamma=$$(echo "$$gamma - 0.1" | bc); xrandr --output "HDMI-1-2" --brightness $$gamma; done;sleep 0.1';\
fi
@rm -rf $(OBJS_DIR)
@make --no-print-directory -C ./libft fclean
@if [ ! $(USER) = "marde-vr" ];then\
bash -c 'gamma=0;while (( $$(echo "$$gamma < 1" | bc -l) )); do gamma=$$(echo "$$gamma + 0.1" | bc);xrandr --output "HDMI-1-2" --brightness $$gamma;done&';\
fi
bonus: all
@$(CC) $(FLAGS) $(OBJS) $(LIBFT) -lreadline -o $(NAME)_bonus
install: $(NAME)
cp $(NAME) ~/.local/bin/msh
cp $(NAME) ~/.local/bin/minishell
fclean: clean
rm -f $(NAME)
rm -f $(NAME) $(NAME)_bonus
re: fclean all

44
README.md Normal file
View File

@ -0,0 +1,44 @@
# 🐚 minishell Custom UNIX Shell 💻
Welcome to **minishell**, a project that implements a **custom UNIX shell** from the ground up! 🌟 This shell allows for command execution, pipe management, and process handling. 🌐
## 📝 Project Overview
In this project, we create a fully functional **UNIX shell** that supports various commands, piping between processes, and robust error handling. The shell is designed to handle signals 📡 and fork processes efficiently 🍴, simulating the behavior of bash and other traditional UNIX shells. 🚀
### Features:
- 🔹 **Command execution**: Run shell commands with ease.
- 🔹 **Pipe management**: Link commands together for streamlined output processing.
- 🔹 **Signal handling**: Manage signals effectively within the shell environment.
- 🔹 **Process forking**: Create child processes to execute commands.
- 🔹 **Error handling**: Robust mechanisms to handle errors gracefully.
## 🛠️ Installation & Setup
To get started, follow these steps to set up and run the project:
1. **Clone the repository**:
```bash
git clone https://github.com/mdev9/minishell.git
cd minishell
make
```
2. **Run the shell**:
```bash
./minishell
```
## 🔍 Technologies Used
- C 💻: Primary language used to implement the shell.
- System Calls 📞: Leveraging UNIX system calls for process management and execution.
- Pipes 🚰: Implementing inter-process communication through pipes.
- Signals ⚡: Handling OS signals for effective process management.
## 🎯 Goals of the Project
- Create a functional UNIX shell that mimics common shell behaviors.
- Understand key operating system concepts such as process management and system calls.
- Enhance programming skills in C through practical application.
Thank you for checking out minishell! 🌟 Happy coding! 💻

View File

@ -6,7 +6,7 @@
# By: tomoron <marvin@42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2023/07/28 00:35:01 by tomoron #+# #+# #
# Updated: 2024/02/11 17:41:50 by tomoron ### ########.fr #
# Updated: 2024/04/29 11:13:55 by marde-vr ### ########.fr #
# #
# **************************************************************************** #
@ -52,7 +52,8 @@ SRCS = ft_atoi.c\
ft_split_set.c\
ft_free_str_arr.c\
ft_set_color.c\
ft_isspace.c
ft_isspace.c\
ft_str_is_only_char.c\
SRCS_BONUS = ft_lstnew.c\
ft_lstadd_front.c\
@ -73,14 +74,14 @@ all: $(NAME)
$(NAME): ft_printf $(OBJS)
make --no-print-directory -C ./ft_printf
cp ./ft_printf/libftprintf.a ./gnl/gnl.a
make --no-print-directory -C ./gnl
cp ./gnl/gnl.a ./$(NAME)
ar rcs $(NAME) $(OBJS)
@make --no-print-directory -C ./ft_printf
@cp ./ft_printf/libftprintf.a ./gnl/gnl.a
@make --no-print-directory -C ./gnl
@cp ./gnl/gnl.a ./$(NAME)
@ar rcs $(NAME) $(OBJS)
.c.o:
$(CC) $(FLAGS) -c $< -o $@
@$(CC) $(FLAGS) -c $< -o $@
bonus: $(OBJS) $(OBJS_BONUS)
ar rcs $(NAME) $(OBJS) $(OBJS_BONUS)

View File

@ -6,7 +6,7 @@
# By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2023/11/04 08:03:00 by tomoron #+# #+# #
# Updated: 2024/02/16 14:22:14 by marde-vr ### ########.fr #
# Updated: 2024/04/02 16:02:53 by tomoron ### ########.fr #
# #
# **************************************************************************** #
@ -34,10 +34,10 @@ OBJS = $(SRCS:.c=.o)
FLAGS = -Wall -Wextra -Werror
$(NAME): $(OBJS)
ar rcs $(NAME) $(OBJS)
@ar rcs $(NAME) $(OBJS)
.c.o:
$(CC) $(FLAGS) -c $< -o $@
@$(CC) $(FLAGS) -c $< -o $@
all: $(NAME)

25
other/test.c → libft/ft_str_is_only_char.c Executable file → Normal file
View File

@ -1,27 +1,20 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* test.c :+: :+: :+: */
/* ft_str_is_only_char.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tomoron <marvin@42.fr> +#+ +:+ +#+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/04 17:30:08 by tomoron #+# #+# */
/* Updated: 2024/02/09 16:41:52 by tomoron ### ########.fr */
/* Created: 2024/04/29 11:11:31 by marde-vr #+# #+# */
/* Updated: 2024/04/29 11:11:57 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
int ft_str_is_only_char(char *str, char c)
{
int i;
i = 0;
while (i < argc)
{
printf("\"%s\"\n", argv[i]);
i++;
}
while (c && *str == c)
str++;
if (!*str && c)
return (1);
return (0);
}

View File

@ -3,10 +3,10 @@
/* ::: :::::::: */
/* ft_strchr.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tomoron <marvin@42.fr> +#+ +:+ +#+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/10/30 13:35:44 by tomoron #+# #+# */
/* Updated: 2023/11/02 11:08:17 by tomoron ### ########.fr */
/* Updated: 2024/03/21 16:41:59 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
@ -17,6 +17,8 @@ char *ft_strchr(const char *s, int c)
char *res;
i = 0;
if (!s)
return (NULL);
res = (char *)s;
while (res[i])
{

View File

@ -6,7 +6,7 @@
# By: tomoron <marvin@42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2023/11/04 08:03:00 by tomoron #+# #+# #
# Updated: 2023/12/04 09:49:24 by tomoron ### ########.fr #
# Updated: 2024/04/02 16:03:57 by tomoron ### ########.fr #
# #
# **************************************************************************** #
@ -22,10 +22,10 @@ OBJS = $(SRCS:.c=.o)
FLAGS = -Wall -Wextra -Werror
$(NAME): $(OBJS)
ar rcs $(NAME) $(OBJS)
@ar rcs $(NAME) $(OBJS)
.c.o:
$(CC) $(FLAGS) -c $< -o $@
@$(CC) $(FLAGS) -c $< -o $@
all: $(NAME)

View File

@ -6,7 +6,7 @@
/* By: tomoron <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/10/30 16:55:48 by tomoron #+# #+# */
/* Updated: 2024/02/11 17:41:32 by tomoron ### ########.fr */
/* Updated: 2024/04/29 11:12:16 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
@ -46,6 +46,7 @@ void ft_lstadd_front(t_list **lst, t_list *new);
char **ft_split(char const *str, char charset);
void ft_lstadd_back(t_list **lst, t_list *new);
char **ft_split_set(char *str, char *charset);
int ft_str_is_only_char(char *str, char c);
void *ft_memset(void *s, int c, size_t n);
char *ft_get_color(int r, int g, int b);
void *ft_calloc(size_t nb, size_t size);

View File

@ -1,79 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* alias.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/16 23:16:07 by marde-vr #+# #+# */
/* Updated: 2024/02/21 17:39:40 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
char *get_alias_name(t_cmd *arg)
{
int i;
char *res;
i = 0;
while (arg->token[i] && arg->token[i] != '=')
i++;
i++;
res = ft_calloc(i, 1);
ft_strlcpy(res, arg->token, i);
return (res);
}
char *get_alias_value(t_cmd *arg)
{
int i;
char *res;
i = 0;
while (arg->token[i] != '=')
i++;
i++;
res = ft_strdup(arg->token + i);
return (res);
}
void print_aliases(t_alias *aliases)
{
t_alias *cur_alias;
cur_alias = aliases;
while (cur_alias)
{
ft_printf("alias %s=%s\n", cur_alias->name, cur_alias->value);
cur_alias = cur_alias->next;
}
}
int alias(t_msh *msh)
{
char *name;
char *value;
if (!msh->cmds->next || msh->cmds->next->type != ARG)
print_aliases(msh->aliases);
else
{
name = get_alias_name(msh->cmds->next);
if (ft_strchr(msh->cmds->next->token, '='))
{
value = get_alias_value(msh->cmds->next);
msh->aliases = alias_add_back(msh->aliases, name, value);
}
else
{
if (get_alias(msh->aliases, name))
ft_printf("alias %s=%s\n", name, get_alias(msh->aliases, name));
else
ft_printf("minishell: alias %s: not found\n", name);
free(name);
}
}
return (0);
}

81
srcs/builtins.c Normal file → Executable file
View File

@ -6,7 +6,7 @@
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/03/05 18:20:21 by marde-vr #+# #+# */
/* Updated: 2024/03/05 18:51:41 by marde-vr ### ########.fr */
/* Updated: 2024/04/29 21:47:25 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
@ -14,9 +14,9 @@
int cmd_is_forkable_builtin(char *cmd_token)
{
if (!ft_strcmp(cmd_token, "echo") || !ft_strcmp(cmd_token, "ret")
|| !ft_strcmp(cmd_token, "env") || !ft_strcmp(cmd_token, "exit")
|| !ft_strcmp(cmd_token, "pwd") || !ft_strcmp(cmd_token, "export")
if (!ft_strcmp(cmd_token, "echo") || !ft_strcmp(cmd_token, "env")
|| !ft_strcmp(cmd_token, "exit") || !ft_strcmp(cmd_token, "pwd")
|| !ft_strcmp(cmd_token, "cd") || !ft_strcmp(cmd_token, "export")
|| !ft_strcmp(cmd_token, "unset"))
return (1);
return (0);
@ -26,54 +26,45 @@ int cmd_is_builtin(t_msh *msh, char *cmd_token)
{
if (!cmd_token)
return (0);
else if (!ft_strcmp(cmd_token, "cd"))
{
cd(msh->cmds);
else if ((msh->in_type == PIPE || msh->out_type == PIPE)
&& cmd_is_forkable_builtin(cmd_token) && ft_strcmp(cmd_token, "export"))
return (1);
}
else if (!ft_strcmp(cmd_token, "unalias"))
{
unalias(msh);
return (1);
}
else if (!ft_strcmp(cmd_token, "alias"))
{
alias(msh);
return (1);
}
else if (!ft_strcmp(cmd_token, "cd") && msh->out_type != PIPE)
g_return_code = cd(msh->tokens, msh);
else if (!ft_strcmp(cmd_token, "exit"))
{
exit_bt(msh);
return (1);
}
return (cmd_is_forkable_builtin(cmd_token));
g_return_code = exit_bt(msh);
else if (!ft_strcmp(cmd_token, "export") && msh->out_type != PIPE)
g_return_code = ft_export(msh, msh->tokens, msh->env);
else if (!ft_strcmp(cmd_token, "unset"))
g_return_code = ft_unset(msh);
else
return (cmd_is_forkable_builtin(cmd_token));
return (1);
}
int exec_builtin(t_msh *msh)
{
if (!msh->cmds->token)
return (STDIN_FILENO);
if (!ft_strcmp(msh->cmds->token, "echo"))
g_return_code = echo(msh->cmds->next);
else if (!ft_strcmp(msh->cmds->token, "ret"))
g_return_code = ft_atoi(msh->cmds->next->token);
else if (!ft_strcmp(msh->cmds->token, "env"))
if (!msh->tokens->value)
return (0);
if (!ft_strcmp(msh->tokens->value, "echo"))
g_return_code = echo(msh->tokens->next);
else if (!ft_strcmp(msh->tokens->value, "env"))
g_return_code = print_env(msh->env);
else if (!ft_strcmp(msh->cmds->token, "exit"))
exit_bt(msh);
else if (!ft_strcmp(msh->cmds->token, "pwd"))
else if (!ft_strcmp(msh->tokens->value, "exit"))
return (1);
else if (!ft_strcmp(msh->tokens->value, "pwd"))
g_return_code = pwd();
else if (!ft_strcmp(msh->cmds->token, "cd"))
g_return_code = cd(msh->cmds);
else if (!ft_strcmp(msh->cmds->token, "export"))
g_return_code = ft_export(msh);
else if (!ft_strcmp(msh->cmds->token, "unset"))
g_return_code = ft_unset(msh);
else if (!ft_strcmp(msh->cmds->token, "alias"))
g_return_code = alias(msh);
else if (!ft_strcmp(msh->cmds->token, "unalias"))
g_return_code = unalias(msh);
else if (!ft_strcmp(msh->tokens->value, "cd") && msh->out_type == PIPE)
g_return_code = cd(msh->tokens, msh);
else if (!ft_strcmp(msh->tokens->value, "cd"))
return (1);
else if (!ft_strcmp(msh->tokens->value, "export") && msh->out_type == PIPE)
g_return_code = ft_export(msh, msh->tokens, msh->env);
else if (!ft_strcmp(msh->tokens->value, "export"))
return (1);
else if (!ft_strcmp(msh->tokens->value, "unset"))
return (1);
else
return (STDIN_FILENO);
return (STDOUT_FILENO);
return (0);
return (1);
}

65
srcs/cd.c Normal file → Executable file
View File

@ -6,30 +6,77 @@
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/16 21:02:54 by marde-vr #+# #+# */
/* Updated: 2024/03/06 08:43:53 by marde-vr ### ########.fr */
/* Updated: 2024/05/03 08:39:33 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int cd(t_cmd *args)
void cd_update_pwd(t_msh *msh)
{
char *pwd;
char *new;
new = getcwd(0, 16382);
if (!new)
return ;
pwd = ft_get_env(msh->env, "PWD");
pwd = ft_strdup(pwd);
if (!pwd)
pwd = ft_strdup("");
if (!pwd)
free(new);
if (!pwd)
return ;
msh->env = export_set_env(msh->env, ft_strdup("OLDPWD"), pwd, 0);
msh->env = export_set_env(msh->env, ft_strdup("PWD"), new, 0);
}
char *get_new_wd(t_token *arg, t_msh *msh)
{
char *nw_wd;
if (arg)
{
nw_wd = arg->value;
if (!ft_strcmp("-", nw_wd))
{
nw_wd = ft_get_env(msh->env, "OLDPWD");
if (!nw_wd)
ft_putstr_fd("minishell: cd: OLDPWD not set\n", 2);
if (!nw_wd)
return (0);
ft_printf_fd((1 * (msh->out_fd == 0)) + msh->out_fd, "%s\n", nw_wd);
}
}
else
{
nw_wd = ft_get_env(msh->env, "HOME");
if (!nw_wd)
ft_putstr_fd("minishell: cd: HOME not set\n", 2);
if (!nw_wd)
return (0);
}
return (nw_wd);
}
int cd(t_token *args, t_msh *msh)
{
char *new_wd;
if (args->next && args->next->next && args->next->next->type == ARG)
if (args->next && args->next->next)
{
ft_printf_fd(2, "minishell: cd: too many arguments\n");
g_return_code = 1;
return (1);
}
if (!args->next || args->next->type != ARG)
new_wd = getenv("HOME");
else
new_wd = args->next->token;
new_wd = get_new_wd(args->next, msh);
if (!new_wd)
return (1);
if (chdir(new_wd) == -1)
{
perror("minishell: cd");
g_return_code = 1;
return (1);
}
cd_update_pwd(msh);
return (0);
}

120
srcs/check_syntax.c Normal file
View File

@ -0,0 +1,120 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* check_syntax.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tomoron <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/24 14:50:15 by tomoron #+# #+# */
/* Updated: 2024/04/26 14:39:48 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int check_parens_syntax(t_cmd *cmd, t_cmd *last, t_env *env)
{
t_cmd *parsed_cmd;
t_cmd *tmp;
if (last && is_cmd_type(last))
{
ft_putstr_fd("minishell: syntax error\n", 2);
g_return_code = 2;
return (0);
}
parsed_cmd = parsing_bonus(cmd->value);
if (!parsed_cmd)
{
ft_putstr_fd("minishell: syntax error\n", 2);
g_return_code = 2;
return (0);
}
tmp = check_cmds_syntax(parsed_cmd, env);
if (tmp)
print_syntax_error_bonus(tmp, 0);
free_cmd(parsed_cmd);
return (tmp == 0);
}
int check_cmd_type_syntax(t_cmd *cmds, t_cmd *last, t_env *env)
{
if (cmds->cmd_type == CMD)
{
if (!check_tokens_syntax(cmds, last, env))
return (0);
}
else if (cmds->cmd_type == PAREN)
{
if (!check_parens_syntax(cmds, last, env))
return (0);
}
return (1);
}
int check_cmd_syntax(t_cmd *cmds, t_cmd *last, t_env *env)
{
if (cmds->cmd_type == ERR)
return (1);
if (!is_operand_type(cmds) && cmds->cmd_type != PIPE
&& cmds->value == 0)
return (1);
if (is_operand_type(cmds) || cmds->cmd_type == PIPE)
if ((!is_cmd_type(last) && !is_output_type(last)
&& !is_input_type(last)) || !cmds->next
|| (!is_cmd_type(cmds->next) && !is_output_type(cmds->next)
&& !is_input_type(cmds->next)))
return (1);
if (is_cmd_type(cmds) && !check_cmd_type_syntax(cmds, last, env))
return (1);
return (0);
}
t_cmd *check_cmds_syntax(t_cmd *cmds, t_env *env)
{
t_cmd *last;
if (!cmds || is_operand_type(cmds) || cmds->cmd_type == PIPE)
return (cmds);
if (!is_operand_type(cmds) && cmds->cmd_type != PIPE && cmds->value == 0)
return (cmds);
last = cmds;
if (is_cmd_type(cmds) && !check_cmd_type_syntax(cmds, 0, env))
return (cmds);
cmds = cmds->next;
while (cmds)
{
if (check_cmd_syntax(cmds, last, env))
return (cmds);
last = cmds;
cmds = cmds->next;
}
return (0);
}
int check_str_syntax(char *cmd)
{
int in_quote;
int in_dquote;
int parenthesis;
in_quote = 0;
in_dquote = 0;
parenthesis = 0;
while (*cmd)
{
if (*cmd == '\'' && !in_dquote)
in_quote = !in_quote;
if (*cmd == '"' && !in_quote)
in_dquote = !in_dquote;
if ((*cmd == '(' || *cmd == ')') && !in_quote && !in_dquote)
parenthesis += 1 - (2 * (*cmd == ')'));
cmd++;
}
if (in_quote || in_dquote || parenthesis)
{
ft_putstr_fd("minishell: syntax error\n", 2);
g_return_code = 2;
}
return (!(in_quote || in_dquote || parenthesis));
}

52
srcs/check_syntax_utils.c Normal file
View File

@ -0,0 +1,52 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* check_syntax_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tomoron <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/24 14:54:53 by tomoron #+# #+# */
/* Updated: 2024/05/03 08:13:45 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void print_syntax_error_bonus(t_cmd *cmd, t_cmd *cmds)
{
if (cmd->cmd_type == CMD || cmd->cmd_type == PAREN)
{
free_cmd(cmds);
return ;
}
ft_printf_fd(2, "minishell : syntax error near unexpected token `");
g_return_code = 2;
if (cmd->cmd_type == AND)
ft_printf_fd(2, "&&");
if (cmd->cmd_type == OR)
ft_printf_fd(2, "||");
if (cmd->cmd_type == PIPE)
ft_printf_fd(2, "|");
if (cmd->cmd_type == ERR)
ft_printf_fd(2, "&");
ft_printf_fd(2, "'\n");
free_cmd(cmds);
}
int check_tokens_syntax(t_cmd *cmd, t_cmd *last, t_env *env)
{
t_token *token;
if (last && is_cmd_type(last))
{
g_return_code = 2;
ft_putstr_fd("minishell : syntax error\n", 2);
g_return_code = 2;
return (0);
}
token = parse_cmds_to_token(cmd, env);
if (token == (void *)1)
return (0);
free_token(token);
return (1);
}

89
srcs/commands.c Normal file → Executable file
View File

@ -6,49 +6,25 @@
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/03/05 18:22:15 by marde-vr #+# #+# */
/* Updated: 2024/03/05 18:24:19 by marde-vr ### ########.fr */
/* Updated: 2024/04/23 13:46:25 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int get_cmd_count(t_cmd *cmds)
int get_args_count(t_token *cmds)
{
int count;
t_cmd *cur_cmd;
t_token *cur_cmd;
count = 0;
cur_cmd = cmds;
while (cur_cmd->next != 0)
{
if (cur_cmd->type != ARG)
if (cur_cmd->type == PIPE)
count++;
cur_cmd = cur_cmd->next;
}
if (cur_cmd->type == ARG)
if (cur_cmd)
count++;
return (count);
}
int get_args_count(t_cmd *cmds)
{
int count;
t_cmd *cur_cmd;
count = 0;
cur_cmd = cmds;
if (cur_cmd->type == ARG)
count++;
while (cur_cmd->next)
while (cur_cmd && cur_cmd->next)
{
if (cur_cmd->type == PIPE)
break ;
cur_cmd = cur_cmd->next;
if (cur_cmd->type == ARG)
count++;
else if (cur_cmd->type != PIPE)
cur_cmd = cur_cmd->next;
count++;
}
return (count);
}
@ -56,22 +32,24 @@ int get_args_count(t_cmd *cmds)
char **get_cmd_args(t_msh *msh)
{
char **cmd_args;
t_cmd *cur_cmd;
t_token *cur_cmd;
int args_count;
int i;
args_count = get_args_count(msh->cmds);
args_count = get_args_count(msh->tokens);
cmd_args = ft_calloc(args_count + 1, sizeof(char *));
if (!cmd_args || !msh->fds)
if (!cmd_args)
ft_exit(msh, 1);
cur_cmd = msh->cmds;
cur_cmd = msh->tokens;
i = 0;
while (i < args_count)
{
if (cur_cmd->type == ARG)
if (cur_cmd)
{
cmd_args[i] = cur_cmd->token;
i++;
if (!i)
cmd_args[i++] = remove_path(cur_cmd->value);
else
cmd_args[i++] = cur_cmd->value;
}
else
cur_cmd = cur_cmd->next;
@ -82,28 +60,19 @@ char **get_cmd_args(t_msh *msh)
void remove_command_from_msh(t_msh *msh)
{
t_cmd *cur_cmd;
t_cmd *cmd_tmp;
t_cmd *tmp;
cur_cmd = msh->cmds;
while (cur_cmd && cur_cmd->next)
{
if (cur_cmd->type == PIPE)
{
cmd_tmp = cur_cmd;
cur_cmd = cur_cmd->next;
msh->in_type = cmd_tmp->type;
free(cmd_tmp->token);
free(cmd_tmp);
msh->cmds = cur_cmd;
return ;
}
cmd_tmp = cur_cmd;
cur_cmd = cur_cmd->next;
msh->in_type = cur_cmd->type;
free(cmd_tmp->token);
free(cmd_tmp);
msh->cmds = cur_cmd;
}
msh->in_type = msh->cmds->type;
free_token(msh->tokens);
while (msh->cmds && !is_cmd_type(msh->cmds))
msh->cmds = msh->cmds->next;
while (msh->cmds && (is_cmd_type(msh->cmds) || is_input_type(msh->cmds)
|| is_output_type(msh->cmds)))
msh->cmds = msh->cmds->next;
tmp = msh->cmds;
while (tmp && !is_cmd_type(tmp))
tmp = tmp->next;
if (tmp)
msh->tokens = parse_cmds_to_token(tmp, msh->env);
else
msh->tokens = 0;
}

View File

@ -6,41 +6,43 @@
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/07 15:30:37 by tomoron #+# #+# */
/* Updated: 2024/03/05 19:00:53 by marde-vr ### ########.fr */
/* Updated: 2024/04/29 22:11:06 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
#include <unistd.h>
void put_args(t_cmd *args)
void put_args(t_token *args)
{
int first;
first = 1;
while (args && args->type != PIPE)
while (args)
{
if (args->type != ARG)
args = args->next;
else
{
if (!first)
ft_putchar_fd(' ', STDOUT_FILENO);
ft_putstr_fd(args->token, STDOUT_FILENO);
first = 0;
}
if (!first)
ft_putchar_fd(' ', STDOUT_FILENO);
ft_putstr_fd(args->value, STDOUT_FILENO);
first = 0;
args = args->next;
}
}
int echo(t_cmd *args)
int echo(t_token *args)
{
int put_nl;
int i;
put_nl = 1;
while (args && args->token && !strcmp(args->token, "-n"))
while (args && args->value && args->value[0] == '-')
{
put_nl = 0;
i = 1;
while (args->value[i] == 'n')
i++;
if (!args->value[i] && i > 1)
put_nl = 0;
else
break ;
args = args->next;
}
put_args(args);

104
srcs/env.c Normal file
View File

@ -0,0 +1,104 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* env.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/24 10:58:36 by marde-vr #+# #+# */
/* Updated: 2024/05/03 14:25:03 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_env *dup_env(t_env *env)
{
t_env *res;
res = 0;
while (env)
{
res = env_add_back(res, env->name, env->value, 0);
env = env->next;
}
return (res);
}
void sort_env(t_env *env)
{
t_env *tmp;
t_env *start;
char *tmp_str;
tmp = env;
start = env;
while (tmp)
{
env = start;
while (env)
{
if (ft_strcmp(tmp->name, env->name) < 0)
{
tmp_str = tmp->name;
tmp->name = env->name;
env->name = tmp_str;
tmp_str = tmp->value;
tmp->value = env->value;
env->value = tmp_str;
}
env = env->next;
}
tmp = tmp->next;
}
}
void print_env_declare(t_msh *msh, t_env *env_orig)
{
t_env *env;
t_env *start;
env = dup_env(env_orig);
sort_env(env);
start = env;
if (!msh->out_fd)
msh->out_fd = 1;
while (env)
{
if (strcmp(env->name, "_"))
{
if (env->value)
ft_printf_fd(msh->out_fd, "declare -x %s=\"%s\"\n", env->name,
env->value);
else
ft_printf_fd(msh->out_fd, "declare -x %s\n", env->name);
}
env = env->next;
}
free_env_cpy(start);
}
void delete_from_env(t_msh *msh, char *name)
{
t_env *tmp_env;
t_env *prev;
tmp_env = msh->env;
prev = 0;
while (tmp_env)
{
if (!strcmp(name, tmp_env->name))
{
free(tmp_env->name);
free(tmp_env->value);
if (!prev)
msh->env = tmp_env->next;
else
prev->next = tmp_env->next;
free(tmp_env);
return ;
}
prev = tmp_env;
tmp_env = tmp_env->next;
}
}

25
srcs/env_to_char_tab.c → srcs/env_utils.c Normal file → Executable file
View File

@ -1,12 +1,12 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* env_to_char_tab.c :+: :+: :+: */
/* env_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/16 13:30:18 by tomoron #+# #+# */
/* Updated: 2024/02/16 15:08:53 by marde-vr ### ########.fr */
/* Updated: 2024/05/16 13:18:46 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
@ -43,3 +43,24 @@ char **env_to_char_tab(t_env *env)
}
return (res);
}
char **split_paths_from_env(t_env *env)
{
t_env *cur_env_var;
int path_in_envp;
path_in_envp = 0;
cur_env_var = env;
while (cur_env_var)
{
if (!ft_strcmp(cur_env_var->name, "PATH"))
{
path_in_envp = 1;
break ;
}
cur_env_var = cur_env_var->next;
}
if (!path_in_envp)
return (0);
return (ft_split(cur_env_var->value, ':'));
}

View File

@ -1,94 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* exec.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/07 14:12:49 by tomoron #+# #+# */
/* Updated: 2024/03/05 19:05:20 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int exec(t_msh *msh, char **cmd_args, int i, int cmd_count)
{
pid_t pid;
if (i != cmd_count - 1)
{
if (pipe(msh->fds[i]) == -1)
{
perror("pipe");
ft_exit(msh, 1);
}
}
pid = fork();
if (pid == -1)
{
perror("fork");
ft_exit(msh, 1);
}
if (pid == 0)
child(msh, cmd_args, i);
else
{
parent(msh, i, cmd_count);
msh->pids[i] = pid;
free(cmd_args);
}
return (0);
}
void exec_command(t_msh *msh, int i, int cmd_count)
{
g_return_code = 0;
msh->fds[i] = ft_calloc(2, sizeof(int *));
if (!msh->fds[i])
ft_exit(msh, 1);
if (first_is_in_type(msh))
{
get_in_type(msh, msh->cmds);
if (!g_return_code)
get_out_type(msh, msh->cmds);
}
else
{
get_out_type(msh, msh->cmds);
if (!g_return_code)
get_in_type(msh, msh->cmds);
}
if (!cmd_is_builtin(msh, msh->cmds->token))
get_cmd_path(msh);
exec(msh, get_cmd_args(msh), i, cmd_count);
remove_command_from_msh(msh);
}
void exec_commands(t_msh *msh)
{
int cmd_count;
int i;
i = -1;
if (!msh->cmds)
return ;
cmd_count = get_cmd_count(msh->cmds);
msh->fds = ft_calloc(cmd_count, sizeof(int **));
msh->pids = ft_calloc(cmd_count, sizeof(int *));
if (!msh->pids || !msh->fds)
ft_exit(msh, 1);
while (++i < cmd_count)
exec_command(msh, i, cmd_count);
i = cmd_count;
while (--i >= 0)
waitpid(msh->pids[i], 0, 0);
i = 0;
while (i < cmd_count)
{
free(msh->fds[i]);
i++;
}
free(msh->fds);
free(msh->pids);
}

155
srcs/exec_bonus.c Executable file
View File

@ -0,0 +1,155 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* exec_bonus.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/03/28 13:50:14 by tomoron #+# #+# */
/* Updated: 2024/05/07 17:26:49 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void exec_command_bonus(t_msh *msh, char *cmd_str)
{
t_cmd *cmds;
t_cmd *tmp;
if (!cmd_str)
return ;
cmds = parsing_bonus(cmd_str);
free(cmd_str);
tmp = check_cmds_syntax(cmds, msh->env);
if (tmp)
{
print_syntax_error_bonus(tmp, cmds);
return ;
}
msh->cmds_head = cmds;
while (cmds)
{
msh->tokens = parse_cmds_to_token(cmds, msh->env);
msh->cmds = cmds;
exec_commands(msh);
msh->in_fd = 0;
msh->out_fd = 0;
cmds = get_next_command(cmds);
}
free_cmd(msh->cmds_head);
msh->cmds_head = 0;
}
int exec(t_msh *msh, char **cmd_args, int i, int cmd_count)
{
pid_t pid;
if (i != cmd_count - 1)
{
if (pipe(msh->fds[i]) == -1)
{
perror("minishell: pipe");
free(cmd_args);
ft_exit(msh, 1);
}
}
pid = fork();
if (pid == -1)
{
perror("minishell: fork");
free(cmd_args);
ft_exit(msh, 1);
}
if (pid == 0)
child(msh, cmd_args, i);
if (pid != 0)
msh->pids[i] = pid;
if (pid != 0)
parent(msh, i, cmd_count, cmd_args);
return (0);
}
void exec_command(t_msh *msh, int i, int cmd_count)
{
get_redirections(msh, msh->cmds);
if (msh->in_fd != -2)
{
msh->last_return_code = g_return_code;
g_return_code = 0;
msh->fds[i] = ft_calloc(2, sizeof(int *));
if (!msh->fds[i])
ft_exit(msh, 1);
if (msh->tokens && !cmd_is_builtin(msh, msh->tokens->value))
get_cmd_path(msh);
if (((msh->tokens && msh->tokens->value) || is_parenthesis(msh->cmds)))
exec(msh, get_cmd_args(msh), i, cmd_count);
else
{
if (msh->in_fd > 2)
close(msh->in_fd);
if (msh->out_fd > 2)
close(msh->out_fd);
if (!g_return_code)
g_return_code = 1;
}
}
remove_command_from_msh(msh);
}
void end_execution(t_msh *msh, int cmd_count)
{
int i;
int status;
i = 0;
status = 0;
while (i < cmd_count)
waitpid(msh->pids[i++], &status, 0);
close_all_pipes(msh);
if (!g_return_code && WIFEXITED(status))
g_return_code = WEXITSTATUS(status);
if (WIFSIGNALED(status))
print_signaled(status);
if (msh->here_doc_filename)
{
unlink(msh->here_doc_filename);
free(msh->here_doc_filename);
msh->here_doc_filename = 0;
}
free(msh->pids);
free_fds(msh);
msh->pids = 0;
free(msh->fds);
signal(SIGINT, signal_handler_interactive);
signal(SIGQUIT, signal_handler_interactive);
}
void exec_commands(t_msh *msh)
{
int cmd_count;
int i;
if (!msh->tokens && !is_parenthesis(msh->cmds))
{
get_redirections(msh, msh->cmds);
g_return_code = (msh->in_fd < 0 || msh->out_fd < 0);
remove_here_doc_file(msh);
if (msh->in_fd > 2)
close(msh->in_fd);
if (msh->out_fd > 2)
close(msh->out_fd);
return ;
}
cmd_count = get_cmd_count(msh->cmds);
msh->fds = ft_calloc(cmd_count + 1, sizeof(int **));
msh->pids = ft_calloc(cmd_count, sizeof(int *));
if (!msh->pids || !msh->fds)
ft_exit(msh, 1);
i = -1;
while (++i < cmd_count && msh->in_fd != -2)
exec_command(msh, i, cmd_count);
free_token(msh->tokens);
msh->tokens = 0;
end_execution(msh, cmd_count);
}

100
srcs/exec_utils.c Normal file
View File

@ -0,0 +1,100 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* exec_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/24 10:46:28 by marde-vr #+# #+# */
/* Updated: 2024/05/06 10:56:52 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void get_redirections(t_msh *msh, t_cmd *cmds)
{
msh->in_type = 0;
msh->out_type = 0;
msh->in_fd = 0;
msh->out_fd = 0;
if (first_is_in_type(cmds))
{
if (!get_in_type(msh, cmds, cmds, 1))
get_out_type(msh, cmds);
}
else
{
if (!get_out_type(msh, cmds))
get_in_type(msh, cmds, cmds, 1);
}
}
t_cmd *get_next_command(t_cmd *cmd)
{
while (cmd)
{
while (cmd && !is_operand_type(cmd))
cmd = cmd->next;
if (cmd && cmd->cmd_type == AND && !g_return_code)
return (cmd->next);
if (cmd && cmd->cmd_type == OR && g_return_code)
return (cmd->next);
if (cmd)
cmd = cmd->next;
}
return (0);
}
int get_cmd_count(t_cmd *cmds)
{
int nb;
nb = 1;
while (cmds && !is_operand_type(cmds))
{
if (cmds && cmds->cmd_type == PIPE)
{
nb++;
}
cmds = cmds->next;
}
return (nb);
}
int is_parenthesis(t_cmd *cmd)
{
if (!cmd)
return (0);
return (cmd->cmd_type == PAREN || (cmd->cmd_type == PIPE
&& cmd->next->cmd_type == PAREN));
}
void print_signaled(int status)
{
int signal;
static const char *sigmsg[] = {0, "Hangup", 0, "Quit", "Illegal \
instruction", "Trace/breakpoint trap", "Aborted", "Bus error",
"Floating point exception", "Killed", "User defined signal 1",
"Segmentation fault (skill issue)", "User defined signal 2", 0,
"Alarm clock", "Terminated", "Stack fault", 0, 0, "Stopped", "Stopped",
"Stopped", "Stopped", 0, "CPU time limit exceeded",
"File size limit exceeded", "Virtual time expired",
"Profiling timer expired", "I/O possible", "Power failure",
"Bad system call"};
signal = WTERMSIG(status);
if (signal < 31 && sigmsg[signal])
{
ft_putstr_fd((char *)sigmsg[signal], 2);
}
if (signal >= 34 && signal <= 64)
{
ft_putstr_fd("Real-time signal ", 2);
ft_putnbr_fd(signal - 34, 2);
}
if (WCOREDUMP(status))
ft_putstr_fd(" (core dumped)", 2);
ft_putstr_fd("\n", 2);
g_return_code = signal + 128;
}

View File

@ -6,7 +6,7 @@
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/07 16:04:11 by tomoron #+# #+# */
/* Updated: 2024/03/06 09:10:11 by marde-vr ### ########.fr */
/* Updated: 2024/05/16 12:49:41 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
@ -20,29 +20,42 @@ void numeric_arg_err(char *arg, int *exit_code)
*exit_code = 2;
}
void exit_bt(t_msh *msh)
int is_too_big(char *num_str)
{
t_cmd *cur_cmd;
if ((strlen(num_str) == 19 && strcmp(num_str, "9223372036854775807") > 0)
|| (strlen(num_str) == 20 && num_str[0] == '-' && strcmp(num_str,
"-9223372036854775808") > 0) || strlen(num_str) >= 20)
return (1);
return (0);
}
void get_exit_bt_return_code(t_msh *msh, int *exit_code)
{
t_token *cur_cmd;
cur_cmd = msh->tokens->next;
if (cur_cmd && (!ft_strisnbr(cur_cmd->value) || is_too_big(cur_cmd->value)))
numeric_arg_err(cur_cmd->value, exit_code);
else if (cur_cmd)
*exit_code = (unsigned char)ft_atoi(cur_cmd->value);
else
*exit_code = msh->last_return_code;
}
int exit_bt(t_msh *msh)
{
t_token *cur_cmd;
int exit_code;
cur_cmd = msh->cmds->next;
cur_cmd = msh->tokens->next;
ft_printf("exit\n");
if (cur_cmd && cur_cmd->next && cur_cmd->next->type == ARG
&& ft_strisnbr(cur_cmd->token))
{
if (cur_cmd && cur_cmd->next && ft_strisnbr(cur_cmd->value))
ft_putstr_fd("minishell: exit: too many arguments\n", 2);
g_return_code = 1;
}
else
{
if (cur_cmd && cur_cmd->type == ARG
&& !ft_strisnbr(cur_cmd->token))
numeric_arg_err(cur_cmd->token, &exit_code);
else if (cur_cmd && cur_cmd->type == ARG)
exit_code = (unsigned char)ft_atoi(cur_cmd->token);
else
exit_code = g_return_code;
get_exit_bt_return_code(msh, &exit_code);
free_msh(msh);
exit(exit_code);
}
return (1);
}

102
srcs/export.c Normal file → Executable file
View File

@ -6,26 +6,108 @@
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/18 18:29:20 by marde-vr #+# #+# */
/* Updated: 2024/02/28 12:45:59 by marde-vr ### ########.fr */
/* Updated: 2024/05/03 14:50:57 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int ft_export(t_msh *msh)
int export_invalid_identifier(char *arg, char *name)
{
t_cmd *cmd;
ft_putstr_fd("minishell: export: `", 2);
ft_putstr_fd(arg, 2);
ft_putstr_fd("': not a valid identifier\n", 2);
free(name);
return (1);
}
cmd = msh->cmds;
(void)cmd;
t_env *set_env(t_env *env, char *name, char *value, int flags)
{
t_env *tmp;
tmp = env;
while (tmp)
{
if (!ft_strcmp(name, tmp->name))
{
free(name);
if (!*value && !(flags & 0b10))
{
free(value);
return (env);
}
if ((flags & 0b1) && tmp->value)
value = ft_strjoin_free(tmp->value, value, 2);
if (!value)
return (env);
free(tmp->value);
tmp->value = value;
return (env);
}
tmp = tmp->next;
}
return (env_add_back(env, name, value, !(flags & 0b10)));
}
t_env *export_set_env(t_env *env, char *name, char *value, int flags)
{
if (!value || !name)
{
free(name);
free(value);
ft_printf_fd(2, "minishell: malloc failed");
return (env);
}
return (set_env(env, name, value, flags));
}
int export_var(t_token *cmd, t_env **env)
{
char *arg;
char *name;
char *value;
int len;
int flags;
len = 0;
arg = cmd->value;
while (arg[len] && arg[len] != '=' && arg[len] != '+')
len++;
name = ft_substr(arg, 0, len);
flags = arg[len] == '+';
if (arg[len] == '+' && arg[len + 1] == '=')
len++;
if (arg[len] == '=')
{
flags += 0b10;
len++;
}
if (!name || !check_var_name(name) || arg[len] == '+')
return (export_invalid_identifier(arg, name));
value = ft_strdup(arg + len);
*env = export_set_env(*env, name, value, flags);
return (0);
}
int ft_unset(t_msh *msh)
int ft_export(t_msh *msh, t_token *cmd, t_env *env)
{
t_cmd *cmd;
int error;
cmd = msh->cmds;
(void)cmd;
return (0);
error = 0;
if (cmd && !cmd->next)
{
print_env_declare(msh, env);
return (0);
}
cmd = cmd->next;
while (cmd->next)
{
if (export_var(cmd, &env))
error = 1;
cmd = cmd->next;
}
if (export_var(cmd, &env))
error = 1;
msh->env = env;
return (error);
}

64
srcs/free.c Normal file
View File

@ -0,0 +1,64 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* free.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/24 10:51:13 by marde-vr #+# #+# */
/* Updated: 2024/04/25 19:01:49 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void free_fds(t_msh *msh)
{
int i;
if (msh->fds)
{
i = 0;
while (msh->fds[i])
{
free(msh->fds[i]);
msh->fds[i] = 0;
i++;
}
free(msh->fds);
msh->fds = 0;
}
}
void free_msh(t_msh *msh)
{
if (msh)
{
free_env(msh->env);
free(msh->pids);
free_cmd(msh->cmds_head);
free_fds(msh);
free(msh->here_doc_filename);
free_token(msh->tokens);
free(msh);
}
}
void free_env_cpy(t_env *env)
{
if (env && env->next)
free_env_cpy(env->next);
free(env);
}
void free_env(t_env *env)
{
if (env && env->next)
free_env(env->next);
if (env)
{
free(env->name);
free(env->value);
}
free(env);
}

81
srcs/get_len_bonus.c Normal file
View File

@ -0,0 +1,81 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_len_bonus.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tomoron <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/24 14:51:00 by tomoron #+# #+# */
/* Updated: 2024/05/06 11:14:51 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int get_normal_cmd_len(char *cmd)
{
int len;
int in_quote;
int in_dquote;
len = 0;
in_quote = 0;
in_dquote = 0;
while (cmd[len] && (in_quote || in_dquote || (cmd[len] != '|'
&& cmd[len] != '&' && cmd[len] != '(' && cmd[len] != ')'
&& cmd[len] != '<' && cmd[len] != '>')))
{
if (cmd[len] == '\'' && !in_dquote)
in_quote = !in_quote;
if (cmd[len] == '"' && !in_quote)
in_dquote = !in_dquote;
len++;
}
return (len);
}
int get_next_arg_len(char *cmd)
{
int len;
int in_quote;
int in_dquote;
len = 0;
in_quote = 0;
in_dquote = 0;
while (cmd[len] && ((!ft_isspace(cmd[len]) && cmd[len] != '&'
&& cmd[len] != '|' && cmd[len] != '<' && cmd[len] != '>'
&& cmd[len] != '(' && cmd[len] != ')')
|| in_quote || in_dquote))
{
if (cmd[len] == '\'' && !in_dquote)
in_quote = !in_quote;
if (cmd[len] == '"' && !in_quote)
in_dquote = !in_dquote;
len++;
}
return (len);
}
int get_parenthesis_cmd_len(char *cmd)
{
int len;
int parenthesis;
int in_quote;
int in_dquote;
len = 0;
parenthesis = 1;
in_quote = 0;
in_dquote = 0;
while (cmd[len] && parenthesis)
{
if (cmd[len] == '\'' && !in_dquote)
in_quote = !in_quote;
if (cmd[len] == '"' && !in_quote)
in_dquote = !in_dquote;
if ((cmd[len] == '(' || cmd[len] == ')') && !in_quote && !in_dquote)
parenthesis += 1 - ((cmd[len] == ')') * 2);
len++;
}
return (len - 1);
}

127
srcs/here_doc.c Normal file → Executable file
View File

@ -5,105 +5,96 @@
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/26 20:20:31 by marde-vr #+# #+# */
/* Updated: 2024/03/05 17:45:51 by marde-vr ### ########.fr */
/* Created: 2024/03/24 17:44:32 by marde-vr #+# #+# */
/* Updated: 2024/05/22 13:48:39 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
char *get_tmp_file_name(t_msh *msh)
{
int i;
char *tmp_file_name;
char *res;
char *i_char;
i = 0;
tmp_file_name = ".tmp";
i_char = ft_itoa(i);
res = ft_strjoin(tmp_file_name, i_char);
if (!res)
ft_exit(msh, 1);
free(i_char);
while (!access(res, F_OK))
{
free(res);
i_char = ft_itoa(i);
res = ft_strjoin(tmp_file_name, i_char);
if (!res)
ft_exit(msh, 1);
free(i_char);
i++;
}
return (res);
}
int contains_newline(char *str)
{
int i;
i = 0;
if (!str)
return (0);
while (str[i])
{
if (str[i] == '\n')
return (1);
i++;
}
return (0);
}
void get_here_doc_input(t_msh *msh, char *eof)
{
char *line;
int new_line;
line = NULL;
new_line = 1;
ft_printf_fd(1, "> ");
while (1)
{
free(line);
line = get_next_line(0);
if (!line && new_line)
line = readline("> ");
if (!line)
{
ft_printf_fd(2, "\nminishell: warning: here-document delimited by");
ft_printf_fd(2, " end-of-file, wanted %s", eof);
ft_printf_fd(2, " end-of-file, (wanted `%s')\n", eof);
break ;
}
if (line && new_line && !ft_strncmp(line, eof, ft_strlen(eof)))
if (line && !ft_strcmp(line, eof))
break ;
new_line = contains_newline(line);
if (new_line)
ft_printf_fd(1, "> ");
write(msh->in_fd, line, ft_strlen(line));
parse_var(msh, line);
write(msh->in_fd, "\n", 1);
}
free(eof);
free(line);
}
void here_doc_child(t_msh *msh, char *eof)
{
rl_catch_signals = 1;
here_doc_variables(1, msh);
set_echoctl(0);
signal(SIGINT, signal_handler_here_doc);
signal(SIGQUIT, SIG_IGN);
get_here_doc_input(msh, eof);
close(msh->in_fd);
close_all_pipes(msh);
ft_exit(msh, 0);
}
void here_doc_signal(t_msh *msh, int child_pid, char *here_doc_file)
{
int status;
signal(SIGINT, signal_handler_command);
signal(SIGQUIT, signal_handler_here_doc);
waitpid(child_pid, &status, 0);
set_echoctl(msh->echoctl);
signal(SIGINT, signal_handler_interactive);
signal(SIGQUIT, signal_handler_interactive);
if (msh->in_fd > 2)
close(msh->in_fd);
if (WIFEXITED(status) && WEXITSTATUS(status))
{
unlink(here_doc_file);
msh->in_fd = -2;
g_return_code = 130;
return ;
}
msh->in_fd = open(here_doc_file, O_RDWR, 0644);
if (msh->in_fd == -1 && !(WIFEXITED(status) && WEXITSTATUS(status)))
perror("open");
}
void handle_here_doc(t_msh *msh, char *eof)
{
char *here_doc_file;
int pid;
here_doc_file = get_tmp_file_name(msh);
if (msh->here_doc_filename)
{
if (msh->in_fd)
close(msh->in_fd);
unlink(msh->here_doc_filename);
free(msh->here_doc_filename);
}
msh->here_doc_filename = here_doc_file;
msh->in_fd = open(here_doc_file, O_CREAT | O_RDWR, 0644);
if (msh->in_fd == -1)
{
perror("open");
ft_exit(msh, 1);
}
eof = ft_strjoin_free(eof, "\n", 1);
if (!eof)
ft_exit(msh, 1);
get_here_doc_input(msh, eof);
close(msh->in_fd);
msh->in_fd = open(here_doc_file, O_RDWR, 0644);
if (msh->in_fd == -1)
{
perror("open");
ft_exit(msh, 1);
}
pid = fork();
if (pid == 0)
here_doc_child(msh, eof);
else
here_doc_signal(msh, pid, here_doc_file);
}

90
srcs/here_doc_utils.c Executable file
View File

@ -0,0 +1,90 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* here_doc_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/03/26 09:06:51 by marde-vr #+# #+# */
/* Updated: 2024/05/08 12:31:54 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
char *get_tmp_file_name(t_msh *msh)
{
int i;
char *tmp_file_name;
char *res;
char *i_char;
i = 0;
tmp_file_name = ".tmp";
i_char = ft_itoa(i);
res = ft_strjoin_free(tmp_file_name, i_char, 2);
if (!res)
ft_exit(msh, 1);
while (!access(res, F_OK))
{
free(res);
i_char = ft_itoa(i);
res = ft_strjoin_free(tmp_file_name, i_char, 2);
if (!res)
ft_exit(msh, 1);
i++;
}
return (res);
}
int contains_newline(char *str)
{
int i;
i = 0;
if (!str)
return (0);
while (str[i])
{
if (str[i] == '\n')
return (1);
i++;
}
return (0);
}
void parse_var(t_msh *msh, char *line)
{
char *var_name;
while (*line)
{
if (*line == '$')
{
var_name = get_var_name(line + 1);
if (!var_name)
return ;
line += ft_strlen(var_name);
if (!*var_name)
write(msh->in_fd, "$", 1);
else if (!ft_strcmp(var_name, "?"))
ft_putnbr_fd(g_return_code, msh->in_fd);
else
ft_putstr_fd(ft_get_env(msh->env, var_name), msh->in_fd);
free(var_name);
}
else
write(msh->in_fd, line, 1);
line++;
}
}
void remove_here_doc_file(t_msh *msh)
{
if (msh->here_doc_filename)
{
unlink(msh->here_doc_filename);
free(msh->here_doc_filename);
msh->here_doc_filename = 0;
}
}

106
srcs/input_redirections.c Normal file → Executable file
View File

@ -6,74 +6,98 @@
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/03/05 18:15:27 by marde-vr #+# #+# */
/* Updated: 2024/03/05 19:19:33 by marde-vr ### ########.fr */
/* Updated: 2024/05/06 14:43:48 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void redirect_input(t_msh *msh, int i)
void redirect_input(t_msh *msh, int i, char **cmd_args)
{
if (msh->in_type != PIPE)
{
if (dup2(msh->in_fd, 0) < 0)
{
free(cmd_args);
close_pipe_fds(msh, i);
ft_exit(msh, 1);
}
close(msh->in_fd);
}
else
{
if (dup2(msh->fds[i - 1][0], 0) < 0)
ft_exit(msh, 1);
}
}
void open_input_file(t_msh *msh, t_cmd **cur_cmd)
{
if ((*cur_cmd)->type == HERE_DOC)
handle_here_doc(msh, (*cur_cmd)->next->token);
if ((*cur_cmd)->type == RED_I)
{
if (msh->in_fd != 0)
close(msh->in_fd);
msh->in_fd = open((*cur_cmd)->next->token, O_RDONLY | O_CREAT);
if (msh->in_fd == -1 && !g_return_code)
{
ft_printf_fd(2, "minishell: %s: ", (*cur_cmd)->next->token);
perror("");
g_return_code = 1;
free(cmd_args);
close_pipe_fds(msh, i);
ft_exit(msh, 1);
}
}
}
void get_in_type(t_msh *msh, t_cmd *cmds)
int open_input_redirection_file(t_msh *msh, t_cmd **cur_token)
{
t_cmd *cur_cmd;
t_token *filename;
cur_cmd = cmds;
while (cur_cmd && cur_cmd->next && cur_cmd->type == ARG)
cur_cmd = cur_cmd->next;
if (cur_cmd->type)
if (msh->in_fd != 0 && msh->in_type != PIPE)
close(msh->in_fd);
if (ft_strchr((*cur_token)->value, '$'))
{
msh->in_type = cur_cmd->type;
if (cur_cmd->type == HERE_DOC || cur_cmd->type == RED_I)
open_input_file(msh, &cur_cmd);
ambiguous_redirect((*cur_token)->value, msh);
return (1);
}
while (cur_cmd && cur_cmd->next && cur_cmd->next->type == ARG)
cur_cmd = cur_cmd->next;
if (cur_cmd->next && (cur_cmd->next->type == HERE_DOC
|| cur_cmd->next->type == RED_I))
get_in_type(msh, cur_cmd);
filename = parse_tokens((*cur_token)->value, msh->env);
if (!filename)
ft_exit(msh, 1);
if (filename->next)
ambiguous_redirect((*cur_token)->value, msh);
if (!filename->next)
msh->in_fd = open(filename->value, O_RDONLY);
if (msh->in_fd == -1 && !filename->next)
{
ft_printf_fd(2, "minishell: %s: ", filename->value);
perror("");
free_token(filename);
return (1);
}
free_token(filename);
return (msh->in_fd == -2);
}
int first_is_in_type(t_msh *msh)
int open_input_file(t_msh *msh, t_cmd **cur_token)
{
t_cmd *cur_cmd;
if ((*cur_token)->cmd_type == HERE_DOC)
handle_here_doc(msh, (*cur_token)->value);
if ((*cur_token)->cmd_type == RED_I)
return (open_input_redirection_file(msh, cur_token));
return (msh->in_fd == -2);
}
cur_cmd = msh->cmds;
while (cur_cmd && cur_cmd->type == ARG && cur_cmd->next)
cur_cmd = cur_cmd->next;
if (cur_cmd->type == PIPE || cur_cmd->type == RED_I
|| cur_cmd->type == HERE_DOC)
return (1);
int get_in_type(t_msh *msh, t_cmd *t_strt, t_cmd *tokens, int here_doc)
{
t_cmd *cur_token;
cur_token = tokens;
if (cur_token && cur_token->cmd_type == PIPE)
{
msh->in_type = PIPE;
cur_token = cur_token->next;
}
while (cur_token && (cur_token->cmd_type == CMD
|| cur_token->cmd_type == PAREN))
cur_token = cur_token->next;
if (cur_token && ((cur_token->cmd_type == HERE_DOC && here_doc)
|| (cur_token->cmd_type == RED_I && !here_doc)))
{
msh->in_type = cur_token->cmd_type;
if (open_input_file(msh, &cur_token))
return (1);
}
if (cur_token && cur_token->next
&& !is_operand_type(cur_token) && !is_operand_type(cur_token->next)
&& cur_token->cmd_type != PIPE && cur_token->next->cmd_type != PIPE)
return (get_in_type(msh, t_strt, cur_token->next, here_doc));
if (here_doc)
return (get_in_type(msh, t_strt, t_strt, 0));
return (0);
}

View File

@ -6,7 +6,7 @@
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/03/05 17:31:53 by marde-vr #+# #+# */
/* Updated: 2024/03/05 17:35:39 by marde-vr ### ########.fr */
/* Updated: 2024/04/23 16:41:42 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */

View File

@ -6,22 +6,27 @@
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/06 20:46:19 by tomoron #+# #+# */
/* Updated: 2024/02/21 23:12:34 by marde-vr ### ########.fr */
/* Updated: 2024/04/26 13:45:08 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_cmd *cmd_add_back(t_cmd *cmd, char *token, t_token_type type)
t_cmd *cmd_add_back(t_cmd *cmd, char *value, t_cmd_type type)
{
t_cmd *res;
t_cmd *current;
if (value && !*value && type != PAREN)
{
free(value);
return (cmd);
}
res = ft_calloc(1, sizeof(t_cmd));
if (!res)
return (cmd);
res->token = token;
res->type = type;
res->value = value;
res->cmd_type = type;
if (!cmd)
return (res);
current = cmd;
@ -31,14 +36,22 @@ t_cmd *cmd_add_back(t_cmd *cmd, char *token, t_token_type type)
return (cmd);
}
void free_cmd(t_cmd *cmd)
t_cmd *free_cmd(t_cmd *cmd)
{
if (cmd)
{
if (cmd && cmd->token)
free(cmd->token);
if (cmd && cmd->value)
{
free(cmd->value);
cmd->value = 0;
}
if (cmd && cmd->next)
{
free_cmd(cmd->next);
cmd->next = 0;
}
free(cmd);
cmd = 0;
}
return (0);
}

View File

@ -6,22 +6,25 @@
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/06 20:46:19 by tomoron #+# #+# */
/* Updated: 2024/02/17 04:33:17 by tomoron ### ########.fr */
/* Updated: 2024/05/06 10:56:39 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_env *env_add_back(t_env *env, char *name, char *value)
t_env *env_add_back(t_env *env, char *name, char *value, int empty)
{
t_env *res;
t_env *current;
if (empty)
free(value);
res = ft_calloc(1, sizeof(t_env));
if (!res)
return (env);
res->name = name;
res->value = value;
if (!empty)
res->value = value;
if (!env)
return (res);
current = env;
@ -31,23 +34,12 @@ t_env *env_add_back(t_env *env, char *name, char *value)
return (env);
}
void free_env(t_env *env)
{
if (env && env->next)
free_env(env->next);
if (env)
{
free(env->name);
free(env->value);
}
free(env);
}
int print_env(t_env *env)
{
while (env)
{
ft_printf("%s=%s\n", env->name, env->value);
if (env->value)
ft_printf("%s=%s\n", env->name, env->value);
env = env->next;
}
return (0);

View File

@ -1,55 +1,56 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* lst_alias.c :+: :+: :+: */
/* lst_token.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/06 20:46:19 by tomoron #+# #+# */
/* Updated: 2024/02/21 13:09:00 by marde-vr ### ########.fr */
/* Updated: 2024/04/24 18:04:15 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_alias *alias_add_back(t_alias *alias, char *name, char *value)
t_token *token_add_back(t_token *token, char *value, int is_var)
{
t_alias *res;
t_alias *current;
t_token *res;
t_token *current;
res = ft_calloc(1, sizeof(t_alias));
if (value && !*value && is_var)
{
free(value);
return (token);
}
res = ft_calloc(1, sizeof(t_token));
if (!res)
return (alias);
res->name = name;
return (token);
res->value = value;
if (!alias)
if (!token)
return (res);
current = alias;
current = token;
while (current->next)
current = current->next;
current->next = res;
return (alias);
return (token);
}
void free_alias(t_alias *alias)
t_token *free_token(t_token *token)
{
if (alias && alias->next)
free_alias(alias->next);
if (alias)
if (token)
{
free(alias->name);
free(alias->value);
}
free(alias);
}
char *get_alias(t_alias *alias, char *name)
{
while (alias)
{
if (!ft_strcmp(alias->name, name))
return (alias->value);
alias = alias->next;
if (token && token->value)
{
free(token->value);
token->value = 0;
}
if (token && token->next)
{
free_token(token->next);
token->next = 0;
}
free(token);
token = 0;
}
return (0);
}

View File

@ -6,7 +6,7 @@
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/02 21:59:20 by tomoron #+# #+# */
/* Updated: 2024/03/06 08:32:18 by marde-vr ### ########.fr */
/* Updated: 2024/05/06 14:25:27 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
@ -22,19 +22,23 @@ char *get_prompt(t_env *env)
res = ft_strjoin_free("\001", ft_get_color(10, 255, 80), 2);
res = ft_strjoin_free(res, "\033[1m\002", 1);
res = ft_strjoin_free(res, getenv("USER"), 1);
res = ft_strjoin_free(res, "@", 1);
res = ft_strjoin_free(res, "minishell\001\033[0m\002:\001", 1);
if (getenv("USER"))
{
res = ft_strjoin_free(res, getenv("USER"), 1);
res = ft_strjoin_free(res, "@", 1);
}
res = ft_strjoin_free(res, "hell\001\033[0m\002:\001", 1);
res = ft_strjoin_free(res, ft_get_color(80, 80, 255), 3);
res = ft_strjoin_free(res, "\033[1m\002", 1);
cwd = getcwd(cwd_buffer, 99);
if (ft_get_env(env, "HOME") && !ft_strncmp(cwd_buffer, ft_get_env(env,
"HOME"), ft_strlen(ft_get_env(env, "HOME"))))
if (cwd && ft_get_env(env, "HOME") && !ft_strncmp(cwd_buffer,
ft_get_env(env, "HOME"), ft_strlen(ft_get_env(env, "HOME"))))
{
cwd += ft_strlen(getenv("HOME")) - 1;
cwd[0] = '~';
}
res = ft_strjoin_free(res, cwd, 1);
if (cwd)
res = ft_strjoin_free(res, cwd, 1);
res = ft_strjoin_free(res, "\001\033[0m\002$ ", 1);
return (res);
}
@ -58,7 +62,7 @@ t_env *get_env(char **envp)
j++;
name = ft_substr(*envp, 0, i);
value = ft_substr(*envp, i + 1, j);
env = env_add_back(env, name, value);
env = env_add_back(env, name, value, 0);
if (!name || !value)
free_env(env);
if (!name || !value)
@ -68,15 +72,43 @@ t_env *get_env(char **envp)
return (env);
}
t_env *add_shlvl(t_env *env)
{
int nb;
char *tmp;
tmp = ft_get_env(env, "SHLVL");
if (!tmp)
nb = 0;
else
nb = ft_atoi(tmp);
nb++;
if (nb < 0)
nb = 0;
env = export_set_env(env, ft_strdup("SHLVL"), ft_itoa(nb), 0);
return (env);
}
int init_minishell(t_msh **msh, int argc, char **argv, char **envp)
{
struct termios t_p;
*msh = ft_calloc(1, sizeof(t_msh));
if (!*msh)
ft_exit(*msh, 1);
exit(1);
(void)argc;
(void)argv;
if (isatty(1))
{
tcgetattr(1, &t_p);
(*msh)->echoctl = t_p.c_lflag & ECHOCTL;
}
(*msh)->env = get_env(envp);
(*msh)->aliases = 0;
(*msh)->env = add_shlvl((*msh)->env);
rl_catch_signals = 0;
g_return_code = 0;
signal(SIGINT, signal_handler_interactive);
signal(SIGQUIT, signal_handler_interactive);
return (0);
}
@ -88,22 +120,16 @@ int main(int argc, char **argv, char **envp)
commands = (char *)1;
init_minishell(&msh, argc, argv, envp);
//handle_minishellrc(msh);
while (msh->env && commands)
while (commands)
{
prompt = get_prompt(msh->env);
if (!prompt)
exit(STDIN_FILENO);
ft_exit(msh, 1);
commands = readline(prompt);
free(prompt);
add_history(commands);
msh->cmds = parse_command(commands, msh->env);
free(commands);
msh->cmds = handle_alias(msh);
exec_commands(msh);
free_cmd(msh->cmds);
exec_command_bonus(msh, commands);
}
rl_clear_history();
free_msh(msh);
return (g_return_code);
printf("exit\n");
ft_exit(msh, g_return_code);
}

View File

@ -6,7 +6,7 @@
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/04 17:31:38 by tomoron #+# #+# */
/* Updated: 2024/03/06 10:19:27 by marde-vr ### ########.fr */
/* Updated: 2024/05/22 13:49:58 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
@ -16,29 +16,43 @@
# include <readline/readline.h>
# include <readline/history.h>
# include <limits.h>
# include <stdio.h>//debug
# include <stdio.h>
# include <sys/wait.h>
# include "../libft/libft.h"
# include "fcntl.h"
# include <sys/stat.h>
# include <signal.h>
# include <stdint.h>
# include <termios.h>
# include <dirent.h>
typedef enum e_token_type
typedef enum e_cmd_type
{
ARG,
CMD,
PAREN,
AND,
OR,
PIPE,
RED_O,
RED_O_APP,
RED_I,
HERE_DOC,
} t_token_type;
RED_O,
RED_I,
ERR
} t_cmd_type;
typedef struct s_cmd
{
t_token_type type;
char *token;
t_cmd_type cmd_type;
char *value;
struct s_cmd *next;
} t_cmd;
typedef struct s_token
{
char *value;
struct s_token *next;
} t_token;
typedef struct s_env
{
char *name;
@ -46,76 +60,126 @@ typedef struct s_env
struct s_env *next;
} t_env;
typedef struct s_alias
{
char *name;
char *value;
struct s_alias *next;
} t_alias;
typedef struct s_msh
{
struct s_alias *aliases;
struct s_env *env;
struct s_cmd *cmds;
int **fds;
int *pids;
enum e_token_type in_type;
enum e_token_type out_type;
int in_fd;
int out_fd;
t_env *env;
t_token *tokens;
t_cmd *cmds;
t_cmd *cmds_head;
int **fds;
int *pids;
t_cmd_type in_type;
t_cmd_type out_type;
int in_fd;
int out_fd;
int echoctl;
int last_return_code;
int locked_return_code;
char *here_doc_filename;
} t_msh;
extern int g_return_code;
t_cmd *cmd_add_back(t_cmd *res, char *token, t_token_type type);
void free_cmd(t_cmd *cmd);
void exec_commands(t_msh *msh);
int echo(t_cmd *args);
void exit_bt(t_msh *msh);
t_env *env_add_back(t_env *env, char *name, char *value);
void free_env(t_env *env);
int print_env(t_env *env);
t_cmd *parse_command(char *command, t_env *env);
int get_token_len(char *cmd, t_env *env);
int add_var_to_str(char *res, char **command, t_env *env);
int get_var_name_len(char *command);
char *ft_get_env(t_env *env, char *var_name);
int pwd(void);
int is_cmd_char(char c);
void print_parsed_cmd(t_cmd *cmd);//debug
void ft_exit(t_msh *msh, int error_code);
char **env_to_char_tab(t_env *env);
void handle_minishellrc(t_msh *msh);
t_cmd *handle_alias(t_msh *msh);
int cd(t_cmd *args);
int alias(t_msh *msh);
void free_alias(t_alias *alias);
char *get_alias(t_alias *alias, char *var_name);
t_alias *alias_add_back(t_alias *alias, char *name, char *value);
int unalias(t_msh *msh);
int ft_export(t_msh *msh);
void free_msh(t_msh *msh);
char **split_paths_from_env(t_env *env);
int get_in_type(t_msh *msh, t_cmd *t_strt, t_cmd *tokens, int here_doc);
t_env *export_set_env(t_env *env, char *name, char *value, int append);
t_env *env_add_back(t_env *env, char *name, char *value, int empty);
int add_var_to_str(char *res, char **cmd, t_env *env, int quote);
void parent(t_msh *msh, int i, int cmd_count, char **cmd_args);
char *expand_variables(char *command, t_env *env, int *is_var);
t_token *expand_wildcards(t_token *res, char *value, int is_var);
int check_tokens_syntax(t_cmd *cmd, t_cmd *last, t_env *env);
t_token *token_add_back(t_token *res, char *token, int is_var);
int recursive_filename_check(char *wildcard, char **value);
int get_variable_expantion_len(char *command, t_env *env);
t_cmd *cmd_add_back(t_cmd *res, char *cmd, t_cmd_type type);
int get_var_len(char **command, t_env *env, int dquote);
void find_cmd_path(t_msh *msh, char **paths, int *found);
void get_cmd_path(t_msh *msh);
void handle_here_doc(t_msh *msh, char *eof);
int ft_unset(t_msh *msh);
void get_in_type(t_msh *msh, t_cmd *cmds);
void get_out_type(t_msh *msh, t_cmd *cmds);
int first_is_in_type(t_msh *msh);
void redirect_input(t_msh *msh, int i);
void redirect_output(t_msh *msh, int i);
void child(t_msh *msh, char **cmd_args, int i);
void parent(t_msh *msh, int i, int cmd_count);
void free_msh(t_msh *msh);
void ft_exit(t_msh *msh, int exit_code);
void redirect_output(t_msh *msh, int i, char **cmd_args);
void redirect_input(t_msh *msh, int i, char **cmd_args);
void print_syntax_error_bonus(t_cmd *cmd, t_cmd *cmds);
int filename_corresponds(char *wildcard, char *value);
t_token *parse_cmds_to_token(t_cmd *command, t_env *env);
int ft_export(t_msh *msh, t_token *cmd, t_env *env);
void print_env_declare(t_msh *msh, t_env *env_orig);
void exec_command_bonus(t_msh *msh, char *cmd_str);
void print_cmd_type(t_cmd_type type, char *value);
t_token *add_token_back(t_token *res, t_token *next);
t_cmd *check_cmds_syntax(t_cmd *cmds, t_env *env);
int cmd_is_builtin(t_msh *msh, char *cmd_token);
int exec_builtin(t_msh *msh);
int get_cmd_count(t_cmd *cmds);
int get_args_count(t_cmd *cmds);
char **get_cmd_args(t_msh *msh);
void remove_command_from_msh(t_msh *msh);
void *here_doc_variables(int write, void *data);
void get_redirections(t_msh *msh, t_cmd *cmds);
void ambiguous_redirect(char *str, t_msh *msh);
void child(t_msh *msh, char **cmd_args, int i);
int cmd_is_forkable_builtin(char *cmd_token);
t_token *parse_tokens(char *command, t_env *env);
void delete_from_env(t_msh *msh, char *name);
char *ft_get_env(t_env *env, char *var_name);
void handle_here_doc(t_msh *msh, char *eof);
void signal_handler_interactive(int signum);
int get_out_type(t_msh *msh, t_cmd *cmds);
void signal_handler_here_doc(int signum);
t_token *parsing_syntax_error(t_token *res);
int file_access(t_msh *msh, int *found);
void remove_command_from_msh(t_msh *msh);
void ft_exit(t_msh *msh, int error_code);
void sort_wildcards_token(t_token *list);
void signal_handler_command(int signum);
void ft_exit(t_msh *msh, int exit_code);
int get_parenthesis_cmd_len(char *cmd);
char **split_paths_from_env(t_env *env);
int add_return_code_to_str(char *res);
void close_pipe_fds(t_msh *msh, int i);
void parse_var(t_msh *msh, char *line);
void remove_here_doc_file(t_msh *msh);
int get_var_name_len(char *command);
void handle_minishellrc(t_msh *msh);
char *get_tmp_file_name(t_msh *msh);
int cd(t_token *args, t_msh *msh);
int get_normal_cmd_len(char *cmd);
t_cmd *get_next_command(t_cmd *cmd);
int get_args_count(t_token *cmds);
char **env_to_char_tab(t_env *env);
int get_token_len(char *command);
int first_is_in_type(t_cmd *cmd);
void print_msh_struct(t_msh *msh);
int get_next_arg_len(char *cmd);
int check_str_syntax(char *cmd);
void close_all_pipes(t_msh *msh);
int is_operand_type(t_cmd *cmd);
int contains_newline(char *str);
t_token *free_token(t_token *token);
int get_cmd_count(t_cmd *cmds);
int check_var_name(char *name);
char **get_cmd_args(t_msh *msh);
int get_cmd_count(t_cmd *cmds);
int is_parenthesis(t_cmd *cmd);
int is_output_type(t_cmd *cmd);
int is_parenthesis(t_cmd *cmd);
void print_signaled(int status);
void exec_commands(t_msh *msh);
int is_input_type(t_cmd *cmd);
char *remove_path(char *token);
t_cmd *parsing_bonus(char *cmd);
void free_env_cpy(t_env *env);
char *get_var_name(char *str);
int exec_builtin(t_msh *msh);
void get_cmd_path(t_msh *msh);
int is_cmd_type(t_cmd *cmd);
int get_home_var_len(void);
int set_echoctl(int value);
int print_env(t_env *env);
t_cmd *free_cmd(t_cmd *cmd);
void free_env(t_env *env);
int ft_unset(t_msh *msh);
void free_fds(t_msh *msh);
t_env *dup_env(t_env *env);
void sort_env(t_env *env);
void free_msh(t_msh *msh);
void free_msh(t_msh *msh);
int echo(t_token *args);
int exit_bt(t_msh *msh);
int is_cmd_char(char c);
int is_fd_open(int fd);
int pwd(void);
#endif

View File

@ -1,55 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* minishellrc.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/16 17:40:16 by marde-vr #+# #+# */
/* Updated: 2024/03/05 18:33:30 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void exec_rc_file(t_msh *msh, int fd)
{
char *line;
line = get_next_line(fd);
while (line)
{
if (line[0] != '#')
{
msh->cmds = parse_command(line, msh->env);
exec_commands(msh);
free_cmd(msh->cmds);
}
free(line);
line = get_next_line(fd);
}
free(line);
}
void handle_minishellrc(t_msh *msh)
{
char *home;
char *rc_path;
int fd;
home = ft_get_env(msh->env, "HOME");
rc_path = ft_strjoin(home, "/.minishellrc");
if (access(rc_path, R_OK) != -1)
{
fd = open(rc_path, O_RDONLY);
if (fd == -1)
{
free(msh->env);
perror("open");
return ;
}
exec_rc_file(msh, fd);
close(fd);
}
free(rc_path);
}

105
srcs/output_redirections.c Normal file → Executable file
View File

@ -3,71 +3,104 @@
/* ::: :::::::: */
/* output_redirections.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* By: tomoron <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/03/05 19:10:52 by marde-vr #+# #+# */
/* Updated: 2024/03/05 19:28:25 by marde-vr ### ########.fr */
/* Created: 2024/04/19 14:09:44 by tomoron #+# #+# */
/* Updated: 2024/05/06 14:43:45 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void redirect_output(t_msh *msh, int i)
void redirect_output(t_msh *msh, int i, char **cmd_args)
{
if (msh->out_type != PIPE)
{
if (dup2(msh->out_fd, 1) < 0)
{
free(cmd_args);
ft_exit(msh, 1);
}
}
else
{
if (dup2(msh->fds[i][1], 1) < 0)
{
perror("dup2");
free(cmd_args);
ft_exit(msh, 1);
}
}
}
void open_out_file(t_msh *msh, t_cmd **cur_cmd)
int open_out_file(t_msh *msh, t_cmd **cur_cmd, char *filename)
{
msh->out_type = (*cur_cmd)->type;
if (msh->out_type == RED_O)
msh->out_fd = open((*cur_cmd)->next->token,
O_CREAT | O_WRONLY | O_TRUNC, 0644);
msh->out_fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (msh->out_type == RED_O_APP)
msh->out_fd = open((*cur_cmd)->next->token,
O_CREAT | O_RDWR | O_APPEND, 0644);
msh->out_fd = open(filename, O_CREAT | O_WRONLY | O_APPEND, 0644);
if (msh->out_fd == -1)
{
g_return_code = 1;
perror("open");
ft_putstr_fd("minishell: ", 2);
perror(filename);
return (1);
}
if ((*cur_cmd)->cmd_type != PIPE)
{
while ((*cur_cmd)->next && is_cmd_type((*cur_cmd)->next))
*cur_cmd = (*cur_cmd)->next;
if ((*cur_cmd)->next && is_output_type((*cur_cmd)->next))
get_out_type(msh, (*cur_cmd)->next);
}
return (0);
}
void go_to_next_out_type(t_cmd **cur_cmd)
{
while (*cur_cmd && (*cur_cmd)->next && (!is_cmd_type(*cur_cmd)
&& !is_output_type(*cur_cmd)))
*cur_cmd = (*cur_cmd)->next;
while (*cur_cmd && (*cur_cmd)->next && !is_output_type(*cur_cmd)
&& !is_operand_type(*cur_cmd) && (*cur_cmd)->cmd_type != PIPE)
*cur_cmd = (*cur_cmd)->next;
}
void get_out_file(t_msh *msh, t_cmd *cur_cmd, int *ret)
{
t_token *filename;
msh->out_type = cur_cmd->cmd_type;
if (ft_strchr(cur_cmd->value, '$'))
{
ambiguous_redirect(cur_cmd->value, msh);
return ;
}
if ((*cur_cmd)->type != PIPE)
{
while ((*cur_cmd)->next && (*cur_cmd)->next->type == ARG)
*cur_cmd = (*cur_cmd)->next;
if ((*cur_cmd)->next && ((*cur_cmd)->next->type == RED_O
|| (*cur_cmd)->next->type == RED_O_APP))
get_out_type(msh, *cur_cmd);
}
filename = parse_tokens(cur_cmd->value, msh->env);
if (!filename)
ft_exit(msh, 1);
if (filename->next)
ambiguous_redirect(cur_cmd->value, msh);
if (!filename->next)
*ret = open_out_file(msh, &cur_cmd, filename->value);
free_token(filename);
}
void get_out_type(t_msh *msh, t_cmd *cmds)
int get_out_type(t_msh *msh, t_cmd *cur_cmd)
{
t_cmd *cur_cmd;
int ret;
msh->out_type = ARG;
msh->out_type = CMD;
if (msh->out_fd > 2)
close(msh->out_fd);
msh->out_fd = 0;
cur_cmd = cmds;
if (cmds->type && msh->cmds == cmds)
{
while (msh->cmds->type != ARG && msh->cmds->next->next)
msh->cmds = msh->cmds->next->next;
}
while (cur_cmd && cur_cmd->next && (cur_cmd->type == ARG
|| cur_cmd->type > 3))
cur_cmd = cur_cmd->next;
if (!cur_cmd->type)
msh->out_type = ARG;
else
open_out_file(msh, &cur_cmd);
ret = 0;
go_to_next_out_type(&cur_cmd);
if (cur_cmd && (cur_cmd->cmd_type == CMD || cur_cmd->cmd_type == PAREN))
msh->out_type = 0;
else if (cur_cmd && is_output_type(cur_cmd) && !is_operand_type(cur_cmd)
&& cur_cmd->cmd_type != PIPE)
get_out_file(msh, cur_cmd, &ret);
else if (cur_cmd && cur_cmd->cmd_type == PIPE)
msh->out_type = PIPE;
return (ret || msh->in_fd == -2);
}

View File

@ -6,16 +6,11 @@
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/09 15:26:01 by tomoron #+# #+# */
/* Updated: 2024/02/28 18:48:27 by marde-vr ### ########.fr */
/* Updated: 2024/05/22 13:52:40 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int is_cmd_char(char c)
{
return (!ft_isspace(c) && c != '|' && c != '&' && c != '<' && c != '>');
}
int add_home_to_str(char *res)
{
int i;
@ -23,15 +18,20 @@ int add_home_to_str(char *res)
i = 0;
str = getenv("HOME");
while (str[i])
while (str && str[i])
{
res[i] = str[i];
i++;
}
if (!str)
{
res[i] = '~';
return (1);
}
return (i);
}
char *get_token(char **cmd, int *in_quote, int *in_dquote, t_env *env)
char *get_token(char **cmd, int quotes[2])
{
char *res;
int i;
@ -39,21 +39,16 @@ char *get_token(char **cmd, int *in_quote, int *in_dquote, t_env *env)
i = 0;
while (ft_isspace(**cmd))
(*cmd)++;
res = ft_calloc(get_token_len(*cmd, env) + 1, 1);
while (res && **cmd && (is_cmd_char(**cmd) || *in_quote || *in_dquote))
res = ft_calloc(get_token_len(*cmd) + 1, 1);
while (res && **cmd && (!ft_isspace(**cmd) || quotes[0] || quotes[1]))
{
if (**cmd == '"' && !*in_quote)
*in_dquote = !*in_dquote;
if (**cmd == '\'' && !*in_dquote)
*in_quote = !*in_quote;
if (**cmd == '$' && !*in_quote)
{
(*cmd)++;
i += add_var_to_str(res + i, cmd, env);
}
else if (**cmd == '~' && !*in_quote && !*in_dquote)
if (**cmd == '"' && !quotes[0])
quotes[1] = !quotes[1];
if (**cmd == '\'' && !quotes[1])
quotes[0] = !quotes[0];
else if (**cmd == '~' && !quotes[0] && !quotes[1])
i += add_home_to_str(res + i);
else if (((**cmd == '\'' && *in_dquote) || (**cmd == '"' && *in_quote))
else if (((**cmd == '\'' && quotes[1]) || (**cmd == '"' && quotes[0]))
|| (**cmd != '\'' && **cmd != '"'))
res[i++] = **cmd;
(*cmd)++;
@ -61,58 +56,50 @@ char *get_token(char **cmd, int *in_quote, int *in_dquote, t_env *env)
return (res);
}
t_token_type get_token_type(char **command)
t_token *parse_tokens(char *command, t_env *env)
{
t_token_type res;
int quotes[2];
char *tmp;
t_token *res;
char *value;
int is_var;
while (ft_isspace(**command))
(*command)++;
if ((*command)[0] == '>' && (*command)[1] == '>')
res = RED_O_APP;
else if ((*command)[0] == '<' && (*command)[1] == '<')
res = HERE_DOC;
else if ((*command)[0] == '>')
res = RED_O;
else if ((*command)[0] == '<')
res = RED_I;
else if ((*command)[0] == '|')
res = PIPE;
else
res = ARG;
if (res == RED_O_APP || res == HERE_DOC)
(*command) += 2;
if (res == RED_O || res == RED_I || res == PIPE)
(*command)++;
return (res);
}
t_cmd *parse_command(char *command, t_env *env)
{
int in_quote;
int in_dquote;
t_cmd *res;
char *token;
t_token_type type;
in_quote = EXIT_SUCCESS;
in_dquote = STDIN_FILENO;
quotes[0] = 0;
quotes[1] = 0;
res = 0;
is_var = 0;
command = expand_variables(command, env, &is_var);
tmp = command;
while (command && *command)
{
type = get_token_type(&command);
if (type == ARG)
token = get_token(&command, &in_quote, &in_dquote, env);
else
token = 0;
res = cmd_add_back(res, token, type);
value = get_token(&command, quotes);
if (!value)
return (free_token(res));
res = expand_wildcards(res, value, is_var);
while (ft_isspace(*command))
command++;
}
if (command && (in_quote || in_dquote))
free(tmp);
if (tmp && (quotes[0] || quotes[1]))
return (parsing_syntax_error(res));
return (res);
}
t_token *parse_cmds_to_token(t_cmd *command, t_env *env)
{
t_token *res;
t_token *new;
res = 0;
while (command && (command->cmd_type == CMD || is_output_type(command)
|| is_input_type(command)))
{
free_cmd(res);
ft_putstr_fd("minishell: syntax error\n", 2);
return (0);
if (command->cmd_type == CMD)
{
new = parse_tokens(command->value, env);
res = add_token_back(res, new);
}
command = command->next;
}
return (res);
}

105
srcs/parsing_bonus.c Executable file
View File

@ -0,0 +1,105 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* parsing_bonus.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tomoron <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/03/27 14:40:44 by tomoron #+# #+# */
/* Updated: 2024/04/26 14:32:51 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_cmd_type str_to_cmd_type(char *cmd)
{
if (*cmd == '|' && cmd[1] != '|')
return (PIPE);
else if (*cmd == '|' && cmd[1] == '|')
return (OR);
else if (*cmd == '&' && cmd[1] == '&')
return (AND);
else if (*cmd == '>' && cmd[1] == '>')
return (RED_O_APP);
else if (*cmd == '<' && cmd[1] == '<')
return (HERE_DOC);
else if (*cmd == '>')
return (RED_O);
else if (*cmd == '<')
return (RED_I);
else if (*cmd == '(')
return (PAREN);
else if (*cmd == '&')
return (ERR);
return (CMD);
}
t_cmd_type get_cmd_type_bonus(char **cmd)
{
t_cmd_type res;
res = str_to_cmd_type(*cmd);
if (res != CMD)
(*cmd)++;
if (res == OR || res == AND || res == RED_O_APP || res == HERE_DOC)
(*cmd)++;
return (res);
}
char *get_cmd_value(char **cmd, t_cmd_type type)
{
int len;
char *res;
if (type == PAREN)
len = get_parenthesis_cmd_len(*cmd);
else
len = get_normal_cmd_len(*cmd);
res = ft_substr(*cmd, 0, len);
(*cmd) += len;
if (type == PAREN)
(*cmd)++;
return (res);
}
char *get_next_arg(char **cmd)
{
int len;
char *res;
while (ft_isspace(**cmd))
(*cmd)++;
len = get_next_arg_len(*cmd);
if (!len)
return (0);
res = ft_substr(*cmd, 0, len);
*cmd += len;
return (res);
}
t_cmd *parsing_bonus(char *cmd)
{
t_cmd *res;
t_cmd_type type;
char *value;
res = 0;
if (!check_str_syntax(cmd))
return (0);
while (*cmd)
{
while (ft_isspace(*cmd))
cmd++;
type = get_cmd_type_bonus(&cmd);
if (type == CMD || type == PAREN)
value = get_cmd_value(&cmd, type);
else if (type == RED_O || type == RED_O_APP || type == RED_I
|| type == HERE_DOC)
value = get_next_arg(&cmd);
else
value = 0;
res = cmd_add_back(res, value, type);
}
return (res);
}

22
other/test2.c → srcs/parsing_utils.c Executable file → Normal file
View File

@ -1,20 +1,24 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* test2.c :+: :+: :+: */
/* parsing_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tomoron <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/07 13:30:04 by tomoron #+# #+# */
/* Updated: 2024/02/09 16:42:59 by tomoron ### ########.fr */
/* Created: 2024/05/22 13:49:17 by tomoron #+# #+# */
/* Updated: 2024/05/22 13:50:31 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
#include "minishell.h"
int get_home_var_len(void)
{
if (argc == 2)
return (atoi(argv[1]));
return (0);
char *str;
str = getenv("HOME");
if (!str)
return (1);
else
return (ft_strlen("HOME"));
}

View File

@ -6,7 +6,7 @@
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/09 15:24:36 by tomoron #+# #+# */
/* Updated: 2024/03/05 17:29:06 by marde-vr ### ########.fr */
/* Updated: 2024/05/22 13:52:29 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
@ -22,14 +22,22 @@ char *get_var_name(char *command)
return (res);
}
int get_var_len(char **command, t_env *env)
int get_var_len(char **command, t_env *env, int in_dquote)
{
char *var_name;
char *env_var;
(*command)++;
if (**command == '\'' || **command == '"')
if ((**command == '\'' || **command == '"') && !in_dquote)
{
(*command)--;
return (0);
}
if (!**command || (**command == '"' && in_dquote))
{
(*command)--;
return (1);
}
if (!ft_isalnum(**command) && **command != '_' && **command != '?')
return (2);
if (**command == '?')
@ -43,7 +51,7 @@ int get_var_len(char **command, t_env *env)
return (ft_strlen(env_var));
}
int get_token_len(char *command, t_env *env)
int get_token_len(char *command)
{
int in_quote;
int in_dquote;
@ -52,16 +60,14 @@ int get_token_len(char *command, t_env *env)
in_quote = 0;
in_dquote = 0;
res = 0;
while (*command && (is_cmd_char(*command) || in_quote || in_dquote))
while (*command && (!ft_isspace(*command) || in_quote || in_dquote))
{
if (*command == '"' && !in_quote)
in_dquote = !in_dquote;
if (*command == '\'' && !in_dquote)
in_quote = !in_quote;
if (*command == '$' && !in_quote)
res += get_var_len(&command, env);
else if (*command == '~' && !in_quote && !in_dquote)
res += ft_strlen(getenv("HOME"));
res += get_home_var_len();
else if (*command != '\'' && *command != '"')
res++;
else if ((*command == '\'' && in_dquote) || (*command == '"'
@ -72,51 +78,37 @@ int get_token_len(char *command, t_env *env)
return (res);
}
int add_return_code_to_str(char *res)
int invalid_variable_char(char *res, char c)
{
char *var;
int i;
i = 0;
var = ft_itoa(g_return_code);
while (var && var[i])
{
res[i] = var[i];
i++;
}
free(var);
return (i);
res[0] = '$';
res[1] = c;
return (2);
}
int add_var_to_str(char *res, char **command, t_env *env)
int add_var_to_str(char *res, char **command, t_env *env, int dquote)
{
char *var_name;
char *var;
int i;
i = 0;
if (**command == '\'' || **command == '"')
(*command)++;
if (**command == '\'' || **command == '"' || !**command)
{
*res = '$';
if ((**command != '\'' && **command != '"') || dquote)
*res = '$';
(*command)--;
return (1);
return ((*(*command + 1) != '\'' && *(*command + 1) != '"') || dquote);
}
if (!ft_isalnum(**command) && **command != '_' && **command != '?')
{
res[0] = '$';
res[1] = **command;
return (2);
}
return (invalid_variable_char(res, **command));
if (**command == '?')
return (add_return_code_to_str(res));
var_name = get_var_name(*command);
var = ft_get_env(env, var_name);
free(var_name);
while (var && var[i])
{
res[i] = var[i];
i++;
}
while (var && var[i++])
res[i - 1] = var[i - 1];
*command += get_var_name_len(*command) - 1;
return (i);
return (i - (1 - (i == 0)));
}

62
srcs/path.c Normal file → Executable file
View File

@ -6,37 +6,13 @@
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/21 21:47:15 by marde-vr #+# #+# */
/* Updated: 2024/03/06 10:18:53 by marde-vr ### ########.fr */
/* Updated: 2024/05/07 16:08:17 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
#include <unistd.h>
char **split_paths_from_env(t_env *env)
{
t_env *cur_env_var;
int path_in_envp;
path_in_envp = 0;
cur_env_var = env;
while (cur_env_var->next != 0)
{
if (!ft_strcmp(cur_env_var->name, "PATH"))
{
path_in_envp = 1;
break ;
}
cur_env_var = cur_env_var->next;
}
if (!path_in_envp)
{
ft_printf_fd(2, "minishell: error: PATH not found\n");
return (0);
}
return (ft_split(cur_env_var->value, ':'));
}
void find_cmd_path(t_msh *msh, char **paths, int *found)
{
char *tmp;
@ -50,15 +26,15 @@ void find_cmd_path(t_msh *msh, char **paths, int *found)
tmp = ft_strjoin(path, "/");
if (!tmp)
ft_exit(msh, 1);
path = ft_strjoin(tmp, msh->cmds->token);
path = ft_strjoin(tmp, msh->tokens->value);
if (!path)
ft_exit(msh, 1);
free(tmp);
if (access(path, X_OK) != -1)
{
*found = 1;
free(msh->cmds->token);
msh->cmds->token = path;
free(msh->tokens->value);
msh->tokens->value = path;
break ;
}
free(path);
@ -71,7 +47,7 @@ void free_paths(char **paths)
int i;
i = 0;
while (paths[i])
while (paths && paths[i])
{
free(paths[i]);
i++;
@ -84,32 +60,46 @@ void get_path(t_msh *msh, int *found)
char **paths;
paths = split_paths_from_env(msh->env);
if (!paths)
if (!paths || !*(msh->tokens->value)
|| ft_str_is_only_char(msh->tokens->value, '.'))
{
free_paths(paths);
ft_exit(msh, 1);
return ;
}
find_cmd_path(msh, paths, found);
free_paths(paths);
}
char *remove_path(char *token)
{
while (ft_strchr(token, '/'))
token++;
return (token);
}
void get_cmd_path(t_msh *msh)
{
int found;
int found;
found = 0;
if (ft_strchr(msh->cmds->token, '/'))
if (ft_strchr(msh->tokens->value, '/'))
{
if (!file_access(msh, &found))
{
free(msh->tokens->value);
msh->tokens->value = 0;
return ;
}
}
else
get_path(msh, &found);
if (!found)
{
ft_printf_fd(2, "%s: command not found\n", msh->cmds->token);
free(msh->cmds->token);
msh->cmds->token = 0;
if (!*(msh->tokens->value))
ft_printf_fd(2, "'': command not found\n");
else
ft_printf_fd(2, "%s: command not found\n", msh->tokens->value);
close_all_pipes(msh);
g_return_code = 127;
}
}

104
srcs/pipe.c Normal file → Executable file
View File

@ -6,7 +6,7 @@
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/03/05 18:17:25 by marde-vr #+# #+# */
/* Updated: 2024/03/06 08:22:46 by marde-vr ### ########.fr */
/* Updated: 2024/05/06 14:06:33 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
@ -14,62 +14,98 @@
void close_pipe_fds(t_msh *msh, int i)
{
if (i != 0)
if (msh->fds)
{
if (msh->fds[i - 1][0] > 2)
close(msh->fds[i - 1][0]);
if (msh->fds[i - 1][1] > 2)
close(msh->fds[i - 1][1]);
if (i != 0)
{
if (msh->fds[i - 1] && msh->fds[i - 1][0] > 2)
close(msh->fds[i - 1][0]);
if (msh->fds[i - 1] && msh->fds[i - 1][1] > 2)
close(msh->fds[i - 1][1]);
}
if (msh->fds[i] && msh->fds[i][0] > 2)
close(msh->fds[i][0]);
if (msh->fds[i] && msh->fds[i][1] > 2)
close(msh->fds[i][1]);
}
if (msh->fds[i][0] > 2)
close(msh->fds[i][0]);
if (msh->fds[i][1] > 2)
close(msh->fds[i][1]);
}
void execute_command(t_msh *msh, char **cmd_args, int i)
void handle_parenthesis(t_msh *msh)
{
if (msh->cmds->token && (!ft_strcmp(msh->cmds->token, "cd")
|| !ft_strcmp(msh->cmds->token, "alias")
|| !ft_strcmp(msh->cmds->token, "unalias")
|| !ft_strcmp(msh->cmds->token, "exit") || exec_builtin(msh)))
char *command;
command = 0;
if (msh->cmds->cmd_type == PAREN)
command = ft_strdup(msh->cmds->value);
else if (msh->cmds->cmd_type == PIPE)
command = ft_strdup(msh->cmds->next->value);
if (!command)
{
while (i >= 0)
{
free(msh->fds[i]);
i--;
}
free(cmd_args);
ft_printf_fd(2, "an error occured");
ft_exit(msh, 1);
}
if (msh->cmds->token)
execve(msh->cmds->token, cmd_args, env_to_char_tab(msh->env));
free(msh->pids);
free_cmd(msh->cmds_head);
free_fds(msh);
msh->in_type = 0;
msh->out_type = 0;
msh->in_fd = 0;
msh->out_fd = 0;
msh->locked_return_code = 0;
exec_command_bonus(msh, command);
ft_exit(msh, g_return_code);
}
void execute_command(t_msh *msh, char **cmd_args)
{
char **env;
if (is_parenthesis(msh->cmds))
{
free(cmd_args);
handle_parenthesis(msh);
}
if (exec_builtin(msh))
{
free(cmd_args);
ft_exit(msh, g_return_code);
}
if (msh->tokens->value)
{
env = env_to_char_tab(msh->env);
if (env)
execve(msh->tokens->value, cmd_args, env);
ft_free_str_arr(env);
}
}
void child(t_msh *msh, char **cmd_args, int i)
{
if ((msh->in_type != ARG && msh->in_type != PIPE)
if ((msh->in_type != CMD && msh->in_type != PAREN && msh->in_type != AND
&& msh->in_type != OR && msh->in_type != PIPE)
|| (msh->in_type == PIPE && i > 0))
redirect_input(msh, i);
redirect_input(msh, i, cmd_args);
if (msh->out_type == PIPE || msh->out_type == RED_O
|| msh->out_type == RED_O_APP)
redirect_output(msh, i);
redirect_output(msh, i, cmd_args);
close_pipe_fds(msh, i);
execute_command(msh, cmd_args, i);
if (msh->in_fd > 2)
close(msh->in_fd);
if (msh->out_fd > 2)
close(msh->out_fd);
execute_command(msh, cmd_args);
close(0);
close(1);
close(2);
while (i >= 0)
{
free(msh->fds[i]);
i--;
}
free(cmd_args);
ft_exit(msh, 1);
ft_exit(msh, g_return_code);
}
void parent(t_msh *msh, int i, int cmd_count)
void parent(t_msh *msh, int i, int cmd_count, char **cmd_args)
{
free(cmd_args);
signal(SIGINT, signal_handler_command);
signal(SIGQUIT, signal_handler_command);
if (i != 0)
{
if (msh->fds[i - 1][0] > 2)

View File

@ -6,7 +6,7 @@
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/09 18:31:21 by tomoron #+# #+# */
/* Updated: 2024/02/21 12:47:39 by marde-vr ### ########.fr */
/* Updated: 2024/04/18 20:48:59 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"

View File

@ -1,35 +1,32 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* handle_alias.c :+: :+: :+: */
/* redirection_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/17 02:54:36 by tomoron #+# #+# */
/* Updated: 2024/02/21 17:21:27 by marde-vr ### ########.fr */
/* Created: 2024/05/03 14:11:22 by marde-vr #+# #+# */
/* Updated: 2024/05/03 14:11:50 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_cmd *handle_alias(t_msh *msh)
void ambiguous_redirect(char *str, t_msh *msh)
{
t_cmd *res;
t_cmd *tmp;
char *alias_command;
alias_command = 0;
if (!msh->cmds)
return (0);
if (msh->cmds->type == ARG)
alias_command = get_alias(msh->aliases, msh->cmds->token);
if (!alias_command)
return (msh->cmds);
res = parse_command(alias_command, msh->env);
tmp = res;
while (tmp->next)
tmp = tmp->next;
tmp->next = msh->cmds->next;
free(msh->cmds);
return (res);
ft_printf_fd(2, "minishell: %s: ambiguous redirect\n", str);
msh->in_fd = -2;
g_return_code = 1;
}
int first_is_in_type(t_cmd *cmd)
{
t_cmd *cur_token;
cur_token = cmd;
while (cur_token && cur_token->cmd_type == CMD && cur_token->next)
cur_token = cur_token->next;
if (is_input_type(cur_token) || cur_token->cmd_type == PIPE)
return (1);
return (0);
}

75
srcs/signal_handler.c Executable file
View File

@ -0,0 +1,75 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* signal_handler.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/03/22 14:31:13 by tomoron #+# #+# */
/* Updated: 2024/04/26 11:09:27 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void signal_handler_interactive(int signum)
{
if (signum == SIGINT)
{
g_return_code = 130;
rl_replace_line("", 0);
printf("^C\n");
rl_on_new_line();
rl_redisplay();
}
}
void *here_doc_variables(int write, void *data)
{
static void *variable;
if (write)
variable = data;
else
return (variable);
return (0);
}
void signal_handler_here_doc(int signum)
{
t_msh *msh;
if (signum == SIGINT)
{
msh = here_doc_variables(0, 0);
rl_on_new_line();
printf("^C\n");
if (msh->in_fd > 2)
close(msh->in_fd);
ft_exit(msh, 1);
}
}
int set_echoctl(int value)
{
struct termios t_p;
if (!isatty(1))
return (0);
if (tcgetattr(1, &t_p))
return (1);
if (((t_p.c_lflag & ECHOCTL) != 0) == value)
return (0);
if (value)
t_p.c_lflag = t_p.c_lflag | ECHOCTL;
else
t_p.c_lflag = t_p.c_lflag & (~ECHOCTL);
if (tcsetattr(1, TCSANOW, &t_p))
return (1);
return (0);
}
void signal_handler_command(int signum)
{
(void)signum;
}

56
srcs/sort_wildcard_list.c Normal file
View File

@ -0,0 +1,56 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* sort_wildcard_list.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tomoron <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/17 09:12:33 by tomoron #+# #+# */
/* Updated: 2024/04/22 19:30:43 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int wildcard_cmp(char *s1, char *s2, char *order)
{
while (*s1 && *s2)
{
while (*s1 && !ft_isalnum(*s1))
s1++;
while (*s2 && !ft_isalnum(*s2))
s2++;
if (*s1 != *s2)
return ((ft_strchr(order, *s2) - order) - (ft_strchr(order, *s1)
- order));
s1++;
s2++;
}
return ((ft_strchr(order, *s2) - order) - (ft_strchr(order, *s1) - order));
}
void sort_wildcards_token(t_token *list)
{
t_token *tmp;
t_token *start;
char *swap;
tmp = list;
start = list;
while (tmp)
{
list = start;
while (list->next)
{
if (wildcard_cmp(list->value, list->next->value, \
"zZyYxXwWvVuUtTsSrRqQpPoOnNmMlLkKjJiIhHgGfFeEdDcCbBaA9876543210") > 0)
{
swap = list->value;
list->value = list->next->value;
list->next->value = swap;
}
list = list->next;
}
tmp = tmp->next;
}
}

View File

@ -1,57 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* unalias.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/21 13:11:45 by marde-vr #+# #+# */
/* Updated: 2024/02/21 17:44:30 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int remove_alias(t_msh *msh)
{
t_alias *alias;
alias = msh->aliases;
while (alias)
{
if (alias->next && msh->cmds->next
&& !ft_strcmp(alias->next->name, msh->cmds->next->token))
{
if (alias->next->next)
alias->next = alias->next->next;
else
alias->next = 0;
alias->next = 0;
free_alias(alias);
return (1);
}
if (alias->next)
alias = alias->next;
else
alias = 0;
}
return (0);
}
int unalias(t_msh *msh)
{
if (msh->cmds->next && !ft_strcmp(msh->cmds->next->token, "-a"))
{
free_alias(msh->aliases);
msh->aliases = 0;
return (0);
}
if (remove_alias(msh))
return (1);
if (msh->cmds->next && msh->cmds->next->type == ARG)
ft_printf("minishell: unalias: %s: not found\n",
msh->cmds->next->token);
else
ft_printf("unalias: usage: unalias name\n");
return (1);
}

View File

@ -1,36 +1,28 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* debug.c :+: :+: :+: */
/* unset.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/18 15:46:50 by tomoron #+# #+# */
/* Updated: 2024/02/21 12:59:08 by marde-vr ### ########.fr */
/* Created: 2024/04/26 10:52:20 by marde-vr #+# #+# */
/* Updated: 2024/04/26 10:52:28 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void print_parsed_cmd(t_cmd *cmd)
int ft_unset(t_msh *msh)
{
t_token *cmd;
cmd = msh->tokens;
if (cmd)
cmd = cmd->next;
while (cmd)
{
printf("[");
if (cmd->type == ARG)
printf("ARG : \"%s\"", cmd->token);
else if (cmd->type == PIPE)
printf("PIPE");
else if (cmd->type == RED_O)
printf("RED_O");
else if (cmd->type == RED_O_APP)
printf("RED_O_APP");
else if (cmd->type == RED_I)
printf("RED_I");
else if (cmd->type == HERE_DOC)
printf("HERE_DOC");
printf("] ");
delete_from_env(msh, cmd->value);
cmd = cmd->next;
}
printf("\n");
return (0);
}

76
srcs/utils.c Normal file → Executable file
View File

@ -6,54 +6,82 @@
/* By: marde-vr <marde-vr@42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/03/05 18:19:26 by marde-vr #+# #+# */
/* Updated: 2024/03/06 10:19:58 by marde-vr ### ########.fr */
/* Updated: 2024/05/07 17:07:16 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void free_msh(t_msh *msh)
{
if (msh)
{
if (msh->cmds)
free_cmd(msh->cmds);
if (msh->env)
free_env(msh->env);
if (msh->aliases)
free_alias(msh->aliases);
if (msh->pids)
free(msh->pids);
if (msh->fds)
free(msh->fds);
free(msh);
}
}
void ft_exit(t_msh *msh, int exit_code)
{
free_msh(msh);
rl_clear_history();
exit(exit_code);
}
int check_var_name(char *name)
{
if (ft_isdigit(*name) || !*name)
return (0);
while (*name)
{
if (!ft_isalnum(*name) && *name != '_')
return (0);
name++;
}
return (1);
}
int add_return_code_to_str(char *res)
{
char *var;
int i;
i = 0;
var = ft_itoa(g_return_code);
while (var && var[i])
{
res[i] = var[i];
i++;
}
free(var);
return (i);
}
int file_access(t_msh *msh, int *found)
{
if (open(msh->cmds->token, O_DIRECTORY) != -1)
int fd;
fd = open(msh->tokens->value, O_DIRECTORY);
if (fd != -1)
{
ft_printf_fd(2, "minishell: %s: Is a directory\n", msh->cmds->token);
close(fd);
ft_printf_fd(2, "minishell: %s: Is a directory\n", msh->tokens->value);
g_return_code = 126;
return (0);
}
if (access(msh->cmds->token, X_OK) != -1)
if (access(msh->tokens->value, X_OK) != -1)
*found = 1;
else
{
ft_printf_fd(2, "minishell: %s: ", msh->cmds->token);
ft_printf_fd(2, "minishell: %s: ", msh->tokens->value);
perror("");
g_return_code = 127;
if (access(msh->cmds->token, F_OK) != -1)
if (access(msh->tokens->value, F_OK) != -1)
g_return_code = 126;
return (0);
}
return (1);
}
void close_all_pipes(t_msh *msh)
{
int i;
i = 0;
while (msh->fds && msh->fds[i])
{
close_pipe_fds(msh, i);
i++;
}
}

41
srcs/utils_bonus.c Executable file
View File

@ -0,0 +1,41 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* utils_bonus.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tomoron <tomoron@student.42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/03/27 17:19:27 by tomoron #+# #+# */
/* Updated: 2024/04/25 13:51:44 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_token *parsing_syntax_error(t_token *res)
{
free_token(res);
ft_putstr_fd("minishell: syntax error\n", 2);
g_return_code = 2;
return ((void *)1);
}
int is_input_type(t_cmd *cmd)
{
return (cmd->cmd_type == HERE_DOC || cmd->cmd_type == RED_I);
}
int is_output_type(t_cmd *cmd)
{
return (cmd->cmd_type == RED_O || cmd->cmd_type == RED_O_APP);
}
int is_cmd_type(t_cmd *cmd)
{
return (cmd->cmd_type == CMD || cmd->cmd_type == PAREN);
}
int is_operand_type(t_cmd *cmd)
{
return (cmd->cmd_type == AND || cmd->cmd_type == OR);
}

64
srcs/variable_expantion.c Normal file
View File

@ -0,0 +1,64 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* variable_expantion.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tomoron <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/06 10:57:33 by tomoron #+# #+# */
/* Updated: 2024/05/08 12:29:17 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int get_variable_expantion_len(char *command, t_env *env)
{
int in_quote;
int in_dquote;
int i;
i = 0;
in_dquote = 0;
in_quote = 0;
while (*command)
{
if (*command == '\'' && !in_dquote)
in_quote = !in_quote;
if (*command == '"' && !in_quote)
in_dquote = !in_dquote;
if (*command == '$' && !in_quote)
i += get_var_len(&command, env, in_dquote);
else
i++;
command++;
}
return (i);
}
char *expand_variables(char *command, t_env *env, int *is_var)
{
char *res;
int i;
int in_dquote;
int in_quote;
if (!command)
return (0);
res = ft_calloc(get_variable_expantion_len(command, env) + 1, 1);
in_quote = 0;
in_dquote = 0;
i = 0;
while (res && *command)
{
if (*command == '\'' && !in_dquote)
in_quote = !in_quote;
if (*command == '"' && !in_quote)
in_dquote = !in_dquote;
if (*command == '$' && !in_quote && ++(*is_var))
i += add_var_to_str(res + i, &command, env, in_dquote);
else
res[i++] = *command;
command++;
}
return (res);
}

106
srcs/wildcards.c Normal file
View File

@ -0,0 +1,106 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* wildcards.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tomoron <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/15 12:53:29 by tomoron #+# #+# */
/* Updated: 2024/04/29 11:12:40 by marde-vr ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int recursive_filename_check(char *wildcard, char **value)
{
while (**value)
{
if (filename_corresponds(wildcard + 1, *value))
return (1);
(*value)++;
}
return (0);
}
int filename_corresponds(char *wildcard, char *value)
{
if (*value == '.' && *wildcard != '.')
return (0);
while (*wildcard && *value)
{
if (*wildcard == '*')
{
while (*wildcard == '*' && wildcard[1] == '*')
wildcard++;
if (!wildcard[1])
return (1);
if (recursive_filename_check(wildcard, &value))
return (1);
return (0);
}
else if (*wildcard == *value)
{
wildcard++;
value++;
if (ft_str_is_only_char(wildcard, '*') && !*value)
return (1);
}
else
return (0);
}
return (!*wildcard && !*value);
}
t_token *get_all_files(DIR *dir, char *wildcard, int is_var)
{
struct dirent *content;
t_token *res;
res = 0;
content = readdir(dir);
while (content)
{
if (filename_corresponds(wildcard, content->d_name))
res = token_add_back(res, ft_strdup(content->d_name), is_var);
content = readdir(dir);
}
return (res);
}
t_token *add_token_back(t_token *res, t_token *next)
{
t_token *start;
if (!res)
return (next);
start = res;
while (res->next)
res = res->next;
res->next = next;
return (start);
}
t_token *expand_wildcards(t_token *res, char *value, int is_var)
{
DIR *dir;
char *cwd;
t_token *new;
if (!ft_strchr(value, '*'))
return (token_add_back(res, value, is_var));
cwd = getcwd(NULL, 100000);
if (!cwd)
return (token_add_back(res, value, is_var));
dir = opendir(cwd);
free(cwd);
if (!dir)
return (token_add_back(res, value, is_var));
new = get_all_files(dir, value, is_var);
closedir(dir);
if (!new)
return (token_add_back(res, value, is_var));
free(value);
sort_wildcards_token(new);
res = add_token_back(res, new);
return (res);
}