亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? remove.c

?? linux開發技術詳解一書的源碼
?? C
?? 第 1 頁 / 共 3 頁
字號:
	exit (EXIT_FAILURE);
    }

  if (lstat (".", &sb))
    error (EXIT_FAILURE, errno,
	   _("cannot lstat `.' in %s"), quote (full_filename (".")));

  if (1 < AD_stack_height ())
    {
      /*  Ensure that post-chdir dev/ino match the stored ones.  */
      if ( ! SAME_INODE (sb, top->u.a))
	error (EXIT_FAILURE, 0,
	       _("%s changed dev/ino"), quote (full_filename (".")));
    }

  return dir;
}

/* Initialize *HT if it is NULL.
   Insert FILENAME into HT.  */
static void
AD_mark_helper (Hash_table **ht, char const *filename)
{
  if (*ht == NULL)
    *ht = hash_initialize (HT_UNREMOVABLE_INITIAL_CAPACITY, NULL, hash_pjw,
			   hash_compare_strings, hash_freer);
  if (*ht == NULL)
    xalloc_die ();
  if (! hash_insert (*ht, filename))
    xalloc_die ();
}

/* Mark FILENAME (in current directory) as unremovable.  */
static void
AD_mark_as_unremovable (char const *filename)
{
  AD_mark_helper (&AD_stack_top()->unremovable, xstrdup (filename));
}

/* Mark the current directory as unremovable.  I.e., mark the entry
   in the parent directory corresponding to `.'.
   This happens e.g., when an opendir fails and the only name
   the caller has conveniently at hand is `.'.  */
static void
AD_mark_current_as_unremovable (void)
{
  struct AD_ent *top = AD_stack_top ();
  const char *curr = top_dir ();

  assert (1 < AD_stack_height ());

  --top;
  AD_mark_helper (&top->unremovable, curr);
}

/* Push the initial cwd info onto the stack.
   This will always be the bottommost entry on the stack.  */
static void
AD_push_initial (struct saved_cwd const *cwd)
{
  struct AD_ent *top;

  /* Extend the stack.  */
  obstack_blank (&Active_dir, sizeof (struct AD_ent));

  /* Fill in the new values.  */
  top = AD_stack_top ();
  top->u.saved_cwd = *cwd;
  top->status = RM_OK;
  top->unremovable = NULL;
}

/* Push info about the current working directory (".") onto the
   active directory stack.  DIR is the ./-relative name through
   which we've just `chdir'd to this directory.  DIR_SB_FROM_PARENT
   is the result of calling lstat on DIR from the parent of DIR.  */
static void
AD_push (char const *dir, struct stat const *dir_sb_from_parent)
{
  struct stat sb;
  struct AD_ent *top;

  push_dir (dir);

  if (lstat (".", &sb))
    error (EXIT_FAILURE, errno,
	   _("cannot lstat `.' in %s"), quote (full_filename (".")));

  if ( ! SAME_INODE (sb, *dir_sb_from_parent))
    error (EXIT_FAILURE, errno,
	   _("%s changed dev/ino"), quote (full_filename (".")));

  /* Extend the stack.  */
  obstack_blank (&Active_dir, sizeof (struct AD_ent));

  /* Fill in the new values.  */
  top = AD_stack_top ();
  top->u.a.st_dev = sb.st_dev;
  top->u.a.st_ino = sb.st_ino;
  top->status = RM_OK;
  top->unremovable = NULL;
}

static int
AD_is_removable (char const *file)
{
  struct AD_ent *top = AD_stack_top ();
  return ! (top->unremovable && hash_lookup (top->unremovable, file));
}

static inline bool
is_power_of_two (unsigned int i)
{
  return (i & (i - 1)) == 0;
}

