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

📄 fileio.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
	  p++;	}      if (!lose)	{#ifdef VMS	  if (index (nm, '/'))	    return build_string (sys_translate_unix (nm));#endif /* VMS */	  if (nm == XSTRING (name)->data)	    return name;	  return build_string (nm);	}    }  /* Now determine directory to start with and put it in NEWDIR.  */  newdir = 0;  if (nm[0] == '~')    {      if (nm[1] == '/'#ifdef VMS	  || nm[1] == ':'#endif /* VMS */	  || nm[1] == 0)	{	  /* Handle ~ on its own.  */	  newdir = (unsigned char *) egetenv ("HOME");	}      else	{	  /* Handle ~ followed by user name.  */	  unsigned char *user = nm + 1;	  /* Find end of name.  */	  unsigned char *ptr = (unsigned char *) index (user, '/');	  int len = ptr ? ptr - user : strlen (user);#ifdef VMS	  unsigned char *ptr1 = index (user, ':');	  if (ptr1 != 0 && ptr1 - user < len)	    len = ptr1 - user;#endif /* VMS */	  /* Copy the user name into temp storage.  */	  o = (unsigned char *) alloca (len + 1);	  bcopy ((char *) user, o, len);	  o[len] = 0;	  /* Look up the user name.  */	  pw = (struct passwd *) getpwnam (o);	  if (!pw)	    error ("User \"%s\" is not known", o);	  newdir = (unsigned char *) pw->pw_dir;	  /* Discard the user name from NM.  */	  nm += len;	}      /* Discard the ~ from NM.  */      nm++;#ifdef VMS      if (*nm != 0)	nm++;			/* Don't leave the slash in nm.  */#endif /* VMS */      if (newdir == 0)	newdir = (unsigned char *) "";    }  if (nm[0] != '/'#ifdef VMS      && !index (nm, ':')#endif /* not VMS */      && !newdir)    {      if (NULL (defalt))	defalt = current_buffer->directory;      CHECK_STRING (defalt, 1);      newdir = XSTRING (defalt)->data;    }  /* Now concatenate the directory and name to new space in the stack frame */  tlen = (newdir ? strlen (newdir) + 1 : 0) + strlen (nm) + 1;  target = (unsigned char *) alloca (tlen);  *target = 0;  if (newdir)    {#ifndef VMS      if (nm[0] == 0 || nm[0] == '/')	strcpy (target, newdir);      else#endif      file_name_as_directory (target, newdir);    }  strcat (target, nm);#ifdef VMS  if (index (target, '/'))    strcpy (target, sys_translate_unix (target));#endif /* VMS */  /* Now canonicalize by removing /. and /foo/.. if they appear */  p = target;  o = target;  while (*p)    {#ifdef VMS      if (*p != ']' && *p != '>' && *p != '-')	{	  if (*p == '\\')	    p++;	  *o++ = *p++;	}      else if ((p[0] == ']' || p[0] == '>') && p[0] == p[1] + 2)	/* brackets are offset from each other by 2 */	{	  p += 2;	  if (*p != '.' && *p != '-' && o[-1] != '.')	    /* convert [foo][bar] to [bar] */	    while (o[-1] != '[' && o[-1] != '<')	      o--;	  else if (*p == '-' && *o != '.')	    *--p = '.';	}      else if (p[0] == '-' && o[-1] == '.' &&	       (p[1] == '.' || p[1] == ']' || p[1] == '>'))	/* flush .foo.- ; leave - if stopped by '[' or '<' */	{	  do	    o--;	  while (o[-1] != '.' && o[-1] != '[' && o[-1] != '<');	  if (p[1] == '.')	/* foo.-.bar ==> bar*/	    p += 2;	  else if (o[-1] == '.') /* '.foo.-]' ==> ']' */	    p++, o--;	  /* else [foo.-] ==> [-] */	}      else	{#ifndef VMS4_4	  if (*p == '-' &&	      o[-1] != '[' && o[-1] != '<' && o[-1] != '.' &&	      p[1] != ']' && p[1] != '>' && p[1] != '.')	    *p = '_';#endif /* VMS4_4 */	  *o++ = *p++;	}#else /* not VMS */      if (*p != '/') 	{	  *o++ = *p++;	}      else if (!strncmp (p, "//", 2)#ifdef APOLLO	       /* // at start of filename is meaningful in Apollo system */	       && o != target#endif /* APOLLO */	       )	{	  o = target;	  p++;	}      else if (p[0] == '/' && p[1] == '.' &&	       (p[2] == '/' || p[2] == 0))	p += 2;      else if (!strncmp (p, "/..", 3)	       /* `/../' is the "superroot" on certain file systems.  */	       && o != target	       && (p[3] == '/' || p[3] == 0))	{	  while (o != target && *--o != '/')	    ;#ifdef APOLLO	  if (o == target + 1 && o[-1] == '/' && o[0] == '/')	    ++o;	  else#endif APOLLO	  if (o == target && *o == '/')	    ++o;	  p += 3;	}      else 	{	  *o++ = *p++;	}#endif /* not VMS */    }  return make_string (target, o - target);}DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name,  Ssubstitute_in_file_name, 1, 1, 0,  "Substitute environment variables referred to in STRING.\n\A $ begins a request to substitute; the env variable name is the alphanumeric\n\characters and underscores after the $, or is surrounded by braces.\n\If a ~ appears following a /, everything through that / is discarded.\n\On VMS, $ substitution is not done; this function does little and only\n\duplicates what expand-file-name does.")  (string)     Lisp_Object string;{  unsigned char *nm;  register unsigned char *s, *p, *o, *x, *endp;  unsigned char *target;  int total = 0;  int substituted = 0;  unsigned char *xnm;  CHECK_STRING (string, 0);  nm = XSTRING (string)->data;  endp = nm + XSTRING (string)->size;  /* If /~ or // appears, discard everything through first slash. */  for (p = nm; p != endp; p++)    {      if ((p[0] == '~' ||#ifdef APOLLO	   /* // at start of file name is meaningful in Apollo system */	   (p[0] == '/' && p - 1 != nm)#else /* not APOLLO */	   p[0] == '/'#endif /* not APOLLO */	   )	  && p != nm &&#ifdef VMS	  (p[-1] == ':' || p[-1] == ']' || p[-1] == '>' ||#endif /* VMS */	  p[-1] == '/')#ifdef VMS	  )#endif /* VMS */	{	  nm = p;	  substituted = 1;	}    }#ifdef VMS  return build_string (nm);#else  /* See if any variables are substituted into the string     and find the total length of their values in `total' */  for (p = nm; p != endp;)    if (*p != '$')      p++;    else      {	p++;	if (p == endp)	  goto badsubst;	else if (*p == '$')	  {	    /* "$$" means a single "$" */	    p++;	    total -= 1;	    substituted = 1;	    continue;	  }	else if (*p == '{')	  {	    o = ++p;	    while (p != endp && *p != '}') p++;	    if (*p != '}') goto missingclose;	    s = p;	  }	else	  {	    o = p;	    while (p != endp && (isalnum (*p) || *p == '_')) p++;	    s = p;	  }	/* Copy out the variable name */	target = (unsigned char *) alloca (s - o + 1);	strncpy (target, o, s - o);	target[s - o] = 0;	/* Get variable value */	o = (unsigned char *) egetenv (target);/* The presence of this code makes vax 5.0 crash, for reasons yet unknown */#if 0#ifdef USG	if (!o && !strcmp (target, "USER"))	  o = egetenv ("LOGNAME");#endif /* USG */#endif /* 0 */	if (!o) goto badvar;	total += strlen (o);	substituted = 1;      }  if (!substituted)    return string;  /* If substitution required, recopy the string and do it */  /* Make space in stack frame for the new copy */  xnm = (unsigned char *) alloca (XSTRING (string)->size + total + 1);  x = xnm;  /* Copy the rest of the name through, replacing $ constructs with values */  for (p = nm; *p;)    if (*p != '$')      *x++ = *p++;    else      {	p++;	if (p == endp)	  goto badsubst;	else if (*p == '$')	  {	    *x++ = *p++;	    continue;	  }	else if (*p == '{')	  {	    o = ++p;	    while (p != endp && *p != '}') p++;	    if (*p != '}') goto missingclose;	    s = p++;	  }	else	  {	    o = p;	    while (p != endp && (isalnum (*p) || *p == '_')) p++;	    s = p;	  }	/* Copy out the variable name */	target = (unsigned char *) alloca (s - o + 1);	strncpy (target, o, s - o);	target[s - o] = 0;	/* Get variable value */	o = (unsigned char *) egetenv (target);/* The presence of this code makes vax 5.0 crash, for reasons yet unknown */#if 0#ifdef USG	if (!o && !strcmp (target, "USER"))	  o = egetenv ("LOGNAME");#endif /* USG */#endif /* 0 */	if (!o)	  goto badvar;	strcpy (x, o);	x += strlen (o);      }  *x = 0;  /* If /~ or // appears, discard everything through first slash. */  for (p = xnm; p != x; p++)    if ((p[0] == '~' ||#ifdef APOLLO	 /* // at start of file name is meaningful in Apollo system */	 (p[0] == '/' && p - 1 != xnm)#else /* not APOLLO */	 p[0] == '/'#endif /* not APOLLO */	 )	&& p != nm && p[-1] == '/')      xnm = p;  return make_string (xnm, x - xnm); badsubst:  error ("Bad format environment-variable substitution"); missingclose:  error ("Missing \"}\" in environment-variable substitution"); badvar:  error ("Substituting nonexistent environment variable \"%s\"", target);  /* NOTREACHED */#endif /* not VMS */}Lisp_Objectexpand_and_dir_to_file (filename, defdir)     Lisp_Object filename, defdir;{  register Lisp_Object abspath;  abspath = Fexpand_file_name (filename, defdir);#ifdef VMS  {    register int c = XSTRING (abspath)->data[XSTRING (abspath)->size - 1];    if (c == ':' || c == ']' || c == '>')      abspath = Fdirectory_file_name (abspath);  }#else  /* Remove final slash, if any (unless path is root).     stat behaves differently depending!  */  if (XSTRING (abspath)->size > 1      && XSTRING (abspath)->data[XSTRING (abspath)->size - 1] == '/')    {      if (EQ (abspath, filename))	abspath = Fcopy_sequence (abspath);      XSTRING (abspath)->data[XSTRING (abspath)->size - 1] = 0;    }#endif  return abspath;}barf_or_query_if_file_exists (absname, querystring, interactive)     Lisp_Object absname;     unsigned char *querystring;     int interactive;{  register Lisp_Object tem;  struct gcpro gcpro1;  if (access (XSTRING (absname)->data, 4) >= 0)    {      if (! interactive)	Fsignal (Qfile_already_exists,		 Fcons (build_string ("File already exists"),			Fcons (absname, Qnil)));      GCPRO1 (absname);      tem = Fyes_or_no_p (format1 ("File %s already exists; %s anyway? ",				   XSTRING (absname)->data, querystring));      UNGCPRO;      if (NULL (tem))	Fsignal (Qfile_already_exists,		 Fcons (build_string ("File already exists"),			Fcons (absname, Qnil)));    }  return;}DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 4,  "fCopy file: \nFCopy %s to file: \np",  "Copy FILE to NEWNAME.  Both args strings.\n\Signals a  file-already-exists  error if NEWNAME already exists,\n\unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.\n\A number as third arg means request confirmation if NEWNAME already exists.\n\This is what happens in interactive use with M-x.\n\Fourth arg non-nil means give the new file the same last-modified time\n\that the old one has.  (This works on only some systems.)")  (filename, newname, ok_if_already_exists, keep_date)     Lisp_Object filename, newname, ok_if_already_exists, keep_date;{  int ifd, ofd, n;  char buf[16 * 1024];  struct stat st;  struct gcpro gcpro1, gcpro2;  GCPRO2 (filename, newname);  CHECK_STRING (filename, 0);  CHECK_STRING (newname, 1);  filename = Fexpand_file_name (filename, Qnil);  newname = Fexpand_file_name (newname, Qnil);  if (NULL (ok_if_already_exists)      || XTYPE (ok_if_already_exists) == Lisp_Int)    barf_or_query_if_file_exists (newname, "copy to it",				  XTYPE (ok_if_already_exists) == Lisp_Int);  ifd = open (XSTRING (filename)->data, 0);  if (ifd < 0)    report_file_error ("Opening input file", Fcons (filename, Qnil));#ifdef VMS  /* Create the copy file with the same record format as the input file */  ofd = sys_creat (XSTRING (newname)->data, 0666, ifd);#else  ofd = creat (XSTRING (newname)->data, 0666);#endif /* VMS */  if (ofd < 0)    {      close (ifd);      report_file_error ("Opening output file", Fcons (newname, Qnil));    }  while ((n = read (ifd, buf, sizeof buf)) > 0)    if (write (ofd, buf, n) != n)      {	close (ifd);	close (ofd);	report_file_error ("I/O error", Fcons (newname, Qnil));      }  if (fstat (ifd, &st) >= 0)    {#ifdef HAVE_TIMEVAL      if (!NULL (keep_date))	{#ifdef USE_UTIME/* AIX has utimes() in compatibility package, but it dies.  So use good old   utime interface instead. */	  struct {	    time_t atime;	    time_t mtime;	  } tv;	  tv.atime = st.st_atime;	  tv.mtime = st.st_mtime;	  utime (XSTRING (newname)->data, &tv);#else /* not USE_UTIME */	  struct timeval timevals[2];	  timevals[0].tv_sec = st.st_atime;	  timevals[1].tv_sec = st.st_mtime;	  timevals[0].tv_usec = timevals[1].tv_usec = 0;	  utimes (XSTRING (newname)->data, timevals);#endif /* not USE_UTIME */	}#endif /* HAVE_TIMEVALS */#ifdef APOLLO      if (!egetenv ("USE_DOMAIN_ACLS"))#endif      chmod (XSTRING (newname)->data, st.st_mode & 07777);    }  close (ifd);  if (close (ofd) < 0)    report_file_error ("I/O error", Fcons (newname, Qnil));  UNGCPRO;  return Qnil;}DEFUN ("delete-file", Fdelete_file, Sdelete_file, 1, 1, "fDelete file: ",  "Delete specified file.  One argument, a file name string.\n\If file has multiple names, it continues to exist with the other names.")  (filename)     Lisp_Object filename;{  CHECK_STRING (filename, 0);  filename = Fexpand_file_name (filename, Qnil);  if (0 > unlink (XSTRING (filename)->data))    report_file_error ("Removing old name", Flist (1, &filename));  return Qnil;}DEFUN ("rename-file", Frename_file, Srename_file, 2, 3,  "fRename file: \nFRename %s to file: \np",  "Rename FILE as NEWNAME.  Both args strings.\n\If file has names other than FILE, it continues to have those names.\n\Signals a  file-already-exists  error if NEWNAME already exists\n\unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.\n\A number as third arg means request confirmation if NEWNAME already exists.\n\This is what happens in interactive use with M-x.")  (filename, newname, ok_if_already_exists)     Lisp_Object filename, newname, ok_if_already_exists;{#ifdef NO_ARG_ARRAY  Lisp_Object args[2];#endif  struct gcpro gcpro1, gcpro2;  GCPRO2 (filename, newname);  CHECK_STRING (filename, 0);  CHECK_STRING (newname, 1);  filename = Fexpand_file_name (filename, Qnil);  newname = Fexpand_file_name (newname, Qnil);  if (NULL (ok_if_already_exists)      || XTYPE (ok_if_already_exists) == Lisp_Int)    barf_or_query_if_file_exists (newname, "rename to it",				  XTYPE (ok_if_already_exists) == Lisp_Int);#ifndef BSD4_1  if (0 > rename (XSTRING (filename)->data, XSTRING (newname)->data))

⌨️ 快捷键说明

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