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

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? remove.c

?? linux開發(fā)技術(shù)詳解一書的源碼
?? C
?? 第 1 頁 / 共 3 頁
字號:
/* remove.c -- core functions for removing files and directories
   Copyright (C) 88, 90, 91, 1994-2002 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

/* Extracted from rm.c and librarified, then rewritten by Jim Meyering.  */

#ifdef _AIX
 #pragma alloca
#endif

#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include <assert.h>

#include "save-cwd.h"
#include "system.h"
#include "dirname.h"
#include "error.h"
#include "file-type.h"
#include "hash.h"
#include "hash-pjw.h"
#include "obstack.h"
#include "quote.h"
#include "remove.h"

/* Avoid shadowing warnings because these are functions declared
   in dirname.h as well as locals used below.  */
#define dir_name rm_dir_name
#define dir_len rm_dir_len

#define obstack_chunk_alloc malloc
#define obstack_chunk_free free

#ifndef PARAMS
# if defined (__GNUC__) || __STDC__
#  define PARAMS(args) args
# else
#  define PARAMS(args) ()
# endif
#endif

/* FIXME: if possible, use autoconf...  */
#ifdef __GLIBC__
# define ROOT_CAN_UNLINK_DIRS 0
#else
# define ROOT_CAN_UNLINK_DIRS 1
#endif

enum Ternary
  {
    T_UNKNOWN = 2,
    T_NO,
    T_YES
  };
typedef enum Ternary Ternary;

/* The prompt function may be called twice a given directory.
   The first time, we ask whether to descend into it, and the
   second time, we ask whether to remove it.  */
enum Prompt_action
  {
    PA_DESCEND_INTO_DIR = 2,
    PA_REMOVE_DIR
  };

/* On systems with an lstat function that accepts the empty string,
   arrange to make lstat calls go through the wrapper function.  */
#if HAVE_LSTAT_EMPTY_STRING_BUG
int rpl_lstat PARAMS((const char *, struct stat *));
# define lstat(Name, Stat_buf) rpl_lstat(Name, Stat_buf)
#endif

#ifdef D_INO_IN_DIRENT
# define D_INO(dp) ((dp)->d_ino)
# define ENABLE_CYCLE_CHECK
#else
/* Some systems don't have inodes, so fake them to avoid lots of ifdefs.  */
# define D_INO(dp) 1
#endif

#if !defined S_ISLNK
# define S_ISLNK(Mode) 0
#endif

/* Initial capacity of per-directory hash table of entries that have
   been processed but not been deleted.  */
#define HT_UNREMOVABLE_INITIAL_CAPACITY 13

/* An entry in the active directory stack.
   Each entry corresponds to an `active' directory.  */
struct AD_ent
{
  /* For a given active directory, this is the set of names of
     entries in that directory that could/should not be removed.
     For example, `.' and `..', as well as files/dirs for which
     unlink/rmdir failed e.g., due to access restrictions.  */
  Hash_table *unremovable;

  /* Record the status for a given active directory; we need to know
     whether an entry was not removed, either because of an error or
     because the user declined.  */
  enum RM_status status;

  union
  {
    /* The directory's dev/ino.  Used to ensure that `chdir some-subdir', then
       `chdir ..' takes us back to the same directory from which we started).
       (valid for all but the bottommost entry on the stack.  */
    struct dev_ino a;

    /* Enough information to restore the initial working directory.
       (valid only for the bottommost entry on the stack)  */
    struct saved_cwd saved_cwd;
  } u;
};

int euidaccess ();
int yesno ();

extern char *program_name;

/* The name of the directory (starting with and relative to a command
   line argument) being processed.  When a subdirectory is entered, a new
   component is appended (pushed).  When RM chdir's out of a directory,
   the top component is removed (popped).  This is used to form a full
   file name when necessary.  */
static struct obstack dir_stack;

/* Stack of lengths of directory names (including trailing slash)
   appended to dir_stack.  We have to have a separate stack of lengths
   (rather than just popping back to previous slash) because the first
   element pushed onto the dir stack may contain slashes.  */
static struct obstack len_stack;

/* Stack of active directory entries.
   The first `active' directory is the initial working directory.
   Additional active dirs are pushed onto the stack as rm `chdir's
   into each nonempty directory it must remove.  When rm has finished
   removing the hierarchy under a directory, it pops the active dir stack.  */
static struct obstack Active_dir;

static void
hash_freer (void *x)
{
  free (x);
}

