From: Gurusamy Sarathy Date: Mon, 7 Feb 2000 11:47:06 +0000 (+0000) Subject: various Windows tweaks: make $^E a little less buggy by saving X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=e9ff6d2717dce18093d60b3839463976bb523752;p=p5sagit%2Fp5-mst-13.2.git various Windows tweaks: make $^E a little less buggy by saving and restoring system error across TLS fetch; avoid needless copying of buffers p4raw-id: //depot/perl@5024 --- diff --git a/win32/Makefile b/win32/Makefile index e482037..6bf5e6e 100644 --- a/win32/Makefile +++ b/win32/Makefile @@ -432,7 +432,7 @@ $(o).dll: -out:$@ $(LINK_FLAGS) $(LIBFILES) $< $(LIBPERL) .rc.res: - $(RSC) $< + $(RSC) -i.. $< # # various targets diff --git a/win32/makefile.mk b/win32/makefile.mk index 6327bee..64f89fd 100644 --- a/win32/makefile.mk +++ b/win32/makefile.mk @@ -540,7 +540,7 @@ $(o).dll: .ENDIF .rc.res: - $(RSC) $< + $(RSC) -i.. $< # # various targets diff --git a/win32/perllib.c b/win32/perllib.c index 84a2a6d..26135f8 100644 --- a/win32/perllib.c +++ b/win32/perllib.c @@ -259,13 +259,19 @@ static DWORD g_TlsAllocIndex; EXTERN_C DllExport bool SetPerlInterpreter(void *interp) { - return TlsSetValue(g_TlsAllocIndex, interp); + DWORD dwErr = GetLastError(); + bool bResult = TlsSetValue(g_TlsAllocIndex, interp); + SetLastError(dwErr); + return bResult; } EXTERN_C DllExport void* GetPerlInterpreter(void) { - return TlsGetValue(g_TlsAllocIndex); + DWORD dwErr = GetLastError(); + LPVOID pResult = TlsGetValue(g_TlsAllocIndex); + SetLastError(dwErr); + return pResult; } EXTERN_C DllExport int diff --git a/win32/win32.c b/win32/win32.c index 86bfbb9..71097ea 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -1037,6 +1037,7 @@ win32_stat(const char *path, struct stat *sbuf) int l = strlen(path); int res; WCHAR wbuffer[MAX_PATH+1]; + WCHAR* pwbuffer; HANDLE handle; int nlink = 1; @@ -1069,12 +1070,13 @@ win32_stat(const char *path, struct stat *sbuf) /* This also gives us an opportunity to determine the number of links. */ if (USING_WIDE()) { A2WHELPER(path, wbuffer, sizeof(wbuffer)); - wcscpy(wbuffer, PerlDir_mapW(wbuffer)); - handle = CreateFileW(wbuffer, 0, 0, NULL, OPEN_EXISTING, 0, NULL); + pwbuffer = PerlDir_mapW(wbuffer); + handle = CreateFileW(pwbuffer, 0, 0, NULL, OPEN_EXISTING, 0, NULL); } else { - strcpy(buffer, PerlDir_mapA(path)); - handle = CreateFileA(buffer, 0, 0, NULL, OPEN_EXISTING, 0, NULL); + path = PerlDir_mapA(path); + l = strlen(path); + handle = CreateFileA(path, 0, 0, NULL, OPEN_EXISTING, 0, NULL); } if (handle != INVALID_HANDLE_VALUE) { BY_HANDLE_FILE_INFORMATION bhi; @@ -1083,12 +1085,12 @@ win32_stat(const char *path, struct stat *sbuf) CloseHandle(handle); } - /* wbuffer or path will be mapped correctly above */ + /* pwbuffer or path will be mapped correctly above */ if (USING_WIDE()) { - res = _wstat(wbuffer, (struct _stat *)sbuf); + res = _wstat(pwbuffer, (struct _stat *)sbuf); } else { - res = stat(buffer, sbuf); + res = stat(path, sbuf); } sbuf->st_nlink = nlink; @@ -1099,10 +1101,10 @@ win32_stat(const char *path, struct stat *sbuf) * Windows of 1995) */ DWORD r; if (USING_WIDE()) { - r = GetFileAttributesW(wbuffer); + r = GetFileAttributesW(pwbuffer); } else { - r = GetFileAttributesA(buffer); + r = GetFileAttributesA(path); } if (r != 0xffffffff && (r & FILE_ATTRIBUTE_DIRECTORY)) { /* sbuf may still contain old garbage since stat() failed */ @@ -1120,8 +1122,8 @@ win32_stat(const char *path, struct stat *sbuf) { /* The drive can be inaccessible, some _stat()s are buggy */ if (USING_WIDE() - ? !GetVolumeInformationW(wbuffer,NULL,0,NULL,NULL,NULL,NULL,0) - : !GetVolumeInformationA(buffer,NULL,0,NULL,NULL,NULL,NULL,0)) { + ? !GetVolumeInformationW(pwbuffer,NULL,0,NULL,NULL,NULL,NULL,0) + : !GetVolumeInformationA(path,NULL,0,NULL,NULL,NULL,NULL,0)) { errno = ENOENT; return -1; } @@ -1396,35 +1398,35 @@ win32_unlink(const char *filename) if (USING_WIDE()) { WCHAR wBuffer[MAX_PATH+1]; + WCHAR* pwBuffer; A2WHELPER(filename, wBuffer, sizeof(wBuffer)); - wcscpy(wBuffer, PerlDir_mapW(wBuffer)); - attrs = GetFileAttributesW(wBuffer); + pwBuffer = PerlDir_mapW(wBuffer); + attrs = GetFileAttributesW(pwBuffer); if (attrs == 0xFFFFFFFF) goto fail; if (attrs & FILE_ATTRIBUTE_READONLY) { - (void)SetFileAttributesW(wBuffer, attrs & ~FILE_ATTRIBUTE_READONLY); - ret = _wunlink(wBuffer); + (void)SetFileAttributesW(pwBuffer, attrs & ~FILE_ATTRIBUTE_READONLY); + ret = _wunlink(pwBuffer); if (ret == -1) - (void)SetFileAttributesW(wBuffer, attrs); + (void)SetFileAttributesW(pwBuffer, attrs); } else - ret = _wunlink(wBuffer); + ret = _wunlink(pwBuffer); } else { - char buffer[MAX_PATH+1]; - strcpy(buffer, PerlDir_mapA(filename)); - attrs = GetFileAttributesA(buffer); + filename = PerlDir_mapA(filename); + attrs = GetFileAttributesA(filename); if (attrs == 0xFFFFFFFF) goto fail; if (attrs & FILE_ATTRIBUTE_READONLY) { - (void)SetFileAttributesA(buffer, attrs & ~FILE_ATTRIBUTE_READONLY); - ret = unlink(buffer); + (void)SetFileAttributesA(filename, attrs & ~FILE_ATTRIBUTE_READONLY); + ret = unlink(filename); if (ret == -1) - (void)SetFileAttributesA(buffer, attrs); + (void)SetFileAttributesA(filename, attrs); } else - ret = unlink(buffer); + ret = unlink(filename); } return ret; fail: @@ -1442,17 +1444,17 @@ win32_utime(const char *filename, struct utimbuf *times) FILETIME ftWrite; struct utimbuf TimeBuffer; WCHAR wbuffer[MAX_PATH+1]; - char buffer[MAX_PATH+1]; + WCHAR* pwbuffer; int rc; if (USING_WIDE()) { A2WHELPER(filename, wbuffer, sizeof(wbuffer)); - wcscpy(wbuffer, PerlDir_mapW(wbuffer)); - rc = _wutime(wbuffer, (struct _utimbuf*)times); + pwbuffer = PerlDir_mapW(wbuffer); + rc = _wutime(pwbuffer, (struct _utimbuf*)times); } else { - strcpy(buffer, PerlDir_mapA(filename)); - rc = utime(buffer, times); + filename = PerlDir_mapA(filename); + rc = utime(filename, times); } /* EACCES: path specifies directory or readonly file */ if (rc == 0 || errno != EACCES /* || !IsWinNT() */) @@ -1466,12 +1468,12 @@ win32_utime(const char *filename, struct utimbuf *times) /* This will (and should) still fail on readonly files */ if (USING_WIDE()) { - handle = CreateFileW(wbuffer, GENERIC_READ | GENERIC_WRITE, + handle = CreateFileW(pwbuffer, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); } else { - handle = CreateFileA(buffer, GENERIC_READ | GENERIC_WRITE, + handle = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); } diff --git a/win32/win32.h b/win32/win32.h index f8e8dc7..924ce8a 100644 --- a/win32/win32.h +++ b/win32/win32.h @@ -422,13 +422,15 @@ struct interp_intern { /* Use CP_ACP when mode is ANSI */ /* Use CP_UTF8 when mode is UTF8 */ -#define A2WHELPER(lpa, lpw, nBytes)\ - lpw[0] = 0, MultiByteToWideChar((IN_BYTE) ? CP_ACP : CP_UTF8, 0, \ - lpa, -1, lpw, (nBytes/sizeof(WCHAR))) - -#define W2AHELPER(lpw, lpa, nChars)\ - lpa[0] = '\0', WideCharToMultiByte((IN_BYTE) ? CP_ACP : CP_UTF8, 0, \ - lpw, -1, (LPSTR)lpa, nChars, NULL, NULL) +#define A2WHELPER_LEN(lpa, alen, lpw, nBytes)\ + (lpw[0] = 0, MultiByteToWideChar((IN_BYTE) ? CP_ACP : CP_UTF8, 0, \ + lpa, alen, lpw, (nBytes/sizeof(WCHAR)))) +#define A2WHELPER(lpa, lpw, nBytes) A2WHELPER_LEN(lpa, -1, lpw, nBytes) + +#define W2AHELPER_LEN(lpw, wlen, lpa, nChars)\ + (lpa[0] = '\0', WideCharToMultiByte((IN_BYTE) ? CP_ACP : CP_UTF8, 0, \ + lpw, wlen, (LPSTR)lpa, nChars,NULL,NULL)) +#define W2AHELPER(lpw, lpa, nChars) W2AHELPER_LEN(lpw, -1, lpa, nChars) #define USING_WIDE() (PL_bigchar && PerlEnv_os_id() == VER_PLATFORM_WIN32_NT)