exit
. Then add cd
, then path
. Then implement the ability to execute commands with execv
, then add batch mode, then redirection, and finally parallel commands.path
command, make sure you can handle both absolute and relative paths (i.e., path tests
as well as path /usr/bin
.i
, you can check tests/i.err
and tests/i.rc
to see how many errors your shell should generate and compare to tests-out/i.err
and tests-out/i.rc
.ls: cannot access ...
and your shell outputs /bin/ls: cannot access ...
or /usr/bin/ls: cannot access ...
, try modifying your $PATH environment variable to start with /bin
. If that doesn’t work, just modify tests/3.err
to match the output your system gives. You can’t modify your system’s output without messing with the implementation of ls
and/or execv
, so it’s okay to skip this test as long as it’s working in spirit./tests/3.pre
to use /bin/ls
due to how it’s set up on my system, in order to pass all the tests. Alternatively you can add export PATH="/bin:$PATH"
to your .profile
or .bashrc
file.This assignment makes it really easy to create pointers to stack variables that will no longer exist once they’re out of scope, thus causing a segmentation fault. Make sure that if you set a pointer to point to a string, that string is something you allocated on the heap, and not on the stack.
That said, if you do use a string on the stack, you can copy it into a heap-allocated string using strcpy()
, strncpy()
, strcat()
, and strncat()
.
Only use strcpy()
and strcat()
for fixed-size strings and make sure the buffer you’re copying into has enough space to hold the string, plus an extra character for \0
.
For strncpy()
and strncat()
, make sure n
is large enough to fit the \0
terminator, or add it manually.
Watch out for use-after-frees, especially in the implementation of path
.
Make sure you free any strings from getline()
and strdup()
, but watch out for double-frees, e.g. don’t free a substring of a string you already freed.
Avoid the C library function strtok()
; it’s not thread-safe. Use strsep()
instead.
When you use strsep()
, make sure you keep a copy of the original pointer to the string around so that you can free it later, because strsep()
will modify the pointer, so if you free that later on, you’ll corrupt the page table.
strsep(&buf, delim)
, check whether buf
is NULL
before dereferencing it.create_xxx
function, you should have a corresponding destroy_xxx
function. That way, you always allocate and free memory at the same function depth, which makes it easier to avoid memory errors.malloc
, calloc
, or realloc
, check whether the result is NULL
.calloc
instead of malloc
if you’re creating an array of pointers to avoid creating pointers to garbage values.update_path
I had to fix that issue where most of the tests do path /bin /usr/bin
, but one of them did path tests
. So i just assumed that if your path starts with a slash, it’s an absolute path and you should copy it in as is; if it doesn’t, it’s a relative path and you should add a ./ at the beginning.