Skip to content

Commit

Permalink
Sys props (#1218)
Browse files Browse the repository at this point in the history
* Set os.name system property

I noticed that scala.util.Properties.isMac didn't work because the
"os.name" system property wasn't set. I added this functionality for OSX
and Linux, but not windows because I don't know what it's supposed to
run. I only set the version for Linux because uname can't reliably used
to get the os.version string. I add support for that in a subsequent
commit, but it requires adding objective c support to the toolchain,
which I imagine may be contentious.

Bonus: move up initializing of streams so that println may be used in
loadProperties

* Remove unused private method in java.io.File

This was left behind in 40dd654.

* Move platform specific code into platform.c

We want to move away from having portable code implemented with runtime
branching, so I moved the setting of the os.name (and version on linux)
into platform.c.

I also added the java.io.tmpdir system property on all platforms. The
semantics are different than the jvm on osx (which uses a user
specific path that can only be accessed using objective c apis in the
foundation framework). Instead of the user specific temp directory, it
just uses /tmp, which is probably fine for most applications. It also
isn't possible to precisely determine the os version on osx without
shelling out to the `sw_vers` command or using different objective c
apis from the foundation framework. For now, we'll just leave the os
version blank on osx (and windows -- there are different issues with
getting this to work correctly on windows and right now there seem to
be very few windows users of scala native).
  • Loading branch information
eatkins authored and densh committed Jul 13, 2018
1 parent a5288f1 commit 6de017a
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 53 deletions.
10 changes: 0 additions & 10 deletions javalib/src/main/scala/java/io/File.scala
Expand Up @@ -540,14 +540,4 @@ object File {
minLength = true,
throwOnError = true)

private def tempDir(): File = {
val dir = getenv(c"TMPDIR")
if (dir == null) {
new File(System.getProperty("java.io.tmpdir") match {
case null => "/tmp"
case d => d
})
} else new File(fromCString(dir))
}

}
22 changes: 14 additions & 8 deletions javalib/src/main/scala/java/lang/System.scala
Expand Up @@ -4,6 +4,8 @@ import java.io._
import java.util.{Collections, HashMap, Map, Properties}
import scala.scalanative.native._
import scala.scalanative.posix.unistd
import scala.scalanative.posix.sys.utsname._
import scala.scalanative.posix.sys.uname._
import scala.scalanative.runtime.time
import scala.scalanative.runtime.Platform
import scala.scalanative.runtime.GC
Expand Down Expand Up @@ -73,7 +75,18 @@ object System {
sysProps
}

private var systemProperties = loadProperties()
var in: InputStream =
new FileInputStream(FileDescriptor.in)
var out: PrintStream =
new PrintStream(new FileOutputStream(FileDescriptor.out))
var err: PrintStream =
new PrintStream(new FileOutputStream(FileDescriptor.err))

private val systemProperties = loadProperties()
Platform.setOSProps(
CFunctionPtr.fromFunction2((key: CString, value: CString) => {
systemProperties.setProperty(fromCString(key), fromCString(value));
}))

