diff options
Diffstat (limited to 'linux-user/syscall.c')
-rw-r--r-- | linux-user/syscall.c | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index ea04db1a3e..c62d8754f0 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4863,12 +4863,35 @@ int host_to_target_waitstatus(int status) return status; } +static int relstr_to_int(const char *s) +{ + /* Convert a uname release string like "2.6.18" to an integer + * of the form 0x020612. (Beware that 0x020612 is *not* 2.6.12.) + */ + int i, n, tmp; + + tmp = 0; + for (i = 0; i < 3; i++) { + n = 0; + while (*s >= '0' && *s <= '9') { + n *= 10; + n += *s - '0'; + s++; + } + tmp = (tmp << 8) + n; + if (*s == '.') { + s++; + } + } + return tmp; +} + int get_osversion(void) { static int osversion; struct new_utsname buf; const char *s; - int i, n, tmp; + if (osversion) return osversion; if (qemu_uname_release && *qemu_uname_release) { @@ -4878,22 +4901,33 @@ int get_osversion(void) return 0; s = buf.release; } - tmp = 0; - for (i = 0; i < 3; i++) { - n = 0; - while (*s >= '0' && *s <= '9') { - n *= 10; - n += *s - '0'; - s++; - } - tmp = (tmp << 8) + n; - if (*s == '.') - s++; - } - osversion = tmp; + osversion = relstr_to_int(s); return osversion; } +void init_qemu_uname_release(void) +{ + /* Initialize qemu_uname_release for later use. + * If the host kernel is too old and the user hasn't asked for + * a specific fake version number, we might want to fake a minimum + * target kernel version. + */ +#ifdef UNAME_MINIMUM_RELEASE + struct new_utsname buf; + + if (qemu_uname_release && *qemu_uname_release) { + return; + } + + if (sys_uname(&buf)) { + return; + } + + if (relstr_to_int(buf.release) < relstr_to_int(UNAME_MINIMUM_RELEASE)) { + qemu_uname_release = UNAME_MINIMUM_RELEASE; + } +#endif +} static int open_self_maps(void *cpu_env, int fd) { |