diff --git a/flang/include/flang/Runtime/extensions.h b/flang/include/flang/Runtime/extensions.h index b34edb94ada43..1ed750f3b70e0 100644 --- a/flang/include/flang/Runtime/extensions.h +++ b/flang/include/flang/Runtime/extensions.h @@ -30,10 +30,10 @@ std::int32_t FORTRAN_PROCEDURE_NAME(iargc)(); // GNU Fortran 77 compatibility subroutine GETARG(N, ARG). void FORTRAN_PROCEDURE_NAME(getarg)( - std::int32_t &n, std::int8_t *arg, std::int64_t length); + std::int32_t &n, char *arg, std::int64_t length); // GNU extension subroutine GETLOG(C). -void FORTRAN_PROCEDURE_NAME(getlog)(std::byte *name, std::int64_t length); +void FORTRAN_PROCEDURE_NAME(getlog)(char *name, std::int64_t length); } // extern "C" #endif // FORTRAN_RUNTIME_EXTENSIONS_H_ diff --git a/flang/runtime/execute.cpp b/flang/runtime/execute.cpp index c327f07f5cbff..097d0b50f9722 100644 --- a/flang/runtime/execute.cpp +++ b/flang/runtime/execute.cpp @@ -151,19 +151,19 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait, // add "cmd.exe /c " to the beginning of command const char *prefix{"cmd.exe /c "}; - char *newCmdWin{(char *)AllocateMemoryOrCrash( - terminator, std::strlen(prefix) + std::strlen(newCmd) + 1)}; + char *newCmdWin{static_cast(AllocateMemoryOrCrash( + terminator, std::strlen(prefix) + std::strlen(newCmd) + 1))}; std::strcpy(newCmdWin, prefix); std::strcat(newCmdWin, newCmd); // Convert the char to wide char const size_t sizeNeeded{mbstowcs(NULL, newCmdWin, 0) + 1}; - wchar_t *wcmd{(wchar_t *)AllocateMemoryOrCrash( - terminator, sizeNeeded * sizeof(wchar_t))}; + wchar_t *wcmd{static_cast( + AllocateMemoryOrCrash(terminator, sizeNeeded * sizeof(wchar_t)))}; if (std::mbstowcs(wcmd, newCmdWin, sizeNeeded) == static_cast(-1)) { terminator.Crash("Char to wide char failed for newCmd"); } - FreeMemory((void *)newCmdWin); + FreeMemory(newCmdWin); if (CreateProcess(nullptr, wcmd, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi)) { @@ -179,7 +179,7 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait, CheckAndCopyCharsToDescriptor(cmdmsg, "CreateProcess failed."); } } - FreeMemory((void *)wcmd); + FreeMemory(wcmd); #else // terminated children do not become zombies signal(SIGCHLD, SIG_IGN); @@ -200,7 +200,7 @@ void RTNAME(ExecuteCommandLine)(const Descriptor &command, bool wait, } // Deallocate memory if EnsureNullTerminated dynamically allocated memory if (newCmd != command.OffsetElement()) { - FreeMemory((void *)newCmd); + FreeMemory(newCmd); } } diff --git a/flang/runtime/extensions.cpp b/flang/runtime/extensions.cpp index 352da8f11d9d5..38a0633a3648d 100644 --- a/flang/runtime/extensions.cpp +++ b/flang/runtime/extensions.cpp @@ -47,8 +47,7 @@ extern "C" { namespace Fortran::runtime { -void GetUsernameEnvVar( - const char *envName, std::byte *arg, std::int64_t length) { +void GetUsernameEnvVar(const char *envName, char *arg, std::int64_t length) { Descriptor name{*Descriptor::Create( 1, std::strlen(envName) + 1, const_cast(envName), 0)}; Descriptor value{*Descriptor::Create(1, length, arg, 0)}; @@ -91,36 +90,23 @@ std::int32_t FORTRAN_PROCEDURE_NAME(iargc)() { return RTNAME(ArgumentCount)(); } // CALL GETARG(N, ARG) void FORTRAN_PROCEDURE_NAME(getarg)( - std::int32_t &n, std::int8_t *arg, std::int64_t length) { + std::int32_t &n, char *arg, std::int64_t length) { Descriptor value{*Descriptor::Create(1, length, arg, 0)}; (void)RTNAME(GetCommandArgument)( n, &value, nullptr, nullptr, __FILE__, __LINE__); } // CALL GETLOG(USRNAME) -void FORTRAN_PROCEDURE_NAME(getlog)(std::byte *arg, std::int64_t length) { +void FORTRAN_PROCEDURE_NAME(getlog)(char *arg, std::int64_t length) { #if _REENTRANT || _POSIX_C_SOURCE >= 199506L - int nameMaxLen; -#ifdef LOGIN_NAME_MAX - nameMaxLen = LOGIN_NAME_MAX + 1; -#else - nameMaxLen = sysconf(_SC_LOGIN_NAME_MAX) + 1; - if (nameMaxLen == -1) - nameMaxLen = _POSIX_LOGIN_NAME_MAX + 1; -#endif - std::vector str(nameMaxLen); - - int error{getlogin_r(str.data(), nameMaxLen)}; - if (error == 0) { - // no error: find first \0 in string then pad from there - CopyAndPad(reinterpret_cast(arg), str.data(), length, - std::strlen(str.data())); - } else { - // error occur: get username from environment variable - GetUsernameEnvVar("LOGNAME", arg, length); + if (length >= 1 && getlogin_r(arg, length) == 0) { + auto loginLen{std::strlen(arg)}; + std::memset( + arg + loginLen, ' ', static_cast(length) - loginLen); + return; } -#elif _WIN32 - // Get username from environment to avoid link to Advapi32.lib +#endif +#if _WIN32 GetUsernameEnvVar("USERNAME", arg, length); #else GetUsernameEnvVar("LOGNAME", arg, length); diff --git a/flang/unittests/Runtime/CommandTest.cpp b/flang/unittests/Runtime/CommandTest.cpp index a0f14c519412a..6b30333001d52 100644 --- a/flang/unittests/Runtime/CommandTest.cpp +++ b/flang/unittests/Runtime/CommandTest.cpp @@ -681,10 +681,7 @@ TEST_F(EnvironmentVariables, ErrMsgTooShort) { TEST_F(EnvironmentVariables, GetlogGetName) { const int charLen{3}; char input[charLen]{"\0\0"}; - - FORTRAN_PROCEDURE_NAME(getlog) - (reinterpret_cast(input), charLen); - + FORTRAN_PROCEDURE_NAME(getlog)(input, charLen); EXPECT_NE(input[0], '\0'); } @@ -700,10 +697,7 @@ TEST_F(EnvironmentVariables, GetlogPadSpace) { charLen = _POSIX_LOGIN_NAME_MAX + 2; #endif std::vector input(charLen); - - FORTRAN_PROCEDURE_NAME(getlog) - (reinterpret_cast(input.data()), charLen); - + FORTRAN_PROCEDURE_NAME(getlog)(input.data(), charLen); EXPECT_EQ(input[charLen - 1], ' '); } #endif @@ -715,8 +709,7 @@ TEST_F(EnvironmentVariables, GetlogEnvGetName) { << "Environment variable USERNAME does not exist"; char input[]{"XXXXXXXXX"}; - FORTRAN_PROCEDURE_NAME(getlog) - (reinterpret_cast(input), sizeof(input)); + FORTRAN_PROCEDURE_NAME(getlog)(input, sizeof(input)); CheckCharEqStr(input, "loginName"); } @@ -728,8 +721,7 @@ TEST_F(EnvironmentVariables, GetlogEnvBufferShort) { << "Environment variable USERNAME does not exist"; char input[]{"XXXXXX"}; - FORTRAN_PROCEDURE_NAME(getlog) - (reinterpret_cast(input), sizeof(input)); + FORTRAN_PROCEDURE_NAME(getlog)(input, sizeof(input)); CheckCharEqStr(input, "loginN"); } @@ -741,8 +733,7 @@ TEST_F(EnvironmentVariables, GetlogEnvPadSpace) { << "Environment variable USERNAME does not exist"; char input[]{"XXXXXXXXXX"}; - FORTRAN_PROCEDURE_NAME(getlog) - (reinterpret_cast(input), sizeof(input)); + FORTRAN_PROCEDURE_NAME(getlog)(input, sizeof(input)); CheckCharEqStr(input, "loginName "); }