#ifdef FILE_CODING
#include "mule/file-coding.h"
#endif
+#include "ent/ent.h"
#ifdef HAVE_LIBGEN_H /* Must come before sysfile.h */
#include <libgen.h>
Bytecount match = -1;
Bytecount len = XSTRING_LENGTH( extension );
if ( len > 0 ) {
- char re[len+6],
+ char re[len+6],
*rep = re;
Bufbyte *ext = XSTRING_DATA(extension);
Lisp_Object regexp;
terminator if need to append...
*/
rep += len-1;
- if ( *rep++ != '$' )
+ if ( *rep++ != '$' )
*rep++ = '$';
*rep = '\0';
regexp = make_string( (Bufbyte*)re, strlen(re));
res = make_string(p, end - p);
if ( STRINGP( extension ) ) {
Bytecount match;
- match = file_basename_match_extension(res,
+ match = file_basename_match_extension(res,
extension);
if ( match >= 0 )
RETURN_UNGCPRO(make_string(p, match));
do {
ext = XCAR(rest);
Bytecount match;
- match = file_basename_match_extension(res,
+ match = file_basename_match_extension(res,
ext);
if ( match >= 0 )
RETURN_UNGCPRO(make_string(p, match));
return Ffile_name_directory(filename);
}
\f
-static char *file_name_as_directory(char *out, char *in)
+static char *file_name_as_directory(char *out, const char *in, size_t len)
{
/* This function cannot GC */
int size = strlen(in);
if (size == 0) {
+ assert(len >= 3);
out[0] = '.';
out[1] = DIRECTORY_SEP;
out[2] = '\0';
} else {
- strcpy(out, in);
+ xstrncpy(out, in, len);
/* Append a slash if necessary */
if (!IS_ANY_SEP(out[size - 1])) {
out[size] = DIRECTORY_SEP;
(filename))
{
/* This function can GC. GC checked 2000-07-28 ben */
- char *buf;
- Lisp_Object handler;
+ size_t len = 0;
+ char *buf = NULL;
+ Lisp_Object handler = Qnil;
CHECK_STRING(filename);
return call2_check_string(handler, Qfile_name_as_directory,
filename);
- buf = (char *)alloca(XSTRING_LENGTH(filename) + 10);
+ len = XSTRING_LENGTH(filename) + 10;
+ buf = (char *)alloca(len);
return build_string(file_name_as_directory
- (buf, (char *)XSTRING_DATA(filename)));
+ (buf, (char*)XSTRING_DATA(filename), len));
}
\f
/*
* Value is nonzero if the string output is different from the input.
*/
-static int directory_file_name(const char *src, char *dst)
+static int directory_file_name(const char *src, char *dst, size_t len)
{
/* This function cannot GC */
long slen = strlen(src);
/* Process as Unix format: just remove any final slash.
But leave "/" unchanged; do not change it to "". */
- strcpy(dst, src);
+ xstrncpy(dst, src, len);
if (slen > 1 && IS_DIRECTORY_SEP(dst[slen - 1])
)
dst[slen - 1] = 0;
(directory))
{
/* This function can GC. GC checked 2000-07-28 ben */
- char *buf;
+ size_t len = 0;
+ char *buf = NULL;
Lisp_Object handler;
CHECK_STRING(directory);
if (!NILP(handler))
return call2_check_string(handler, Qdirectory_file_name,
directory);
- buf = (char *)alloca(XSTRING_LENGTH(directory) + 20);
- directory_file_name((char *)XSTRING_DATA(directory), buf);
+ len = XSTRING_LENGTH(directory) + 20;
+ buf = (char *)alloca(len);
+ directory_file_name((char *)XSTRING_DATA(directory), buf, len);
return build_string(buf);
}
\f
if (newdir) {
if (nm[0] == 0 || IS_DIRECTORY_SEP(nm[0]))
- strcpy((char *)target, (char *)newdir);
+ xstrncpy((char *)target, (char *)newdir, tlen);
else
- file_name_as_directory((char *)target, (char *)newdir);
+ file_name_as_directory((char *)target, (char *)newdir, tlen);
}
- strcat((char *)target, (char *)nm);
+ xstrncat((char *)target, (char *)nm, tlen-1);
/* ASSERT (IS_DIRECTORY_SEP (target[0])) if not VMS */
{
Lisp_Object handler =
- Ffind_file_name_handler(expanded_name, Qfile_truename);
+ Ffind_file_name_handler(expanded_name, Qfile_truename);
if (!NILP(handler))
RETURN_UNGCPRO
- (call2_check_string
- (handler, Qfile_truename, expanded_name));
+ (call2_check_string
+ (handler, Qfile_truename, expanded_name));
}
{
char resolved_path[MAXPATHLEN];
- Extbyte *path;
- Extbyte *p;
+ Extbyte *path = NULL;
+ Extbyte *p = NULL;
Extcount elen;
TO_EXTERNAL_FORMAT(LISP_STRING, expanded_name,
ALLOCA, (path, elen), Qfile_name);
-
p = path;
if (elen > MAXPATHLEN)
goto toolong;
/* Try doing it all at once. */
- /* !! Does realpath() Mule-encapsulate?
- Answer: Nope! So we do it above */
- if (!xrealpath((char *)path, resolved_path)) {
- /* Didn't resolve it -- have to do it one component at a time. */
- /* "realpath" is a typically useless, stupid un*x piece of crap.
- It claims to return a useful value in the "error" case, but since
- there is no indication provided of how far along the pathname
- the function went before erring, there is no way to use the
- partial result returned. What a piece of junk.
-
- The above comment refers to historical versions of
- realpath(). The Unix98 specs state:
-
- "On successful completion, realpath() returns a
- pointer to the resolved name. Otherwise, realpath()
- returns a null pointer and sets errno to indicate the
- error, and the contents of the buffer pointed to by
- resolved_name are undefined."
-
- Since we depend on undocumented semantics of various system realpath()s,
- we just use our own version in realpath.c. */
+ /* !! Does realpath() Mule-encapsulate? Answer: Nope!
+ So we do it above */
+ if (path != NULL && !xrealpath((char *)path, resolved_path)) {
+ /* Didn't resolve it -- have to do it one
+ component at a time.
+
+ "realpath" is a typically useless, stupid
+ un*x piece of crap. It claims to return a
+ useful value in the "error" case, but since
+ there is no indication provided of how far
+ along the pathname the function went before
+ erring, there is no way to use the partial
+ result returned. What a piece of junk.
+
+ The above comment refers to historical
+ versions of realpath(). The Unix98 specs
+ state:
+
+ "On successful completion, realpath()
+ returns a pointer to the resolved
+ name. Otherwise, realpath() returns a null
+ pointer and sets errno to indicate the
+ error, and the contents of the buffer
+ pointed to by resolved_name are undefined."
+
+ Since we depend on undocumented semantics
+ of various system realpath()s, we just use
+ our own version in realpath.c.
+ */
for (;;) {
- Extbyte *pos;
+ Extbyte *pos = NULL;
- for (pos = p + 1; pos < path + elen; pos++)
+ for (pos = p + 1; pos < path + elen; pos++) {
if (IS_DIRECTORY_SEP(*pos)) {
*(p = pos) = 0;
break;
}
+ }
if (p != pos)
p = 0;
break;
} else if (errno == ENOENT || errno == EACCES) {
- /* Failed on this component. Just tack on the rest of
- the string and we are done. */
+ /* Failed on this component.
+ Just tack on the rest of
+ the string and we are
+ done. */
int rlen = strlen(resolved_path);
- /* "On failure, it returns NULL, sets errno to indicate
- the error, and places in resolved_path the absolute pathname
- of the path component which could not be resolved." */
-
- if (p) {
- int plen = elen - (p - path);
+ /* "On failure, it returns
+ NULL, sets errno to
+ indicate the error, and
+ places in resolved_path the
+ absolute pathname of the
+ path component which could
+ not be resolved."
+ */
+ if (p == NULL ) {
+ break;
+ }
+ int plen = elen - (p - path);
- if (rlen > 1
- &&
- IS_DIRECTORY_SEP
- (resolved_path[rlen - 1]))
- rlen = rlen - 1;
+ if (rlen > 1 &&
+ IS_DIRECTORY_SEP
+ (resolved_path[rlen - 1]))
+ rlen = rlen - 1;
- if (plen + rlen + 1 >
- countof(resolved_path))
- goto toolong;
+ if ((plen + rlen + 1) >
+ countof(resolved_path))
+ goto toolong;
- resolved_path[rlen] =
- DIRECTORY_SEP;
- memcpy(resolved_path + rlen + 1,
- p + 1, plen + 1 - 1);
- }
+ resolved_path[rlen] = DIRECTORY_SEP;
+ memcpy(resolved_path + rlen + 1,
+ p + 1, plen + 1 - 1);
break;
} else
goto lose;
{
Lisp_Object resolved_name;
int rlen = strlen(resolved_path);
+
if (elen > 0
- &&
- IS_DIRECTORY_SEP(XSTRING_BYTE
- (expanded_name, elen - 1))
- && !(rlen > 0
- && IS_DIRECTORY_SEP(resolved_path[rlen - 1])))
- {
+ && IS_DIRECTORY_SEP(
+ XSTRING_BYTE(expanded_name, elen-1))
+ && !(rlen > 0 &&
+ IS_DIRECTORY_SEP(resolved_path[rlen-1]))) {
if (rlen + 1 > countof(resolved_path))
goto toolong;
resolved_path[rlen++] = DIRECTORY_SEP;
RETURN_UNGCPRO(resolved_name);
}
- toolong:
+ toolong:
errno = ENAMETOOLONG;
goto lose;
- lose:
+ lose:
report_file_error("Finding truename", list1(expanded_name));
}
RETURN_UNGCPRO(Qnil);
Bufbyte *target = 0;
int total = 0;
int substituted = 0;
+ size_t avail = 0;
Bufbyte *xnm;
Lisp_Object handler;
/* If substitution required, recopy the filename and do it */
/* Make space in stack frame for the new copy */
- xnm = (Bufbyte *) alloca(XSTRING_LENGTH(filename) + total + 1);
+ avail = XSTRING_LENGTH(filename) + total + 1;
+ xnm = (Bufbyte *) alloca(avail);
x = xnm;
/* Copy the rest of the name through, replacing $ constructs with values */
for (p = nm; *p;)
- if (*p != '$')
+ if (*p != '$') {
*x++ = *p++;
- else {
+ avail--;
+ } else {
p++;
if (p == endp)
goto badsubst;
else if (*p == '$') {
*x++ = *p++;
+ avail--;
continue;
} else if (*p == '{') {
o = ++p;
if (!o)
goto badvar;
- strcpy((char *)x, (char *)o);
+ xstrncpy((char *)x, (char *)o, avail);
x += strlen((char *)o);
+ avail -= strlen((char *)o);
}
*x = 0;
O_RDONLY | OPEN_BINARY, 0);
if (ifd < 0) {
report_file_error("Opening input file", list1(filename));
+ goto end;
}
record_unwind_protect(close_file_unwind, make_int(ifd));
report_file_error("I/O error", list1(newname));
}
+ if(close(ifd) <0)
+ report_file_error("I/O error", list1(filename));
/* Closing the output clobbers the file times on some systems. */
if (close(ofd) < 0)
report_file_error("I/O error", list1(newname));
unbind_to(speccount, Qnil);
}
+end:
UNGCPRO;
return Qnil;
}
}
strncpy(dir, (char *)XSTRING_DATA(dirname_),
XSTRING_LENGTH(dirname_) + 1);
- dir[XSTRING_LENGTH(dirname_)]='\0';
+ dir[XSTRING_LENGTH(dirname_)]='\0';
if (dir[XSTRING_LENGTH(dirname_) - 1] == '/')
- dir[XSTRING_LENGTH(dirname_) - 1] = '\0';
+ dir[XSTRING_LENGTH(dirname_) - 1] = '\0';
if (mkdir(dir, 0777) != 0)
report_file_error("Creating directory", list1(dirname_));
to avoid a "file has changed on disk" warning on
next attempt to save. */
if (visiting)
- if (stat_res == 0)
+ if (stat_res == 0)
current_buffer->modtime = st.st_mtime;
- /* else:
+ /* else:
If sxemacs_stat failed, we have bigger problems, and
most likely the file is gone, so the error next time is
the right behavior
- */
+ */
if (failure) {
errno = save_errno;
if (listdesc < 0 && !auto_saved && STRINGP(listfile))
unlink((char *)XSTRING_DATA(listfile));
+ if (listdesc >= 0)
+ close(listdesc);
+
/* Show "...done" only if the echo area would otherwise be empty. */
if (auto_saved && NILP(no_message)
&& NILP(clear_echo_area(selected_frame(), Qauto_saving, 0))) {