forked from microsoft/WSL
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtimezone.cpp
More file actions
142 lines (98 loc) · 2.82 KB
/
timezone.cpp
File metadata and controls
142 lines (98 loc) · 2.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*++
Copyright (c) Microsoft. All rights reserved.
Module Name:
timezone.c
Abstract:
This file contains methods for configuring the timezone.
--*/
#include "common.h"
#include "util.h"
#include "WslDistributionConfig.h"
#define TIMEZONE_LOCALTIME_FILE ETC_FOLDER "localtime"
#define TIMEZONE_SETTING_FILE ETC_FOLDER "timezone"
void UpdateTimezone(std::string_view Timezone, const wsl::linux::WslDistributionConfig& Config)
/*++
Routine Description:
This routine updates the instance's timezone information by creating the
/etc/localtime symlink and writing /etc/timezone.
Arguments:
Timezone - Supplies the Linux timezone.
Config - Supplies the distribution configuration.
Return Value:
None.
--*/
try
{
//
// If automatic timezone translation is disabled, do nothing.
//
if (!Config.AutoUpdateTimezone)
{
return;
}
if (Timezone.empty())
{
LOG_WARNING("Windows to Linux timezone mapping was not possible.");
return;
}
//
// Construct the /etc/localtime symlink target and ensure it will exist.
//
std::string Target{"/usr/share/zoneinfo/"};
Target += Timezone;
if (access(Target.c_str(), F_OK) < 0)
{
LOG_WARNING("{} not found. Is the tzdata package installed?", Target.c_str());
return;
}
//
// Update the /etc/localtime symlink.
//
if ((unlink(TIMEZONE_LOCALTIME_FILE) < 0) && (errno != ENOENT))
{
LOG_ERROR("unlink failed {}", errno);
return;
}
if (symlink(Target.c_str(), TIMEZONE_LOCALTIME_FILE) < 0)
{
LOG_ERROR("symlink failed {}", errno);
return;
}
//
// Write the contents of /etc/timezone to contain the IANA identifier.
//
wil::unique_fd TimezoneFile{TEMP_FAILURE_RETRY(open(TIMEZONE_SETTING_FILE, (O_CREAT | O_TRUNC | O_RDWR), 0644))};
if (!TimezoneFile)
{
LOG_ERROR("open({}) failed {}", TIMEZONE_SETTING_FILE, errno);
return;
}
std::string FileContents(Timezone);
FileContents += '\n';
if (UtilWriteStringView(TimezoneFile.get(), FileContents) < 0)
{
LOG_ERROR("write failed {}", errno);
return;
}
return;
}
CATCH_LOG()
void UpdateTimezone(gsl::span<gsl::byte> Buffer, const wsl::linux::WslDistributionConfig& Config)
/*++
Routine Description:
This routine processes an update timezone message.
Arguments:
Buffer - Supplies the message.
Config - Supplies the distribution configuration.
Return Value:
None.
--*/
{
auto* TimezoneInfo = gslhelpers::try_get_struct<const LX_INIT_TIMEZONE_INFORMATION>(Buffer);
if (!TimezoneInfo)
{
LOG_ERROR("Unexpected message size {}", Buffer.size());
return;
}
UpdateTimezone(wsl::shared::string::FromSpan(Buffer, TimezoneInfo->TimezoneOffset), Config);
}