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

📄 ftw.c

📁 Newlib 嵌入式 C库 标准实现代码
💻 C
📖 第 1 页 / 共 2 页
字号:
			{			  /* Please note that we overwrite a slash.  */			  data->dirbuf[data->ftw.base - 1] = '\0';			  if (chdir (data->dirbuf) < 0)			    result = -1;			  data->dirbuf[data->ftw.base - 1] = '/';			}		    }		}	    }	}      else	result = (*data->func) (data->dirbuf, &st, data->cvt_arr[flag],				&data->ftw);    }  return result;}static intftw_dir (struct ftw_data *data, struct STAT *st){  struct dir_data dir;  struct dirent64 *d;  int previous_base = data->ftw.base;  int result;  char *startp;  /* Open the stream for this directory.  This might require that     another stream has to be closed.  */  result = open_dir_stream (data, &dir);  if (result != 0)    {      if (errno == EACCES)	/* We cannot read the directory.  Signal this with a special flag.  */	result = (*data->func) (data->dirbuf, st, FTW_DNR, &data->ftw);      return result;    }  /* First, report the directory (if not depth-first).  */  if (!(data->flags & FTW_DEPTH))    {      result = (*data->func) (data->dirbuf, st, FTW_D, &data->ftw);      if (result != 0)	return result;    }  /* If necessary, change to this directory.  */  if (data->flags & FTW_CHDIR)    {      if (fchdir (dirfd (dir.stream)) < 0)	{	  if (errno == ENOSYS)	    {	      if (chdir (data->dirbuf) < 0)		result = -1;	    }	  else	    result = -1;	}      if (result != 0)	{	  int save_err = errno;	  closedir (dir.stream);	  __set_errno (save_err);	  if (data->actdir-- == 0)	    data->actdir = data->maxdir - 1;	  data->dirstreams[data->actdir] = NULL;	  return result;	}    }  /* Next, update the `struct FTW' information.  */  ++data->ftw.level;  startp = strchr (data->dirbuf, '\0');  /* There always must be a directory name.  */  assert (startp != data->dirbuf);  if (startp[-1] != '/')    *startp++ = '/';  data->ftw.base = startp - data->dirbuf;  while (dir.stream != NULL && (d = __readdir64 (dir.stream)) != NULL)    {      result = process_entry (data, &dir, d->d_name, strlen (d->d_name));      if (result != 0)	break;    }  if (dir.stream != NULL)    {      /* The stream is still open.  I.e., we did not need more	 descriptors.  Simply close the stream now.  */      int save_err = errno;      assert (dir.content == NULL);      closedir (dir.stream);      __set_errno (save_err);      if (data->actdir-- == 0)	data->actdir = data->maxdir - 1;      data->dirstreams[data->actdir] = NULL;    }  else    {      int save_err;      char *runp = dir.content;      while (result == 0 && *runp != '\0')	{	  char *endp = strchr (runp, '\0');	  result = process_entry (data, &dir, runp, endp - runp);	  runp = endp + 1;	}      save_err = errno;      free (dir.content);      __set_errno (save_err);    }  /* Prepare the return, revert the `struct FTW' information.  */  data->dirbuf[data->ftw.base - 1] = '\0';  --data->ftw.level;  data->ftw.base = previous_base;  /* Finally, if we process depth-first report the directory.  */  if (result == 0 && (data->flags & FTW_DEPTH))    result = (*data->func) (data->dirbuf, st, FTW_DP, &data->ftw);  return result;}static intftw_startup (const char *dir, int is_nftw, void *func, int descriptors,	     int flags){  struct ftw_data data;  struct STAT st;  int result = 0;  int save_err;  int len;  char *cwd = NULL;  char *cp;  /* First make sure the parameters are reasonable.  */  if (dir[0] == '\0')    {      __set_errno (ENOENT);      return -1;    }  if (access (dir, R_OK) != 0)    return -1;  data.maxdir = descriptors < 1 ? 1 : descriptors;  data.actdir = 0;  data.dirstreams = (struct dir_data **) alloca (data.maxdir						 * sizeof (struct dir_data *));  memset (data.dirstreams, '\0', data.maxdir * sizeof (struct dir_data *));#ifdef PATH_MAX  data.dirbufsize = MAX (2 * strlen (dir), PATH_MAX);#else  data.dirbufsize = 2 * strlen (dir);#endif  data.dirbuf = (char *) malloc (data.dirbufsize);  if (data.dirbuf == NULL)    return -1;  len = strlen (dir);  cp = mempcpy (data.dirbuf, dir, len);  /* Strip trailing slashes.  */  while (cp > data.dirbuf + 1 && cp[-1] == '/')    --cp;  *cp = '\0';  data.ftw.level = 0;  /* Find basename.  */  while (cp > data.dirbuf && cp[-1] != '/')    --cp;  data.ftw.base = cp - data.dirbuf;  data.flags = flags;  /* This assignment might seem to be strange but it is what we want.     The trick is that the first three arguments to the `ftw' and     `nftw' callback functions are equal.  Therefore we can call in     every case the callback using the format of the `nftw' version     and get the correct result since the stack layout for a function     call in C allows this.  */  data.func = (NFTW_FUNC_T) func;  /* Since we internally use the complete set of FTW_* values we need     to reduce the value range before calling a `ftw' callback.  */  data.cvt_arr = is_nftw ? nftw_arr : ftw_arr;  /* No object known so far.  */  data.known_objects = NULL;  /* Now go to the directory containing the initial file/directory.  */  if ((flags & FTW_CHDIR) && data.ftw.base > 0)    {      /* GNU extension ahead.  */      cwd =  getcwd (NULL, 0);      if (cwd == NULL)	result = -1;      else	{	  /* Change to the directory the file is in.  In data.dirbuf	     we have a writable copy of the file name.  Just NUL	     terminate it for now and change the directory.  */	  if (data.ftw.base == 1)	    /* I.e., the file is in the root directory.  */	    result = chdir ("/");	  else	    {	      char ch = data.dirbuf[data.ftw.base - 1];	      data.dirbuf[data.ftw.base - 1] = '\0';	      result = chdir (data.dirbuf);	      data.dirbuf[data.ftw.base - 1] = ch;	    }	}    }  /* Get stat info for start directory.  */  if (result == 0)    {      if (((flags & FTW_PHYS)	   ? LXSTAT (data.dirbuf, &st)	   : XSTAT (data.dirbuf, &st)) < 0)	{	  if (errno == EACCES)	    result = (*data.func) (data.dirbuf, &st, FTW_NS, &data.ftw);	  else if (!(flags & FTW_PHYS)		   && errno == ENOENT		   && LXSTAT (dir, &st) == 0		   && S_ISLNK (st.st_mode))	    result = (*data.func) (data.dirbuf, &st, data.cvt_arr[FTW_SLN],				   &data.ftw);	  else	    /* No need to call the callback since we cannot say anything	       about the object.  */	    result = -1;	}      else	{	  if (S_ISDIR (st.st_mode))	    {	      /* Remember the device of the initial directory in case		 FTW_MOUNT is given.  */	      data.dev = st.st_dev;	      /* We know this directory now.  */	      if (!(flags & FTW_PHYS))		result = add_object (&data, &st);	      if (result == 0)		result = ftw_dir (&data, &st);	    }	  else	    {	      int flag = S_ISLNK (st.st_mode) ? FTW_SL : FTW_F;	      result = (*data.func) (data.dirbuf, &st, data.cvt_arr[flag],				     &data.ftw);	    }	}    }  /* Return to the start directory (if necessary).  */  if (cwd != NULL)    {      int save_err = errno;      chdir (cwd);      free (cwd);      __set_errno (save_err);    }  /* Free all memory.  */  save_err = errno;  tdestroy (data.known_objects, free);  free (data.dirbuf);  __set_errno (save_err);  return result;}/* Entry points.  */intFTW_NAME (path, func, descriptors)     const char *path;     FTW_FUNC_T func;     int descriptors;{  return ftw_startup (path, 0, func, descriptors, 0);}intNFTW_NAME (path, func, descriptors, flags)     const char *path;     NFTW_FUNC_T func;     int descriptors;     int flags;{  return ftw_startup (path, 1, func, descriptors, flags);}

⌨️ 快捷键说明

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