Welcome to mirror list, hosted at ThFree Co, Russian Federation.

pal.h « hostmisc « cli « corehost « installer « src - github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 432756a3f37320649ef623f307a9181d2057f0d7 (plain)
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#ifndef PAL_H
#define PAL_H

#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <iostream>
#include <cstring>
#include <cstdarg>
#include <cstdint>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <memory>
#include <algorithm>
#include <cassert>

#if defined(_WIN32)

#define NOMINMAX
#include <windows.h>

#define xerr std::wcerr
#define xout std::wcout
#define DIR_SEPARATOR L'\\'
#define PATH_SEPARATOR L';'
#define PATH_MAX MAX_PATH
#define _X(s) L ## s

#else

#include <cstdlib>
#include <unistd.h>
#include <libgen.h>
#include <mutex>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>

#define xerr std::cerr
#define xout std::cout
#define DIR_SEPARATOR '/'
#define PATH_SEPARATOR ':'
#undef _X
#define _X(s) s

#define S_OK        0x00000000
#define E_NOTIMPL   0x80004001
#define E_FAIL      0x80004005

#define SUCCEEDED(Status) ((Status) >= 0)

#endif

// When running on a platform that is not supported in RID fallback graph (because it was unknown
// at the time the SharedFX in question was built), we need to use a reasonable fallback RID to allow
// consuming the native assets.
//
// For Windows and OSX, we will maintain the last highest RID-Platform we are known to support for them as the
// degree of compat across their respective releases is usually high.
//
// We cannot maintain the same (compat) invariant for linux and thus, we will fallback to using lowest RID-Plaform.
#if defined(_WIN32)
#define LIB_PREFIX
#define MAKE_LIBNAME(NAME) (_X(NAME) _X(".dll"))
#define FALLBACK_HOST_RID _X("win10")
#elif defined(TARGET_OSX)
#define LIB_PREFIX _X("lib")
#define MAKE_LIBNAME(NAME) (LIB_PREFIX _X(NAME) _X(".dylib"))
#define FALLBACK_HOST_RID _X("osx.10.12")
#else
#define LIB_PREFIX _X("lib")
#define MAKE_LIBNAME(NAME) (LIB_PREFIX _X(NAME) _X(".so"))
#define FALLBACK_HOST_RID _X("linux")
#endif

#define LIBCLRJIT_NAME MAKE_LIBNAME("clrjit")

#define LIBCORECLR_FILENAME (LIB_PREFIX _X("coreclr"))
#define LIBCORECLR_NAME MAKE_LIBNAME("coreclr")

#define CORELIB_NAME _X("System.Private.CoreLib.dll")

#define LIBHOSTPOLICY_FILENAME (LIB_PREFIX _X("hostpolicy"))
#define LIBHOSTPOLICY_NAME MAKE_LIBNAME("hostpolicy")

#define LIBFXR_NAME MAKE_LIBNAME("hostfxr")

#if !defined(PATH_MAX) && !defined(_WIN32)
#define PATH_MAX    4096
#endif


namespace pal
{
#if defined(_WIN32)
    #ifdef EXPORT_SHARED_API
        #define SHARED_API extern "C" __declspec(dllexport)
    #else
        #define SHARED_API
    #endif

    #define STDMETHODCALLTYPE __stdcall

    typedef wchar_t char_t;
    typedef std::wstring string_t;
    typedef std::wstringstream stringstream_t;
    // TODO: Agree on the correct encoding of the files: The PoR for now is to
    // temporarily wchar for Windows and char for Unix. Current implementation
    // implicitly expects the contents on both Windows and Unix as char and
    // converts them to wchar in code for Windows. This line should become:
    // typedef std::basic_ifstream<char_t> ifstream_t.
    typedef std::basic_ifstream<char> ifstream_t;
    typedef std::istreambuf_iterator<ifstream_t::char_type> istreambuf_iterator_t;
    typedef std::basic_istream<char> istream_t;
    typedef HRESULT hresult_t;
    typedef HMODULE dll_t;
    typedef FARPROC proc_t;

    // Lockable object backed by CRITICAL_SECTION such that it does not pull in ConcRT.
    class mutex_t
    {
    public:
        mutex_t();
        ~mutex_t();

        mutex_t(const mutex_t&) = delete;
        mutex_t& operator=(const mutex_t&) = delete;

        void lock();
        void unlock();

    private:
        CRITICAL_SECTION _impl;
    };

    inline string_t exe_suffix() { return _X(".exe"); }

