authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-10-14 17:39:44-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-10-14 17:39:44-04:00
log61d715d784f3969ed9cff8b9f16cb6a051d3533a
treed4aa5138463b524db5119c1d41a33e1bf690fe97
parentad6eec94804d4bfc8c16ea8c852cd32f1f822e97

implement std.os.symLink for windows


3 files changed, 41 insertions(+), 16 deletions(-)

std/cstr.zig+1-1
...@@ -45,5 +45,5 @@ pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) -> %[]u8 {...@@ -45,5 +45,5 @@ pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) -> %[]u8 {
45 const result = %return allocator.alloc(u8, slice.len + 1);45 const result = %return allocator.alloc(u8, slice.len + 1);
46 mem.copy(u8, result, slice);46 mem.copy(u8, result, slice);
47 result[slice.len] = 0;47 result[slice.len] = 0;
48 return result[0..slice.len];48 return result;
49}49}
std/os/index.zig+23-1
...@@ -322,7 +322,7 @@ pub fn createNullDelimitedEnvMap(allocator: &Allocator, env_map: &const BufMap)...@@ -322,7 +322,7 @@ pub fn createNullDelimitedEnvMap(allocator: &Allocator, env_map: &const BufMap)
322322
323pub fn freeNullDelimitedEnvMap(allocator: &Allocator, envp_buf: []?&u8) {323pub fn freeNullDelimitedEnvMap(allocator: &Allocator, envp_buf: []?&u8) {
324 for (envp_buf) |env| {324 for (envp_buf) |env| {
325 const env_buf = if (env) |ptr| cstr.toSlice(ptr) else break;325 const env_buf = if (env) |ptr| ptr[0 .. cstr.len(ptr) + 1] else break;
326 allocator.free(env_buf);326 allocator.free(env_buf);
327 }327 }
328 allocator.free(envp_buf);328 allocator.free(envp_buf);
...@@ -490,6 +490,28 @@ test "os.getCwd" {...@@ -490,6 +490,28 @@ test "os.getCwd" {
490}490}
491491
492pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void {492pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void {
493 if (is_windows) {
494 return symLinkWindows(allocator, existing_path, new_path);
495 } else {
496 return symLinkPosix(allocator, existing_path, new_path);
497 }
498}
499
500pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void {
501 const existing_with_null = %return cstr.addNullByte(allocator, existing_path);
502 defer allocator.free(existing_with_null);
503 const new_with_null = %return cstr.addNullByte(allocator, new_path);
504 defer allocator.free(new_with_null);
505
506 if (windows.CreateSymbolicLinkA(existing_with_null.ptr, new_with_null.ptr, 0) == 0) {
507 const err = windows.GetLastError();
508 return switch (err) {
509 else => error.Unexpected,
510 };
511 }
512}
513
514pub fn symLinkPosix(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void {
493 const full_buf = %return allocator.alloc(u8, existing_path.len + new_path.len + 2);515 const full_buf = %return allocator.alloc(u8, existing_path.len + new_path.len + 2);
494 defer allocator.free(full_buf);516 defer allocator.free(full_buf);
495517
std/os/windows/index.zig+17-14
...@@ -25,6 +25,9 @@ pub extern "kernel32" stdcallcc fn CreateProcessA(lpApplicationName: ?LPCSTR, lp...@@ -25,6 +25,9 @@ pub extern "kernel32" stdcallcc fn CreateProcessA(lpApplicationName: ?LPCSTR, lp
25 dwCreationFlags: DWORD, lpEnvironment: ?LPVOID, lpCurrentDirectory: ?LPCSTR, lpStartupInfo: &STARTUPINFOA,25 dwCreationFlags: DWORD, lpEnvironment: ?LPVOID, lpCurrentDirectory: ?LPCSTR, lpStartupInfo: &STARTUPINFOA,
26 lpProcessInformation: &PROCESS_INFORMATION) -> BOOL;26 lpProcessInformation: &PROCESS_INFORMATION) -> BOOL;
2727
28pub extern "kernel32" stdcallcc fn CreateSymbolicLinkA(lpSymlinkFileName: LPCSTR, lpTargetFileName: LPCSTR,
29 dwFlags: DWORD) -> BOOLEAN;
30
28pub extern "kernel32" stdcallcc fn DeleteFileA(lpFileName: LPCSTR) -> bool;31pub extern "kernel32" stdcallcc fn DeleteFileA(lpFileName: LPCSTR) -> bool;
2932
30pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: UINT) -> noreturn;33pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: UINT) -> noreturn;
...@@ -74,34 +77,34 @@ pub extern "user32" stdcallcc fn MessageBoxA(hWnd: ?HANDLE, lpText: ?LPCTSTR, lp...@@ -74,34 +77,34 @@ pub extern "user32" stdcallcc fn MessageBoxA(hWnd: ?HANDLE, lpText: ?LPCTSTR, lp
7477
75pub const PROV_RSA_FULL = 1;78pub const PROV_RSA_FULL = 1;
7679
77pub const UNICODE = false;
78pub const LPTSTR = if (UNICODE) LPWSTR else LPSTR;
79pub const LPWSTR = &WCHAR;
80pub const LPSTR = &CHAR;
81pub const CHAR = u8;
82pub const PWSTR = &WCHAR;
83pub const SIZE_T = usize;
84
85pub const BOOL = bool;80pub const BOOL = bool;
81pub const BOOLEAN = BYTE;
86pub const BYTE = u8;82pub const BYTE = u8;
87pub const WORD = u16;83pub const CHAR = u8;
88pub const DWORD = u32;84pub const DWORD = u32;
89pub const FLOAT = f32;85pub const FLOAT = f32;
90pub const HANDLE = &c_void;86pub const HANDLE = &c_void;
91pub const HINSTANCE = &@OpaqueType();
92pub const HCRYPTPROV = ULONG_PTR;87pub const HCRYPTPROV = ULONG_PTR;
93pub const LPCTSTR = &const TCHAR;88pub const HINSTANCE = &@OpaqueType();
89pub const INT = c_int;
90pub const LPBYTE = &BYTE;
94pub const LPCSTR = &const CHAR;91pub const LPCSTR = &const CHAR;
92pub const LPCTSTR = &const TCHAR;
93pub const LPCVOID = &const c_void;
95pub const LPDWORD = &DWORD;94pub const LPDWORD = &DWORD;
95pub const LPSTR = &CHAR;
96pub const LPTSTR = if (UNICODE) LPWSTR else LPSTR;
96pub const LPVOID = &c_void;97pub const LPVOID = &c_void;
98pub const LPWSTR = &WCHAR;
97pub const PVOID = &c_void;99pub const PVOID = &c_void;
100pub const PWSTR = &WCHAR;
101pub const SIZE_T = usize;
98pub const TCHAR = if (UNICODE) WCHAR else u8;102pub const TCHAR = if (UNICODE) WCHAR else u8;
99pub const UINT = c_uint;103pub const UINT = c_uint;
100pub const INT = c_int;
101pub const ULONG_PTR = usize;104pub const ULONG_PTR = usize;
105pub const UNICODE = false;
102pub const WCHAR = u16;106pub const WCHAR = u16;
103pub const LPCVOID = &const c_void;107pub const WORD = u16;
104pub const LPBYTE = &BYTE;
105108
106/// The standard input device. Initially, this is the console input buffer, CONIN$.109/// The standard input device. Initially, this is the console input buffer, CONIN$.
107pub const STD_INPUT_HANDLE = @maxValue(DWORD) - 10 + 1;110pub const STD_INPUT_HANDLE = @maxValue(DWORD) - 10 + 1;