| 117 | |
| 118 | #if defined(DEATH_TARGET_UNIX) |
| 119 | Containers::String GetUnixFlavor() |
| 120 | { |
| 121 | FILE* fp = ::fopen("/etc/os-release", "r"); |
| 122 | if (fp == nullptr) { |
| 123 | fp = ::fopen("/usr/lib/os-release", "r"); |
| 124 | if (fp == nullptr) { |
| 125 | return {}; |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | Containers::String result; |
| 130 | |
| 131 | char* line = nullptr; |
| 132 | std::size_t length = 0; |
| 133 | ssize_t readChars; |
| 134 | while ((readChars = ::getline(&line, &length, fp)) != -1) { |
| 135 | if (strncmp(line, "PRETTY_NAME=", sizeof("PRETTY_NAME=") - 1) == 0) { |
| 136 | char* versionStart = line + sizeof("PRETTY_NAME=") - 1; |
| 137 | bool startsWithBackslash = false; |
| 138 | if (versionStart[0] == '\\' && versionStart[1] == '"') { |
| 139 | versionStart += 2; |
| 140 | startsWithBackslash = true; |
| 141 | } else if (versionStart[0] == '"') { |
| 142 | versionStart += 1; |
| 143 | } |
| 144 | char* versionEnd = line + readChars - 1; |
| 145 | while (versionStart <= versionEnd && (versionEnd[0] == '\0' || versionEnd[0] == '\r' || versionEnd[0] == '\n' || versionEnd[0] == '"')) { |
| 146 | versionEnd--; |
| 147 | } |
| 148 | if (startsWithBackslash) { |
| 149 | if (versionEnd[0] == '"' && versionEnd[-1] == '\\') { |
| 150 | versionEnd -= 2; |
| 151 | } |
| 152 | } else { |
| 153 | if (versionEnd[0] == '"') { |
| 154 | versionEnd -= 1; |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | char* versionShortEnd = versionEnd; |
| 159 | while (true) { |
| 160 | if (versionStart >= versionShortEnd) { |
| 161 | versionShortEnd = nullptr; |
| 162 | break; |
| 163 | } |
| 164 | if (versionShortEnd[0] == '(') { |
| 165 | versionShortEnd--; |
| 166 | while (versionStart < versionShortEnd && versionShortEnd[0] == ' ') { |
| 167 | versionShortEnd--; |
| 168 | } |
| 169 | break; |
| 170 | } |
| 171 | versionShortEnd--; |
| 172 | } |
| 173 | |
| 174 | if (versionShortEnd != nullptr) { |
| 175 | versionEnd = versionShortEnd; |
| 176 | } |