static bool
hash_compare_strings (void const *x, void const *y)
{
  return STREQ (x, y) ? true : false;
}

static inline void
push_dir (const char *dir_name)
{
  size_t len;

  len = strlen (dir_name);

  /* Append the string onto the stack.  */
  obstack_grow (&dir_stack, dir_name, len);

  /* Append a trailing slash.  */
  obstack_1grow (&dir_stack, '/');

  /* Add one for the slash.  */
  ++len;

  /* Push the length (including slash) onto its stack.  */
  obstack_grow (&len_stack, &len, sizeof (len));
}

/* Return the entry name of the directory on the top of the stack
   in malloc'd storage.  */
static inline char *
top_dir (void)
{
  int n_lengths = obstack_object_size (&len_stack) / sizeof (size_t);
  size_t *length = (size_t *) obstack_base (&len_stack);
  size_t top_len = length[n_lengths - 1];
  char const *p = obstack_next_free (&dir_stack) - top_len;
  char *q = xmalloc (top_len);
  memcpy (q, p, top_len - 1);
  q[top_len - 1] = 0;
  return q;
}

static inline void
pop_dir (void)
{
  int n_lengths = obstack_object_size (&len_stack) / sizeof (size_t);
  size_t *length = (size_t *) obstack_base (&len_stack);
  size_t top_len;

  assert (n_lengths > 0);
  top_len = length[n_lengths - 1];
  assert (top_len >= 2);

  /* Pop off the specified length of pathname.  */
  assert (obstack_object_size (&dir_stack) >= top_len);
  obstack_blank (&dir_stack, -top_len);

  /* Pop the length stack, too.  */
  assert (obstack_object_size (&len_stack) >= sizeof (size_t));
  obstack_blank (&len_stack, (int) -(sizeof (size_t)));
}

/* Copy the SRC_LEN bytes of data beginning at SRC into the DST_LEN-byte
   buffer, DST, so that the last source byte is at the end of the destination
   buffer.  If SRC_LEN is longer than DST_LEN, then set *TRUNCATED to non-zero.
   Set *RESULT to point to the beginning of (the portion of) the source data
   in DST.  Return the number of bytes remaining in the destination buffer.  */

static size_t
right_justify (char *dst, size_t dst_len, const char *src, size_t src_len,
	       char **result, int *truncated)
{
  const char *sp;
  char *dp;

  if (src_len <= dst_len)
    {
      sp = src;
      dp = dst + (dst_len - src_len);
      *truncated = 0;
    }
  else
    {
      sp = src + (src_len - dst_len);
      dp = dst;
      src_len = dst_len;
      *truncated = 1;
    }

  *result = memcpy (dp, sp, src_len);
  return dst_len - src_len;
}

/* Using the global directory name obstack, create the full path to FILENAME.
   Return it in sometimes-realloc'd space that should not be freed by the
   caller.  Realloc as necessary.  If realloc fails, use a static buffer
   and put as long a suffix in that buffer as possible.  */

static char *
full_filename (const char *filename)
{
  static char *buf = NULL;
  static size_t n_allocated = 0;

  int dir_len = obstack_object_size (&dir_stack);
  char *dir_name = (char *) obstack_base (&dir_stack);
  size_t n_bytes_needed;
  size_t filename_len;

  filename_len = strlen (filename);
  n_bytes_needed = dir_len + filename_len + 1;

  if (n_bytes_needed > n_allocated)
    {
      /* This code requires that realloc accept NULL as the first arg.
         This function must not use xrealloc.  Otherwise, an out-of-memory
	 error involving a file name to be expanded here wouldn't ever
	 be issued.  Use realloc and fall back on using a static buffer
	 if memory allocation fails.  */
      buf = realloc (buf, n_bytes_needed);
      n_allocated = n_bytes_needed;

      if (buf == NULL)
	{
#define SBUF_SIZE 512
#define ELLIPSES_PREFIX "[...]"
	  static char static_buf[SBUF_SIZE];
	  int truncated;
	  size_t len;
	  char *p;

	  len = right_justify (static_buf, SBUF_SIZE, filename,
			       filename_len + 1, &p, &truncated);
	  right_justify (static_buf, len, dir_name, dir_len, &p, &truncated);
	  if (truncated)
	    {
	      memcpy (static_buf, ELLIPSES_PREFIX,
		      sizeof (ELLIPSES_PREFIX) - 1);
	    }
	  return p;
	}
    }

  /* Copy directory part, including trailing slash, and then
     append the filename part, including a trailing zero byte.  */
  memcpy (mempcpy (buf, dir_name, dir_len), filename, filename_len + 1);

  assert (strlen (buf) + 1 == n_bytes_needed);

  return buf;
}

