📄 tclwinfile.c
字号:
} } } } Tcl_DStringFree(&buffer); FindClose(handle); ckfree(newPattern); return result;}/* *---------------------------------------------------------------------- * * TclChdir -- * * Change the current working directory. * * Results: * The result is a standard Tcl result. If an error occurs and * interp isn't NULL, an error message is left in interp->result. * * Side effects: * The working directory for this application is changed. Also * the cache maintained used by TclGetCwd is deallocated and * set to NULL. * *---------------------------------------------------------------------- */intTclChdir(interp, dirName) Tcl_Interp *interp; /* If non NULL, used for error reporting. */ char *dirName; /* Path to new working directory. */{ if (currentDir != NULL) { ckfree(currentDir); currentDir = NULL; } if (!SetCurrentDirectory(dirName)) { TclWinConvertError(GetLastError()); if (interp != NULL) { Tcl_AppendResult(interp, "couldn't change working directory to \"", dirName, "\": ", Tcl_PosixError(interp), (char *) NULL); } return TCL_ERROR; } return TCL_OK;}/* *---------------------------------------------------------------------- * * TclGetCwd -- * * Return the path name of the current working directory. * * Results: * The result is the full path name of the current working * directory, or NULL if an error occurred while figuring it * out. If an error occurs and interp isn't NULL, an error * message is left in interp->result. * * Side effects: * The path name is cached to avoid having to recompute it * on future calls; if it is already cached, the cached * value is returned. * *---------------------------------------------------------------------- */char *TclGetCwd(interp) Tcl_Interp *interp; /* If non NULL, used for error reporting. */{ static char buffer[MAXPATHLEN+1]; char *bufPtr, *p; if (currentDir == NULL) { if (GetCurrentDirectory(MAXPATHLEN+1, buffer) == 0) { TclWinConvertError(GetLastError()); if (interp != NULL) { if (errno == ERANGE) { Tcl_SetResult(interp, "working directory name is too long", TCL_STATIC); } else { Tcl_AppendResult(interp, "error getting working directory name: ", Tcl_PosixError(interp), (char *) NULL); } } return NULL; } /* * Watch for the wierd Windows '95 c:\\UNC syntax. */ if (buffer[0] != '\0' && buffer[1] == ':' && buffer[2] == '\\' && buffer[3] == '\\') { bufPtr = &buffer[2]; } else { bufPtr = buffer; } /* * Convert to forward slashes for easier use in scripts. */ for (p = bufPtr; *p != '\0'; p++) { if (*p == '\\') { *p = '/'; } } } return bufPtr;}#if 0/* *------------------------------------------------------------------------- * * TclWinResolveShortcut -- * * Resolve a potential Windows shortcut to get the actual file or * directory in question. * * Results: * Returns 1 if the shortcut could be resolved, or 0 if there was * an error or if the filename was not a shortcut. * If bufferPtr did hold the name of a shortcut, it is modified to * hold the resolved target of the shortcut instead. * * Side effects: * Loads and unloads OLE package to determine if filename refers to * a shortcut. * *------------------------------------------------------------------------- */intTclWinResolveShortcut(bufferPtr) Tcl_DString *bufferPtr; /* Holds name of file to resolve. On * return, holds resolved file name. */{ HRESULT hres; IShellLink *psl; IPersistFile *ppf; WIN32_FIND_DATA wfd; WCHAR wpath[MAX_PATH]; char *path, *ext; char realFileName[MAX_PATH]; /* * Windows system calls do not automatically resolve * shortcuts like UNIX automatically will with symbolic links. */ path = Tcl_DStringValue(bufferPtr); ext = strrchr(path, '.'); if ((ext == NULL) || (stricmp(ext, ".lnk") != 0)) { return 0; } CoInitialize(NULL); path = Tcl_DStringValue(bufferPtr); realFileName[0] = '\0'; hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, &psl); if (SUCCEEDED(hres)) { hres = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, &ppf); if (SUCCEEDED(hres)) { MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, sizeof(wpath)); hres = ppf->lpVtbl->Load(ppf, wpath, STGM_READ); if (SUCCEEDED(hres)) { hres = psl->lpVtbl->Resolve(psl, NULL, SLR_ANY_MATCH | SLR_NO_UI); if (SUCCEEDED(hres)) { hres = psl->lpVtbl->GetPath(psl, realFileName, MAX_PATH, &wfd, 0); } } ppf->lpVtbl->Release(ppf); } psl->lpVtbl->Release(psl); } CoUninitialize(); if (realFileName[0] != '\0') { Tcl_DStringSetLength(bufferPtr, 0); Tcl_DStringAppend(bufferPtr, realFileName, -1); return 1; } return 0;}#endif/* *---------------------------------------------------------------------- * * TclpStat, TclpLstat -- * * These functions replace the library versions of stat and lstat. * * The stat and lstat functions provided by some Windows compilers * are incomplete. Ideally, a complete rewrite of stat would go * here; now, the only fix is that stat("c:") used to return an * error instead infor for current dir on specified drive. * * Results: * See stat documentation. * * Side effects: * See stat documentation. * *---------------------------------------------------------------------- */intTclpStat(path, buf) CONST char *path; /* Path of file to stat (in current CP). */ struct stat *buf; /* Filled with results of stat call. */{ char name[4]; int result; if ((strlen(path) == 2) && (path[1] == ':')) { strcpy(name, path); name[2] = '.'; name[3] = '\0'; path = name; }#undef stat result = stat(path, buf);#ifndef _MSC_VER /* * Borland's stat doesn't take into account localtime. */ if ((result == 0) && (buf->st_mtime != 0)) { TIME_ZONE_INFORMATION tz; int time, bias; time = GetTimeZoneInformation(&tz); bias = tz.Bias; if (time == TIME_ZONE_ID_DAYLIGHT) { bias += tz.DaylightBias; } bias *= 60; buf->st_atime -= bias; buf->st_ctime -= bias; buf->st_mtime -= bias; }#endif return result;}/* *--------------------------------------------------------------------------- * * TclpAccess -- * * This function replaces the library version of access. * * The library version of access returns that all files have execute * permission. * * Results: * See access documentation. * * Side effects: * See access documentation. * *--------------------------------------------------------------------------- */intTclpAccess( CONST char *path, /* Path of file to access (in current CP). */ int mode) /* Permission setting. */{ int result; CONST char *p;#undef access result = access(path, mode); if (result == 0) { if (mode & 1) { if (GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY) { /* * Directories are always executable. */ return 0; } p = strrchr(path, '.'); if (p != NULL) { p++; if ((stricmp(p, "exe") == 0) || (stricmp(p, "com") == 0) || (stricmp(p, "bat") == 0)) { /* * File that ends with .exe, .com, or .bat is executable. */ return 0; } } errno = EACCES; return -1; } } return result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -