For part of a project, I was given this directive:The find command will use the directory (dirent) function calls, but  will require you to start at a directory and then determine if a file  is a directory or a file and if it is a directory you will need to  walk down that directory as well. You will need a method/algorithm to  note the new directories and build a logical graph or thread out every  directory to find if the filename is in that directory and display the  absolute path to that file.I thought the nftw() function would be optimal for this, and I believe it makes my application pretty robust and fast.  On my Mac (ommiting 196 lines of filename output each):$ time find ../../ -name CMakeLists.txtreal    0m0.337suser    0m0.025ssys 0m0.292s$ time ./my_find ../../ -name CMakeLists.txtreal    0m0.326suser    0m0.022ssys 0m0.278sfind.c:#define _XOPEN_SOURCE 1#define _XOPEN_SOURCE_EXTENDED 1#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <dirent.h>#include <ftw.h>#include <unistd.h>#ifndef streq#define streq(x, y) (strcmp((x), (y)) == 0)#endiftypedef enum {SUCCESS, INVALD_DIR, OPENDIR_ERR, NFTW_ERR} Return;const char* str = NULL;int check_path(const char* path){    DIR* dir = opendir(path);    if (dir)  // directory exists    {        closedir(dir);        return 0;    }    else if (ENOENT == errno) // directory doesn't exist        return INVALD_DIR;    else // opendir failed for some other reason        return OPENDIR_ERR;}int callback(const char *file, const struct stat *sb, int flag, struct FTW *s){    int err = 0;    const char *name = file + s->base;    switch (flag)    {        case FTW_F:            if (streq(name, str))                puts(file);            break;        case FTW_D:        case FTW_DNR:        case FTW_SL:        case FTW_NS:            break; // continue as normal        case FTW_DP:        case FTW_SLN:        default:            err = NFTW_ERR; // error occured            break;    }    return err;}int process(const char* path){    int err = nftw(path, callback, getdtablesize(), 0);    return err;}void usage(const char* prog_name){    fprintf(stdout, usage: %s [path] -name <name>\n, prog_name);    exit(EXIT_SUCCESS);}int main(int argc, char **argv){    if(argc < 4)        usage(argv[0]);    const char* path = argv[1];    str = argv[3];    int err = check_path(path);    if (err)    {        fprintf(stderr, %s: %s: %s\n, argv[0], path, strerror(errno));        return err;    }    else        process(path);    return err;}Any suggestions?
The fastest finder of them all?
algorithm;c;file;reinventing the wheel;homework
I like your solution, it's clever & fast, however I can't help but feel like it goes against the spirit of the assignment.  You've found a built in system call that greatly simplifies what it is your need to do, which is great, but in doing so you've delegated the algorithm, which may not be what is expected from the assignment.The assignment reads as if it's expecting your to use things like opendir and readdir to iterate through the folders yourself.  You would then be responsible for maintaining state, and writing the iteration algorithm.-name or not -nameYour argument handling is also a little bit on the naive side.  Should I really be able to run it like this:./my_find ../../ -ThisArgumentIsNeverCheckedSoICanPutPrettyMuchAnything CMakeLists.txtWhy both having the second argument if you're not going to check it, it's just extra typing...WildcardsIt's not really clear from the spec, however the built in 'find' command supports wildcards.  Your current implementation doesn't appear to (you're only doing an exact match).