static void
cycle_check (struct stat const *sb)
{
#ifdef ENABLE_CYCLE_CHECK
  /* If there is a directory cycle, detect it (lazily) and die.  */
  static struct dev_ino dir_cycle_detect_dev_ino;
  static unsigned int chdir_counter;

  /* If the current directory ever happens to be the same
     as the one we last recorded for the cycle detection,
     then it's obviously part of a cycle.  */
  if (chdir_counter && SAME_INODE (*sb, dir_cycle_detect_dev_ino))
    {
      error (0, 0, _("\
WARNING: Circular directory structure.\n\
This almost certainly means that you have a corrupted file system.\n\
NOTIFY YOUR SYSTEM MANAGER.\n\
The following directory is part of the cycle:\n  %s\n"),
	     quote (full_filename (".")));
      exit (EXIT_FAILURE);
    }

  /* If the number of `descending' chdir calls is a power of two,
     record the dev/ino of the current directory.  */
  if (is_power_of_two (++chdir_counter))
    {
      dir_cycle_detect_dev_ino.st_dev = sb->st_dev;
      dir_cycle_detect_dev_ino.st_ino = sb->st_ino;
    }
#endif
}

static bool
is_empty_dir (char const *dir)
{
  DIR *dirp = opendir (dir);
  if (dirp == NULL)
    {
      closedir (dirp);
      return false;
    }

  while (1)
    {
      struct dirent *dp;
      const char *f;

      errno = 0;
      dp = readdir (dirp);
      if (dp == NULL)
	{
	  closedir (dirp);
	  return errno == 0 ? true : false;
	}

      f = dp->d_name;
      if ( ! DOT_OR_DOTDOT (f))
	{
	  closedir (dirp);
	  return false;
	}
    }
}

/* Prompt whether to remove FILENAME, if required via a combination of
   the options specified by X and/or file attributes.  If the file may
   be removed, return RM_OK.  If the user declines to remove the file,
   return RM_USER_DECLINED.  If not ignoring missing files and we
   cannot lstat FILENAME, then return RM_ERROR.

   Depending on MODE, ask whether to `descend into' or to `remove' the
   directory FILENAME.  MODE is ignored when FILENAME is not a directory.
   Set *IS_EMPTY to T_YES if FILENAME is an empty directory, and it is
   appropriate to try to remove it with rmdir (e.g. recursive mode).
   Don't even try to set *IS_EMPTY when MODE == PA_REMOVE_DIR.
   Set *IS_DIR to T_YES or T_NO if we happen to determine whether
   FILENAME is a directory.  */
static enum RM_status
prompt (char const *filename, struct rm_options const *x,
	enum Prompt_action mode, Ternary *is_dir, Ternary *is_empty)
{
  int write_protected = 0;
  struct stat sbuf, sbuf0;
  int _stat;
  *is_empty = T_UNKNOWN;
  *is_dir = T_UNKNOWN;
  _stat = lstat (filename, &sbuf);

  // Handle the special case of dangling/recursive symlinks - they shouldn't
  // appear write protected.
  write_protected = euidaccess (filename, W_OK);
  if (write_protected && errno == EACCES && S_ISLNK (sbuf.st_mode)
      && stat (filename, &sbuf0))
    write_protected = 0;

