From d6dcec526db6ac58027be54be977dc50d5b559b3 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 5 Feb 2015 23:28:17 -0800 Subject: Making the gpr_tmpfile's win32 version a bit more Windows-y. Also adding windows helpers to convert to and from TCHAR strings. --- build.json | 1 + src/core/support/env_win32.c | 1 + src/core/support/file_win32.c | 51 +++++++++++++++++++---------------- src/core/support/string_win32.c | 29 ++++++++++++++++++++ src/core/support/string_win32.h | 49 +++++++++++++++++++++++++++++++++ vsprojects/vs2013/gpr.vcxproj | 1 + vsprojects/vs2013/gpr.vcxproj.filters | 3 +++ 7 files changed, 112 insertions(+), 23 deletions(-) create mode 100644 src/core/support/string_win32.h diff --git a/build.json b/build.json index 170b148067..579ede329f 100644 --- a/build.json +++ b/build.json @@ -231,6 +231,7 @@ "src/core/support/file.h", "src/core/support/murmur_hash.h", "src/core/support/string.h", + "src/core/support/string_win32.h", "src/core/support/thd_internal.h" ], "src": [ diff --git a/src/core/support/env_win32.c b/src/core/support/env_win32.c index a31fa79d68..3159c20f7d 100644 --- a/src/core/support/env_win32.c +++ b/src/core/support/env_win32.c @@ -39,6 +39,7 @@ #include +#include #include char *gpr_getenv(const char *name) { diff --git a/src/core/support/file_win32.c b/src/core/support/file_win32.c index d415281e0d..af7eebe3de 100644 --- a/src/core/support/file_win32.c +++ b/src/core/support/file_win32.c @@ -35,43 +35,48 @@ #ifdef GPR_WIN32 -#include "src/core/support/file.h" - #include #include #include +#include #include #include -FILE *gpr_tmpfile(const char *prefix, char **tmp_filename) { +#include "src/core/support/file.h" +#include "src/core/support/string_win32.h" + +FILE *gpr_tmpfile(const char *prefix, char **tmp_filename_out) { FILE *result = NULL; - char *template; + LPTSTR template_string = NULL; + TCHAR tmp_path[MAX_PATH]; + TCHAR tmp_filename[MAX_PATH]; + DWORD status; + UINT success; - if (tmp_filename != NULL) *tmp_filename = NULL; + if (tmp_filename_out != NULL) *tmp_filename_out = NULL; - gpr_asprintf(&template, "%s_XXXXXX", prefix); - GPR_ASSERT(template != NULL); + /* Convert our prefix to TCHAR. */ + template_string = gpr_char_to_tchar(prefix); + GPR_ASSERT(template_string); - /* _mktemp_s can only create a maximum of 26 file names for any combination of - base and template values which is kind of sad... We may revisit this - function later to have something better... */ - if (_mktemp_s(template, strlen(template) + 1) != 0) { - gpr_log(LOG_ERROR, "Could not create tmp file."); - goto end; - } - if (fopen_s(&result, template, "wb+") != 0) { - gpr_log(GPR_ERROR, "Could not open file %s", template); - result = NULL; - goto end; - } + /* Get the path to the best temporary folder available. */ + status = GetTempPath(MAX_PATH, tmp_path); + if (status == 0 || status > MAX_PATH) goto end; + + /* Generate a unique filename with our template + temporary path. */ + success = GetTempFileName(tmp_path, template_string, 0, tmp_filename); + if (!success) goto end; + + /* Open a file there. */ + if (_tfopen_s(&result, tmp_filename, TEXT("wb+")) != 0) goto end; end: - if (result != NULL && tmp_filename != NULL) { - *tmp_filename = template; - } else { - gpr_free(template); + if (result && tmp_filename) { + *tmp_filename_out = gpr_tchar_to_char(tmp_filename); } + + gpr_free(tmp_filename); return result; } diff --git a/src/core/support/string_win32.c b/src/core/support/string_win32.c index 1c4c8547dc..02e1c74d9c 100644 --- a/src/core/support/string_win32.c +++ b/src/core/support/string_win32.c @@ -37,6 +37,7 @@ #ifdef GPR_WIN32 +#include #include #include #include @@ -78,4 +79,32 @@ int gpr_asprintf(char **strp, const char *format, ...) { return -1; } +#if defined UNICODE || defined _UNICODE +LPTSTR gpr_char_to_tchar(LPCSTR input) { + LPTSTR ret; + int needed = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0); + if (needed == 0) return NULL; + ret = gpr_malloc(needed * sizeof(TCHAR)); + MultiByteToWideChar(CP_UTF8, 0, input, -1, ret, needed); + return ret; +} + +LPSTR gpr_tchar_to_char(LPCTSTR input) { + LPSTR ret; + int needed = WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL); + if (needed == 0) return NULL; + ret = gpr_malloc(needed); + WideCharToMultiByte(CP_UTF8, 0, input, -1, ret, needed, NULL, NULL); + return ret; +} +#else +char *gpr_tchar_to_char(LPTSTR input) { + return gpr_strdup(input); +} + +char *gpr_char_to_tchar(LPTSTR input) { + return gpr_strdup(input); +} +#endif + #endif /* GPR_WIN32 */ diff --git a/src/core/support/string_win32.h b/src/core/support/string_win32.h new file mode 100644 index 0000000000..9102d98256 --- /dev/null +++ b/src/core/support/string_win32.h @@ -0,0 +1,49 @@ +/* + * + * Copyright 2014, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __GRPC_SUPPORT_STRING_WIN32_H__ +#define __GRPC_SUPPORT_STRING_WIN32_H__ + +#include + +#ifdef GPR_WIN32 + +#include + +/* These allocate new strings using gpr_malloc to convert from and to utf-8. */ +LPTSTR gpr_char_to_tchar(LPCSTR input); +LPSTR gpr_tchar_to_char(LPCTSTR input); + +#endif /* GPR_WIN32 */ + +#endif /* __GRPC_SUPPORT_STRING_WIN32_H__ */ diff --git a/vsprojects/vs2013/gpr.vcxproj b/vsprojects/vs2013/gpr.vcxproj index d1f7085383..8276082cfd 100644 --- a/vsprojects/vs2013/gpr.vcxproj +++ b/vsprojects/vs2013/gpr.vcxproj @@ -100,6 +100,7 @@ + diff --git a/vsprojects/vs2013/gpr.vcxproj.filters b/vsprojects/vs2013/gpr.vcxproj.filters index 13add834a8..2329acc9da 100644 --- a/vsprojects/vs2013/gpr.vcxproj.filters +++ b/vsprojects/vs2013/gpr.vcxproj.filters @@ -176,6 +176,9 @@ src\core\support + + src\core\support + src\core\support -- cgit v1.2.3