today I wanted to look back at a project I had to do as a student, and I struggled a LOT at the time, and found the project very boring.
Basically, I had to develop ls, with the -l -r -R and -a options, and with only malloc, free, write, stat, ctime, time, getpwuid, getgrgid, readdir, opendir and closedir.
As always, I wanted to challenge myself again to rewrite some C. At first, I told myself that it would be an easy 2 hours project as an old C developer, but holy ***, it didn’t. It took me around 5 hours to write a code I’m not proud of, with the not-allowed use of sprintf that saved me time. It still need a lot of testing, memory leak finding, and refactoring (it always need :) ).
But yeah, it’s a great basic project. I would suggest anyone that want to learn C development, to learn basic algorithmic and memory handling to try this one.
There is 3things at least you will learn.
Rewriting code in a language without garbage collector can be a pain in the ass. It’s hard to keep track of ALL allocated memory to free it after. But after a while, it’s really pleasant to do so. You can really go in fond of performance, and allocate just the minimum memory to your needs for the best algorithm.
GDB is a wonderful tool that will help anyone debugging C code, but it’s slow to debug C in general, so the best way to have a C program working is to really think a lot before coding.
In C, with just the basic functions given, you don’t have great strings/arrays/hashes/linked-list functions. It’s wild.
I started to do all my data structuration with simple string parsing, and then sorting was a pain, so I worked on a linked-list data structure. Pretty straightforward, but add-delete-sort are basic but great to start algorithmics. It’s good to understand what is behind a sort in Ruby for example. You have a better idea of what is performance and what are the different sort you could use.
You will need to parse strings, transform a string to a integer, transform an integer to a binary strings etc. A lot of manipulation that leads to a LOT of bugs, that will reduce over time of refactoring.
It’s important to have a big picture in C development, and not rush to the result, because you will not have any result but “Game over, your code has segfault, try again”
This part is really important for the -R (recursive) option, as if you just print as you see, it’ll be impossible to apply the algorithm to the folder inside the folders :)
Everyone one that had use an unix terminal in their lives know what ls is, and what it’s used for. But ls has many many options to format data and use it for your scripts.
for example, the most known ls -l will give you a string that look like
-rw-r — r — 1 poilon staff 41 22 jul 13:55 Makefile
-rwxr-xr-x 1 poilon staff 14248 22 jul 13:58 c_ls
and while coding it, you’ll have a better idea of how it works. The read-write-execute rights, the number of links, the owners: user and group etc.
It’ll for sure be useful for the people that just had a bootcamp in development and don’t use a unix-based system every day.
This project gave me a real satisfaction when I had a ls -alRr working. I took it as a speedrun of a game, and I had the ls -alRr working in 5h and 12m. Now I’m really tired !
That was really entertaining and pleasant to redo some C, and I’m sure it made me a better developer anyway !
Hope you liked the read, tell me what you think and if you want me to do maybe a streamed/youtube version of this kind of challenge, or any other format.