diff --git a/build.json b/build.json index 170b148067181accf61e7b819cee26fa70b21e76..579ede329f6795b9911e578f26f97eb92957497b 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 a31fa79d68ea61db226d8591b7aabb56241ceb9b..3159c20f7d7a164e504c3908db640b5a385647fc 100644 --- a/src/core/support/env_win32.c +++ b/src/core/support/env_win32.c @@ -39,6 +39,7 @@ #include <stdlib.h> +#include <grpc/support/alloc.h> #include <grpc/support/log.h> char *gpr_getenv(const char *name) { diff --git a/src/core/support/file_win32.c b/src/core/support/file_win32.c index d415281e0d37b4e5e13635b5f298998347ca0126..af7eebe3de813588f5af654473741c7dc575ff56 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 <io.h> #include <stdio.h> #include <string.h> +#include <tchar.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> -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 1c4c8547dc931b4bebf4d4650c9605b2cc23850b..02e1c74d9cefcd81919c44a7cf1c8e620cf6b06a 100644 --- a/src/core/support/string_win32.c +++ b/src/core/support/string_win32.c @@ -37,6 +37,7 @@ #ifdef GPR_WIN32 +#include <windows.h> #include <stdio.h> #include <stdarg.h> #include <string.h> @@ -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 0000000000000000000000000000000000000000..9102d98256964dff3a5027510aec357015b4c88a --- /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 <grpc/support/port_platform.h> + +#ifdef GPR_WIN32 + +#include <windows.h> + +/* 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 d1f70853839258a8bcf7278b19723f9bb0270d82..8276082cfdaee5ae5bc64d91a3eebbd946074ba0 100644 --- a/vsprojects/vs2013/gpr.vcxproj +++ b/vsprojects/vs2013/gpr.vcxproj @@ -100,6 +100,7 @@ <ClInclude Include="..\..\src\core\support\file.h" /> <ClInclude Include="..\..\src\core\support\murmur_hash.h" /> <ClInclude Include="..\..\src\core\support\string.h" /> + <ClInclude Include="..\..\src\core\support\string_win32.h" /> <ClInclude Include="..\..\src\core\support\thd_internal.h" /> </ItemGroup> <ItemGroup> diff --git a/vsprojects/vs2013/gpr.vcxproj.filters b/vsprojects/vs2013/gpr.vcxproj.filters index 13add834a88b9d976f4b676ebfe5f845cda9e652..2329acc9daee8ef6371e7d469edbe2306ddb188c 100644 --- a/vsprojects/vs2013/gpr.vcxproj.filters +++ b/vsprojects/vs2013/gpr.vcxproj.filters @@ -176,6 +176,9 @@ <ClInclude Include="..\..\src\core\support\string.h"> <Filter>src\core\support</Filter> </ClInclude> + <ClInclude Include="..\..\src\core\support\string_win32.h"> + <Filter>src\core\support</Filter> + </ClInclude> <ClInclude Include="..\..\src\core\support\thd_internal.h"> <Filter>src\core\support</Filter> </ClInclude>