[flang] Implement external routine usage of hostnm() (#134900)
Previously, `hostnm` extended intrinsic was implemented as proper
intrinsic. Since then we found out that some applications use `hostnm`
as external routine via `external hostnm`. This prevents `hostnm` from
being recognized as an intrinsic. This PR implements `hostnm` as
external routine.
diff --git a/flang-rt/lib/runtime/extensions.cpp b/flang-rt/lib/runtime/extensions.cpp
index 6b553ff..e70dff3 100644
--- a/flang-rt/lib/runtime/extensions.cpp
+++ b/flang-rt/lib/runtime/extensions.cpp
@@ -264,6 +264,38 @@
#endif
}
+int FORTRAN_PROCEDURE_NAME(hostnm)(char *hn, int length) {
+ std::int32_t status{0};
+
+ if (!hn || length < 0) {
+ return EINVAL;
+ }
+
+#ifdef _WIN32
+ DWORD dwSize{static_cast<DWORD>(length)};
+
+ // Note: Winsock has gethostname(), but use Win32 API GetComputerNameEx(),
+ // in order to avoid adding dependency on Winsock.
+ if (!GetComputerNameExA(ComputerNameDnsHostname, hn, &dwSize)) {
+ status = GetLastError();
+ }
+#else
+ if (gethostname(hn, length) < 0) {
+ status = errno;
+ }
+#endif
+
+ if (status == 0) {
+ // Find zero terminator and fill the string from the
+ // zero terminator to the end with spaces
+ char *str_end{hn + length};
+ char *str_zero{std::find(hn, str_end, '\0')};
+ std::fill(str_zero, str_end, ' ');
+ }
+
+ return status;
+}
+
int FORTRAN_PROCEDURE_NAME(ierrno)() { return errno; }
void FORTRAN_PROCEDURE_NAME(qsort)(int *array, int *len, int *isize,
diff --git a/flang/include/flang/Runtime/extensions.h b/flang/include/flang/Runtime/extensions.h
index db22458..06ae7f3 100644
--- a/flang/include/flang/Runtime/extensions.h
+++ b/flang/include/flang/Runtime/extensions.h
@@ -60,7 +60,7 @@
void FORTRAN_PROCEDURE_NAME(getlog)(char *name, std::int64_t length);
// GNU extension subroutine HOSTNM(C)
-void FORTRAN_PROCEDURE_NAME(hostnm)(char *name, std::int64_t length);
+int FORTRAN_PROCEDURE_NAME(hostnm)(char *hn, int length);
std::intptr_t RTNAME(Malloc)(std::size_t size);