Everything you need to know to start coding your own shell
- getppid
Getting the process ID:
Compile the code:
gcc -Wall -Werror -pedantic pid.c -o mypid && ./mypid
Run the program:
./mypid
- /proc/sys/kernel/pid_max
Get the max PID:
Compile the code:
gcc -Wall -Werror -pedantic pid_max.c -o pid_max && ./pid_max
Run the code:
./pid_max
Sample output:
Maximum process ID: -1
Exercises 0. av
Write a program that prints all the arguments, without using ac
.
- Read line
Write a program that prints "$ "
, wait for the user to enter a command, prints it on the next line.
man 3 getline
important make sure you read the man, and the RETURN VALUE
section, in order to know when to stop reading.
Keyword: “end-of-file”
, or EOF
(or Ctrl+D
).
Compile the code:
gcc -Wall -Wextra -Werror -pedantic prompt.c -o prompt
Run the program:
./prompt
Sample output:
./prompt
$ cat prompt.c
cat prompt.c
- command line to av
Write a function that splits a string and returns an array of each word of the string.
man strtok
File: commandlinetoav
Compile the code:
gcc -Wall -Wextra -Werror -pedantic commandlinetoav.c -o commandlinetoav
Run the program:
./commandlinetoav
Sample output:
shell# ./commandlinetoav
Number of words: 5
Words:
This
is
a
test
string
The system call execve
allows a process to execute another program (man 2 execve
). Note that this system
call does load the new program into the current process’ memory in place of the “previous” program: on
success execve
does not return to continue the rest of the “previous” program.
Warning: in this example, execve
is used without the current environment (last argument), don’t forget to add it in your Shell!
See exec.c
Compile the code:
gcc -Wall -Wextra -Werror -pedantic exec.c -o exec
Run the program:
./exec
Sample output:
Before execve
total 64
drwxr-xr-x 1 root root 20480 Mar 30 2022 bin
drwxr-xr-x 2 root root 6 Apr 15 2020 games
drwxr-xr-x 1 root root 4096 Mar 30 2022 include
drwxr-xr-x 1 root root 4096 Mar 30 2022 lib
drwxr-xr-x 1 root root 4096 Mar 30 2022 lib32
drwxr-xr-x 1 root root 34 Mar 30 2022 lib64
drwxr-xr-x 1 root root 95 Mar 30 2022 libexec
drwxr-xr-x 1 root root 4096 Mar 30 2022 libx32
drwxr-xr-x 1 root root 19 Mar 16 2022 local
drwxr-xr-x 1 root root 4096 Mar 30 2022 sbin
drwxr-xr-x 1 root root 4096 Mar 30 2022 share
drwxr-xr-x 2 root root 6 Apr 15 2020 src
The system call fork
(man 2 fork
) creates a new child process, almost identical to the parent (the process
that calls fork
). Once fork
successfully returns, two processes continue to run the same program, but with
different stacks, datas and heaps.
see fork.c
.
Compile the code:
gcc -Wall -Wextra -Werror -pedantic fork.c -o fork
Run the program:
./fork
Sample output:
Before fork
After fork
My pid is 120
After fork
My pid is 121
Similarly, Using the return value of fork, it is possible to know if
the current process is the father or the child: fork will return 0 to the child,
and the PID of the child to the father.
See: fork2.c
Compile the code:
gcc -Wall -Wextra -Werror -pedantic fork2.c -o fork2
Run the program:
./fork2
Sample output:
shell# ./fork2
My pid is 192
(192) 193, I am your father
My pid is 193
(193) Nooooooooo!
The wait
system call (man 2 wait
) suspends execution of the calling process until one of its children terminates.
See wait.c
Compile the code:
gcc -Wall -Wextra -Werror -pedantic wait.c -o wait
Run the program:
./wait
Sample output:
Wait for me, wait for me
Oh, it's all better now
Write a program that executes the command ls -l /tmp
in 5 different child processes.
Each child should be created by the same process (the father).
Wait for a child to exit before creating a new child.
Compile the code:
gcc -Wall -Wextra -Werror -pedantic forkwaitexecve.c -o forkwaitexecve
Run the program:
./forkwaitexecve
Sample output:
shell# ./forkwaitexecve
Child process 1: PID 220
total 0
drwx------ 2 mysql mysql 6 Mar 30 2022 tmp.DAOEzJT0J6
drwx------ 2 mysql mysql 6 Mar 30 2022 tmp.dOKjikw0Ig
drwx------ 2 root root 22 Mar 30 2022 tmpztrs6ymg
Child process 2: PID 221
total 0
drwx------ 2 mysql mysql 6 Mar 30 2022 tmp.DAOEzJT0J6
drwx------ 2 mysql mysql 6 Mar 30 2022 tmp.dOKjikw0Ig
drwx------ 2 root root 22 Mar 30 2022 tmpztrs6ymg
Child process 3: PID 222
total 0
drwx------ 2 mysql mysql 6 Mar 30 2022 tmp.DAOEzJT0J6
drwx------ 2 mysql mysql 6 Mar 30 2022 tmp.dOKjikw0Ig
drwx------ 2 root root 22 Mar 30 2022 tmpztrs6ymg
Child process 4: PID 223
total 0
drwx------ 2 mysql mysql 6 Mar 30 2022 tmp.DAOEzJT0J6
drwx------ 2 mysql mysql 6 Mar 30 2022 tmp.dOKjikw0Ig
drwx------ 2 root root 22 Mar 30 2022 tmpztrs6ymg
Child process 5: PID 224
total 0
drwx------ 2 mysql mysql 6 Mar 30 2022 tmp.DAOEzJT0J6
drwx------ 2 mysql mysql 6 Mar 30 2022 tmp.dOKjikw0Ig
drwx------ 2 root root 22 Mar 30 2022 tmpztrs6ymg
gcc -Wall -Wextra -Werror -pedantic firstsimpleshell.c -o firstsimpleshell
Run the program:
./firstsimpleshell
Sample output:
shell# ./firstsimpleshell
#cisfun$ ls
av custom_getline exec.c fork fork.c getppid pid.c prompt stat.c
commandlinetoav env-main.c firstsimpleshell fork2 forkwaitexecve main.h pid_max prompt.c wait