126 {
127#ifdef WIN32
128 struct close_handle
129 {
130 void operator()(HANDLE handle) const noexcept
131 {
132 CloseHandle(handle);
133 }
134 };
135
136 std::unique_ptr<void, close_handle> process = nullptr;
137 {
138 HANDLE temp{};
139 const bool fail = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, std::addressof(temp)) == 0;
140 process.reset(temp);
141 if (fail)
142 return {};
143 }
144
145 DWORD sid_size = 0;
146 GetTokenInformation(process.get(), TokenOwner, nullptr, 0, std::addressof(sid_size));
147 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
148 return {};
149
150 std::unique_ptr<char[]> sid{new char[sid_size]};
151 if (!GetTokenInformation(process.get(), TokenOwner, sid.get(), sid_size, std::addressof(sid_size)))
152 return {};
153
154 const PSID psid = reinterpret_cast<const PTOKEN_OWNER>(sid.get())->Owner;
155 const DWORD daclSize =
156 sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD);
157
158 const std::unique_ptr<char[]> dacl{new char[daclSize]};
159 if (!InitializeAcl(reinterpret_cast<PACL>(dacl.get()), daclSize, ACL_REVISION))
160 return {};
161
162 if (!AddAccessAllowedAce(reinterpret_cast<PACL>(dacl.get()), ACL_REVISION, (READ_CONTROL | FILE_GENERIC_READ | DELETE), psid))
163 return {};
164
165 SECURITY_DESCRIPTOR descriptor{};
166 if (!InitializeSecurityDescriptor(std::addressof(descriptor), SECURITY_DESCRIPTOR_REVISION))
167 return {};
168
169 if (!SetSecurityDescriptorDacl(std::addressof(descriptor), true, reinterpret_cast<PACL>(dacl.get()), false))
170 return {};
171
172 SECURITY_ATTRIBUTES attributes{sizeof(SECURITY_ATTRIBUTES), std::addressof(descriptor), false};
173 std::unique_ptr<void, close_handle> file{
174 CreateFile(
176 GENERIC_WRITE, FILE_SHARE_READ,
177 std::addressof(attributes),
178 CREATE_NEW, (FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE),
179 nullptr
180 )
181 };
182 if (file)
183 {
184 const int fd = _open_osfhandle(
reinterpret_cast<intptr_t>(file.get()), 0);
185 if (0 <= fd)
186 {
187 file.release();
188 std::FILE* real_file = _fdopen(fd, "w");
189 if (!real_file)
190 {
191 _close(fd);
192 }
193 return {real_file, std::move(name)};
194 }
195 }
196#else
197 const int fdr = open(
name.c_str(), (O_RDONLY | O_CREAT), S_IRUSR);
198 if (0 <= fdr)
199 {
200 struct stat rstats = {};
201 if (fstat(fdr, std::addressof(rstats)) != 0)
202 {
203 close(fdr);
204 return {};
205 }
206 fchmod(fdr, (S_IRUSR | S_IWUSR));
207 const int fdw = open(
name.c_str(), O_RDWR);
208 fchmod(fdr, rstats.st_mode);
209 close(fdr);
210
211 if (0 <= fdw)
212 {
213 struct stat wstats = {};
214 if (fstat(fdw, std::addressof(wstats)) == 0 &&
215 rstats.st_dev == wstats.st_dev && rstats.st_ino == wstats.st_ino &&
216 flock_exnb(fdw) == 0 && ftruncate(fdw, 0) == 0)
217 {
218 std::FILE* file = fdopen(fdw, "w");
219 if (file) return {file, std::move(name)};
220 }
221 close(fdw);
222 }
223 }
224#endif
225 return {};
226 }