⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 df.c

📁 Linux下文件工具。
💻 C
📖 第 1 页 / 共 2 页
字号:
  /* Restore the original cwd.  */  {    int save_errno = errno;    if (restore_cwd (&cwd, 0, mp))      exit (1);			/* We're scrod.  */    free_cwd (&cwd);    errno = save_errno;  }  return mp;}/* Figure out which device file or directory POINT is mounted on   and show its disk usage.   STATP is the results of `stat' on POINT.  */static voidshow_point (const char *point, const struct stat *statp){  struct stat disk_stats;  struct mount_entry *me;  struct mount_entry *matching_dummy = NULL;  char *needs_freeing = NULL;  /* If POINT is an absolute path name, see if we can find the     mount point without performing any extra stat calls at all.  */  if (*point == '/')    {      for (me = mount_list; me; me = me->me_next)	{	  if (STREQ (me->me_mountdir, point) && !STREQ (me->me_type, "lofs"))	    {	      /* Prefer non-dummy entries.  */	      if (! me->me_dummy)		goto show_me;	      matching_dummy = me;	    }	}      if (matching_dummy)	goto show_matching_dummy;    }  /* Ideally, the following mess of #if'd code would be in a separate     file, and there'd be a single function call here.  FIXME, someday.  */#if HAVE_REALPATH || HAVE_RESOLVEPATH || HAVE_CANONICALIZE_FILE_NAME  /* Calculate the real absolute path for POINT, and use that to find     the mount point.  This avoids statting unavailable mount points,     which can hang df.  */  {    char const *abspoint = point;    char *resolved;    ssize_t resolved_len;    struct mount_entry *best_match = NULL;# if HAVE_CANONICALIZE_FILE_NAME    resolved = canonicalize_file_name (abspoint);    resolved_len = resolved ? strlen (resolved) : -1;# else#  if HAVE_RESOLVEPATH    /* All known hosts with resolvepath (e.g. Solaris 7) don't turn       relative names into absolute ones, so prepend the working       directory if the path is not absolute.  */    if (*point != '/')      {	static char const *wd;	if (! wd)	  {	    struct stat pwd_stats;	    struct stat dot_stats;	    /* Use PWD if it is correct; this is usually cheaper than               xgetcwd.  */	    wd = getenv ("PWD");	    if (! (wd		   && stat (wd, &pwd_stats) == 0		   && stat (".", &dot_stats) == 0		   && SAME_INODE (pwd_stats, dot_stats)))	      wd = xgetcwd ();	  }	if (wd)	  {	    needs_freeing = path_concat (wd, point, NULL);	    if (needs_freeing)	      abspoint = needs_freeing;	  }      }#  endif#  if HAVE_RESOLVEPATH    {      size_t resolved_size = strlen (abspoint);      while (1)	{	  resolved_size = 2 * resolved_size + 1;	  resolved = xmalloc (resolved_size);	  resolved_len = resolvepath (abspoint, resolved, resolved_size);	  if (resolved_len < resolved_size)	    break;	  free (resolved);	}    }#  else    /* Use realpath only as a last resort.       It provides a very poor interface.  */    resolved = xmalloc (PATH_MAX + 1);    resolved = (char *) realpath (abspoint, resolved);    resolved_len = resolved ? strlen (resolved) : -1;#  endif# endif    if (1 <= resolved_len && resolved[0] == '/')      {	size_t best_match_len = 0;	for (me = mount_list; me; me = me->me_next)	  if (! me->me_dummy)	    {	      size_t len = strlen (me->me_mountdir);	      if (best_match_len < len && len <= resolved_len		  && (len == 1 /* root file system */		      || ((len == resolved_len || resolved[len] == '/')			  && strncmp (me->me_mountdir, resolved, len) == 0)))		{		  best_match = me;		  best_match_len = len;		}	    }      }    if (resolved)      free (resolved);    if (best_match && !STREQ (best_match->me_type, "lofs")	&& stat (best_match->me_mountdir, &disk_stats) == 0	&& disk_stats.st_dev == statp->st_dev)      {	me = best_match;	goto show_me;      }  }#endif  for (me = mount_list; me; me = me->me_next)    {      if (me->me_dev == (dev_t) -1)	{	  if (stat (me->me_mountdir, &disk_stats) == 0)	    me->me_dev = disk_stats.st_dev;	  else	    {	      error (0, errno, "%s", quote (me->me_mountdir));	      exit_status = 1;	      /* So we won't try and fail repeatedly. */	      me->me_dev = (dev_t) -2;	    }	}      if (statp->st_dev == me->me_dev)	{	  /* Skip bogus mtab entries.  */	  if (stat (me->me_mountdir, &disk_stats) != 0	      || disk_stats.st_dev != me->me_dev)	    {	      me->me_dev = (dev_t) -2;	      continue;	    }	  /* Prefer non-dummy entries.  */	  if (! me->me_dummy)	    goto show_me;	  matching_dummy = me;	}    }  if (matching_dummy)    goto show_matching_dummy;  /* We couldn't find the mount entry corresponding to POINT.  Go ahead and     print as much info as we can; methods that require the device to be     present will fail at a later point.  */  {    /* Find the actual mount point.  */    char *mp = find_mount_point (point, statp);    if (mp)      {	show_dev (0, mp, 0, 0, 0);	free (mp);      }    else      error (0, errno, "%s", quote (point));  }  goto free_then_return; show_matching_dummy:  me = matching_dummy; show_me:  show_dev (me->me_devname, me->me_mountdir, me->me_type, me->me_dummy,	    me->me_remote); free_then_return:  if (needs_freeing)    free (needs_freeing);}/* Determine what kind of node PATH is and show the disk usage   for it.  STATP is the results of `stat' on PATH.  */static voidshow_entry (const char *path, const struct stat *statp){  if (S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode))    show_disk (path);  else    show_point (path, statp);}/* Show all mounted filesystems, except perhaps those that are of   an unselected type or are empty. */static voidshow_all_entries (void){  struct mount_entry *me;  for (me = mount_list; me; me = me->me_next)    show_dev (me->me_devname, me->me_mountdir, me->me_type,	      me->me_dummy, me->me_remote);}/* Add FSTYPE to the list of filesystem types to display. */static voidadd_fs_type (const char *fstype){  struct fs_type_list *fsp;  fsp = (struct fs_type_list *) xmalloc (sizeof (struct fs_type_list));  fsp->fs_name = (char *) fstype;  fsp->fs_next = fs_select_list;  fs_select_list = fsp;}/* Add FSTYPE to the list of filesystem types to be omitted. */static voidadd_excluded_fs_type (const char *fstype){  struct fs_type_list *fsp;  fsp = (struct fs_type_list *) xmalloc (sizeof (struct fs_type_list));  fsp->fs_name = (char *) fstype;  fsp->fs_next = fs_exclude_list;  fs_exclude_list = fsp;}voidusage (int status){  if (status != 0)    fprintf (stderr, _("Try `%s --help' for more information.\n"),	     program_name);  else    {      printf (_("Usage: %s [OPTION]... [FILE]...\n"), program_name);      fputs (_("\Show information about the filesystem on which each FILE resides,\n\or all filesystems by default.\n\\n\"), stdout);      fputs (_("\Mandatory arguments to long options are mandatory for short options too.\n\"), stdout);      fputs (_("\  -a, --all             include filesystems having 0 blocks\n\  -B, --block-size=SIZE use SIZE-byte blocks\n\  -h, --human-readable  print sizes in human readable format (e.g., 1K 234M 2G)\n\  -H, --si              likewise, but use powers of 1000 not 1024\n\"), stdout);      fputs (_("\  -i, --inodes          list inode information instead of block usage\n\  -k                    like --block-size=1K\n\  -l, --local           limit listing to local filesystems\n\      --no-sync         do not invoke sync before getting usage info (default)\n\"), stdout);      fputs (_("\  -P, --portability     use the POSIX output format\n\      --sync            invoke sync before getting usage info\n\  -t, --type=TYPE       limit listing to filesystems of type TYPE\n\  -T, --print-type      print filesystem type\n\  -x, --exclude-type=TYPE   limit listing to filesystems not of type TYPE\n\  -v                    (ignored)\n\"), stdout);      fputs (HELP_OPTION_DESCRIPTION, stdout);      fputs (VERSION_OPTION_DESCRIPTION, stdout);      fputs (_("\n\SIZE may be (or may be an integer optionally followed by) one of following:\n\kB 1000, K 1024, MB 1,000,000, M 1,048,576, and so on for G, T, P, E, Z, Y.\n\"), stdout);      printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);    }  exit (status);}intmain (int argc, char **argv){  int c;  struct stat *stats IF_LINT (= 0);  int n_valid_args = 0;  program_name = argv[0];  setlocale (LC_ALL, "");  bindtextdomain (PACKAGE, LOCALEDIR);  textdomain (PACKAGE);  atexit (close_stdout);  fs_select_list = NULL;  fs_exclude_list = NULL;  inode_format = 0;  show_all_fs = 0;  show_listed_fs = 0;  human_block_size (getenv ("DF_BLOCK_SIZE"), 0, &output_block_size);  print_type = 0;  posix_format = 0;  exit_status = 0;  while ((c = getopt_long (argc, argv, "aB:iF:hHklmPTt:vx:", long_options, NULL))	 != -1)    {      switch (c)	{	case 0:			/* Long option. */	  break;	case 'a':	  show_all_fs = 1;	  break;	case 'B':	  human_block_size (optarg, 1, &output_block_size);	  break;	case 'i':	  inode_format = 1;	  break;	case 'h':	  output_block_size = -1024;	  break;	case 'H':	  output_block_size = -1000;	  break;	case 'k':	  output_block_size = 1024;	  break;	case 'l':	  show_local_fs = 1;	  break;	case 'm': /* obsolescent */	  output_block_size = 1024 * 1024;	  break;	case 'T':	  print_type = 1;	  break;	case 'P':	  posix_format = 1;	  break;	case SYNC_OPTION:	  require_sync = 1;	  break;	case NO_SYNC_OPTION:	  require_sync = 0;	  break;	case 'F':	  /* Accept -F as a synonym for -t for compatibility with Solaris.  */	case 't':	  add_fs_type (optarg);	  break;	case 'v':		/* For SysV compatibility. */	  /* ignore */	  break;	case 'x':	  add_excluded_fs_type (optarg);	  break;	case_GETOPT_HELP_CHAR;	case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);	default:	  usage (1);	}    }  /* Fail if the same file system type was both selected and excluded.  */  {    int match = 0;    struct fs_type_list *fs_incl;    for (fs_incl = fs_select_list; fs_incl; fs_incl = fs_incl->fs_next)      {	struct fs_type_list *fs_excl;	for (fs_excl = fs_exclude_list; fs_excl; fs_excl = fs_excl->fs_next)	  {	    if (STREQ (fs_incl->fs_name, fs_excl->fs_name))	      {		error (0, 0,		       _("file system type %s both selected and excluded"),		       quote (fs_incl->fs_name));		match = 1;		break;	      }	  }      }    if (match)      exit (1);  }  {    int i;    /* stat all the given entries to make sure they get automounted,       if necessary, before reading the filesystem table.  */    stats = (struct stat *)      xmalloc ((argc - optind) * sizeof (struct stat));    for (i = optind; i < argc; ++i)      {	if (stat (argv[i], &stats[i - optind]))	  {	    error (0, errno, "%s", quote (argv[i]));	    exit_status = 1;	    argv[i] = NULL;	  }	else	  {	    ++n_valid_args;	  }      }  }  mount_list =    read_filesystem_list ((fs_select_list != NULL			   || fs_exclude_list != NULL			   || print_type			   || show_local_fs));  if (mount_list == NULL)    {      /* Couldn't read the table of mounted filesystems.	 Fail if df was invoked with no file name arguments;	 Otherwise, merely give a warning and proceed.  */      const char *warning = (optind == argc ? "" : _("Warning: "));      int status = (optind == argc ? 1 : 0);      error (status, errno,	     _("%scannot read table of mounted filesystems"), warning);    }  if (require_sync)    sync ();  if (optind == argc)    {      print_header ();      show_all_entries ();    }  else    {      int i;      /* Display explicitly requested empty filesystems. */      show_listed_fs = 1;      if (n_valid_args > 0)	print_header ();      for (i = optind; i < argc; ++i)	if (argv[i])	  show_entry (argv[i], &stats[i - optind]);    }  exit (exit_status);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -