mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-10-30 10:45:40 +03:00 
			
		
		
		
	2003-11-07 Jakub Jelinek <jakub@redhat.com> * io/ftw.c (NFTW_OLD_NAME, NFTW_NEW_NAME): Define. (ftw_dir, ftw_startup): Add __attribute ((noinline)). (NFTW_OLD_NAME, NFTW_NEW_NAME): New functions. (NFTW_NAME): Only define if !_LIBC, add versioned_symbol and compat_symbol. * io/ftw64.c (NFTW_OLD_NAME, NFTW_NEW_NAME): Define. * io/Versions (libc): Export nftw@@GLIBC_2.3.3 and nftw64@@GLIBC_2.3.3. * io/ftw.h (FTW_ACTIONRETVAL): New flag. (FTW_CONTINUE, FTW_STOP, FTW_SKIP_SUBTREE, FTW_SKIP_SIBLINGS): New. * io/ftw.c (ftw_dir): Add old_dir argument. Clear result if it was FTW_SKIP_SIBLINGS after processing all dir entries. Change cwd back if old_dir != NULL. (process_entry): Adjust caller. Don't change cwd back here. Change FTW_SKIP_SUBTREE result to 0. (ftw_startup): Adjust ftw_dir caller. Clear result if it was FTW_SKIP_SUBTREE or FTW_SKIP_SIBLINGS. * io/ftwtest.c (skip_subtree, skip_siblings): New variables. (options, main): Add --skip-subtree and --skip-siblings options. (cb): Use return FTW_CONTINUE instead of return 0. Handle --skip-subtree and --skip-siblings. * io/ftwtest-sh: Add tests for FTW_ACTIONRETVAL. * manual/filesys.texi: Document FTW_ACTIONRETVAL.
		
			
				
	
	
		
			121 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include <ftw.h>
 | |
| #include <getopt.h>
 | |
| #include <mcheck.h>
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <unistd.h>
 | |
| #include <sys/stat.h>
 | |
| 
 | |
| 
 | |
| int do_depth;
 | |
| int do_chdir;
 | |
| int do_phys;
 | |
| int do_exit;
 | |
| char *skip_subtree;
 | |
| char *skip_siblings;
 | |
| 
 | |
| struct option options[] =
 | |
| {
 | |
|   { "depth", no_argument, &do_depth, 1 },
 | |
|   { "chdir", no_argument, &do_chdir, 1 },
 | |
|   { "phys", no_argument, &do_phys, 1 },
 | |
|   { "skip-subtree", required_argument, NULL, 't' },
 | |
|   { "skip-siblings", required_argument, NULL, 's' },
 | |
|   { "early-exit", no_argument, &do_exit, 1 },
 | |
|   { NULL, 0, NULL, 0 }
 | |
| };
 | |
| 
 | |
| const char *flag2name[] =
 | |
| {
 | |
|   [FTW_F] = "FTW_F",
 | |
|   [FTW_D] = "FTW_D",
 | |
|   [FTW_DNR] = "FTW_DNR",
 | |
|   [FTW_NS] = "FTW_NS",
 | |
|   [FTW_SL] = "FTW_SL",
 | |
|   [FTW_DP] = "FTW_DP",
 | |
|   [FTW_SLN] = "FTW_SLN"
 | |
| };
 | |
| 
 | |
| 
 | |
| static int
 | |
| cb (const char *name, const struct stat *st, int flag, struct FTW *f)
 | |
| {
 | |
|   if (do_exit && strcmp (name + f->base, "file@2"))
 | |
|     return FTW_CONTINUE;
 | |
| 
 | |
|   printf ("base = \"%.*s\", file = \"%s\", flag = %s",
 | |
| 	  f->base, name, name + f->base, flag2name[flag]);
 | |
|   if (do_chdir)
 | |
|     {
 | |
|       char *cwd = getcwd (NULL, 0);
 | |
|       printf (", cwd = %s", cwd);
 | |
|       free (cwd);
 | |
|     }
 | |
|   printf (", level = %d\n", f->level);
 | |
| 
 | |
|   if (skip_siblings && strcmp (name + f->base, skip_siblings) == 0)
 | |
|     return FTW_SKIP_SIBLINGS;
 | |
| 
 | |
|   if (skip_subtree && strcmp (name + f->base, skip_subtree) == 0)
 | |
|     return FTW_SKIP_SUBTREE;
 | |
| 
 | |
|   return do_exit ? 26 : FTW_CONTINUE;
 | |
| }
 | |
| 
 | |
| int
 | |
| main (int argc, char *argv[])
 | |
| {
 | |
|   int opt;
 | |
|   int r;
 | |
|   int flag = 0;
 | |
|   mtrace ();
 | |
| 
 | |
|   while ((opt = getopt_long_only (argc, argv, "", options, NULL)) != -1)
 | |
|     {
 | |
|       if (opt == 't')
 | |
|         skip_subtree = optarg;
 | |
|       else if (opt == 's')
 | |
|         skip_siblings = optarg;
 | |
|     }
 | |
| 
 | |
|   if (do_chdir)
 | |
|     flag |= FTW_CHDIR;
 | |
|   if (do_depth)
 | |
|     flag |= FTW_DEPTH;
 | |
|   if (do_phys)
 | |
|     flag |= FTW_PHYS;
 | |
|   if (skip_subtree || skip_siblings)
 | |
|     {
 | |
|       flag |= FTW_ACTIONRETVAL;
 | |
|       if (do_exit)
 | |
| 	{
 | |
| 	  printf ("--early-exit cannot be used together with --skip-{siblings,subtree}");
 | |
| 	  exit (1);
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|   char *cw1 = getcwd (NULL, 0);
 | |
| 
 | |
|   r = nftw (optind < argc ? argv[optind] : ".", cb, do_exit ? 1 : 3, flag);
 | |
|   if (r < 0)
 | |
|     perror ("nftw");
 | |
| 
 | |
|   char *cw2 = getcwd (NULL, 0);
 | |
| 
 | |
|   if (strcmp (cw1, cw2) != 0)
 | |
|     {
 | |
|       printf ("current working directory before and after nftw call differ:\n"
 | |
| 	      "before: %s\n"
 | |
| 	      "after:  %s\n", cw1, cw2);
 | |
|       exit (1);
 | |
|     }
 | |
| 
 | |
|   if (do_exit)
 | |
|     {
 | |
|       puts (r == 26 ? "succeeded" : "failed");
 | |
|       return r == 26 ? 0 : 1;
 | |
|     }
 | |
|   return r;
 | |
| }
 |