todo.c Todo is a simple program for managing a todo file. I keep mine at ~/.todo Each line is a different task to do, if todo is called without any args, then it displays the todo file. Todo accepts the flags -s, -a, and -d for show, add, and delete respectively. Only -d takes an argument for the line number to remove. Writing todo was relatively simple. Showing the todo is trivial, open the file for reading, write each character to stdout until the end of file. Appending to the todo is straight forward as well, read characters from stdin and append to the file until a newline is seen. Deleting a line was a little trickier. I elected not to read the file into memory and modify it there, but instead read the portions of the todo file I wanted to keep into a temporary stream, counting newline characters to determine which line was to be skipped. Then the todo file is truncated and the temporary stream is rewound and read back into the location of the original todo file. Additional features I am considering: Displaying the todo file with line numbers so it is easier to know the right line to remove when a task is completed. Accept additional args for the append flag, -a, so a new task may be added by $ todo -a <new todo here> Let the default location of the todo file be discovered relative to a user's home instead of being hardcoded. Right now the current file location is declared in a global at the top of the source file. Neat things learned: Adding the -H flag to the $CFLAGS displays all headers sourced and their paths. I like how easy it is to look through headers for additional information. e.g. I knew there was a global variable for the max size on an integer, but didn't know precisely where it was defined or what it was named. Knowing header locations on my system made it easy to find without needing to look online. There is an interesting security nuance around the system calls to create tmp files. mktemp, tmpnam, and tempname all return paths for temporary files. Typically these paths are then used to create, write, or read from later in the file. Primarily there is a race condition, between getting the name and reading the file, and an attacker may place a file at the expected location. Secondarily, tmp file locations and permissions are system dependent and may not be created securely. This information is layed out in the openbsd man pages tmpnam(3), mktemp(3) and related pages. Exploiting a race condition in my own program would be a fun challenge. I sidestepped these issues using tmpfile(3) which is based on mkstemp(3).