Schedule
Labs
Assignments
TA office hours
Topic videos
Some course notes
Extra problems
Lecture recordings
The real scandir() also takes function-pointer arguments to allow selecting a subset of the directory list, and to allow sorting the directory list in arbitrary ways. You won't emulate these aspects of scandir(); your "myscandir()" will take just two arguments. The first argument is a string indicating the directory to scan; this is simply passed to opendir().
The second argument is a pointer to a variable which will be set to the array information. The array will be an array of pointers-to-struct-dirent (since you will call malloc() for each struct dirent). Therefore myscandir() needs to give the caller a pointer to the zeroth item of this list; such a pointer would be a pointer-to-pointer-to-struct-dirent. Thus the second argument to myscandir() is actually a pointer-to-pointer-to-pointer-to-struct-dirent, which myscandir() dereferences to assign the pointer-to-pointer-to-struct-dirent value to the appropriate variable as chosen by the caller.
myscandir(), like scandir(), returns type int. It returns the number of items in the resulting array, or −1 for error.
The resulting data structure needs a small loop to free() properly. You will also write "myfreescandir()", which takes a pointer-to-pointer-to-struct-dirent argument and an integer argument (the latter being the original return value from myscandir()). (It is not valid to call myfreescandir() if myscandir() returned −1.)
There is a myscandir.h in /u/csc209h/summer/pub/a3/myscandir.h which you must copy without editing, and #include in your myscandir.c. It simply declares myscandir() and myfreescandir(). Also in that directory is an example test driver with a main() which you may want to use in testing. (You submit only myscandir.c, without a main().)
The search keys are integers, and the values are arbitrary character strings of size up to 9 bytes (i.e. stored in an array of size 10). The initial process is the root node. The key and value are specified on the command-line (the key is argv[1] and the value is argv[2]).
The initial process reads lines from stdin in a loop. The line can be simply an integer; this means to search for that key. Otherwise, the line can be an integer, a space, and the value; this means to set that key to that value. In either case the (possibly new) key and value are output.
Each process loops until EOF, getting a key or a key+value either from stdin (in the case of the root node process) or from the pipe from its parent (in the case of all other processes). Then, if the key matches its own key, it can return the key+value information up the pipe to its parent (or, if it's the root node, output it to stdout). Otherwise, it passes the request down to either its left child or right child as appropriate. When a process is first created, it doesn't have a left child or right child; when it goes to pass a request down to a child, it calls fork() if necessary (setting up the new child, which then does its own loop).
Do not attempt to height-balance your binary search tree.
Upon EOF from the pipe from the parent, close the pipes to any child node processes, wait for all child node processes, then exit. Your child nodes, if any, will thus get EOF from their pipes to their parents (you), and do the same; and so on all the way down the tree. Similarly, when the root node process gets EOF from stdin, it will also do this process (close pipes to children, wait, exit). This will cause an orderly shutdown of the entire tree when you signal EOF on stdin (e.g. by pressing control-D). (Note that this scheme means that the root node will not exit until all other nodes have exited, which is good because the shell you ran the program from is waiting for the initial process, which is the root node.)
There is "starter code" in /u/csc209h/summer/pub/a3/tree.c.starter which contains a suitable main() function dealing with argv, plus a function to parse the key+value data (from stdin in the main process) into a struct containing the integer key and the string value. You can then simply read() and write() this struct between parents and children.
You do not necessarily need to modify the main() in tree.c.starter, but you can do so if you wish; similarly for the utility functions in tree.c.starter.
You should call your assignment files myscandir.c and tree.c. Auxiliary files are not permitted. Submit with commands such as
submit -c csc209h -a a3 myscandir.c tree.cand the other 'submit' commands are as before.
Please see the assignment Q&A web page at https://www.teach.cs.toronto.edu/~ajr/209/a3/qna.html for other reminders, and answers to common questions.
Despite the above, I'd like to be clear that if there is a legitimate reason for lateness, please do submit your assignment late and send me that written explanation.
And above all: Do not commit an academic offence. Your work must be your own. Do not look at other students' assignments, and do not show your assignment (complete or partial) to other students. Collaborate with other students only on material which is not being submitted for course credit.