  if ((!x->ignore_missing_files && (x->interactive || x->stdin_tty)
       && write_protected)
      || x->interactive)
    {
      if (_stat)
	{
	  /* lstat failed.  This happens e.g., with `rm '''.  */
	  error (0, errno, _("cannot lstat %s"),
		 quote (full_filename (filename)));
	  return RM_ERROR;
	}

      /* Using permissions doesn't make sense for symlinks.  */
      if (S_ISLNK (sbuf.st_mode))
	{
	  if ( ! x->interactive)
	    return RM_OK;
	  write_protected = 0;
	}

      /* Issue the prompt.  */
      {
	char const *quoted_name = quote (full_filename (filename));

	*is_dir = (S_ISDIR (sbuf.st_mode) ? T_YES : T_NO);
	*is_empty = (is_empty_dir (filename) ? T_YES : T_NO);

	/* FIXME: use a variant of error (instead of fprintf) that doesn't
	   append a newline.  Then we won't have to declare program_name in
	   this file.  */
	if (S_ISDIR (sbuf.st_mode)
	    && x->recursive
	    && mode == PA_DESCEND_INTO_DIR
	    && *is_empty == T_NO)
	  fprintf (stderr,
		   (write_protected
		    ? _("%s: descend into write-protected directory %s? ")
		    : _("%s: descend into directory %s? ")),
		   program_name, quoted_name);
	else
	  {
	    /* TRANSLATORS: You may find it more convenient to translate
	       the equivalent of _("%s: remove %s (write-protected) %s? ").
	       It should avoid grammatical problems with the output
	       of file_type.  */
	    fprintf (stderr,
		     (write_protected
		      ? _("%s: remove write-protected %s %s? ")
		      : _("%s: remove %s %s? ")),
		     program_name, file_type (&sbuf), quoted_name);
	  }

	if (!yesno ())
	  return RM_USER_DECLINED;
      }
    }
  return RM_OK;
}

#if HAVE_STRUCT_DIRENT_D_TYPE
# define DT_IS_DIR(D) ((D)->d_type == DT_DIR)
#else
/* Use this only if the member exists -- i.e., don't return 0.  */
# define DT_IS_DIR(D) do_not_use_this_macro
#endif

#define DO_UNLINK(Filename, X)						\
  do									\
    {									\
      if (unlink (Filename) == 0)					\
	{								\
	  if ((X)->verbose)						\
	    printf (_("removed %s\n"), quote (full_filename (Filename))); \
	  return RM_OK;							\
	}								\
									\
      if (errno == ENOENT && (X)->ignore_missing_files)			\
	return RM_OK;							\
    }									\
  while (0)

#define DO_RMDIR(Filename, X)				\
  do							\
    {							\
      if (rmdir (Filename) == 0)			\
	{						\
	  if ((X)->verbose)				\
	    printf (_("removed directory: %s\n"),	\
		    quote (full_filename (Filename)));	\
	  return RM_OK;					\
	}						\
							\
      if (errno == ENOENT && (X)->ignore_missing_files)	\
	return RM_OK;					\
							\
      if (errno == ENOTEMPTY || errno == EEXIST)	\
	return RM_NONEMPTY_DIR;				\
    }							\
  while (0)

/* Remove the file or directory specified by FILENAME.
   Return RM_OK if it is removed, and RM_ERROR or RM_USER_DECLINED if not.
   But if FILENAME specifies a non-empty directory, return RM_NONEMPTY_DIR. */

static enum RM_status
remove_entry (char const *filename, struct rm_options const *x,
	      struct dirent const *dp)
{
  Ternary is_dir;
  Ternary is_empty_directory;
  enum RM_status s = prompt (filename, x, PA_DESCEND_INTO_DIR,
			     &is_dir, &is_empty_directory);

  if (s != RM_OK)
    return s;

  /* Why bother with the following #if/#else block?  Because on systems with
     an unlink function that *can* unlink directories, we must determine the
     type of each entry before removing it.  Otherwise, we'd risk unlinking an
     entire directory tree simply by unlinking a single directory;  then all
     the storage associated with that hierarchy would not be freed until the
     next reboot.  Not nice.  To avoid that, on such slightly losing systems, we
     need to call lstat to determine the type of each entry, and that represents
     extra overhead that -- it turns out -- we can avoid on GNU-libc-based
     systems, since there, unlink will never remove a directory.  */

#if ROOT_CAN_UNLINK_DIRS