static size_t
AD_stack_height (void)
{
  return obstack_object_size (&Active_dir) / sizeof (struct AD_ent);
}

static struct AD_ent *
AD_stack_top (void)
{
  return (struct AD_ent *)
    ((char *) obstack_next_free (&Active_dir) - sizeof (struct AD_ent));
}

static void
AD_stack_pop (void)
{
  /* operate on Active_dir.  pop and free top entry */
  struct AD_ent *top = AD_stack_top ();
  if (top->unremovable)
    hash_free (top->unremovable);
  obstack_blank (&Active_dir, -sizeof (struct AD_ent));
  pop_dir ();
}

/* chdir `up' one level.
   Whenever using chdir '..', verify that the post-chdir
   dev/ino numbers for `.' match the saved ones.
   Return the name (in malloc'd storage) of the
   directory (usually now empty) from which we're coming.  */
static char *
AD_pop_and_chdir (void)
{
  /* Get the name of the current directory from the top of the stack.  */
  char *dir = top_dir ();
  enum RM_status old_status = AD_stack_top()->status;
  struct stat sb;
  struct AD_ent *top;

  AD_stack_pop ();

  /* Propagate any failure to parent.  */
  UPDATE_STATUS (AD_stack_top()->status, old_status);

  assert (AD_stack_height ());

  top = AD_stack_top ();
  if (1 < AD_stack_height ())
    {
      /* We can give a better diagnostic here, since the target is relative. */
      if (chdir (".."))
	{
	  error (EXIT_FAILURE, errno,
		 _("cannot chdir from %s to .."),
		 quote (full_filename (".")));
	}
    }
  else
    {
      if (restore_cwd (&top->u.saved_cwd, NULL, NULL))

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
看电视剧不卡顿的网站| 欧洲激情一区二区| 久久99国产精品久久| 无吗不卡中文字幕| 午夜欧美大尺度福利影院在线看| 亚洲欧美在线观看| 亚洲私人黄色宅男| 一级精品视频在线观看宜春院| 最新中文字幕一区二区三区 | 亚洲自拍都市欧美小说| 一区二区在线观看不卡| 亚洲精品视频免费看| 夜夜嗨av一区二区三区中文字幕| 亚洲精品免费视频| 欧美精品18+| 91女人视频在线观看| 波多野结衣亚洲一区| 99精品久久只有精品| 91蝌蚪porny九色| 在线观看精品一区| 欧美一区二区免费| 国产日产欧美一区二区三区| 国产精品国产自产拍高清av王其| 中文字幕一区二区日韩精品绯色| 亚洲乱码中文字幕综合| 亚洲地区一二三色| 国内精品伊人久久久久av影院 | 一本久久a久久精品亚洲| 91精品1区2区| 777午夜精品视频在线播放| 日韩亚洲欧美成人一区| 国产欧美精品在线观看| 亚洲精品综合在线| 免费xxxx性欧美18vr| 国产美女一区二区三区| 91丝袜美女网| 91精品在线一区二区| 久久蜜桃香蕉精品一区二区三区| 中文字幕一区二区不卡| 日本欧美一区二区在线观看| 国产在线国偷精品产拍免费yy| 国产成人免费视| 欧美三区在线观看| 精品久久国产老人久久综合| 中文一区在线播放| 五月婷婷激情综合网| 国产露脸91国语对白| 一本一道综合狠狠老| 日韩视频免费观看高清在线视频| 国产偷国产偷亚洲高清人白洁| 亚洲精选视频在线| 国产中文一区二区三区| 99re在线精品| 精品日韩欧美在线| 一区二区在线看| 国产精品一区免费视频| 欧美色欧美亚洲另类二区| 日韩欧美高清一区| 夜夜精品视频一区二区| 懂色中文一区二区在线播放| 欧美军同video69gay| 国产精品国产三级国产aⅴ中文 | 日韩一级片网址| 中文字幕一区二区三区av| 开心九九激情九九欧美日韩精美视频电影| heyzo一本久久综合| 久久亚洲一级片| 天天综合色天天综合| 99久久精品免费看国产| 日韩欧美精品在线| 亚洲国产精品一区二区尤物区| 丁香亚洲综合激情啪啪综合| 日韩一级欧美一级| 五月婷婷欧美视频| 在线精品视频一区二区| 国产欧美一区二区在线| 久久不见久久见免费视频1| 欧美综合一区二区| 中文字幕在线不卡一区| 国产在线播放一区| 欧美不卡一区二区| 日韩va亚洲va欧美va久久| 欧美亚洲动漫制服丝袜| 日韩美女久久久| 成人高清免费在线播放| 久久综合成人精品亚洲另类欧美 | 91国偷自产一区二区使用方法| 国产日韩精品久久久| 国内精品久久久久影院薰衣草| 这里只有精品免费| 天堂va蜜桃一区二区三区 | 中文av一区二区| 国产麻豆精品theporn| 日韩欧美久久久| 蜜桃在线一区二区三区| 4438x成人网最大色成网站| 亚洲第一久久影院| 欧美三级电影在线看| 亚洲自拍偷拍av| 欧美三级视频在线播放| 亚洲亚洲人成综合网络| 欧美视频一区二| 亚洲成人tv网| 7777女厕盗摄久久久| 日韩av一区二区在线影视| 欧美精品高清视频| 青青草97国产精品免费观看无弹窗版 | 国产一区美女在线| 久久精品一区二区| 国产精品456| 国产午夜精品久久久久久久| 国产不卡在线视频| 日韩美女视频一区二区 | 亚洲女人的天堂| 色香蕉成人二区免费| 亚洲自拍欧美精品| 7777女厕盗摄久久久| 日本va欧美va欧美va精品| 91精品国产福利在线观看| 久久成人免费日本黄色| 26uuu精品一区二区| 国产成人激情av| 亚洲人成小说网站色在线| 欧美伊人精品成人久久综合97| 亚洲成人激情综合网| 欧美一区二区三区婷婷月色| 久久不见久久见中文字幕免费| 久久精品视频一区二区| 成人国产一区二区三区精品| 亚洲视频资源在线| 欧美日韩电影在线| 久久精品国产第一区二区三区| 久久嫩草精品久久久久| 91视频com| 日韩福利电影在线观看| 久久色视频免费观看| 99这里只有久久精品视频| 亚洲高清三级视频| 久久网这里都是精品| 色欧美日韩亚洲| 欧美aaaaa成人免费观看视频| 久久精品视频免费观看| 色综合亚洲欧洲| 琪琪久久久久日韩精品| 国产精品天美传媒沈樵| 欧美日韩综合在线免费观看| 久久丁香综合五月国产三级网站| 国产日本欧洲亚洲| 欧美日韩一二三区| 国产美女精品人人做人人爽| 中文字幕五月欧美| 制服丝袜中文字幕一区| 成人的网站免费观看| 天堂va蜜桃一区二区三区| 国产精品情趣视频| 7777精品伊人久久久大香线蕉完整版| 国产精品一区二区你懂的| 一区二区三区精品在线观看| 欧美va在线播放| 欧洲视频一区二区| 国产成人鲁色资源国产91色综| 亚洲国产欧美一区二区三区丁香婷| 久久这里只有精品首页| 欧美性大战久久久久久久蜜臀| 国模一区二区三区白浆| 亚洲国产日韩一级| 国产精品久久久一区麻豆最新章节| 欧美精品乱人伦久久久久久| 成人精品视频一区二区三区尤物| 丝袜亚洲精品中文字幕一区| 成人免费视频在线观看| 精品处破学生在线二十三| 欧美午夜一区二区| 成人激情综合网站| 久久成人久久鬼色| 亚洲成人动漫在线免费观看| 国产精品国产三级国产aⅴ无密码| 欧美tickle裸体挠脚心vk| 欧美在线一二三四区| 成人av网站大全| 国产成人一级电影| 久久福利视频一区二区| 午夜精品一区二区三区免费视频| 中文字幕一区日韩精品欧美| 国产亚洲一二三区| 精品粉嫩超白一线天av| 欧美一区二区三区人| 欧洲日韩一区二区三区| 91最新地址在线播放| 成人激情免费网站| 国产精品一区一区| 国产在线一区二区| 麻豆精品精品国产自在97香蕉| 亚洲国产精品久久艾草纯爱| 亚洲欧美视频在线观看| 亚洲欧洲www| 国产精品久久久久久久久果冻传媒 | 欧美成人精品1314www| 欧美精品三级在线观看| 欧美喷潮久久久xxxxx|