blob: f84a2a5f81ba78469895b0275f1bd672f379466e [file] [log] [blame]
dgozman@chromium.org4fadf422011-04-05 20:31:42 +09001// Copyright (c) 2011 The Chromium Authors. All rights reserved.
evan@chromium.org54b72102009-07-22 09:35:18 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/sys_info.h"
6
7#include "base/basictypes.h"
8#include "base/file_path.h"
9#include "base/file_util.h"
dgozman@chromium.org4fadf422011-04-05 20:31:42 +090010#include "base/lazy_instance.h"
brettw@chromium.orgc1093e22010-08-01 02:29:25 +090011#include "base/string_number_conversions.h"
tedvessenes@gmail.comf3697362011-12-20 01:10:55 +090012#include "base/string_piece.h"
evan@chromium.org54b72102009-07-22 09:35:18 +090013#include "base/string_tokenizer.h"
brettw@chromium.org5b5f5e02011-01-01 10:01:06 +090014#include "base/threading/thread_restrictions.h"
evan@chromium.org54b72102009-07-22 09:35:18 +090015
dgozman@chromium.org4fadf422011-04-05 20:31:42 +090016#include <execinfo.h>
17
evan@chromium.org54b72102009-07-22 09:35:18 +090018namespace base {
19
dgozman@chromium.org4fadf422011-04-05 20:31:42 +090020static const char* kLinuxStandardBaseVersionKeys[] = {
21 "CHROMEOS_RELEASE_VERSION",
22 "GOOGLE_RELEASE",
23 "DISTRIB_RELEASE",
24 NULL
25};
evan@chromium.org54b72102009-07-22 09:35:18 +090026
27const char kLinuxStandardBaseReleaseFile[] = "/etc/lsb-release";
28
dgozman@chromium.org4fadf422011-04-05 20:31:42 +090029struct ChromeOSVersionNumbers {
30 ChromeOSVersionNumbers()
31 : major_version(0),
32 minor_version(0),
33 bugfix_version(0),
34 parsed(false) {
35 }
36
37 int32 major_version;
38 int32 minor_version;
39 int32 bugfix_version;
40 bool parsed;
41};
42
43static base::LazyInstance<ChromeOSVersionNumbers>
joth@chromium.orgb24883c2011-11-15 22:31:49 +090044 g_chrome_os_version_numbers = LAZY_INSTANCE_INITIALIZER;
dgozman@chromium.org4fadf422011-04-05 20:31:42 +090045
evan@chromium.org54b72102009-07-22 09:35:18 +090046// static
pkasting@chromium.org271d9db2011-04-08 07:15:34 +090047void SysInfo::OperatingSystemVersionNumbers(int32* major_version,
48 int32* minor_version,
49 int32* bugfix_version) {
dgozman@chromium.org4fadf422011-04-05 20:31:42 +090050 if (!g_chrome_os_version_numbers.Get().parsed) {
51 // The other implementations of SysInfo don't block on the disk.
52 // See http://code.google.com/p/chromium/issues/detail?id=60394
53 // Perhaps the caller ought to cache this?
54 // Temporary allowing while we work the bug out.
55 base::ThreadRestrictions::ScopedAllowIO allow_io;
evan@chromium.org7c9cd8b2010-10-23 14:19:20 +090056
dgozman@chromium.org4fadf422011-04-05 20:31:42 +090057 FilePath path(kLinuxStandardBaseReleaseFile);
58 std::string contents;
59 if (file_util::ReadFileToString(path, &contents)) {
60 g_chrome_os_version_numbers.Get().parsed = true;
61 ParseLsbRelease(contents,
62 &(g_chrome_os_version_numbers.Get().major_version),
63 &(g_chrome_os_version_numbers.Get().minor_version),
64 &(g_chrome_os_version_numbers.Get().bugfix_version));
65 }
evan@chromium.org54b72102009-07-22 09:35:18 +090066 }
dgozman@chromium.org4fadf422011-04-05 20:31:42 +090067 *major_version = g_chrome_os_version_numbers.Get().major_version;
68 *minor_version = g_chrome_os_version_numbers.Get().minor_version;
69 *bugfix_version = g_chrome_os_version_numbers.Get().bugfix_version;
evan@chromium.org54b72102009-07-22 09:35:18 +090070}
71
72// static
73std::string SysInfo::GetLinuxStandardBaseVersionKey() {
dgozman@chromium.org4fadf422011-04-05 20:31:42 +090074 return std::string(kLinuxStandardBaseVersionKeys[0]);
evan@chromium.org54b72102009-07-22 09:35:18 +090075}
76
77// static
78void SysInfo::ParseLsbRelease(const std::string& lsb_release,
pkasting@chromium.org271d9db2011-04-08 07:15:34 +090079 int32* major_version,
80 int32* minor_version,
81 int32* bugfix_version) {
dgozman@chromium.org4fadf422011-04-05 20:31:42 +090082 size_t version_key_index = std::string::npos;
83 for (int i = 0; kLinuxStandardBaseVersionKeys[i] != NULL; ++i) {
84 version_key_index = lsb_release.find(kLinuxStandardBaseVersionKeys[i]);
85 if (std::string::npos != version_key_index) {
86 break;
87 }
88 }
evan@chromium.org54b72102009-07-22 09:35:18 +090089 if (std::string::npos == version_key_index) {
90 return;
91 }
dgozman@chromium.org4fadf422011-04-05 20:31:42 +090092
evan@chromium.org54b72102009-07-22 09:35:18 +090093 size_t start_index = lsb_release.find_first_of('=', version_key_index);
94 start_index++; // Move past '='.
95 size_t length = lsb_release.find_first_of('\n', start_index) - start_index;
96 std::string version = lsb_release.substr(start_index, length);
97 StringTokenizer tokenizer(version, ".");
rkc@chromium.orgd9ab6062011-10-03 15:22:12 +090098 for (int i = 0; i < 3 && tokenizer.GetNext(); ++i) {
99 if (0 == i) {
tedvessenes@gmail.comf3697362011-12-20 01:10:55 +0900100 StringToInt(StringPiece(tokenizer.token_begin(),
101 tokenizer.token_end()),
erikwright@chromium.orgf8b4b812010-10-23 01:05:47 +0900102 major_version);
evan@chromium.org54b72102009-07-22 09:35:18 +0900103 *minor_version = *bugfix_version = 0;
rkc@chromium.orgd9ab6062011-10-03 15:22:12 +0900104 } else if (1 == i) {
tedvessenes@gmail.comf3697362011-12-20 01:10:55 +0900105 StringToInt(StringPiece(tokenizer.token_begin(),
106 tokenizer.token_end()),
erikwright@chromium.orgf8b4b812010-10-23 01:05:47 +0900107 minor_version);
rkc@chromium.orgd9ab6062011-10-03 15:22:12 +0900108 } else { // 2 == i
tedvessenes@gmail.comf3697362011-12-20 01:10:55 +0900109 StringToInt(StringPiece(tokenizer.token_begin(),
110 tokenizer.token_end()),
erikwright@chromium.orgf8b4b812010-10-23 01:05:47 +0900111 bugfix_version);
evan@chromium.org54b72102009-07-22 09:35:18 +0900112 }
113 }
114}
115
116} // namespace base