  /* If we don't already know whether FILENAME is a directory, find out now.
     Then, if it's a non-directory, we can use unlink on it.  */
  if (is_dir == T_UNKNOWN)
    {
# if HAVE_STRUCT_DIRENT_D_TYPE
      if (dp)
	is_dir = DT_IS_DIR (dp) ? T_YES : T_NO;
      else
# endif
	{
	  struct stat sbuf;
	  if (lstat (filename, &sbuf))
	    {
	      if (errno == ENOENT && x->ignore_missing_files)
		return RM_OK;

	      error (0, errno,
		     _("cannot lstat %s"), quote (full_filename (filename)));
	      return RM_ERROR;
	    }

	  is_dir = S_ISDIR (sbuf.st_mode) ? T_YES : T_NO;
	}
    }

  if (is_dir == T_NO)
    {
      /* At this point, barring race conditions, FILENAME is known
	 to be a non-directory, so it's ok to try to unlink it.  */
      DO_UNLINK (filename, x);

      /* unlink failed with some other error code.  report it.  */

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
eeuss鲁片一区二区三区在线观看| 国产精品电影一区二区三区| 偷拍与自拍一区| 国产福利91精品| 国产欧美日韩一区二区三区在线观看| 成人黄色一级视频| 中文字幕一区二区三区在线不卡| 日本精品免费观看高清观看| 亚洲在线视频一区| 日韩一区二区三区四区| 精品一区二区在线播放| 中文幕一区二区三区久久蜜桃| 99综合影院在线| 亚洲va欧美va人人爽午夜| 69堂国产成人免费视频| 精品一二三四在线| 中文字幕一区二区不卡| 91麻豆精品国产自产在线| 国产黄人亚洲片| 亚洲一区二区在线视频| 久久嫩草精品久久久精品一| 91色婷婷久久久久合中文| 日本不卡一区二区| 国产精品拍天天在线| 欧美日韩免费电影| 国产黑丝在线一区二区三区| 亚洲综合激情另类小说区| 2欧美一区二区三区在线观看视频| 成人av一区二区三区| 青青国产91久久久久久| 国产精品久久久久婷婷| 91精品欧美福利在线观看| www.激情成人| 久久精品噜噜噜成人av农村| 亚洲人成网站在线| 精品国产精品网麻豆系列| 91在线观看地址| 国产真实乱偷精品视频免| 亚洲午夜精品一区二区三区他趣| 欧美va亚洲va| 欧美日韩国产精选| 波多野结衣一区二区三区| 久久av老司机精品网站导航| 亚洲午夜精品久久久久久久久| 亚洲国产精品v| 日韩你懂的在线观看| 欧美日韩免费一区二区三区视频| 成人美女视频在线观看| 麻豆极品一区二区三区| 午夜久久久影院| 亚洲欧美一区二区三区久本道91 | 99久久精品国产一区二区三区| 五月天婷婷综合| 最新欧美精品一区二区三区| 久久亚洲免费视频| 日韩午夜电影在线观看| 欧美日韩一区二区三区免费看| 国产成人亚洲综合a∨猫咪| 免费观看在线综合| 性做久久久久久免费观看 | 91精品国产综合久久精品| 91老师片黄在线观看| 成人免费视频视频在线观看免费| 青青草91视频| 日韩高清不卡在线| 日本欧美一区二区| 午夜亚洲国产au精品一区二区| 亚洲乱码国产乱码精品精小说 | 精品亚洲国产成人av制服丝袜| 亚洲大尺度视频在线观看| 亚洲黄色性网站| 依依成人精品视频| 亚洲另类在线一区| 亚洲精品福利视频网站| 亚洲九九爱视频| 亚洲精品免费在线观看| 一区二区高清在线| 亚洲r级在线视频| 天天综合色天天| 免费人成网站在线观看欧美高清| 日韩电影在线看| 久久精品国产亚洲aⅴ| 麻豆精品国产91久久久久久| 激情综合亚洲精品| 九一久久久久久| 国产尤物一区二区在线| 国产激情一区二区三区桃花岛亚洲| 国产91精品在线观看| 91丨国产丨九色丨pron| 色天天综合色天天久久| 欧美日韩精品免费观看视频| 555夜色666亚洲国产免| 精品成人佐山爱一区二区| 欧美经典一区二区| 一区二区三区色| 日韩电影在线一区| 国产福利一区二区三区视频在线 | 成人午夜电影网站| 99国产精品久| 欧美日韩中字一区| 精品国产一区二区精华| 日本一区二区三级电影在线观看| 1000部国产精品成人观看| 亚洲一区二区三区三| 美美哒免费高清在线观看视频一区二区| 精品一区二区免费在线观看| av福利精品导航| 欧美日韩国产天堂| 国产三级欧美三级日产三级99| 亚洲欧美偷拍卡通变态| 美脚の诱脚舐め脚责91| 99久久综合99久久综合网站| 在线成人午夜影院| 国产精品毛片无遮挡高清| 亚洲成av人片一区二区梦乃| 国内精品视频666| 色吊一区二区三区| 久久中文娱乐网| 亚洲国产成人tv| 成人免费福利片| 欧美一区二区在线免费观看| 国产精品国产三级国产aⅴ入口| 日韩av电影免费观看高清完整版 | 精品午夜久久福利影院| 91麻豆精品在线观看| 日韩欧美国产wwwww| 一区二区不卡在线视频 午夜欧美不卡在| 免费在线观看一区| 99国产精品久久| 久久免费的精品国产v∧| 亚洲愉拍自拍另类高清精品| 国产成人精品亚洲日本在线桃色 | 欧美吞精做爰啪啪高潮| 久久久99久久精品欧美| 亚洲成人资源在线| 99久久久久久| 亚洲精品一区二区精华| 日韩黄色片在线观看| 一本大道久久a久久综合婷婷| 精品国产91洋老外米糕| 丝袜脚交一区二区| 日本韩国欧美一区二区三区| 国产精品青草综合久久久久99| 蜜桃视频第一区免费观看| 欧美日韩日本视频| 一区二区三区日本| 91色乱码一区二区三区| 国产精品免费aⅴ片在线观看| 国产一区二区三区在线观看免费 | 久久精品一区二区| 麻豆视频观看网址久久| 欧美日韩午夜精品| 亚洲网友自拍偷拍| 在线视频国内一区二区| 亚洲激情校园春色| 日本韩国视频一区二区| 亚洲精品日韩综合观看成人91| 99re这里都是精品| 国产精品久久久久天堂| voyeur盗摄精品| 中文文精品字幕一区二区| 国产黄色精品视频| 国产精品午夜在线观看| 国产精品一区在线观看你懂的| 日韩美女视频一区二区在线观看| 日本vs亚洲vs韩国一区三区二区 | 欧美又粗又大又爽| 怡红院av一区二区三区| 欧美亚洲国产bt| 视频一区二区三区入口| 91精品国产综合久久久久久漫画| 日韩中文字幕一区二区三区| 91精品国产综合久久久久久久| 免费一区二区视频| 久久影音资源网| 不卡在线观看av| 亚洲免费av观看| 91精品免费在线观看| 精品一区二区三区的国产在线播放| 久久久久国产成人精品亚洲午夜 | 韩国精品在线观看| 亚洲国产成人私人影院tom| 成人免费高清在线观看| 亚洲黄一区二区三区| 欧美老女人第四色| 老汉av免费一区二区三区| 国产人伦精品一区二区| 99精品欧美一区二区三区小说 | 国产精品二区一区二区aⅴ污介绍| 99在线精品视频| 午夜欧美2019年伦理| 亚洲精品在线观| 91在线观看地址| 蜜桃视频在线观看一区二区| 日本一区二区免费在线观看视频| 94-欧美-setu| 青青青爽久久午夜综合久久午夜| 国产视频一区不卡| 欧美日韩亚洲另类| 国产91露脸合集magnet|