aboutsummaryrefslogtreecommitdiff
path: root/std
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-10-14 17:39:44 -0400
committerAndrew Kelley <superjoe30@gmail.com>2017-10-14 17:39:44 -0400
commit61d715d784f3969ed9cff8b9f16cb6a051d3533a (patch)
treed4aa5138463b524db5119c1d41a33e1bf690fe97 /std
parentad6eec94804d4bfc8c16ea8c852cd32f1f822e97 (diff)
downloadzig-61d715d784f3969ed9cff8b9f16cb6a051d3533a.tar.gz
zig-61d715d784f3969ed9cff8b9f16cb6a051d3533a.zip
implement std.os.symLink for windows
Diffstat (limited to 'std')
-rw-r--r--std/cstr.zig2
-rw-r--r--std/os/index.zig24
-rw-r--r--std/os/windows/index.zig31
3 files changed, 41 insertions, 16 deletions
diff --git a/std/cstr.zig b/std/cstr.zig
index 7e61381b90..e29f90fc01 100644
--- a/std/cstr.zig
+++ b/std/cstr.zig
@@ -45,5 +45,5 @@ pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) -> %[]u8 {
const result = %return allocator.alloc(u8, slice.len + 1);
mem.copy(u8, result, slice);
result[slice.len] = 0;
- return result[0..slice.len];
+ return result;
}
diff --git a/std/os/index.zig b/std/os/index.zig
index a9d91972b1..0b536d3193 100644
--- a/std/os/index.zig
+++ b/std/os/index.zig
@@ -322,7 +322,7 @@ pub fn createNullDelimitedEnvMap(allocator: &Allocator, env_map: &const BufMap)
pub fn freeNullDelimitedEnvMap(allocator: &Allocator, envp_buf: []?&u8) {
for (envp_buf) |env| {
- const env_buf = if (env) |ptr| cstr.toSlice(ptr) else break;
+ const env_buf = if (env) |ptr| ptr[0 .. cstr.len(ptr) + 1] else break;
allocator.free(env_buf);
}
allocator.free(envp_buf);
@@ -490,6 +490,28 @@ test "os.getCwd" {
}
pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void {
+ if (is_windows) {
+ return symLinkWindows(allocator, existing_path, new_path);
+ } else {
+ return symLinkPosix(allocator, existing_path, new_path);
+ }
+}
+
+pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void {
+ const existing_with_null = %return cstr.addNullByte(allocator, existing_path);
+ defer allocator.free(existing_with_null);
+ const new_with_null = %return cstr.addNullByte(allocator, new_path);
+ defer allocator.free(new_with_null);
+
+ if (windows.CreateSymbolicLinkA(existing_with_null.ptr, new_with_null.ptr, 0) == 0) {
+ const err = windows.GetLastError();
+ return switch (err) {
+ else => error.Unexpected,
+ };
+ }
+}
+
+pub fn symLinkPosix(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void {
const full_buf = %return allocator.alloc(u8, existing_path.len + new_path.len + 2);
defer allocator.free(full_buf);
diff --git a/std/os/windows/index.zig b/std/os/windows/index.zig
index 424b3eba4f..eb066c7aa3 100644
--- a/std/os/windows/index.zig
+++ b/std/os/windows/index.zig
@@ -25,6 +25,9 @@ pub extern "kernel32" stdcallcc fn CreateProcessA(lpApplicationName: ?LPCSTR, lp
dwCreationFlags: DWORD, lpEnvironment: ?LPVOID, lpCurrentDirectory: ?LPCSTR, lpStartupInfo: &STARTUPINFOA,
lpProcessInformation: &PROCESS_INFORMATION) -> BOOL;
+pub extern "kernel32" stdcallcc fn CreateSymbolicLinkA(lpSymlinkFileName: LPCSTR, lpTargetFileName: LPCSTR,
+ dwFlags: DWORD) -> BOOLEAN;
+
pub extern "kernel32" stdcallcc fn DeleteFileA(lpFileName: LPCSTR) -> bool;
pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: UINT) -> noreturn;
@@ -74,34 +77,34 @@ pub extern "user32" stdcallcc fn MessageBoxA(hWnd: ?HANDLE, lpText: ?LPCTSTR, lp
pub const PROV_RSA_FULL = 1;
-pub const UNICODE = false;
-pub const LPTSTR = if (UNICODE) LPWSTR else LPSTR;
-pub const LPWSTR = &WCHAR;
-pub const LPSTR = &CHAR;
-pub const CHAR = u8;
-pub const PWSTR = &WCHAR;
-pub const SIZE_T = usize;
-
pub const BOOL = bool;
+pub const BOOLEAN = BYTE;
pub const BYTE = u8;
-pub const WORD = u16;
+pub const CHAR = u8;
pub const DWORD = u32;
pub const FLOAT = f32;
pub const HANDLE = &c_void;
-pub const HINSTANCE = &@OpaqueType();
pub const HCRYPTPROV = ULONG_PTR;
-pub const LPCTSTR = &const TCHAR;
+pub const HINSTANCE = &@OpaqueType();
+pub const INT = c_int;
+pub const LPBYTE = &BYTE;
pub const LPCSTR = &const CHAR;
+pub const LPCTSTR = &const TCHAR;
+pub const LPCVOID = &const c_void;
pub const LPDWORD = &DWORD;
+pub const LPSTR = &CHAR;
+pub const LPTSTR = if (UNICODE) LPWSTR else LPSTR;
pub const LPVOID = &c_void;
+pub const LPWSTR = &WCHAR;
pub const PVOID = &c_void;
+pub const PWSTR = &WCHAR;
+pub const SIZE_T = usize;
pub const TCHAR = if (UNICODE) WCHAR else u8;
pub const UINT = c_uint;
-pub const INT = c_int;
pub const ULONG_PTR = usize;
+pub const UNICODE = false;
pub const WCHAR = u16;
-pub const LPCVOID = &const c_void;
-pub const LPBYTE = &BYTE;
+pub const WORD = u16;
/// The standard input device. Initially, this is the console input buffer, CONIN$.
pub const STD_INPUT_HANDLE = @maxValue(DWORD) - 10 + 1;