    inline int cstrcasecmp(const char* str1, const char* str2) { return ::_stricmp(str1, str2); }
    inline int strcmp(const char_t* str1, const char_t* str2) { return ::wcscmp(str1, str2); }
    inline int strcasecmp(const char_t* str1, const char_t* str2) { return ::_wcsicmp(str1, str2); }
    inline int strncmp(const char_t* str1, const char_t* str2, int len) { return ::wcsncmp(str1, str2, len); }
    inline int strncasecmp(const char_t* str1, const char_t* str2, int len) { return ::_wcsnicmp(str1, str2, len); }

    inline size_t strlen(const char_t* str) { return ::wcslen(str); }
    inline FILE * file_open(const string_t& path, const char_t* mode) { return ::_wfopen(path.c_str(), mode); }

    inline void file_vprintf(FILE* f, const char_t* format, va_list vl) { ::vfwprintf(f, format, vl); ::fputwc(_X('\n'), f); }
    inline void err_fputs(const char_t* message) { ::fputws(message, stderr); ::fputwc(_X('\n'), stderr); }
    inline void out_vprintf(const char_t* format, va_list vl) { ::vfwprintf(stdout, format, vl); ::fputwc(_X('\n'), stdout); }
    inline int str_vprintf(char_t* buffer, size_t count, const char_t* format, va_list vl) { return ::_vsnwprintf(buffer, count, format, vl); }
    inline const char_t* strerror(int errnum) { return ::_wcserror(errnum); }

    bool pal_utf8string(const string_t& str, std::vector<char>* out);
    bool utf8_palstring(const std::string& str, string_t* out);
    bool pal_clrstring(const string_t& str, std::vector<char>* out);
    bool clr_palstring(const char* cstr, string_t* out);

    inline bool mkdir(const char_t* dir, int mode) { return CreateDirectoryW(dir, NULL) != 0; }
    inline bool rmdir (const char_t* path) { return RemoveDirectoryW(path) != 0; }
    inline int rename(const char_t* old_name, const char_t* new_name) { return ::_wrename(old_name, new_name); }
    inline int remove(const char_t* path) { return ::_wremove(path); }
    inline bool unmap_file(void* addr, size_t length) { return UnmapViewOfFile(addr) != 0; }
    inline int get_pid() { return GetCurrentProcessId(); }
    inline void sleep(uint32_t milliseconds) { Sleep(milliseconds); }
#else
    #ifdef EXPORT_SHARED_API
        #define SHARED_API extern "C" __attribute__((__visibility__("default")))
    #else
        #define SHARED_API
    #endif

    #define __cdecl    /* nothing */
    #define __stdcall  /* nothing */
    #if !defined(TARGET_FREEBSD)
        #define __fastcall /* nothing */
    #else
        #include <sys/types.h>
        #include <sys/sysctl.h>
        #include <sys/param.h>
    #endif
    #define STDMETHODCALLTYPE __stdcall

    typedef char char_t;
    typedef std::string string_t;
    typedef std::stringstream stringstream_t;
    typedef std::basic_ifstream<char> ifstream_t;
    typedef std::istreambuf_iterator<ifstream_t::char_type> istreambuf_iterator_t;
    typedef std::basic_istream<char> istream_t;
    typedef int hresult_t;
    typedef void* dll_t;
    typedef void* proc_t;
    typedef std::mutex mutex_t;

    inline string_t exe_suffix() { return _X(""); }

    inline int cstrcasecmp(const char* str1, const char* str2) { return ::strcasecmp(str1, str2); }
    inline int strcmp(const char_t* str1, const char_t* str2) { return ::strcmp(str1, str2); }
    inline int strcasecmp(const char_t* str1, const char_t* str2) { return ::strcasecmp(str1, str2); }
    inline int strncmp(const char_t* str1, const char_t* str2, int len) { return ::strncmp(str1, str2, len); }
    inline int strncasecmp(const char_t* str1, const char_t* str2, int len) { return ::strncasecmp(str1, str2, len); }

    inline size_t strlen(const char_t* str) { return ::strlen(str); }
    inline FILE * file_open(const string_t& path, const char_t* mode) { return fopen(path.c_str(), mode); }
    inline void file_vprintf(FILE* f, const char_t* format, va_list vl) { ::vfprintf(f, format, vl); ::fputc('\n', f); }
    inline void err_fputs(const char_t* message) { ::fputs(message, stderr); ::fputc(_X('\n'), stderr); }
    inline void out_vprintf(const char_t* format, va_list vl) { ::vfprintf(stdout, format, vl); ::fputc('\n', stdout); }
    inline int str_vprintf(char_t* str, size_t size, const char_t* format, va_list vl) { return ::vsnprintf(str, size, format, vl); }
    inline const char_t* strerror(int errnum) { return ::strerror(errnum); }

