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

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

?? remove.c

?? linux 應用開發技術詳解中的附錄源碼
?? 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))

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
久久午夜老司机| 男女性色大片免费观看一区二区 | 日本强好片久久久久久aaa| 久久精品国产成人一区二区三区| 成人精品亚洲人成在线| 欧美视频日韩视频| 国产蜜臀97一区二区三区| 亚洲国产va精品久久久不卡综合| 国产成人免费av在线| 在线成人小视频| 国产精品卡一卡二| 国产一区二区三区免费看| 欧美日韩aaaaaa| 亚洲h在线观看| 色综合中文字幕国产| 91精品国产91久久综合桃花| 最近中文字幕一区二区三区| 国产精品综合在线视频| 日韩一区二区三区在线视频| 性做久久久久久久免费看| 成人黄色在线网站| 国产午夜亚洲精品理论片色戒| 看片的网站亚洲| 91麻豆精品国产91久久久使用方法| 亚洲免费观看高清完整 | 奇米影视7777精品一区二区| 日本精品一区二区三区高清 | 粉嫩欧美一区二区三区高清影视 | 欧美群妇大交群中文字幕| 亚洲制服欧美中文字幕中文字幕| 91免费视频观看| 亚洲欧美另类久久久精品2019| 成人免费毛片嘿嘿连载视频| 国产欧美日韩另类一区| 国产成人精品免费| 国产精品免费久久| 91小宝寻花一区二区三区| 国产精品第13页| 欧洲国产伦久久久久久久| 亚洲国产毛片aaaaa无费看 | 播五月开心婷婷综合| 久久久久国产精品厨房| 国产精品中文字幕欧美| 国产精品乱码一区二区三区软件| 成人h精品动漫一区二区三区| 国产精品区一区二区三区| 波多野结衣亚洲| 艳妇臀荡乳欲伦亚洲一区| 91国偷自产一区二区三区成为亚洲经典 | 欧美国产精品中文字幕| av在线这里只有精品| 一区二区三区中文在线观看| 欧美色精品天天在线观看视频| 日韩精品91亚洲二区在线观看| 日韩一级高清毛片| 国产高清精品网站| 亚洲一区二区三区在线看| 日韩免费高清av| 成人免费不卡视频| 亚洲成av人片在线观看无码| 日韩欧美亚洲另类制服综合在线| 国产一区二区三区四| 亚洲欧美日韩中文字幕一区二区三区 | 国产自产v一区二区三区c| 久久日一线二线三线suv| 中文字幕一区视频| 国产一区二区女| 最新久久zyz资源站| 日韩一区二区免费在线电影| 粉嫩久久99精品久久久久久夜| 夜夜精品浪潮av一区二区三区| 91麻豆精品国产91久久久使用方法 | 国产精品一区在线观看乱码| 自拍av一区二区三区| 91精品国产综合久久福利软件 | 国产精品九色蝌蚪自拍| 欧美日韩高清在线| 成人黄色一级视频| 午夜视频一区二区| 国产精品国产a级| 日韩午夜精品电影| 在线日韩av片| www.亚洲激情.com| 麻豆精品视频在线观看视频| 亚洲免费成人av| 日本一区二区成人| 久久久久一区二区三区四区| 精品视频资源站| 91麻豆精品在线观看| 国产精品资源在线看| 丝袜国产日韩另类美女| 亚洲欧美成人一区二区三区| 久久嫩草精品久久久精品 | 欧美又粗又大又爽| 福利91精品一区二区三区| 青青草原综合久久大伊人精品优势| 亚洲精品视频一区二区| 久久精品一级爱片| 精品久久国产97色综合| 欧美美女喷水视频| 欧美日韩一区久久| 色婷婷激情综合| 97se亚洲国产综合自在线不卡| 国产精品正在播放| 国产一区中文字幕| 国模大尺度一区二区三区| 日本伊人精品一区二区三区观看方式| 亚洲六月丁香色婷婷综合久久 | 亚洲欧洲日韩在线| 国产精品欧美久久久久无广告| 国产三级精品三级| 久久精子c满五个校花| 久久久三级国产网站| 久久视频一区二区| 久久精品一区蜜桃臀影院| 久久久亚洲欧洲日产国码αv| 精品免费日韩av| 欧美精品一区二区高清在线观看| 日韩视频一区二区在线观看| 欧美一区二区三区思思人| 91精品国产欧美一区二区18 | 在线观看亚洲一区| 欧美网站大全在线观看| 欧美色精品在线视频| 欧美日韩国产首页在线观看| 欧美精品在线视频| 欧美大胆一级视频| 欧美激情一区在线| 亚洲天堂a在线| 亚洲123区在线观看| 男男gaygay亚洲| 国产电影精品久久禁18| av在线不卡观看免费观看| 在线视频一区二区三区| 欧美精品三级日韩久久| 欧美大片日本大片免费观看| 国产精品视频一二三区| 夜夜嗨av一区二区三区四季av| 日日摸夜夜添夜夜添亚洲女人| 久草中文综合在线| www.亚洲人| 欧美一区二区在线视频| 久久综合九色欧美综合狠狠| 成人免费一区二区三区在线观看| 夜夜爽夜夜爽精品视频| 久久丁香综合五月国产三级网站| 国产成人av电影免费在线观看| 色琪琪一区二区三区亚洲区| 欧美一区二区三区人| 亚洲国产高清在线| 爽好久久久欧美精品| 国产乱码精品一区二区三区五月婷| 91一区二区三区在线观看| 欧美一级高清片| 中文字幕视频一区| 韩日av一区二区| 欧美日韩三级视频| 国产精品久久久久婷婷二区次| 日韩电影在线免费看| 99久久er热在这里只有精品15| 欧美一级理论片| 亚洲欧美偷拍三级| 国产裸体歌舞团一区二区| 欧美日韩精品一区二区| 国产精品无码永久免费888| 美女久久久精品| 欧美午夜电影一区| 综合久久综合久久| 国产一区二区在线视频| 91精品国产综合久久精品app | 欧美日精品一区视频| 亚洲国产精品ⅴa在线观看| 久久国产精品露脸对白| 欧美日韩国产a| 一区二区不卡在线播放| 成人免费高清在线| xvideos.蜜桃一区二区| 婷婷一区二区三区| 欧美亚洲愉拍一区二区| 国产精品久久久久久久岛一牛影视 | 欧美喷水一区二区| 国产精品麻豆欧美日韩ww| 精品系列免费在线观看| 欧美日韩一区二区不卡| 中文字幕亚洲成人| 成人午夜激情在线| 欧美精品一区二区三| 蜜桃视频在线观看一区二区| 欧美日韩精品欧美日韩精品一| 亚洲欧美国产77777| 97久久超碰精品国产| 国产精品久久久久婷婷二区次| 国产精品1024| 精品理论电影在线观看| 免费精品视频最新在线| 日韩精品一区二区三区在线| 天天综合天天综合色| 欧美日韩色综合| 日韩精品三区四区| 日韩一区二区三区电影|