Implement $hostname variable

The value is not electrified or tied and is read-only. It isn't cached
in the get_hostname_identifier() function as the ENV_GLOBAL $hostname
will cache it for its duration.
This commit is contained in:
Mahmoud Al-Qudsi
2018-03-09 15:02:32 -06:00
parent ed9c0a7f82
commit a756049dac
3 changed files with 12 additions and 7 deletions

View File

@@ -322,7 +322,7 @@ bool string_set_contains(const T &set, const wchar_t *val) {
/// Check if a variable may not be set using the set command.
static bool is_read_only(const wchar_t *val) {
const string_set_t env_read_only = {L"PWD", L"SHLVL", L"_", L"history", L"status", L"version", L"pid"};
const string_set_t env_read_only = {L"PWD", L"SHLVL", L"_", L"history", L"status", L"version", L"pid", L"hostname"};
return string_set_contains(env_read_only, val);
}
@@ -972,6 +972,11 @@ void env_init(const struct config_paths_t *paths /* or NULL */) {
// Set the $pid variable (%self replacement)
env_set_one(L"pid", ENV_GLOBAL, to_string<long>(getpid()));
// Set the $hostname variable
wcstring hostname = L"fish";
get_hostname_identifier(hostname);
env_set_one(L"hostname", ENV_GLOBAL, hostname);
// Set up SHLVL variable. Not we can't use env_get because SHLVL is read-only, and therefore was
// not inherited from the environment.
wcstring nshlvl_str = L"1";

View File

@@ -77,7 +77,6 @@
"changes will be overwritten.\n"
static wcstring get_machine_identifier();
static bool get_hostname_identifier(wcstring *result);
static wcstring vars_filename_in_directory(const wcstring &wdir) {
if (wdir.empty()) return L"";
@@ -496,7 +495,7 @@ bool env_universal_t::load(callback_data_list_t &callbacks) {
// Silently "upgraded."
tried_renaming = true;
wcstring hostname_id;
if (get_hostname_identifier(&hostname_id)) {
if (get_hostname_identifier(hostname_id)) {
const wcstring hostname_path = wdirname(vars_path) + L'/' + hostname_id;
if (0 == wrename(hostname_path, vars_path)) {
// We renamed - try again.
@@ -912,14 +911,14 @@ static bool get_mac_address(unsigned char macaddr[MAC_ADDRESS_MAX_LEN]) { return
#endif
/// Function to get an identifier based on the hostname.
static bool get_hostname_identifier(wcstring *result) {
bool get_hostname_identifier(wcstring &result) {
//The behavior of gethostname if the buffer size is insufficient differs by implementation and libc version
//Work around this by using a "guaranteed" sufficient buffer size then truncating the result.
bool success = false;
char hostname[256] = {};
if (gethostname(hostname, sizeof(hostname)) == 0) {
result->assign(str2wcstring(hostname));
result->assign(truncate(*result, HOSTNAME_LEN));
result.assign(str2wcstring(hostname));
result.assign(truncate(result, HOSTNAME_LEN));
success = true;
}
return success;
@@ -935,7 +934,7 @@ wcstring get_machine_identifier() {
for (size_t i = 0; i < MAC_ADDRESS_MAX_LEN; i++) {
append_format(result, L"%02x", mac_addr[i]);
}
} else if (!get_hostname_identifier(&result)) {
} else if (!get_hostname_identifier(result)) {
result.assign(L"nohost"); // fallback to a dummy value
}
return result;

View File

@@ -28,6 +28,7 @@ struct callback_data_t {
typedef std::vector<struct callback_data_t> callback_data_list_t;
bool get_hostname_identifier(wcstring &result);
/// Class representing universal variables.
class env_universal_t {
var_table_t vars; // current values