def lineSeparator(): String = {
if (Platform.isWindows) "\r\n"
Expand All @@ -100,13 +113,6 @@ object System {
def getenv(): Map[String, String] = envVars
def getenv(key: String): String = envVars.get(key)

var in: InputStream =
new FileInputStream(FileDescriptor.in)
var out: PrintStream =
new PrintStream(new FileOutputStream(FileDescriptor.out))
var err: PrintStream =
new PrintStream(new FileOutputStream(FileDescriptor.err))

def setIn(in: InputStream): Unit =
this.in = in

Expand Down
47 changes: 16 additions & 31 deletions nativelib/src/main/resources/dirent.c
Expand Up @@ -11,33 +11,15 @@ struct scalanative_dirent {
short d_type;
};

int scalanative_dt_unknown() {
return DT_UNKNOWN;
}
int scalanative_dt_fifo() {
return DT_FIFO;
}
int scalanative_dt_chr() {
return DT_CHR;
}
int scalanative_dt_dir() {
return DT_DIR;
}
int scalanative_dt_blk() {
return DT_BLK;
}
int scalanative_dt_reg() {
return DT_REG;
}
int scalanative_dt_lnk() {
return DT_LNK;
}
int scalanative_dt_sock() {
return DT_SOCK;
}
int scalanative_dt_wht() {
return DT_WHT;
}
int scalanative_dt_unknown() { return DT_UNKNOWN; }
int scalanative_dt_fifo() { return DT_FIFO; }
int scalanative_dt_chr() { return DT_CHR; }
int scalanative_dt_dir() { return DT_DIR; }
int scalanative_dt_blk() { return DT_BLK; }
int scalanative_dt_reg() { return DT_REG; }
int scalanative_dt_lnk() { return DT_LNK; }
int scalanative_dt_sock() { return DT_SOCK; }
int scalanative_dt_wht() { return DT_WHT; }

DIR *scalanative_opendir(const char *name) { return opendir(name); }

Expand All @@ -55,10 +37,13 @@ int scalanative_readdir(DIR *dirp, struct scalanative_dirent *buf) {
scalanative_dirent_init(orig_buf, buf);
return 0;
} else {
switch(errno) {
case EBADF: return EBADF;
case EFAULT: return EFAULT;
case EIO: return EIO;
switch (errno) {
case EBADF:
return EBADF;
case EFAULT:
return EFAULT;
case EIO:
return EIO;
}
return -1;
}
Expand Down
6 changes: 3 additions & 3 deletions nativelib/src/main/resources/optional/re2.cpp
Expand Up @@ -149,9 +149,9 @@ int64_t scalanative_cre2_opt_max_mem(scalanative_cre2_options_t *opt) {
return TO_OPT(opt)->max_mem();
}

/** --------------------------------------------------------------------
** Precompiled regular expressions objects.
** ----------------------------------------------------------------- */
/** --------------------------------------------------------------------
** Precompiled regular expressions objects.
** ----------------------------------------------------------------- */

#define TO_RE2(re) (reinterpret_cast<RE2 *>(re))
#define TO_CONST_RE2(re) (reinterpret_cast<const RE2 *>(re))
Expand Down
33 changes: 33 additions & 0 deletions nativelib/src/main/resources/platform.c
@@ -1,7 +1,17 @@
#ifdef _WIN32
#include <Windows.h>
#else
#include <sys/utsname.h>
#endif

int scalanative_platform_is_mac() {
#ifdef __APPLE__
return 1;
#else
return 0;
#endif
}

int scalanative_platform_is_windows() {
#ifdef _WIN32
return 1;
Expand Down Expand Up @@ -33,3 +43,26 @@ int scalanative_little_endian() {
int n = 1;
return (*(char *)&n);
}

void scalanative_set_os_props(void (*add_prop)(const char *, const char *)) {
#ifdef _WIN32
add_prop("os.name", "Windows (Unknown version)");
wchar_t wcharPath[MAX_PATH];
char path[MAX_PATH];
if (GetTempPathW(MAX_PATH, wcharPath) &&
wcstombs(path, wcharPath, MAX_PATH) != -1) {
add_prop("java.io.tmpdir", (const char *)path);
}
#else
#ifdef __APPLE__
add_prop("os.name", "Mac OS X");
#else
struct utsname name;
if (uname(&name) == 0) {
add_prop("os.name", name.sysname);
add_prop("os.version", name.release);
}
#endif
add_prop("java.io.tmpdir", "/tmp");
#endif
}
30 changes: 30 additions & 0 deletions nativelib/src/main/resources/posix/sys/uname.c
@@ -0,0 +1,30 @@
#include <sys/utsname.h>
#include <string.h>

#define NAMELEN 256
struct scalanative_utsname {
char sysname[NAMELEN];
char nodename[NAMELEN];
char release[NAMELEN];
char version[NAMELEN];
char machine[NAMELEN];
};
#undef NAMELEN
#define SET_FIELD(x, y) \
do { \
int len = strlen(y); \
memcpy(x, y, len); \
} while (0);

int scalanative_uname(struct scalanative_utsname *scalanative_utsname) {
struct utsname utsname;
int res = uname(&utsname);
if (res == 0) {
SET_FIELD(&scalanative_utsname->sysname, utsname.sysname)
SET_FIELD(&scalanative_utsname->nodename, utsname.nodename)
SET_FIELD(&scalanative_utsname->release, utsname.release)
SET_FIELD(&scalanative_utsname->version, utsname.version)
SET_FIELD(&scalanative_utsname->machine, utsname.machine)
}
return res;
}
21 changes: 21 additions & 0 deletions nativelib/src/main/scala/scala/scalanative/posix/sys/utsname.scala
@@ -0,0 +1,21 @@
package scala.scalanative.posix.sys

import scala.scalanative.native._

@extern
object utsname {
type _256 = Nat.Digit[Nat._2, Nat.Digit[Nat._5, Nat._6]]
private type str = CArray[Byte, _256]
type utsname = CStruct5[str, str, str, str, str]
@extern def uname(utsname: Ptr[utsname]): CInt = extern
}

object uname {
implicit class utsnameOps(val c: Ptr[utsname.utsname]) {
def sysname = fromCString(c._1.cast[Ptr[CChar]])
def nodename = fromCString(c._2.cast[Ptr[CChar]])
def release = fromCString(c._3.cast[Ptr[CChar]])
def version = fromCString(c._4.cast[Ptr[CChar]])
def machine = fromCString(c._5.cast[Ptr[CChar]])
}
}
@@ -1,10 +1,20 @@
package scala.scalanative
package runtime

import scala.scalanative.native.{CString, extern, name}
import scala.scalanative.native.{
CInt,
CFunctionPtr2,
CString,
Ptr,
extern,
name
}

@extern
object Platform {
@name("scalanative_platform_is_mac")
def isMac(): Boolean = extern

@name("scalanative_platform_is_windows")
def isWindows(): Boolean = extern

Expand All @@ -16,4 +26,8 @@ object Platform {

@name("scalanative_little_endian")
def littleEndian(): Boolean = extern

@name("scalanative_set_os_props")
def setOSProps(addProp: CFunctionPtr2[CString, CString, Unit]): Unit =
extern
}

0 comments on commit 6de017a

Please sign in to comment.