| ... | @@ -1544,6 +1544,40 @@ pub fn openSelfExe() -> %io.File { | ... | @@ -1544,6 +1544,40 @@ pub fn openSelfExe() -> %io.File { |
| 1544 | } | 1544 | } |
| 1545 | } | 1545 | } |
| 1546 | | 1546 | |
| | 1547 | /// Get the path to the current executable. |
| | 1548 | /// If you only need the directory, use selfExeDirPath. |
| | 1549 | /// If you only want an open file handle, use openSelfExe. |
| | 1550 | /// This function may return an error if the current executable |
| | 1551 | /// was deleted after spawning. |
| | 1552 | /// Caller owns returned memory. |
| | 1553 | pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 { |
| | 1554 | switch (builtin.os) { |
| | 1555 | Os.linux => { |
| | 1556 | @compileError("TODO: selfExePath for linux"); |
| | 1557 | }, |
| | 1558 | Os.windows => { |
| | 1559 | var out_path = %return Buffer.initSize(allocator, 256); |
| | 1560 | %defer out_path.deinit(); |
| | 1561 | while (true) { |
| | 1562 | const dword_len = %return math.cast(windows.DWORD, out_path.len()); |
| | 1563 | const copied_amt = windows.GetModuleFileNameA(null, out_path.ptr(), dword_len); |
| | 1564 | if (copied_amt <= 0) { |
| | 1565 | const err = windows.GetLastError(); |
| | 1566 | return switch (err) { |
| | 1567 | else => unexpectedErrorWindows(err), |
| | 1568 | }; |
| | 1569 | } |
| | 1570 | if (copied_amt < out_path.len()) { |
| | 1571 | out_path.shrink(copied_amt); |
| | 1572 | return out_path.toOwnedSlice(); |
| | 1573 | } |
| | 1574 | %return out_path.resize(out_path.len() * 2); |
| | 1575 | } |
| | 1576 | }, |
| | 1577 | else => @compileError("Unsupported OS"), |
| | 1578 | } |
| | 1579 | } |
| | 1580 | |
| 1547 | /// Get the directory path that contains the current executable. | 1581 | /// Get the directory path that contains the current executable. |
| 1548 | /// Caller owns returned memory. | 1582 | /// Caller owns returned memory. |
| 1549 | pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 { | 1583 | pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 { |
| ... | @@ -1559,19 +1593,10 @@ pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 { | ... | @@ -1559,19 +1593,10 @@ pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 { |
| 1559 | return allocator.shrink(u8, full_exe_path, dir.len); | 1593 | return allocator.shrink(u8, full_exe_path, dir.len); |
| 1560 | }, | 1594 | }, |
| 1561 | Os.windows => { | 1595 | Os.windows => { |
| 1562 | @panic("TODO windows std.os.selfExeDirPath"); | 1596 | const self_exe_path = %return selfExePath(allocator); |
| 1563 | //buf_resize(out_path, 256); | 1597 | %defer allocator.free(self_exe_path); |
| 1564 | //for (;;) { | 1598 | const dirname = os.path.dirname(self_exe_path); |
| 1565 | // DWORD copied_amt = GetModuleFileName(nullptr, buf_ptr(out_path), buf_len(out_path)); | 1599 | return allocator.shrink(u8, self_exe_path, dirname.len); |
| 1566 | // if (copied_amt <= 0) { | | |
| 1567 | // return ErrorFileNotFound; | | |
| 1568 | // } | | |
| 1569 | // if (copied_amt < buf_len(out_path)) { | | |
| 1570 | // buf_resize(out_path, copied_amt); | | |
| 1571 | // return 0; | | |
| 1572 | // } | | |
| 1573 | // buf_resize(out_path, buf_len(out_path) * 2); | | |
| 1574 | //} | | |
| 1575 | }, | 1600 | }, |
| 1576 | else => @compileError("unimplemented: std.os.selfExeDirPath for " ++ @tagName(builtin.os)), | 1601 | else => @compileError("unimplemented: std.os.selfExeDirPath for " ++ @tagName(builtin.os)), |
| 1577 | } | 1602 | } |