Skip to content

[flang][runtime] Clean up code to unblock development #78063

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions flang/include/flang/Runtime/extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_
14 changes: 7 additions & 7 deletions flang/runtime/execute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<char *>(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<wchar_t *>(
AllocateMemoryOrCrash(terminator, sizeNeeded * sizeof(wchar_t)))};
if (std::mbstowcs(wcmd, newCmdWin, sizeNeeded) == static_cast<size_t>(-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)) {
Expand All @@ -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);
Expand All @@ -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);
}
}

Expand Down
34 changes: 10 additions & 24 deletions flang/runtime/extensions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<char *>(envName), 0)};
Descriptor value{*Descriptor::Create(1, length, arg, 0)};
Expand Down Expand Up @@ -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<char> 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<char *>(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<std::size_t>(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);
Expand Down
19 changes: 5 additions & 14 deletions flang/unittests/Runtime/CommandTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::byte *>(input), charLen);

FORTRAN_PROCEDURE_NAME(getlog)(input, charLen);
EXPECT_NE(input[0], '\0');
}

Expand All @@ -700,10 +697,7 @@ TEST_F(EnvironmentVariables, GetlogPadSpace) {
charLen = _POSIX_LOGIN_NAME_MAX + 2;
#endif
std::vector<char> input(charLen);

FORTRAN_PROCEDURE_NAME(getlog)
(reinterpret_cast<std::byte *>(input.data()), charLen);

FORTRAN_PROCEDURE_NAME(getlog)(input.data(), charLen);
EXPECT_EQ(input[charLen - 1], ' ');
}
#endif
Expand All @@ -715,8 +709,7 @@ TEST_F(EnvironmentVariables, GetlogEnvGetName) {
<< "Environment variable USERNAME does not exist";

char input[]{"XXXXXXXXX"};
FORTRAN_PROCEDURE_NAME(getlog)
(reinterpret_cast<std::byte *>(input), sizeof(input));
FORTRAN_PROCEDURE_NAME(getlog)(input, sizeof(input));

CheckCharEqStr(input, "loginName");
}
Expand All @@ -728,8 +721,7 @@ TEST_F(EnvironmentVariables, GetlogEnvBufferShort) {
<< "Environment variable USERNAME does not exist";

char input[]{"XXXXXX"};
FORTRAN_PROCEDURE_NAME(getlog)
(reinterpret_cast<std::byte *>(input), sizeof(input));
FORTRAN_PROCEDURE_NAME(getlog)(input, sizeof(input));

CheckCharEqStr(input, "loginN");
}
Expand All @@ -741,8 +733,7 @@ TEST_F(EnvironmentVariables, GetlogEnvPadSpace) {
<< "Environment variable USERNAME does not exist";

char input[]{"XXXXXXXXXX"};
FORTRAN_PROCEDURE_NAME(getlog)
(reinterpret_cast<std::byte *>(input), sizeof(input));
FORTRAN_PROCEDURE_NAME(getlog)(input, sizeof(input));

CheckCharEqStr(input, "loginName ");
}
Expand Down