Skip to content
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

Fix crash when HOME env variable is not set #1738

Merged
merged 8 commits into from
May 19, 2020
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
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ lazy val tests =
testFrameworks += new TestFramework("tests.NativeFramework"),
Test / test / envVars ++= Map(
"USER" -> "scala-native",
"HOME" -> baseDirectory.value.getAbsolutePath,
"HOME" -> System.getProperty("user.home"),
"SCALA_NATIVE_ENV_WITH_EQUALS" -> "1+1=2",
"SCALA_NATIVE_ENV_WITHOUT_VALUE" -> "",
"SCALA_NATIVE_ENV_WITH_UNICODE" -> 0x2192.toChar.toString,
Expand Down
22 changes: 17 additions & 5 deletions javalib/src/main/scala/java/lang/System.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import scala.scalanative.unsafe._
import scala.scalanative.posix.unistd
import scala.scalanative.posix.sys.utsname._
import scala.scalanative.posix.sys.uname._
import scala.scalanative.posix.pwd
import scala.scalanative.posix.pwdOps._
import scala.scalanative.runtime.{time, Platform, GC, Intrinsics}

final class System private ()
Expand Down Expand Up @@ -61,11 +63,21 @@ object System {
sysProps.setProperty("user.language", userLang)
sysProps.setProperty("user.country", userCountry)
}
sysProps.setProperty("user.home", getenv("HOME"))
val buf = stackalloc[scala.Byte](1024)
unistd.getcwd(buf, 1024) match {
case null =>
case b => sysProps.setProperty("user.dir", fromCString(b))
locally {
val buf = stackalloc[pwd.passwd]
val uid = unistd.getuid()
val res = pwd.getpwuid(uid, buf)
if (res == 0 && buf.pw_dir != null) {
sysProps.setProperty("user.home", fromCString(buf.pw_dir))
}
}
locally {
val bufSize = 1024
val buf = stackalloc[scala.Byte](bufSize)
val cwd = unistd.getcwd(buf, bufSize)
if (cwd != null) {
sysProps.setProperty("user.dir", fromCString(cwd))
}
}
}

Expand Down
18 changes: 18 additions & 0 deletions posixlib/src/main/scala/scala/scalanative/posix/pwd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,21 @@ object pwd {
@name("scalanative_getpwnam")
def getpwnam(name: CString, buf: Ptr[passwd]): CInt = extern
}

object pwdOps {
import pwd._

implicit class passwdOps(val ptr: Ptr[passwd]) extends AnyVal {
def pw_name: CString = ptr._1
def pw_name_=(value: CString): Unit = ptr._1 = value
def pw_uid: uid_t = ptr._2
def pw_uid_=(value: uid_t): Unit = ptr._2 = value
def pw_gid: gid_t = ptr._3
def pw_gid_=(value: gid_t): Unit = ptr._3 = value
def pw_dir: CString = ptr._4
def pw_dir_=(value: CString): Unit = ptr._4 = value
def pw_shell: CString = ptr._5
def pw_shell_=(value: CString): Unit = ptr._5 = value
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ object unistd {
def getcwd(buf: CString, size: CSize): CString = extern
def gethostname(name: CString, len: CSize): CInt = extern
def getpid(): CInt = extern
def getuid(): uid_t = extern
def lseek(fildes: CInt, offset: off_t, whence: CInt): off_t = extern
def pipe(fildes: Ptr[CInt]): CInt = extern
def read(fildes: CInt, buf: Ptr[_], nbyte: CSize): CInt = extern
Expand Down