summaryrefslogtreecommitdiffstats
path: root/unix/tclUnixFCmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'unix/tclUnixFCmd.c')
-rw-r--r--unix/tclUnixFCmd.c357
1 files changed, 213 insertions, 144 deletions
diff --git a/unix/tclUnixFCmd.c b/unix/tclUnixFCmd.c
index 9abd70a..b188f21 100644
--- a/unix/tclUnixFCmd.c
+++ b/unix/tclUnixFCmd.c
@@ -113,16 +113,8 @@ typedef int (TraversalProc)(Tcl_DString *srcPtr, Tcl_DString *dstPtr,
* elsewhere in Tcl's core.
*/
-#ifdef DJGPP
-
-/*
- * See contrib/djgpp/tclDjgppFCmd.c for definition.
- */
-
-extern TclFileAttrProcs tclpFileAttrProcs[];
-extern const char *const tclpFileAttrStrings[];
+#ifndef DJGPP
-#else /* !DJGPP */
enum {
#if defined(__CYGWIN__)
UNIX_ARCHIVE_ATTRIBUTE,
@@ -142,10 +134,9 @@ enum {
MACOSX_CREATOR_ATTRIBUTE, MACOSX_TYPE_ATTRIBUTE, MACOSX_HIDDEN_ATTRIBUTE,
MACOSX_RSRCLENGTH_ATTRIBUTE,
#endif
- UNIX_INVALID_ATTRIBUTE /* lint - last enum value needs no trailing , */
+ UNIX_INVALID_ATTRIBUTE
};
-MODULE_SCOPE const char *const tclpFileAttrStrings[];
const char *const tclpFileAttrStrings[] = {
#if defined(__CYGWIN__)
"-archive",
@@ -167,7 +158,6 @@ const char *const tclpFileAttrStrings[] = {
NULL
};
-MODULE_SCOPE const TclFileAttrProcs tclpFileAttrProcs[];
const TclFileAttrProcs tclpFileAttrProcs[] = {
#if defined(__CYGWIN__)
{GetUnixFileAttributes, SetUnixFileAttributes},
@@ -256,7 +246,7 @@ Realpath(
#endif /* PURIFY */
#ifndef NO_REALPATH
-#if defined(__APPLE__) && defined(TCL_THREADS) && \
+#if defined(__APPLE__) && TCL_THREADS && \
defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \
MAC_OS_X_VERSION_MIN_REQUIRED < 1030
/*
@@ -331,8 +321,8 @@ TclpObjRenameFile(
Tcl_Obj *srcPathPtr,
Tcl_Obj *destPathPtr)
{
- return DoRenameFile(Tcl_FSGetNativePath(srcPathPtr),
- Tcl_FSGetNativePath(destPathPtr));
+ return DoRenameFile((const char *)Tcl_FSGetNativePath(srcPathPtr),
+ (const char *)Tcl_FSGetNativePath(destPathPtr));
}
static int
@@ -447,14 +437,14 @@ TclpObjCopyFile(
Tcl_Obj *srcPathPtr,
Tcl_Obj *destPathPtr)
{
- const char *src = Tcl_FSGetNativePath(srcPathPtr);
+ const char *src = (const char *)Tcl_FSGetNativePath(srcPathPtr);
Tcl_StatBuf srcStatBuf;
if (TclOSlstat(src, &srcStatBuf) != 0) { /* INTL: Native. */
return TCL_ERROR;
}
- return DoCopyFile(src, Tcl_FSGetNativePath(destPathPtr), &srcStatBuf);
+ return DoCopyFile(src, (const char *)Tcl_FSGetNativePath(destPathPtr), &srcStatBuf);
}
static int
@@ -610,7 +600,7 @@ TclUnixCopyFile(
if (blockSize <= 0) {
blockSize = DEFAULT_COPY_BLOCK_SIZE;
}
- buffer = ckalloc(blockSize);
+ buffer = (char *)ckalloc(blockSize);
while (1) {
nread = (size_t) read(srcFd, buffer, blockSize);
if ((nread == (size_t) -1) || (nread == 0)) {
@@ -709,7 +699,7 @@ int
TclpObjCreateDirectory(
Tcl_Obj *pathPtr)
{
- return DoCreateDirectory(Tcl_FSGetNativePath(pathPtr));
+ return DoCreateDirectory((const char *)Tcl_FSGetNativePath(pathPtr));
}
static int
@@ -974,7 +964,7 @@ TraverseUnixTree(
errfile = NULL;
result = TCL_OK;
- targetLen = 0; /* lint. */
+ targetLen = 0;
source = Tcl_DStringValue(sourcePtr);
if (TclOSlstat(source, &statBuf) != 0) { /* INTL: Native. */
@@ -1240,14 +1230,14 @@ TraversalCopy(
static int
TraversalDelete(
Tcl_DString *srcPtr, /* Source pathname (native). */
- Tcl_DString *ignore, /* Destination pathname (not used). */
- const Tcl_StatBuf *statBufPtr,
- /* Stat info for file specified by srcPtr. */
+ TCL_UNUSED(Tcl_DString *),
+ TCL_UNUSED(const Tcl_StatBuf *),
int type, /* Reason for call - see TraverseUnixTree(). */
Tcl_DString *errorPtr) /* If non-NULL, uninitialized or free DString
* filled with UTF-8 name of file causing
* error. */
{
+
switch (type) {
case DOTREE_F:
if (TclpDeleteFile(Tcl_DStringValue(srcPtr)) == 0) {
@@ -1289,7 +1279,11 @@ TraversalDelete(
static int
CopyFileAtts(
- const char *src, /* Path name of source file (native). */
+#ifdef MAC_OSX_TCL
+ const char *src, /* Path name of source file (native). */
+#else
+ TCL_UNUSED(const char *) /*src*/,
+#endif
const char *dst, /* Path name of target file (native). */
const Tcl_StatBuf *statBufPtr)
/* Stat info for source file */
@@ -1315,8 +1309,8 @@ CopyFileAtts(
}
}
- tval.actime = statBufPtr->st_atime;
- tval.modtime = statBufPtr->st_mtime;
+ tval.actime = Tcl_GetAccessTimeFromStat(statBufPtr);
+ tval.modtime = Tcl_GetModificationTimeFromStat(statBufPtr);
if (utime(dst, &tval)) { /* INTL: Native. */
return TCL_ERROR;
@@ -1347,7 +1341,7 @@ CopyFileAtts(
static int
GetGroupAttribute(
Tcl_Interp *interp, /* The interp we are using for errors. */
- int objIndex, /* The index of the attribute. */
+ TCL_UNUSED(int) /*objIndex*/,
Tcl_Obj *fileName, /* The name of the file (UTF-8). */
Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */
{
@@ -1369,7 +1363,7 @@ GetGroupAttribute(
groupPtr = TclpGetGrGid(statBuf.st_gid);
if (groupPtr == NULL) {
- *attributePtrPtr = Tcl_NewIntObj((int) statBuf.st_gid);
+ *attributePtrPtr = Tcl_NewWideIntObj(statBuf.st_gid);
} else {
Tcl_DString ds;
const char *utf;
@@ -1401,7 +1395,7 @@ GetGroupAttribute(
static int
GetOwnerAttribute(
Tcl_Interp *interp, /* The interp we are using for errors. */
- int objIndex, /* The index of the attribute. */
+ TCL_UNUSED(int) /*objIndex*/,
Tcl_Obj *fileName, /* The name of the file (UTF-8). */
Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */
{
@@ -1423,7 +1417,7 @@ GetOwnerAttribute(
pwPtr = TclpGetPwUid(statBuf.st_uid);
if (pwPtr == NULL) {
- *attributePtrPtr = Tcl_NewIntObj((int) statBuf.st_uid);
+ *attributePtrPtr = Tcl_NewWideIntObj(statBuf.st_uid);
} else {
Tcl_DString ds;
@@ -1453,7 +1447,7 @@ GetOwnerAttribute(
static int
GetPermissionsAttribute(
Tcl_Interp *interp, /* The interp we are using for errors. */
- int objIndex, /* The index of the attribute. */
+ TCL_UNUSED(int) /*objIndex*/,
Tcl_Obj *fileName, /* The name of the file (UTF-8). */
Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */
{
@@ -1495,23 +1489,22 @@ GetPermissionsAttribute(
static int
SetGroupAttribute(
Tcl_Interp *interp, /* The interp for error reporting. */
- int objIndex, /* The index of the attribute. */
+ TCL_UNUSED(int) /*objIndex*/,
Tcl_Obj *fileName, /* The name of the file (UTF-8). */
Tcl_Obj *attributePtr) /* New group for file. */
{
- long gid;
+ Tcl_WideInt gid;
int result;
const char *native;
- if (Tcl_GetLongFromObj(NULL, attributePtr, &gid) != TCL_OK) {
+ if (Tcl_GetWideIntFromObj(NULL, attributePtr, &gid) != TCL_OK) {
Tcl_DString ds;
struct group *groupPtr = NULL;
const char *string;
- int length;
- string = Tcl_GetStringFromObj(attributePtr, &length);
+ string = TclGetString(attributePtr);
- native = Tcl_UtfToExternalDString(NULL, string, length, &ds);
+ native = Tcl_UtfToExternalDString(NULL, string, attributePtr->length, &ds);
groupPtr = TclpGetGrNam(native); /* INTL: Native. */
Tcl_DStringFree(&ds);
@@ -1529,7 +1522,7 @@ SetGroupAttribute(
gid = groupPtr->gr_gid;
}
- native = Tcl_FSGetNativePath(fileName);
+ native = (const char *)Tcl_FSGetNativePath(fileName);
result = chown(native, (uid_t) -1, (gid_t) gid); /* INTL: Native. */
if (result != 0) {
@@ -1562,23 +1555,22 @@ SetGroupAttribute(
static int
SetOwnerAttribute(
Tcl_Interp *interp, /* The interp for error reporting. */
- int objIndex, /* The index of the attribute. */
+ TCL_UNUSED(int) /*objIndex*/,
Tcl_Obj *fileName, /* The name of the file (UTF-8). */
Tcl_Obj *attributePtr) /* New owner for file. */
{
- long uid;
+ Tcl_WideInt uid;
int result;
const char *native;
- if (Tcl_GetLongFromObj(NULL, attributePtr, &uid) != TCL_OK) {
+ if (Tcl_GetWideIntFromObj(NULL, attributePtr, &uid) != TCL_OK) {
Tcl_DString ds;
struct passwd *pwPtr = NULL;
const char *string;
- int length;
- string = Tcl_GetStringFromObj(attributePtr, &length);
+ string = TclGetString(attributePtr);
- native = Tcl_UtfToExternalDString(NULL, string, length, &ds);
+ native = Tcl_UtfToExternalDString(NULL, string, attributePtr->length, &ds);
pwPtr = TclpGetPwNam(native); /* INTL: Native. */
Tcl_DStringFree(&ds);
@@ -1596,7 +1588,7 @@ SetOwnerAttribute(
uid = pwPtr->pw_uid;
}
- native = Tcl_FSGetNativePath(fileName);
+ native = (const char *)Tcl_FSGetNativePath(fileName);
result = chown(native, (uid_t) uid, (gid_t) -1); /* INTL: Native. */
if (result != 0) {
@@ -1629,11 +1621,11 @@ SetOwnerAttribute(
static int
SetPermissionsAttribute(
Tcl_Interp *interp, /* The interp we are using for errors. */
- int objIndex, /* The index of the attribute. */
+ TCL_UNUSED(int) /*objIndex*/,
Tcl_Obj *fileName, /* The name of the file (UTF-8). */
Tcl_Obj *attributePtr) /* The attribute to set. */
{
- long mode;
+ Tcl_WideInt mode;
mode_t newMode;
int result = TCL_ERROR;
const char *native;
@@ -1652,11 +1644,11 @@ SetPermissionsAttribute(
TclNewLiteralStringObj(modeObj, "0o");
Tcl_AppendToObj(modeObj, modeStringPtr+scanned+1, -1);
- result = Tcl_GetLongFromObj(NULL, modeObj, &mode);
+ result = Tcl_GetWideIntFromObj(NULL, modeObj, &mode);
Tcl_DecrRefCount(modeObj);
}
if (result == TCL_OK
- || Tcl_GetLongFromObj(NULL, attributePtr, &mode) == TCL_OK) {
+ || Tcl_GetWideIntFromObj(NULL, attributePtr, &mode) == TCL_OK) {
newMode = (mode_t) (mode & 0x00007FFF);
} else {
Tcl_StatBuf buf;
@@ -1690,7 +1682,7 @@ SetPermissionsAttribute(
}
}
- native = Tcl_FSGetNativePath(fileName);
+ native = (const char *)Tcl_FSGetNativePath(fileName);
result = chmod(native, newMode); /* INTL: Native. */
if (result != 0) {
if (interp != NULL) {
@@ -1751,7 +1743,7 @@ TclpObjListVolumes(void)
static int
GetModeFromPermString(
- Tcl_Interp *interp, /* The interp we are using for errors. */
+ TCL_UNUSED(Tcl_Interp *),
const char *modeStringPtr, /* Permissions string */
mode_t *modePtr) /* pointer to the mode value */
{
@@ -1924,55 +1916,52 @@ GetModeFromPermString(
*
* TclpObjNormalizePath --
*
- * This function scans through a path specification and replaces it, in
- * place, with a normalized version. A normalized version is one in which
- * all symlinks in the path are replaced with their expanded form (except
- * a symlink at the very end of the path).
+ * Replaces each component except that last one in a pathname that is a
+ * symbolic link with the fully resolved target of that link.
*
* Results:
- * The new 'nextCheckpoint' value, giving as far as we could understand
- * in the path.
+ * Stores the resulting path in pathPtr and returns the offset of the last
+ * byte processed to obtain the resulting path.
*
* Side effects:
- * The pathPtr string, is modified.
*
*---------------------------------------------------------------------------
*/
int
TclpObjNormalizePath(
- Tcl_Interp *interp,
- Tcl_Obj *pathPtr,
- int nextCheckpoint)
+ TCL_UNUSED(Tcl_Interp *),
+ Tcl_Obj *pathPtr, /* An unshared object containing the path to
+ * normalize. */
+ int nextCheckpoint) /* offset to start at in pathPtr. Must either
+ * be 0 or the offset of a directory separator
+ * at the end of a path part that is already
+ * normalized. I.e. this is not the index of
+ * the byte just after the separator. */
+
{
const char *currentPathEndPosition;
- int pathLen;
char cur;
- const char *path = Tcl_GetStringFromObj(pathPtr, &pathLen);
+ const char *path = TclGetString(pathPtr);
+ size_t pathLen = pathPtr->length;
Tcl_DString ds;
const char *nativePath;
#ifndef NO_REALPATH
char normPath[MAXPATHLEN];
#endif
- /*
- * We add '1' here because if nextCheckpoint is zero we know that '/'
- * exists, and if it isn't zero, it must point at a directory separator
- * which we also know exists.
- */
-
currentPathEndPosition = path + nextCheckpoint;
if (*currentPathEndPosition == '/') {
currentPathEndPosition++;
}
#ifndef NO_REALPATH
- /*
- * For speed, try to get the entire path in one go.
- */
-
if (nextCheckpoint == 0 && haveRealpath) {
- char *lastDir = strrchr(currentPathEndPosition, '/');
+ /*
+ * Try to get the entire path in one go
+ */
+
+ const char *lastDir = strrchr(currentPathEndPosition, '/');
if (lastDir != NULL) {
nativePath = Tcl_UtfToExternalDString(NULL, path,
@@ -1980,8 +1969,13 @@ TclpObjNormalizePath(
if (Realpath(nativePath, normPath) != NULL) {
if (*nativePath != '/' && *normPath == '/') {
/*
- * realpath has transformed a relative path into an
- * absolute path, we do not know how to handle this.
+ * realpath transformed a relative path into an
+ * absolute path. Fall back to the long way.
+ */
+
+ /*
+ * To do: This logic seems to be out of date. This whole
+ * routine should be reviewed and cleaed up.
*/
} else {
nextCheckpoint = lastDir - path;
@@ -2020,13 +2014,13 @@ TclpObjNormalizePath(
}
/*
- * Update the acceptable point.
+ * Assign the end of the current component to nextCheckpoint
*/
nextCheckpoint = currentPathEndPosition - path;
} else if (cur == 0) {
/*
- * Reached end of string.
+ * The end of the string.
*/
break;
@@ -2035,22 +2029,19 @@ TclpObjNormalizePath(
}
/*
- * We should really now convert this to a canonical path. We do that with
- * 'realpath' if we have it available. Otherwise we could step through
- * every single path component, checking whether it is a symlink, but that
- * would be a lot of work, and most modern OSes have 'realpath'.
+ * Call 'realpath' to obtain a canonical path.
*/
#ifndef NO_REALPATH
if (haveRealpath) {
- /*
- * If we only had '/foo' or '/' then we never increment nextCheckpoint
- * and we don't need or want to go through 'Realpath'. Also, on some
- * platforms, passing an empty string to 'Realpath' will give us the
- * normalized pwd, which is not what we want at all!
- */
-
if (nextCheckpoint == 0) {
+ /*
+ * The path contains at most one component, e.g. '/foo' or '/', so
+ * so there is nothing to resolve. Also, on some platforms
+ * 'Realpath' transforms an empty string into the normalized pwd,
+ * which is the wrong answer.
+ */
+
return 0;
}
@@ -2063,18 +2054,19 @@ TclpObjNormalizePath(
if ((newNormLen == Tcl_DStringLength(&ds))
&& (strcmp(normPath, nativePath) == 0)) {
/*
- * String is unchanged.
+ * The original path is unchanged.
*/
Tcl_DStringFree(&ds);
/*
- * Enable this to have the native FS claim normalization of
- * the whole path for existing files. That would permit the
- * caller to declare normalization complete without calls to
- * additional filesystems. Saving lots of calls is probably
- * worth the extra access() time here. When no other FS's are
- * registered though, things are less clear.
+ * Uncommenting this would mean that this native filesystem
+ * routine claims the path is normalized if the file exists,
+ * which would permit the caller to avoid iterating through
+ * other filesystems filesystems. Saving lots of calls is
+ * probably worth the extra access() time, but in the common
+ * case that no other filesystems are registered this is an
+ * unnecessary expense.
*
if (0 == access(normPath, F_OK)) {
return pathLen;
@@ -2085,8 +2077,7 @@ TclpObjNormalizePath(
}
/*
- * Free up the native path and put in its place the converted,
- * normalized path.
+ * Free the original path and replace it with the normalized path.
*/
Tcl_DStringFree(&ds);
@@ -2094,7 +2085,7 @@ TclpObjNormalizePath(
if (path[nextCheckpoint] != '\0') {
/*
- * Not at end, append remaining path.
+ * Append the remaining path components.
*/
int normLen = Tcl_DStringLength(&ds);
@@ -2103,7 +2094,8 @@ TclpObjNormalizePath(
pathLen - nextCheckpoint);
/*
- * We recognise up to and including the directory separator.
+ * characters up to and including the directory separator have
+ * been processed
*/
nextCheckpoint = normLen + 1;
@@ -2115,10 +2107,6 @@ TclpObjNormalizePath(
nextCheckpoint = Tcl_DStringLength(&ds);
}
- /*
- * Overwrite with the normalized path.
- */
-
Tcl_SetStringObj(pathPtr, Tcl_DStringValue(&ds),
Tcl_DStringLength(&ds));
}
@@ -2175,56 +2163,56 @@ TclUnixOpenTemporaryFile(
Tcl_Obj *extensionObj,
Tcl_Obj *resultingNameObj)
{
- Tcl_DString template, tmp;
+ Tcl_DString templ, tmp;
const char *string;
- int len, fd;
+ int fd;
/*
* We should also check against making more then TMP_MAX of these.
*/
if (dirObj) {
- string = Tcl_GetStringFromObj(dirObj, &len);
- Tcl_UtfToExternalDString(NULL, string, len, &template);
+ string = TclGetString(dirObj);
+ Tcl_UtfToExternalDString(NULL, string, dirObj->length, &templ);
} else {
- Tcl_DStringInit(&template);
- Tcl_DStringAppend(&template, DefaultTempDir(), -1); /* INTL: native */
+ Tcl_DStringInit(&templ);
+ Tcl_DStringAppend(&templ, DefaultTempDir(), -1); /* INTL: native */
}
- TclDStringAppendLiteral(&template, "/");
+ TclDStringAppendLiteral(&templ, "/");
if (basenameObj) {
- string = Tcl_GetStringFromObj(basenameObj, &len);
- Tcl_UtfToExternalDString(NULL, string, len, &tmp);
- TclDStringAppendDString(&template, &tmp);
+ string = TclGetString(basenameObj);
+ Tcl_UtfToExternalDString(NULL, string, basenameObj->length, &tmp);
+ TclDStringAppendDString(&templ, &tmp);
Tcl_DStringFree(&tmp);
} else {
- TclDStringAppendLiteral(&template, "tcl");
+ TclDStringAppendLiteral(&templ, "tcl");
}
- TclDStringAppendLiteral(&template, "_XXXXXX");
+ TclDStringAppendLiteral(&templ, "_XXXXXX");
#ifdef HAVE_MKSTEMPS
if (extensionObj) {
- string = Tcl_GetStringFromObj(extensionObj, &len);
- Tcl_UtfToExternalDString(NULL, string, len, &tmp);
- TclDStringAppendDString(&template, &tmp);
- fd = mkstemps(Tcl_DStringValue(&template), Tcl_DStringLength(&tmp));
+ string = TclGetString(extensionObj);
+ Tcl_UtfToExternalDString(NULL, string, extensionObj->length, &tmp);
+ TclDStringAppendDString(&templ, &tmp);
+ fd = mkstemps(Tcl_DStringValue(&templ), Tcl_DStringLength(&tmp));
Tcl_DStringFree(&tmp);
} else
#endif
{
- fd = mkstemp(Tcl_DStringValue(&template));
+ fd = mkstemp(Tcl_DStringValue(&templ));
}
if (fd == -1) {
- Tcl_DStringFree(&template);
+ Tcl_DStringFree(&templ);
return -1;
}
if (resultingNameObj) {
- Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(&template),
- Tcl_DStringLength(&template), &tmp);
+ Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(&templ),
+ Tcl_DStringLength(&templ), &tmp);
Tcl_SetStringObj(resultingNameObj, Tcl_DStringValue(&tmp),
Tcl_DStringLength(&tmp));
Tcl_DStringFree(&tmp);
@@ -2235,10 +2223,10 @@ TclUnixOpenTemporaryFile(
* this!
*/
- unlink(Tcl_DStringValue(&template));
+ unlink(Tcl_DStringValue(&templ));
errno = 0;
}
- Tcl_DStringFree(&template);
+ Tcl_DStringFree(&templ);
return fd;
}
@@ -2275,6 +2263,85 @@ DefaultTempDir(void)
return TCL_TEMPORARY_FILE_DIRECTORY;
}
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpCreateTemporaryDirectory --
+ *
+ * Creates a temporary directory, possibly based on the supplied bits and
+ * pieces of template supplied in the arguments.
+ *
+ * Results:
+ * An object (refcount 0) containing the name of the newly-created
+ * directory, or NULL on failure.
+ *
+ * Side effects:
+ * Accesses the native filesystem. Makes a directory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclpCreateTemporaryDirectory(
+ Tcl_Obj *dirObj,
+ Tcl_Obj *basenameObj)
+{
+ Tcl_DString templ, tmp;
+ const char *string;
+
+#define DEFAULT_TEMP_DIR_PREFIX "tcl"
+
+ /*
+ * Build the template in writable memory from the user-supplied pieces and
+ * some defaults.
+ */
+
+ if (dirObj) {
+ string = TclGetString(dirObj);
+ Tcl_UtfToExternalDString(NULL, string, dirObj->length, &templ);
+ } else {
+ Tcl_DStringInit(&templ);
+ Tcl_DStringAppend(&templ, DefaultTempDir(), -1); /* INTL: native */
+ }
+
+ if (Tcl_DStringValue(&templ)[Tcl_DStringLength(&templ) - 1] != '/') {
+ TclDStringAppendLiteral(&templ, "/");
+ }
+
+ if (basenameObj) {
+ string = TclGetString(basenameObj);
+ if (basenameObj->length) {
+ Tcl_UtfToExternalDString(NULL, string, basenameObj->length, &tmp);
+ TclDStringAppendDString(&templ, &tmp);
+ Tcl_DStringFree(&tmp);
+ } else {
+ TclDStringAppendLiteral(&templ, DEFAULT_TEMP_DIR_PREFIX);
+ }
+ } else {
+ TclDStringAppendLiteral(&templ, DEFAULT_TEMP_DIR_PREFIX);
+ }
+
+ TclDStringAppendLiteral(&templ, "_XXXXXX");
+
+ /*
+ * Make the temporary directory.
+ */
+
+ if (mkdtemp(Tcl_DStringValue(&templ)) == NULL) {
+ Tcl_DStringFree(&templ);
+ return NULL;
+ }
+
+ /*
+ * The template has been updated. Tell the caller what it was.
+ */
+
+ Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(&templ),
+ Tcl_DStringLength(&templ), &tmp);
+ Tcl_DStringFree(&templ);
+ return TclDStringToObj(&tmp);
+}
+
#if defined(__CYGWIN__)
static void
@@ -2293,42 +2360,45 @@ winPathFromObj(
Tcl_Obj *fileName)
{
int size;
- const char *native = Tcl_FSGetNativePath(fileName);
+ const char *native = (const char *)Tcl_FSGetNativePath(fileName);
WCHAR *winPath;
size = cygwin_conv_path(1, native, NULL, 0);
- winPath = ckalloc(size);
+ winPath = (WCHAR *)ckalloc(size);
cygwin_conv_path(1, native, winPath, size);
return winPath;
}
static const int attributeArray[] = {
- 0x20, 0, 2, 0, 0, 1, 4};
+ 0x20, 0, 2, 0, 0, 1, 4
+};
/*
*----------------------------------------------------------------------
*
* GetUnixFileAttributes
*
- * Gets the readonly attribute of a file.
+ * Gets an attribute of a file.
*
* Results:
- * Standard TCL result. Returns a new Tcl_Obj in attributePtrPtr if there
- * is no error. The object will have ref count 0.
+ * A standard Tcl result.
*
* Side effects:
- * A new object is allocated.
+ * If there is no error assigns to *attributePtrPtr the address of a new
+ * Tcl_Obj having a refCount of zero and containing the value of the
+ * specified attribute.
+ *
*
*----------------------------------------------------------------------
*/
static int
GetUnixFileAttributes(
- Tcl_Interp *interp, /* The interp we are using for errors. */
+ Tcl_Interp *interp, /* The interp to report errors to. */
int objIndex, /* The index of the attribute. */
- Tcl_Obj *fileName, /* The name of the file (UTF-8). */
- Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */
+ Tcl_Obj *fileName, /* The pathname of the file (UTF-8). */
+ Tcl_Obj **attributePtrPtr) /* Where to store the result. */
{
int fileAttributes;
WCHAR *winPath = winPathFromObj(fileName);
@@ -2341,8 +2411,8 @@ GetUnixFileAttributes(
return TCL_ERROR;
}
- *attributePtrPtr = Tcl_NewIntObj((fileAttributes&attributeArray[objIndex])!=0);
-
+ *attributePtrPtr = Tcl_NewWideIntObj(
+ (fileAttributes & attributeArray[objIndex]) != 0);
return TCL_OK;
}
@@ -2399,7 +2469,7 @@ SetUnixFileAttributes(
return TCL_ERROR;
}
- ckfree(winPath);
+ ckfree(winPath);
return TCL_OK;
}
#elif defined(HAVE_CHFLAGS) && defined(UF_IMMUTABLE)
@@ -2423,7 +2493,7 @@ SetUnixFileAttributes(
static int
GetUnixFileAttributes(
Tcl_Interp *interp, /* The interp we are using for errors. */
- int objIndex, /* The index of the attribute. */
+ TCL_UNUSED(int) /*objIndex*/,
Tcl_Obj *fileName, /* The name of the file (UTF-8). */
Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */
{
@@ -2441,8 +2511,7 @@ GetUnixFileAttributes(
return TCL_ERROR;
}
- *attributePtrPtr = Tcl_NewBooleanObj(statBuf.st_flags&UF_IMMUTABLE);
-
+ *attributePtrPtr = Tcl_NewWideIntObj((statBuf.st_flags & UF_IMMUTABLE) != 0);
return TCL_OK;
}
@@ -2465,7 +2534,7 @@ GetUnixFileAttributes(
static int
SetUnixFileAttributes(
Tcl_Interp *interp, /* The interp we are using for errors. */
- int objIndex, /* The index of the attribute. */
+ TCL_UNUSED(int) /*objIndex*/,
Tcl_Obj *fileName, /* The name of the file (UTF-8). */
Tcl_Obj *attributePtr) /* The attribute to set. */
{
@@ -2494,7 +2563,7 @@ SetUnixFileAttributes(
statBuf.st_flags &= ~UF_IMMUTABLE;
}
- native = Tcl_FSGetNativePath(fileName);
+ native = (const char *)Tcl_FSGetNativePath(fileName);
result = chflags(native, statBuf.st_flags); /* INTL: Native. */
if (result != 0) {
if (interp != NULL) {