Back to index

glibc  2.9
ftwtest.c
Go to the documentation of this file.
00001 #include <ftw.h>
00002 #include <getopt.h>
00003 #include <mcheck.h>
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006 #include <string.h>
00007 #include <unistd.h>
00008 #include <sys/stat.h>
00009 
00010 
00011 int do_depth;
00012 int do_chdir;
00013 int do_phys;
00014 int do_exit;
00015 char *skip_subtree;
00016 char *skip_siblings;
00017 
00018 struct option options[] =
00019 {
00020   { "depth", no_argument, &do_depth, 1 },
00021   { "chdir", no_argument, &do_chdir, 1 },
00022   { "phys", no_argument, &do_phys, 1 },
00023   { "skip-subtree", required_argument, NULL, 't' },
00024   { "skip-siblings", required_argument, NULL, 's' },
00025   { "early-exit", no_argument, &do_exit, 1 },
00026   { NULL, 0, NULL, 0 }
00027 };
00028 
00029 const char *flag2name[] =
00030 {
00031   [FTW_F] = "FTW_F",
00032   [FTW_D] = "FTW_D",
00033   [FTW_DNR] = "FTW_DNR",
00034   [FTW_NS] = "FTW_NS",
00035   [FTW_SL] = "FTW_SL",
00036   [FTW_DP] = "FTW_DP",
00037   [FTW_SLN] = "FTW_SLN"
00038 };
00039 
00040 
00041 static int
00042 cb (const char *name, const struct stat *st, int flag, struct FTW *f)
00043 {
00044   if (do_exit && strcmp (name + f->base, "file@2"))
00045     return FTW_CONTINUE;
00046 
00047   printf ("base = \"%.*s\", file = \"%s\", flag = %s",
00048          f->base, name, name + f->base, flag2name[flag]);
00049   if (do_chdir)
00050     {
00051       char *cwd = getcwd (NULL, 0);
00052       printf (", cwd = %s", cwd);
00053       free (cwd);
00054     }
00055   printf (", level = %d\n", f->level);
00056 
00057   if (skip_siblings && strcmp (name + f->base, skip_siblings) == 0)
00058     return FTW_SKIP_SIBLINGS;
00059 
00060   if (skip_subtree && strcmp (name + f->base, skip_subtree) == 0)
00061     return FTW_SKIP_SUBTREE;
00062 
00063   return do_exit ? 26 : FTW_CONTINUE;
00064 }
00065 
00066 int
00067 main (int argc, char *argv[])
00068 {
00069   int opt;
00070   int r;
00071   int flag = 0;
00072   mtrace ();
00073 
00074   while ((opt = getopt_long_only (argc, argv, "", options, NULL)) != -1)
00075     {
00076       if (opt == 't')
00077         skip_subtree = optarg;
00078       else if (opt == 's')
00079         skip_siblings = optarg;
00080     }
00081 
00082   if (do_chdir)
00083     flag |= FTW_CHDIR;
00084   if (do_depth)
00085     flag |= FTW_DEPTH;
00086   if (do_phys)
00087     flag |= FTW_PHYS;
00088   if (skip_subtree || skip_siblings)
00089     {
00090       flag |= FTW_ACTIONRETVAL;
00091       if (do_exit)
00092        {
00093          printf ("--early-exit cannot be used together with --skip-{siblings,subtree}");
00094          exit (1);
00095        }
00096     }
00097 
00098   char *cw1 = getcwd (NULL, 0);
00099 
00100   r = nftw (optind < argc ? argv[optind] : ".", cb, do_exit ? 1 : 3, flag);
00101   if (r < 0)
00102     perror ("nftw");
00103 
00104   char *cw2 = getcwd (NULL, 0);
00105 
00106   if (strcmp (cw1, cw2) != 0)
00107     {
00108       printf ("current working directory before and after nftw call differ:\n"
00109              "before: %s\n"
00110              "after:  %s\n", cw1, cw2);
00111       exit (1);
00112     }
00113 
00114   if (do_exit)
00115     {
00116       puts (r == 26 ? "succeeded" : "failed");
00117       return r == 26 ? 0 : 1;
00118     }
00119   return r;
00120 }