    inline bool pal_utf8string(const string_t& str, std::vector<char>* out) { out->assign(str.begin(), str.end()); out->push_back('\0'); return true; }
    inline bool utf8_palstring(const std::string& str, string_t* out) { out->assign(str); return true; }
    inline bool pal_clrstring(const string_t& str, std::vector<char>* out) { return pal_utf8string(str, out); }
    inline bool clr_palstring(const char* cstr, string_t* out) { out->assign(cstr); return true; }

    inline bool mkdir(const char_t* dir, int mode) { return ::mkdir(dir, mode) == 0; }
    inline bool rmdir(const char_t* path) { return ::rmdir(path) == 0; }
    inline int rename(const char_t* old_name, const char_t* new_name) { return ::rename(old_name, new_name); }
    inline int remove(const char_t* path) { return ::remove(path); }
    inline bool unmap_file(void* addr, size_t length) { return munmap(addr, length) == 0; }
    inline int get_pid() { return getpid(); }
    inline void sleep(uint32_t milliseconds) { usleep(milliseconds * 1000); }

#endif

    inline int snwprintf(char_t* buffer, size_t count, const char_t* format, ...)
    {
        va_list args;
        va_start(args, format);
        int ret = str_vprintf(buffer, count, format, args);
        va_end(args);
        return ret;
    }

    string_t to_string(int value);
    string_t get_timestamp();

    bool getcwd(string_t* recv);
    string_t to_lower(const string_t& in);


    inline void file_flush(FILE *f) { std::fflush(f); }
    inline void err_flush() { std::fflush(stderr); }
    inline void out_flush() { std::fflush(stdout); }

    // Based upon https://github.com/dotnet/core-setup/blob/master/src/Microsoft.DotNet.PlatformAbstractions/Native/PlatformApis.cs
    string_t get_current_os_rid_platform();
    inline string_t get_current_os_fallback_rid()
    {
        string_t fallbackRid(FALLBACK_HOST_RID);

        return fallbackRid;
    }

    void* map_file_readonly(const string_t& path, size_t& length);
    bool touch_file(const string_t& path);
    bool realpath(string_t* path, bool skip_error_logging = false);
    bool file_exists(const string_t& path);
    inline bool directory_exists(const string_t& path) { return file_exists(path); }
    void readdir(const string_t& path, const string_t& pattern, std::vector<string_t>* list);
    void readdir(const string_t& path, std::vector<string_t>* list);
    void readdir_onlydirectories(const string_t& path, const string_t& pattern, std::vector<string_t>* list);
    void readdir_onlydirectories(const string_t& path, std::vector<string_t>* list);

    bool get_own_executable_path(string_t* recv);
    bool get_own_module_path(string_t* recv);
    bool get_module_path(dll_t mod, string_t* recv);
    bool get_current_module(dll_t *mod);
    bool getenv(const char_t* name, string_t* recv);
    bool get_default_servicing_directory(string_t* recv);

    // Returns the globally registered install location (if any)
    bool get_dotnet_self_registered_dir(string_t* recv);
    // Returns name of the global registry location (for error messages)
    bool get_dotnet_self_registered_config_location(string_t* recv);

    // Returns the default install location for a given platform
    bool get_default_installation_dir(string_t* recv);

    // Returns the global locations to search for SDK/Frameworks - used when multi-level lookup is enabled
    bool get_global_dotnet_dirs(std::vector<string_t>* recv);

    bool get_default_breadcrumb_store(string_t* recv);
    bool is_path_rooted(const string_t& path);

    bool get_temp_directory(string_t& tmp_dir);

    // Returns a platform-specific, user-private directory within get_temp_directory()
    // that can be used for extracting out components of a single-file app.
    bool get_default_bundle_extraction_base_dir(string_t& extraction_dir);

    int xtoi(const char_t* input);

    bool get_loaded_library(const char_t *library_name, const char *symbol_name, /*out*/ dll_t *dll, /*out*/ string_t *path);
    bool load_library(const string_t* path, dll_t* dll);
    proc_t get_symbol(dll_t library, const char* name);
    void unload_library(dll_t library);

    bool is_running_in_wow64();

    bool are_paths_equal_with_normalized_casing(const string_t& path1, const string_t& path2);
}

#endif // PAL_H