authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-25 00:30:28-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-25 00:43:36-05:00
log29e438fd1f77a13c3a3f128434198ac024d3e195
tree73235c0b283adfdf0e621b7d0ed306f420d3d748
parent15d415e10b81a66fa3b887fb2a0c20bbcd614d94
signaturelock-open Commit is signed but in an unrecognized format.

more sentinel-terminated pointers std lib integration

See #3767

14 files changed, 98 insertions(+), 94 deletions(-)

doc/langref.html.in+1-1
...@@ -4865,7 +4865,7 @@ const mem = std.mem;...@@ -4865,7 +4865,7 @@ const mem = std.mem;
4865test "cast *[1][*]const u8 to [*]const ?[*]const u8" {4865test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
4866 const window_name = [1][*]const u8{"window name"};4866 const window_name = [1][*]const u8{"window name"};
4867 const x: [*]const ?[*]const u8 = &window_name;4867 const x: [*]const ?[*]const u8 = &window_name;
4868 assert(mem.eql(u8, std.mem.toSliceConst(u8, x[0].?), "window name"));4868 assert(mem.eql(u8, std.mem.toSliceConst(u8, @ptrCast([*:0]const u8, x[0].?)), "window name"));
4869}4869}
4870 {#code_end#}4870 {#code_end#}
4871 {#header_close#}4871 {#header_close#}
lib/std/c.zig+1-1
...@@ -102,7 +102,7 @@ pub extern "c" fn execve(path: [*]const u8, argv: [*]const ?[*]const u8, envp: [...@@ -102,7 +102,7 @@ pub extern "c" fn execve(path: [*]const u8, argv: [*]const ?[*]const u8, envp: [
102pub extern "c" fn dup(fd: fd_t) c_int;102pub extern "c" fn dup(fd: fd_t) c_int;
103pub extern "c" fn dup2(old_fd: fd_t, new_fd: fd_t) c_int;103pub extern "c" fn dup2(old_fd: fd_t, new_fd: fd_t) c_int;
104pub extern "c" fn readlink(noalias path: [*]const u8, noalias buf: [*]u8, bufsize: usize) isize;104pub extern "c" fn readlink(noalias path: [*]const u8, noalias buf: [*]u8, bufsize: usize) isize;
105pub extern "c" fn realpath(noalias file_name: [*]const u8, noalias resolved_name: [*]u8) ?[*]u8;105pub extern "c" fn realpath(noalias file_name: [*]const u8, noalias resolved_name: [*]u8) ?[*:0]u8;
106pub extern "c" fn sigprocmask(how: c_int, noalias set: *const sigset_t, noalias oset: ?*sigset_t) c_int;106pub extern "c" fn sigprocmask(how: c_int, noalias set: *const sigset_t, noalias oset: ?*sigset_t) c_int;
107pub extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int;107pub extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int;
108pub extern "c" fn sigaction(sig: c_int, noalias act: *const Sigaction, noalias oact: ?*Sigaction) c_int;108pub extern "c" fn sigaction(sig: c_int, noalias act: *const Sigaction, noalias oact: ?*Sigaction) c_int;
lib/std/debug.zig+8-8
...@@ -401,7 +401,7 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres...@@ -401,7 +401,7 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres
401 const vaddr_start = coff_section.header.virtual_address + proc_sym.CodeOffset;401 const vaddr_start = coff_section.header.virtual_address + proc_sym.CodeOffset;
402 const vaddr_end = vaddr_start + proc_sym.CodeSize;402 const vaddr_end = vaddr_start + proc_sym.CodeSize;
403 if (relative_address >= vaddr_start and relative_address < vaddr_end) {403 if (relative_address >= vaddr_start and relative_address < vaddr_end) {
404 break mem.toSliceConst(u8, @ptrCast([*]u8, proc_sym) + @sizeOf(pdb.ProcSym));404 break mem.toSliceConst(u8, @ptrCast([*:0]u8, proc_sym) + @sizeOf(pdb.ProcSym));
405 }405 }
406 },406 },
407 else => {},407 else => {},
...@@ -703,9 +703,9 @@ fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tt...@@ -703,9 +703,9 @@ fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tt
703 return;703 return;
704 };704 };
705705
706 const symbol_name = mem.toSliceConst(u8, di.strings.ptr + symbol.nlist.n_strx);706 const symbol_name = mem.toSliceConst(u8, @ptrCast([*:0]const u8, di.strings.ptr + symbol.nlist.n_strx));
707 const compile_unit_name = if (symbol.ofile) |ofile| blk: {707 const compile_unit_name = if (symbol.ofile) |ofile| blk: {
708 const ofile_path = mem.toSliceConst(u8, di.strings.ptr + ofile.n_strx);708 const ofile_path = mem.toSliceConst(u8, @ptrCast([*:0]const u8, di.strings.ptr + ofile.n_strx));
709 break :blk fs.path.basename(ofile_path);709 break :blk fs.path.basename(ofile_path);
710 } else "???";710 } else "???";
711 if (getLineNumberInfoMacOs(di, symbol.*, adjusted_addr)) |line_info| {711 if (getLineNumberInfoMacOs(di, symbol.*, adjusted_addr)) |line_info| {
...@@ -915,7 +915,7 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {...@@ -915,7 +915,7 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {
915 for (present) |_| {915 for (present) |_| {
916 const name_offset = try pdb_stream.stream.readIntLittle(u32);916 const name_offset = try pdb_stream.stream.readIntLittle(u32);
917 const name_index = try pdb_stream.stream.readIntLittle(u32);917 const name_index = try pdb_stream.stream.readIntLittle(u32);
918 const name = mem.toSlice(u8, name_bytes.ptr + name_offset);918 const name = mem.toSlice(u8, @ptrCast([*:0]u8, name_bytes.ptr + name_offset));
919 if (mem.eql(u8, name, "/names")) {919 if (mem.eql(u8, name, "/names")) {
920 break :str_tab_index name_index;920 break :str_tab_index name_index;
921 }921 }
...@@ -1708,7 +1708,7 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u...@@ -1708,7 +1708,7 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u
1708 const gop = try di.ofiles.getOrPut(ofile);1708 const gop = try di.ofiles.getOrPut(ofile);
1709 const mach_o_file = if (gop.found_existing) &gop.kv.value else blk: {1709 const mach_o_file = if (gop.found_existing) &gop.kv.value else blk: {
1710 errdefer _ = di.ofiles.remove(ofile);1710 errdefer _ = di.ofiles.remove(ofile);
1711 const ofile_path = mem.toSliceConst(u8, di.strings.ptr + ofile.n_strx);1711 const ofile_path = mem.toSliceConst(u8, @ptrCast([*:0]const u8, di.strings.ptr + ofile.n_strx));
17121712
1713 gop.kv.value = MachOFile{1713 gop.kv.value = MachOFile{
1714 .bytes = try std.fs.Dir.cwd().readFileAllocAligned(1714 .bytes = try std.fs.Dir.cwd().readFileAllocAligned(
...@@ -1741,7 +1741,7 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u...@@ -1741,7 +1741,7 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u
1741 if (sect.flags & macho.SECTION_TYPE == macho.S_REGULAR and1741 if (sect.flags & macho.SECTION_TYPE == macho.S_REGULAR and
1742 (sect.flags & macho.SECTION_ATTRIBUTES) & macho.S_ATTR_DEBUG == macho.S_ATTR_DEBUG)1742 (sect.flags & macho.SECTION_ATTRIBUTES) & macho.S_ATTR_DEBUG == macho.S_ATTR_DEBUG)
1743 {1743 {
1744 const sect_name = mem.toSliceConst(u8, &sect.sectname);1744 const sect_name = mem.toSliceConst(u8, @ptrCast([*:0]const u8, &sect.sectname));
1745 if (mem.eql(u8, sect_name, "__debug_line")) {1745 if (mem.eql(u8, sect_name, "__debug_line")) {
1746 gop.kv.value.sect_debug_line = sect;1746 gop.kv.value.sect_debug_line = sect;
1747 } else if (mem.eql(u8, sect_name, "__debug_info")) {1747 } else if (mem.eql(u8, sect_name, "__debug_info")) {
...@@ -2323,8 +2323,8 @@ fn readInitialLengthMem(ptr: *[*]const u8, is_64: *bool) !u64 {...@@ -2323,8 +2323,8 @@ fn readInitialLengthMem(ptr: *[*]const u8, is_64: *bool) !u64 {
2323 }2323 }
2324}2324}
23252325
2326fn readStringMem(ptr: *[*]const u8) []const u8 {2326fn readStringMem(ptr: *[*]const u8) [:0]const u8 {
2327 const result = mem.toSliceConst(u8, ptr.*);2327 const result = mem.toSliceConst(u8, @ptrCast([*:0]const u8, ptr.*));
2328 ptr.* += result.len + 1;2328 ptr.* += result.len + 1;
2329 return result;2329 return result;
2330}2330}
lib/std/dynamic_library.zig+4-4
...@@ -140,7 +140,7 @@ pub const LinuxDynLib = struct {...@@ -140,7 +140,7 @@ pub const LinuxDynLib = struct {
140};140};
141141
142pub const ElfLib = struct {142pub const ElfLib = struct {
143 strings: [*]u8,143 strings: [*:0]u8,
144 syms: [*]elf.Sym,144 syms: [*]elf.Sym,
145 hashtab: [*]os.Elf_Symndx,145 hashtab: [*]os.Elf_Symndx,
146 versym: ?[*]u16,146 versym: ?[*]u16,
...@@ -175,7 +175,7 @@ pub const ElfLib = struct {...@@ -175,7 +175,7 @@ pub const ElfLib = struct {
175 const dynv = maybe_dynv orelse return error.MissingDynamicLinkingInformation;175 const dynv = maybe_dynv orelse return error.MissingDynamicLinkingInformation;
176 if (base == maxInt(usize)) return error.BaseNotFound;176 if (base == maxInt(usize)) return error.BaseNotFound;
177177
178 var maybe_strings: ?[*]u8 = null;178 var maybe_strings: ?[*:0]u8 = null;
179 var maybe_syms: ?[*]elf.Sym = null;179 var maybe_syms: ?[*]elf.Sym = null;
180 var maybe_hashtab: ?[*]os.Elf_Symndx = null;180 var maybe_hashtab: ?[*]os.Elf_Symndx = null;
181 var maybe_versym: ?[*]u16 = null;181 var maybe_versym: ?[*]u16 = null;
...@@ -186,7 +186,7 @@ pub const ElfLib = struct {...@@ -186,7 +186,7 @@ pub const ElfLib = struct {
186 while (dynv[i] != 0) : (i += 2) {186 while (dynv[i] != 0) : (i += 2) {
187 const p = base + dynv[i + 1];187 const p = base + dynv[i + 1];
188 switch (dynv[i]) {188 switch (dynv[i]) {
189 elf.DT_STRTAB => maybe_strings = @intToPtr([*]u8, p),189 elf.DT_STRTAB => maybe_strings = @intToPtr([*:0]u8, p),
190 elf.DT_SYMTAB => maybe_syms = @intToPtr([*]elf.Sym, p),190 elf.DT_SYMTAB => maybe_syms = @intToPtr([*]elf.Sym, p),
191 elf.DT_HASH => maybe_hashtab = @intToPtr([*]os.Elf_Symndx, p),191 elf.DT_HASH => maybe_hashtab = @intToPtr([*]os.Elf_Symndx, p),
192 elf.DT_VERSYM => maybe_versym = @intToPtr([*]u16, p),192 elf.DT_VERSYM => maybe_versym = @intToPtr([*]u16, p),
...@@ -230,7 +230,7 @@ pub const ElfLib = struct {...@@ -230,7 +230,7 @@ pub const ElfLib = struct {
230 }230 }
231};231};
232232
233fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [*]u8) bool {233fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [*:0]u8) bool {
234 var def = def_arg;234 var def = def_arg;
235 const vsym = @bitCast(u32, vsym_arg) & 0x7fff;235 const vsym = @bitCast(u32, vsym_arg) & 0x7fff;
236 while (true) {236 while (true) {
lib/std/event/fs.zig+2-4
...@@ -58,8 +58,7 @@ pub const Request = struct {...@@ -58,8 +58,7 @@ pub const Request = struct {
58 };58 };
5959
60 pub const Open = struct {60 pub const Open = struct {
61 /// must be null terminated. TODO https://github.com/ziglang/zig/issues/26561 path: [:0]const u8,
62 path: []const u8,
63 flags: u32,62 flags: u32,
64 mode: File.Mode,63 mode: File.Mode,
65 result: Error!fd_t,64 result: Error!fd_t,
...@@ -68,8 +67,7 @@ pub const Request = struct {...@@ -68,8 +67,7 @@ pub const Request = struct {
68 };67 };
6968
70 pub const WriteFile = struct {69 pub const WriteFile = struct {
71 /// must be null terminated. TODO https://github.com/ziglang/zig/issues/26570 path: [:0]const u8,
72 path: []const u8,
73 contents: []const u8,71 contents: []const u8,
74 mode: File.Mode,72 mode: File.Mode,
75 result: Error!void,73 result: Error!void,
lib/std/fs.zig+23-21
...@@ -28,6 +28,7 @@ pub const GetAppDataDirError = @import("fs/get_app_data_dir.zig").GetAppDataDirE...@@ -28,6 +28,7 @@ pub const GetAppDataDirError = @import("fs/get_app_data_dir.zig").GetAppDataDirE
28/// This represents the maximum size of a UTF-8 encoded file path.28/// This represents the maximum size of a UTF-8 encoded file path.
29/// All file system operations which return a path are guaranteed to29/// All file system operations which return a path are guaranteed to
30/// fit into a UTF-8 encoded array of this length.30/// fit into a UTF-8 encoded array of this length.
31/// The byte count includes room for a null sentinel byte.
31pub const MAX_PATH_BYTES = switch (builtin.os) {32pub const MAX_PATH_BYTES = switch (builtin.os) {
32 .linux, .macosx, .ios, .freebsd, .netbsd, .dragonfly => os.PATH_MAX,33 .linux, .macosx, .ios, .freebsd, .netbsd, .dragonfly => os.PATH_MAX,
33 // Each UTF-16LE character may be expanded to 3 UTF-8 bytes.34 // Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
...@@ -227,7 +228,7 @@ pub const AtomicFile = struct {...@@ -227,7 +228,7 @@ pub const AtomicFile = struct {
227 try crypto.randomBytes(rand_buf[0..]);228 try crypto.randomBytes(rand_buf[0..]);
228 b64_fs_encoder.encode(tmp_path_buf[dirname_component_len..tmp_path_len], rand_buf);229 b64_fs_encoder.encode(tmp_path_buf[dirname_component_len..tmp_path_len], rand_buf);
229230
230 const file = File.openWriteNoClobberC(&tmp_path_buf, mode) catch |err| switch (err) {231 const file = File.openWriteNoClobberC(@ptrCast([*:0]u8, &tmp_path_buf), mode) catch |err| switch (err) {
231 error.PathAlreadyExists => continue,232 error.PathAlreadyExists => continue,
232 // TODO zig should figure out that this error set does not include PathAlreadyExists since233 // TODO zig should figure out that this error set does not include PathAlreadyExists since
233 // it is handled in the above switch234 // it is handled in the above switch
...@@ -247,7 +248,7 @@ pub const AtomicFile = struct {...@@ -247,7 +248,7 @@ pub const AtomicFile = struct {
247 pub fn deinit(self: *AtomicFile) void {248 pub fn deinit(self: *AtomicFile) void {
248 if (!self.finished) {249 if (!self.finished) {
249 self.file.close();250 self.file.close();
250 deleteFileC(&self.tmp_path_buf) catch {};251 deleteFileC(@ptrCast([*:0]u8, &self.tmp_path_buf)) catch {};
251 self.finished = true;252 self.finished = true;
252 }253 }
253 }254 }
...@@ -258,11 +259,11 @@ pub const AtomicFile = struct {...@@ -258,11 +259,11 @@ pub const AtomicFile = struct {
258 self.finished = true;259 self.finished = true;
259 if (builtin.os == .windows) {260 if (builtin.os == .windows) {
260 const dest_path_w = try os.windows.sliceToPrefixedFileW(self.dest_path);261 const dest_path_w = try os.windows.sliceToPrefixedFileW(self.dest_path);
261 const tmp_path_w = try os.windows.cStrToPrefixedFileW(&self.tmp_path_buf);262 const tmp_path_w = try os.windows.cStrToPrefixedFileW(@ptrCast([*:0]u8, &self.tmp_path_buf));
262 return os.renameW(&tmp_path_w, &dest_path_w);263 return os.renameW(&tmp_path_w, &dest_path_w);
263 }264 }
264 const dest_path_c = try os.toPosixPath(self.dest_path);265 const dest_path_c = try os.toPosixPath(self.dest_path);
265 return os.renameC(&self.tmp_path_buf, &dest_path_c);266 return os.renameC(@ptrCast([*:0]u8, &self.tmp_path_buf), &dest_path_c);
266 }267 }
267};268};
268269
...@@ -274,12 +275,12 @@ pub fn makeDir(dir_path: []const u8) !void {...@@ -274,12 +275,12 @@ pub fn makeDir(dir_path: []const u8) !void {
274}275}
275276
276/// Same as `makeDir` except the parameter is a null-terminated UTF8-encoded string.277/// Same as `makeDir` except the parameter is a null-terminated UTF8-encoded string.
277pub fn makeDirC(dir_path: [*]const u8) !void {278pub fn makeDirC(dir_path: [*:0]const u8) !void {
278 return os.mkdirC(dir_path, default_new_dir_mode);279 return os.mkdirC(dir_path, default_new_dir_mode);
279}280}
280281
281/// Same as `makeDir` except the parameter is a null-terminated UTF16LE-encoded string.282/// Same as `makeDir` except the parameter is a null-terminated UTF16LE-encoded string.
282pub fn makeDirW(dir_path: [*]const u16) !void {283pub fn makeDirW(dir_path: [*:0]const u16) !void {
283 return os.mkdirW(dir_path, default_new_dir_mode);284 return os.mkdirW(dir_path, default_new_dir_mode);
284}285}
285286
...@@ -327,12 +328,12 @@ pub fn deleteDir(dir_path: []const u8) !void {...@@ -327,12 +328,12 @@ pub fn deleteDir(dir_path: []const u8) !void {
327}328}
328329
329/// Same as `deleteDir` except the parameter is a null-terminated UTF8-encoded string.330/// Same as `deleteDir` except the parameter is a null-terminated UTF8-encoded string.
330pub fn deleteDirC(dir_path: [*]const u8) !void {331pub fn deleteDirC(dir_path: [*:0]const u8) !void {
331 return os.rmdirC(dir_path);332 return os.rmdirC(dir_path);
332}333}
333334
334/// Same as `deleteDir` except the parameter is a null-terminated UTF16LE-encoded string.335/// Same as `deleteDir` except the parameter is a null-terminated UTF16LE-encoded string.
335pub fn deleteDirW(dir_path: [*]const u16) !void {336pub fn deleteDirW(dir_path: [*:0]const u16) !void {
336 return os.rmdirW(dir_path);337 return os.rmdirW(dir_path);
337}338}
338339
...@@ -688,7 +689,7 @@ pub const Dir = struct {...@@ -688,7 +689,7 @@ pub const Dir = struct {
688 }689 }
689690
690 /// Same as `open` except the parameter is null-terminated.691 /// Same as `open` except the parameter is null-terminated.
691 pub fn openC(dir_path_c: [*]const u8) OpenError!Dir {692 pub fn openC(dir_path_c: [*:0]const u8) OpenError!Dir {
692 return cwd().openDirC(dir_path_c);693 return cwd().openDirC(dir_path_c);
693 }694 }
694695
...@@ -708,7 +709,7 @@ pub const Dir = struct {...@@ -708,7 +709,7 @@ pub const Dir = struct {
708 }709 }
709710
710 /// Call `File.close` on the result when done.711 /// Call `File.close` on the result when done.
711 pub fn openReadC(self: Dir, sub_path: [*]const u8) File.OpenError!File {712 pub fn openReadC(self: Dir, sub_path: [*:0]const u8) File.OpenError!File {
712 if (builtin.os == .windows) {713 if (builtin.os == .windows) {
713 const path_w = try os.windows.cStrToPrefixedFileW(sub_path);714 const path_w = try os.windows.cStrToPrefixedFileW(sub_path);
714 return self.openReadW(&path_w);715 return self.openReadW(&path_w);
...@@ -719,7 +720,7 @@ pub const Dir = struct {...@@ -719,7 +720,7 @@ pub const Dir = struct {
719 return File.openHandle(fd);720 return File.openHandle(fd);
720 }721 }
721722
722 pub fn openReadW(self: Dir, sub_path_w: [*]const u16) File.OpenError!File {723 pub fn openReadW(self: Dir, sub_path_w: [*:0]const u16) File.OpenError!File {
723 const w = os.windows;724 const w = os.windows;
724725
725 var result = File{ .handle = undefined };726 var result = File{ .handle = undefined };
...@@ -786,7 +787,7 @@ pub const Dir = struct {...@@ -786,7 +787,7 @@ pub const Dir = struct {
786 }787 }
787788
788 /// Same as `openDir` except the parameter is null-terminated.789 /// Same as `openDir` except the parameter is null-terminated.
789 pub fn openDirC(self: Dir, sub_path_c: [*]const u8) OpenError!Dir {790 pub fn openDirC(self: Dir, sub_path_c: [*:0]const u8) OpenError!Dir {
790 if (builtin.os == .windows) {791 if (builtin.os == .windows) {
791 const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path_c);792 const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path_c);
792 return self.openDirW(&sub_path_w);793 return self.openDirW(&sub_path_w);
...@@ -805,7 +806,7 @@ pub const Dir = struct {...@@ -805,7 +806,7 @@ pub const Dir = struct {
805806
806 /// Same as `openDir` except the path parameter is UTF16LE, NT-prefixed.807 /// Same as `openDir` except the path parameter is UTF16LE, NT-prefixed.
807 /// This function is Windows-only.808 /// This function is Windows-only.
808 pub fn openDirW(self: Dir, sub_path_w: [*]const u16) OpenError!Dir {809 pub fn openDirW(self: Dir, sub_path_w: [*:0]const u16) OpenError!Dir {
809 const w = os.windows;810 const w = os.windows;
810811
811 var result = Dir{812 var result = Dir{
...@@ -868,7 +869,7 @@ pub const Dir = struct {...@@ -868,7 +869,7 @@ pub const Dir = struct {
868 }869 }
869870
870 /// Same as `deleteFile` except the parameter is null-terminated.871 /// Same as `deleteFile` except the parameter is null-terminated.
871 pub fn deleteFileC(self: Dir, sub_path_c: [*]const u8) DeleteFileError!void {872 pub fn deleteFileC(self: Dir, sub_path_c: [*:0]const u8) DeleteFileError!void {
872 os.unlinkatC(self.fd, sub_path_c, 0) catch |err| switch (err) {873 os.unlinkatC(self.fd, sub_path_c, 0) catch |err| switch (err) {
873 error.DirNotEmpty => unreachable, // not passing AT_REMOVEDIR874 error.DirNotEmpty => unreachable, // not passing AT_REMOVEDIR
874 else => |e| return e,875 else => |e| return e,
...@@ -903,7 +904,7 @@ pub const Dir = struct {...@@ -903,7 +904,7 @@ pub const Dir = struct {
903 }904 }
904905
905 /// Same as `deleteDir` except the parameter is null-terminated.906 /// Same as `deleteDir` except the parameter is null-terminated.
906 pub fn deleteDirC(self: Dir, sub_path_c: [*]const u8) DeleteDirError!void {907 pub fn deleteDirC(self: Dir, sub_path_c: [*:0]const u8) DeleteDirError!void {
907 os.unlinkatC(self.fd, sub_path_c, os.AT_REMOVEDIR) catch |err| switch (err) {908 os.unlinkatC(self.fd, sub_path_c, os.AT_REMOVEDIR) catch |err| switch (err) {
908 error.IsDir => unreachable, // not possible since we pass AT_REMOVEDIR909 error.IsDir => unreachable, // not possible since we pass AT_REMOVEDIR
909 else => |e| return e,910 else => |e| return e,
...@@ -912,7 +913,7 @@ pub const Dir = struct {...@@ -912,7 +913,7 @@ pub const Dir = struct {
912913
913 /// Same as `deleteDir` except the parameter is UTF16LE, NT prefixed.914 /// Same as `deleteDir` except the parameter is UTF16LE, NT prefixed.
914 /// This function is Windows-only.915 /// This function is Windows-only.
915 pub fn deleteDirW(self: Dir, sub_path_w: [*]const u16) DeleteDirError!void {916 pub fn deleteDirW(self: Dir, sub_path_w: [*:0]const u16) DeleteDirError!void {
916 os.unlinkatW(self.fd, sub_path_w, os.AT_REMOVEDIR) catch |err| switch (err) {917 os.unlinkatW(self.fd, sub_path_w, os.AT_REMOVEDIR) catch |err| switch (err) {
917 error.IsDir => unreachable, // not possible since we pass AT_REMOVEDIR918 error.IsDir => unreachable, // not possible since we pass AT_REMOVEDIR
918 else => |e| return e,919 else => |e| return e,
...@@ -927,7 +928,7 @@ pub const Dir = struct {...@@ -927,7 +928,7 @@ pub const Dir = struct {
927 }928 }
928929
929 /// Same as `readLink`, except the `pathname` parameter is null-terminated.930 /// Same as `readLink`, except the `pathname` parameter is null-terminated.
930 pub fn readLinkC(self: Dir, sub_path_c: [*]const u8, buffer: *[MAX_PATH_BYTES]u8) ![]u8 {931 pub fn readLinkC(self: Dir, sub_path_c: [*:0]const u8, buffer: *[MAX_PATH_BYTES]u8) ![]u8 {
931 return os.readlinkatC(self.fd, sub_path_c, buffer);932 return os.readlinkatC(self.fd, sub_path_c, buffer);
932 }933 }
933934
...@@ -1250,7 +1251,8 @@ pub fn openSelfExe() OpenSelfExeError!File {...@@ -1250,7 +1251,8 @@ pub fn openSelfExe() OpenSelfExeError!File {
1250 var buf: [MAX_PATH_BYTES]u8 = undefined;1251 var buf: [MAX_PATH_BYTES]u8 = undefined;
1251 const self_exe_path = try selfExePath(&buf);1252 const self_exe_path = try selfExePath(&buf);
1252 buf[self_exe_path.len] = 0;1253 buf[self_exe_path.len] = 0;
1253 return File.openReadC(self_exe_path.ptr);1254 // TODO avoid @ptrCast here using slice syntax with https://github.com/ziglang/zig/issues/3731
1255 return File.openReadC(@ptrCast([*:0]u8, self_exe_path.ptr));
1254}1256}
12551257
1256test "openSelfExe" {1258test "openSelfExe" {
...@@ -1277,7 +1279,7 @@ pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]u8 {...@@ -1277,7 +1279,7 @@ pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]u8 {
1277 var u32_len: u32 = out_buffer.len;1279 var u32_len: u32 = out_buffer.len;
1278 const rc = std.c._NSGetExecutablePath(out_buffer, &u32_len);1280 const rc = std.c._NSGetExecutablePath(out_buffer, &u32_len);
1279 if (rc != 0) return error.NameTooLong;1281 if (rc != 0) return error.NameTooLong;
1280 return mem.toSlice(u8, out_buffer);1282 return mem.toSlice(u8, @ptrCast([*:0]u8, out_buffer));
1281 }1283 }
1282 switch (builtin.os) {1284 switch (builtin.os) {
1283 .linux => return os.readlinkC("/proc/self/exe", out_buffer),1285 .linux => return os.readlinkC("/proc/self/exe", out_buffer),
...@@ -1306,9 +1308,9 @@ pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]u8 {...@@ -1306,9 +1308,9 @@ pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]u8 {
1306}1308}
13071309
1308/// The result is UTF16LE-encoded.1310/// The result is UTF16LE-encoded.
1309pub fn selfExePathW() []const u16 {1311pub fn selfExePathW() [:0]const u16 {
1310 const image_path_name = &os.windows.peb().ProcessParameters.ImagePathName;1312 const image_path_name = &os.windows.peb().ProcessParameters.ImagePathName;
1311 return mem.toSliceConst(u16, image_path_name.Buffer);1313 return mem.toSliceConst(u16, @ptrCast([*:0]const u16, image_path_name.Buffer));
1312}1314}
13131315
1314/// `selfExeDirPath` except allocates the result on the heap.1316/// `selfExeDirPath` except allocates the result on the heap.
lib/std/fs/file.zig+7-7
...@@ -31,7 +31,7 @@ pub const File = struct {...@@ -31,7 +31,7 @@ pub const File = struct {
31 }31 }
3232
33 /// Deprecated; call `std.fs.Dir.openReadC` directly.33 /// Deprecated; call `std.fs.Dir.openReadC` directly.
34 pub fn openReadC(path_c: [*]const u8) OpenError!File {34 pub fn openReadC(path_c: [*:0]const u8) OpenError!File {
35 return std.fs.Dir.cwd().openReadC(path_c);35 return std.fs.Dir.cwd().openReadC(path_c);
36 }36 }
3737
...@@ -61,7 +61,7 @@ pub const File = struct {...@@ -61,7 +61,7 @@ pub const File = struct {
6161
62 /// Same as `openWriteMode` except `path` is null-terminated.62 /// Same as `openWriteMode` except `path` is null-terminated.
63 /// TODO: deprecate this and move it to `std.fs.Dir`.63 /// TODO: deprecate this and move it to `std.fs.Dir`.
64 pub fn openWriteModeC(path: [*]const u8, file_mode: Mode) OpenError!File {64 pub fn openWriteModeC(path: [*:0]const u8, file_mode: Mode) OpenError!File {
65 if (builtin.os == .windows) {65 if (builtin.os == .windows) {
66 const path_w = try windows.cStrToPrefixedFileW(path);66 const path_w = try windows.cStrToPrefixedFileW(path);
67 return openWriteModeW(&path_w, file_mode);67 return openWriteModeW(&path_w, file_mode);
...@@ -74,7 +74,7 @@ pub const File = struct {...@@ -74,7 +74,7 @@ pub const File = struct {
7474
75 /// Same as `openWriteMode` except `path` is null-terminated and UTF16LE encoded75 /// Same as `openWriteMode` except `path` is null-terminated and UTF16LE encoded
76 /// TODO: deprecate this and move it to `std.fs.Dir`.76 /// TODO: deprecate this and move it to `std.fs.Dir`.
77 pub fn openWriteModeW(path_w: [*]const u16, file_mode: Mode) OpenError!File {77 pub fn openWriteModeW(path_w: [*:0]const u16, file_mode: Mode) OpenError!File {
78 const handle = try windows.CreateFileW(78 const handle = try windows.CreateFileW(
79 path_w,79 path_w,
80 windows.GENERIC_WRITE,80 windows.GENERIC_WRITE,
...@@ -101,7 +101,7 @@ pub const File = struct {...@@ -101,7 +101,7 @@ pub const File = struct {
101 }101 }
102102
103 /// TODO: deprecate this and move it to `std.fs.Dir`.103 /// TODO: deprecate this and move it to `std.fs.Dir`.
104 pub fn openWriteNoClobberC(path: [*]const u8, file_mode: Mode) OpenError!File {104 pub fn openWriteNoClobberC(path: [*:0]const u8, file_mode: Mode) OpenError!File {
105 if (builtin.os == .windows) {105 if (builtin.os == .windows) {
106 const path_w = try windows.cStrToPrefixedFileW(path);106 const path_w = try windows.cStrToPrefixedFileW(path);
107 return openWriteNoClobberW(&path_w, file_mode);107 return openWriteNoClobberW(&path_w, file_mode);
...@@ -113,7 +113,7 @@ pub const File = struct {...@@ -113,7 +113,7 @@ pub const File = struct {
113 }113 }
114114
115 /// TODO: deprecate this and move it to `std.fs.Dir`.115 /// TODO: deprecate this and move it to `std.fs.Dir`.
116 pub fn openWriteNoClobberW(path_w: [*]const u16, file_mode: Mode) OpenError!File {116 pub fn openWriteNoClobberW(path_w: [*:0]const u16, file_mode: Mode) OpenError!File {
117 const handle = try windows.CreateFileW(117 const handle = try windows.CreateFileW(
118 path_w,118 path_w,
119 windows.GENERIC_WRITE,119 windows.GENERIC_WRITE,
...@@ -142,13 +142,13 @@ pub const File = struct {...@@ -142,13 +142,13 @@ pub const File = struct {
142142
143 /// Same as `access` except the parameter is null-terminated.143 /// Same as `access` except the parameter is null-terminated.
144 /// TODO: deprecate this and move it to `std.fs.Dir`.144 /// TODO: deprecate this and move it to `std.fs.Dir`.
145 pub fn accessC(path: [*]const u8) !void {145 pub fn accessC(path: [*:0]const u8) !void {
146 return os.accessC(path, os.F_OK);146 return os.accessC(path, os.F_OK);
147 }147 }
148148
149 /// Same as `access` except the parameter is null-terminated UTF16LE-encoded.149 /// Same as `access` except the parameter is null-terminated UTF16LE-encoded.
150 /// TODO: deprecate this and move it to `std.fs.Dir`.150 /// TODO: deprecate this and move it to `std.fs.Dir`.
151 pub fn accessW(path: [*]const u16) !void {151 pub fn accessW(path: [*:0]const u16) !void {
152 return os.accessW(path, os.F_OK);152 return os.accessW(path, os.F_OK);
153 }153 }
154154
lib/std/os.zig+37-33
...@@ -655,8 +655,7 @@ pub fn open(file_path: []const u8, flags: u32, perm: usize) OpenError!fd_t {...@@ -655,8 +655,7 @@ pub fn open(file_path: []const u8, flags: u32, perm: usize) OpenError!fd_t {
655655
656/// Open and possibly create a file. Keeps trying if it gets interrupted.656/// Open and possibly create a file. Keeps trying if it gets interrupted.
657/// See also `open`.657/// See also `open`.
658/// TODO https://github.com/ziglang/zig/issues/265658pub fn openC(file_path: [*:0]const u8, flags: u32, perm: usize) OpenError!fd_t {
659pub fn openC(file_path: [*]const u8, flags: u32, perm: usize) OpenError!fd_t {
660 while (true) {659 while (true) {
661 const rc = system.open(file_path, flags, perm);660 const rc = system.open(file_path, flags, perm);
662 switch (errno(rc)) {661 switch (errno(rc)) {
...@@ -697,7 +696,7 @@ pub fn openat(dir_fd: fd_t, file_path: []const u8, flags: u32, mode: usize) Open...@@ -697,7 +696,7 @@ pub fn openat(dir_fd: fd_t, file_path: []const u8, flags: u32, mode: usize) Open
697/// Open and possibly create a file. Keeps trying if it gets interrupted.696/// Open and possibly create a file. Keeps trying if it gets interrupted.
698/// `file_path` is relative to the open directory handle `dir_fd`.697/// `file_path` is relative to the open directory handle `dir_fd`.
699/// See also `openat`.698/// See also `openat`.
700pub fn openatC(dir_fd: fd_t, file_path: [*]const u8, flags: u32, mode: usize) OpenError!fd_t {699pub fn openatC(dir_fd: fd_t, file_path: [*:0]const u8, flags: u32, mode: usize) OpenError!fd_t {
701 while (true) {700 while (true) {
702 const rc = system.openat(dir_fd, file_path, flags, mode);701 const rc = system.openat(dir_fd, file_path, flags, mode);
703 switch (errno(rc)) {702 switch (errno(rc)) {
...@@ -757,7 +756,7 @@ pub const ExecveError = error{...@@ -757,7 +756,7 @@ pub const ExecveError = error{
757/// Like `execve` except the parameters are null-terminated,756/// Like `execve` except the parameters are null-terminated,
758/// matching the syscall API on all targets. This removes the need for an allocator.757/// matching the syscall API on all targets. This removes the need for an allocator.
759/// This function ignores PATH environment variable. See `execvpeC` for that.758/// This function ignores PATH environment variable. See `execvpeC` for that.
760pub fn execveC(path: [*]const u8, child_argv: [*]const ?[*]const u8, envp: [*]const ?[*]const u8) ExecveError {759pub fn execveC(path: [*:0]const u8, child_argv: [*:null]const ?[*:0]const u8, envp: [*:null]const ?[*:0]const u8) ExecveError {
761 switch (errno(system.execve(path, child_argv, envp))) {760 switch (errno(system.execve(path, child_argv, envp))) {
762 0 => unreachable,761 0 => unreachable,
763 EFAULT => unreachable,762 EFAULT => unreachable,
...@@ -784,7 +783,7 @@ pub fn execveC(path: [*]const u8, child_argv: [*]const ?[*]const u8, envp: [*]co...@@ -784,7 +783,7 @@ pub fn execveC(path: [*]const u8, child_argv: [*]const ?[*]const u8, envp: [*]co
784/// matching the syscall API on all targets. This removes the need for an allocator.783/// matching the syscall API on all targets. This removes the need for an allocator.
785/// This function also uses the PATH environment variable to get the full path to the executable.784/// This function also uses the PATH environment variable to get the full path to the executable.
786/// If `file` is an absolute path, this is the same as `execveC`.785/// If `file` is an absolute path, this is the same as `execveC`.
787pub fn execvpeC(file: [*:0]const u8, child_argv: [*]const ?[*:0]const u8, envp: [*]const ?[*:0]const u8) ExecveError {786pub fn execvpeC(file: [*:0]const u8, child_argv: [*:null]const ?[*:0]const u8, envp: [*:null]const ?[*:0]const u8) ExecveError {
788 const file_slice = mem.toSliceConst(u8, file);787 const file_slice = mem.toSliceConst(u8, file);
789 if (mem.indexOfScalar(u8, file_slice, '/') != null) return execveC(file, child_argv, envp);788 if (mem.indexOfScalar(u8, file_slice, '/') != null) return execveC(file, child_argv, envp);
790789
...@@ -799,7 +798,8 @@ pub fn execvpeC(file: [*:0]const u8, child_argv: [*]const ?[*:0]const u8, envp:...@@ -799,7 +798,8 @@ pub fn execvpeC(file: [*:0]const u8, child_argv: [*]const ?[*:0]const u8, envp:
799 path_buf[search_path.len] = '/';798 path_buf[search_path.len] = '/';
800 mem.copy(u8, path_buf[search_path.len + 1 ..], file_slice);799 mem.copy(u8, path_buf[search_path.len + 1 ..], file_slice);
801 path_buf[search_path.len + file_slice.len + 1] = 0;800 path_buf[search_path.len + file_slice.len + 1] = 0;
802 err = execveC(&path_buf, child_argv, envp);801 // TODO avoid @ptrCast here using slice syntax with https://github.com/ziglang/zig/issues/3731
802 err = execveC(@ptrCast([*:0]u8, &path_buf), child_argv, envp);
803 switch (err) {803 switch (err) {
804 error.AccessDenied => seen_eacces = true,804 error.AccessDenied => seen_eacces = true,
805 error.FileNotFound, error.NotDir => {},805 error.FileNotFound, error.NotDir => {},
...@@ -842,10 +842,13 @@ pub fn execvpe(...@@ -842,10 +842,13 @@ pub fn execvpe(
842 const envp_buf = try createNullDelimitedEnvMap(allocator, env_map);842 const envp_buf = try createNullDelimitedEnvMap(allocator, env_map);
843 defer freeNullDelimitedEnvMap(allocator, envp_buf);843 defer freeNullDelimitedEnvMap(allocator, envp_buf);
844844
845 return execvpeC(argv_buf.ptr[0].?, argv_buf.ptr, envp_buf.ptr);845 // TODO avoid @ptrCast here using slice syntax with https://github.com/ziglang/zig/issues/3731
846 const argv_ptr = @ptrCast([*:null]?[*:0]u8, argv_buf.ptr);
847
848 return execvpeC(argv_buf.ptr[0].?, argv_ptr, envp_buf.ptr);
846}849}
847850
848pub fn createNullDelimitedEnvMap(allocator: *mem.Allocator, env_map: *const std.BufMap) ![]?[*:0]u8 {851pub fn createNullDelimitedEnvMap(allocator: *mem.Allocator, env_map: *const std.BufMap) ![:null]?[*:0]u8 {
849 const envp_count = env_map.count();852 const envp_count = env_map.count();
850 const envp_buf = try allocator.alloc(?[*:0]u8, envp_count + 1);853 const envp_buf = try allocator.alloc(?[*:0]u8, envp_count + 1);
851 mem.set(?[*:0]u8, envp_buf, null);854 mem.set(?[*:0]u8, envp_buf, null);
...@@ -860,13 +863,14 @@ pub fn createNullDelimitedEnvMap(allocator: *mem.Allocator, env_map: *const std....@@ -860,13 +863,14 @@ pub fn createNullDelimitedEnvMap(allocator: *mem.Allocator, env_map: *const std.
860 @memcpy(env_buf.ptr + pair.key.len + 1, pair.value.ptr, pair.value.len);863 @memcpy(env_buf.ptr + pair.key.len + 1, pair.value.ptr, pair.value.len);
861 env_buf[env_buf.len - 1] = 0;864 env_buf[env_buf.len - 1] = 0;
862865
863 // TODO avoid @ptrCast using slice syntax with https://github.com/ziglang/zig/issues/3731866 // TODO avoid @ptrCast here using slice syntax with https://github.com/ziglang/zig/issues/3731
864 envp_buf[i] = @ptrCast([*:0]u8, env_buf.ptr);867 envp_buf[i] = @ptrCast([*:0]u8, env_buf.ptr);
865 }868 }
866 assert(i == envp_count);869 assert(i == envp_count);
867 }870 }
871 // TODO avoid @ptrCast here using slice syntax with https://github.com/ziglang/zig/issues/3731
868 assert(envp_buf[envp_count] == null);872 assert(envp_buf[envp_count] == null);
869 return envp_buf;873 return @ptrCast([*:null]?[*:0]u8, envp_buf.ptr)[0..envp_count];
870}874}
871875
872pub fn freeNullDelimitedEnvMap(allocator: *mem.Allocator, envp_buf: []?[*:0]u8) void {876pub fn freeNullDelimitedEnvMap(allocator: *mem.Allocator, envp_buf: []?[*:0]u8) void {
...@@ -967,7 +971,7 @@ pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError!...@@ -967,7 +971,7 @@ pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError!
967971
968/// This is the same as `symlink` except the parameters are null-terminated pointers.972/// This is the same as `symlink` except the parameters are null-terminated pointers.
969/// See also `symlink`.973/// See also `symlink`.
970pub fn symlinkC(target_path: [*]const u8, sym_link_path: [*]const u8) SymLinkError!void {974pub fn symlinkC(target_path: [*:0]const u8, sym_link_path: [*:0]const u8) SymLinkError!void {
971 if (builtin.os == .windows) {975 if (builtin.os == .windows) {
972 const target_path_w = try windows.cStrToPrefixedFileW(target_path);976 const target_path_w = try windows.cStrToPrefixedFileW(target_path);
973 const sym_link_path_w = try windows.cStrToPrefixedFileW(sym_link_path);977 const sym_link_path_w = try windows.cStrToPrefixedFileW(sym_link_path);
...@@ -999,7 +1003,7 @@ pub fn symlinkat(target_path: []const u8, newdirfd: fd_t, sym_link_path: []const...@@ -999,7 +1003,7 @@ pub fn symlinkat(target_path: []const u8, newdirfd: fd_t, sym_link_path: []const
999 return symlinkatC(target_path_c, newdirfd, sym_link_path_c);1003 return symlinkatC(target_path_c, newdirfd, sym_link_path_c);
1000}1004}
10011005
1002pub fn symlinkatC(target_path: [*]const u8, newdirfd: fd_t, sym_link_path: [*]const u8) SymLinkError!void {1006pub fn symlinkatC(target_path: [*:0]const u8, newdirfd: fd_t, sym_link_path: [*:0]const u8) SymLinkError!void {
1003 switch (errno(system.symlinkat(target_path, newdirfd, sym_link_path))) {1007 switch (errno(system.symlinkat(target_path, newdirfd, sym_link_path))) {
1004 0 => return,1008 0 => return,
1005 EFAULT => unreachable,1009 EFAULT => unreachable,
...@@ -1053,7 +1057,7 @@ pub fn unlink(file_path: []const u8) UnlinkError!void {...@@ -1053,7 +1057,7 @@ pub fn unlink(file_path: []const u8) UnlinkError!void {
1053}1057}
10541058
1055/// Same as `unlink` except the parameter is a null terminated UTF8-encoded string.1059/// Same as `unlink` except the parameter is a null terminated UTF8-encoded string.
1056pub fn unlinkC(file_path: [*]const u8) UnlinkError!void {1060pub fn unlinkC(file_path: [*:0]const u8) UnlinkError!void {
1057 if (builtin.os == .windows) {1061 if (builtin.os == .windows) {
1058 const file_path_w = try windows.cStrToPrefixedFileW(file_path);1062 const file_path_w = try windows.cStrToPrefixedFileW(file_path);
1059 return windows.DeleteFileW(&file_path_w);1063 return windows.DeleteFileW(&file_path_w);
...@@ -1093,7 +1097,7 @@ pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!vo...@@ -1093,7 +1097,7 @@ pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!vo
1093}1097}
10941098
1095/// Same as `unlinkat` but `file_path` is a null-terminated string.1099/// Same as `unlinkat` but `file_path` is a null-terminated string.
1096pub fn unlinkatC(dirfd: fd_t, file_path_c: [*]const u8, flags: u32) UnlinkatError!void {1100pub fn unlinkatC(dirfd: fd_t, file_path_c: [*:0]const u8, flags: u32) UnlinkatError!void {
1097 if (builtin.os == .windows) {1101 if (builtin.os == .windows) {
1098 const file_path_w = try windows.cStrToPrefixedFileW(file_path_c);1102 const file_path_w = try windows.cStrToPrefixedFileW(file_path_c);
1099 return unlinkatW(dirfd, &file_path_w, flags);1103 return unlinkatW(dirfd, &file_path_w, flags);
...@@ -1122,7 +1126,7 @@ pub fn unlinkatC(dirfd: fd_t, file_path_c: [*]const u8, flags: u32) UnlinkatErro...@@ -1122,7 +1126,7 @@ pub fn unlinkatC(dirfd: fd_t, file_path_c: [*]const u8, flags: u32) UnlinkatErro
1122}1126}
11231127
1124/// Same as `unlinkat` but `sub_path_w` is UTF16LE, NT prefixed. Windows only.1128/// Same as `unlinkat` but `sub_path_w` is UTF16LE, NT prefixed. Windows only.
1125pub fn unlinkatW(dirfd: fd_t, sub_path_w: [*]const u16, flags: u32) UnlinkatError!void {1129pub fn unlinkatW(dirfd: fd_t, sub_path_w: [*:0]const u16, flags: u32) UnlinkatError!void {
1126 const w = windows;1130 const w = windows;
11271131
1128 const want_rmdir_behavior = (flags & AT_REMOVEDIR) != 0;1132 const want_rmdir_behavior = (flags & AT_REMOVEDIR) != 0;
...@@ -1217,7 +1221,7 @@ pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void {...@@ -1217,7 +1221,7 @@ pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void {
1217}1221}
12181222
1219/// Same as `rename` except the parameters are null-terminated byte arrays.1223/// Same as `rename` except the parameters are null-terminated byte arrays.
1220pub fn renameC(old_path: [*]const u8, new_path: [*]const u8) RenameError!void {1224pub fn renameC(old_path: [*:0]const u8, new_path: [*:0]const u8) RenameError!void {
1221 if (builtin.os == .windows) {1225 if (builtin.os == .windows) {
1222 const old_path_w = try windows.cStrToPrefixedFileW(old_path);1226 const old_path_w = try windows.cStrToPrefixedFileW(old_path);
1223 const new_path_w = try windows.cStrToPrefixedFileW(new_path);1227 const new_path_w = try windows.cStrToPrefixedFileW(new_path);
...@@ -1249,7 +1253,7 @@ pub fn renameC(old_path: [*]const u8, new_path: [*]const u8) RenameError!void {...@@ -1249,7 +1253,7 @@ pub fn renameC(old_path: [*]const u8, new_path: [*]const u8) RenameError!void {
12491253
1250/// Same as `rename` except the parameters are null-terminated UTF16LE encoded byte arrays.1254/// Same as `rename` except the parameters are null-terminated UTF16LE encoded byte arrays.
1251/// Assumes target is Windows.1255/// Assumes target is Windows.
1252pub fn renameW(old_path: [*]const u16, new_path: [*]const u16) RenameError!void {1256pub fn renameW(old_path: [*:0]const u16, new_path: [*:0]const u16) RenameError!void {
1253 const flags = windows.MOVEFILE_REPLACE_EXISTING | windows.MOVEFILE_WRITE_THROUGH;1257 const flags = windows.MOVEFILE_REPLACE_EXISTING | windows.MOVEFILE_WRITE_THROUGH;
1254 return windows.MoveFileExW(old_path, new_path, flags);1258 return windows.MoveFileExW(old_path, new_path, flags);
1255}1259}
...@@ -1283,7 +1287,7 @@ pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void {...@@ -1283,7 +1287,7 @@ pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void {
1283}1287}
12841288
1285/// Same as `mkdir` but the parameter is a null-terminated UTF8-encoded string.1289/// Same as `mkdir` but the parameter is a null-terminated UTF8-encoded string.
1286pub fn mkdirC(dir_path: [*]const u8, mode: u32) MakeDirError!void {1290pub fn mkdirC(dir_path: [*:0]const u8, mode: u32) MakeDirError!void {
1287 if (builtin.os == .windows) {1291 if (builtin.os == .windows) {
1288 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);1292 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);
1289 return windows.CreateDirectoryW(&dir_path_w, null);1293 return windows.CreateDirectoryW(&dir_path_w, null);
...@@ -1333,7 +1337,7 @@ pub fn rmdir(dir_path: []const u8) DeleteDirError!void {...@@ -1333,7 +1337,7 @@ pub fn rmdir(dir_path: []const u8) DeleteDirError!void {
1333}1337}
13341338
1335/// Same as `rmdir` except the parameter is null-terminated.1339/// Same as `rmdir` except the parameter is null-terminated.
1336pub fn rmdirC(dir_path: [*]const u8) DeleteDirError!void {1340pub fn rmdirC(dir_path: [*:0]const u8) DeleteDirError!void {
1337 if (builtin.os == .windows) {1341 if (builtin.os == .windows) {
1338 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);1342 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);
1339 return windows.RemoveDirectoryW(&dir_path_w);1343 return windows.RemoveDirectoryW(&dir_path_w);
...@@ -1380,7 +1384,7 @@ pub fn chdir(dir_path: []const u8) ChangeCurDirError!void {...@@ -1380,7 +1384,7 @@ pub fn chdir(dir_path: []const u8) ChangeCurDirError!void {
1380}1384}
13811385
1382/// Same as `chdir` except the parameter is null-terminated.1386/// Same as `chdir` except the parameter is null-terminated.
1383pub fn chdirC(dir_path: [*]const u8) ChangeCurDirError!void {1387pub fn chdirC(dir_path: [*:0]const u8) ChangeCurDirError!void {
1384 if (builtin.os == .windows) {1388 if (builtin.os == .windows) {
1385 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);1389 const dir_path_w = try windows.cStrToPrefixedFileW(dir_path);
1386 @compileError("TODO implement chdir for Windows");1390 @compileError("TODO implement chdir for Windows");
...@@ -1422,7 +1426,7 @@ pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 {...@@ -1422,7 +1426,7 @@ pub fn readlink(file_path: []const u8, out_buffer: []u8) ReadLinkError![]u8 {
1422}1426}
14231427
1424/// Same as `readlink` except `file_path` is null-terminated.1428/// Same as `readlink` except `file_path` is null-terminated.
1425pub fn readlinkC(file_path: [*]const u8, out_buffer: []u8) ReadLinkError![]u8 {1429pub fn readlinkC(file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 {
1426 if (builtin.os == .windows) {1430 if (builtin.os == .windows) {
1427 const file_path_w = try windows.cStrToPrefixedFileW(file_path);1431 const file_path_w = try windows.cStrToPrefixedFileW(file_path);
1428 @compileError("TODO implement readlink for Windows");1432 @compileError("TODO implement readlink for Windows");
...@@ -1443,7 +1447,7 @@ pub fn readlinkC(file_path: [*]const u8, out_buffer: []u8) ReadLinkError![]u8 {...@@ -1443,7 +1447,7 @@ pub fn readlinkC(file_path: [*]const u8, out_buffer: []u8) ReadLinkError![]u8 {
1443 }1447 }
1444}1448}
14451449
1446pub fn readlinkatC(dirfd: fd_t, file_path: [*]const u8, out_buffer: []u8) ReadLinkError![]u8 {1450pub fn readlinkatC(dirfd: fd_t, file_path: [*:0]const u8, out_buffer: []u8) ReadLinkError![]u8 {
1447 if (builtin.os == .windows) {1451 if (builtin.os == .windows) {
1448 const file_path_w = try windows.cStrToPrefixedFileW(file_path);1452 const file_path_w = try windows.cStrToPrefixedFileW(file_path);
1449 @compileError("TODO implement readlink for Windows");1453 @compileError("TODO implement readlink for Windows");
...@@ -2130,7 +2134,7 @@ pub fn inotify_add_watch(inotify_fd: i32, pathname: []const u8, mask: u32) INoti...@@ -2130,7 +2134,7 @@ pub fn inotify_add_watch(inotify_fd: i32, pathname: []const u8, mask: u32) INoti
2130}2134}
21312135
2132/// Same as `inotify_add_watch` except pathname is null-terminated.2136/// Same as `inotify_add_watch` except pathname is null-terminated.
2133pub fn inotify_add_watchC(inotify_fd: i32, pathname: [*]const u8, mask: u32) INotifyAddWatchError!i32 {2137pub fn inotify_add_watchC(inotify_fd: i32, pathname: [*:0]const u8, mask: u32) INotifyAddWatchError!i32 {
2134 const rc = system.inotify_add_watch(inotify_fd, pathname, mask);2138 const rc = system.inotify_add_watch(inotify_fd, pathname, mask);
2135 switch (errno(rc)) {2139 switch (errno(rc)) {
2136 0 => return @intCast(i32, rc),2140 0 => return @intCast(i32, rc),
...@@ -2287,7 +2291,7 @@ pub fn access(path: []const u8, mode: u32) AccessError!void {...@@ -2287,7 +2291,7 @@ pub fn access(path: []const u8, mode: u32) AccessError!void {
2287}2291}
22882292
2289/// Same as `access` except `path` is null-terminated.2293/// Same as `access` except `path` is null-terminated.
2290pub fn accessC(path: [*]const u8, mode: u32) AccessError!void {2294pub fn accessC(path: [*:0]const u8, mode: u32) AccessError!void {
2291 if (builtin.os == .windows) {2295 if (builtin.os == .windows) {
2292 const path_w = try windows.cStrToPrefixedFileW(path);2296 const path_w = try windows.cStrToPrefixedFileW(path);
2293 _ = try windows.GetFileAttributesW(&path_w);2297 _ = try windows.GetFileAttributesW(&path_w);
...@@ -2314,7 +2318,7 @@ pub fn accessC(path: [*]const u8, mode: u32) AccessError!void {...@@ -2314,7 +2318,7 @@ pub fn accessC(path: [*]const u8, mode: u32) AccessError!void {
2314/// Call from Windows-specific code if you already have a UTF-16LE encoded, null terminated string.2318/// Call from Windows-specific code if you already have a UTF-16LE encoded, null terminated string.
2315/// Otherwise use `access` or `accessC`.2319/// Otherwise use `access` or `accessC`.
2316/// TODO currently this ignores `mode`.2320/// TODO currently this ignores `mode`.
2317pub fn accessW(path: [*]const u16, mode: u32) windows.GetFileAttributesError!void {2321pub fn accessW(path: [*:0]const u16, mode: u32) windows.GetFileAttributesError!void {
2318 const ret = try windows.GetFileAttributesW(path);2322 const ret = try windows.GetFileAttributesW(path);
2319 if (ret != windows.INVALID_FILE_ATTRIBUTES) {2323 if (ret != windows.INVALID_FILE_ATTRIBUTES) {
2320 return;2324 return;
...@@ -2381,7 +2385,7 @@ pub fn sysctl(...@@ -2381,7 +2385,7 @@ pub fn sysctl(
2381}2385}
23822386
2383pub fn sysctlbynameC(2387pub fn sysctlbynameC(
2384 name: [*]const u8,2388 name: [*:0]const u8,
2385 oldp: ?*c_void,2389 oldp: ?*c_void,
2386 oldlenp: ?*usize,2390 oldlenp: ?*usize,
2387 newp: ?*c_void,2391 newp: ?*c_void,
...@@ -2563,7 +2567,7 @@ pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathE...@@ -2563,7 +2567,7 @@ pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathE
2563}2567}
25642568
2565/// Same as `realpath` except `pathname` is null-terminated.2569/// Same as `realpath` except `pathname` is null-terminated.
2566pub fn realpathC(pathname: [*]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {2570pub fn realpathC(pathname: [*:0]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
2567 if (builtin.os == .windows) {2571 if (builtin.os == .windows) {
2568 const pathname_w = try windows.cStrToPrefixedFileW(pathname);2572 const pathname_w = try windows.cStrToPrefixedFileW(pathname);
2569 return realpathW(&pathname_w, out_buffer);2573 return realpathW(&pathname_w, out_buffer);
...@@ -2572,10 +2576,10 @@ pub fn realpathC(pathname: [*]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPat...@@ -2572,10 +2576,10 @@ pub fn realpathC(pathname: [*]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPat
2572 const fd = try openC(pathname, linux.O_PATH | linux.O_NONBLOCK | linux.O_CLOEXEC, 0);2576 const fd = try openC(pathname, linux.O_PATH | linux.O_NONBLOCK | linux.O_CLOEXEC, 0);
2573 defer close(fd);2577 defer close(fd);
25742578
2575 var procfs_buf: ["/proc/self/fd/-2147483648\x00".len]u8 = undefined;2579 var procfs_buf: ["/proc/self/fd/-2147483648".len:0]u8 = undefined;
2576 const proc_path = std.fmt.bufPrint(procfs_buf[0..], "/proc/self/fd/{}\x00", fd) catch unreachable;2580 const proc_path = std.fmt.bufPrint(procfs_buf[0..], "/proc/self/fd/{}\x00", fd) catch unreachable;
25772581
2578 return readlinkC(proc_path.ptr, out_buffer);2582 return readlinkC(@ptrCast([*:0]const u8, proc_path.ptr), out_buffer);
2579 }2583 }
2580 const result_path = std.c.realpath(pathname, out_buffer) orelse switch (std.c._errno().*) {2584 const result_path = std.c.realpath(pathname, out_buffer) orelse switch (std.c._errno().*) {
2581 EINVAL => unreachable,2585 EINVAL => unreachable,
...@@ -2594,7 +2598,7 @@ pub fn realpathC(pathname: [*]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPat...@@ -2594,7 +2598,7 @@ pub fn realpathC(pathname: [*]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPat
2594}2598}
25952599
2596/// Same as `realpath` except `pathname` is null-terminated and UTF16LE-encoded.2600/// Same as `realpath` except `pathname` is null-terminated and UTF16LE-encoded.
2597pub fn realpathW(pathname: [*]const u16, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {2601pub fn realpathW(pathname: [*:0]const u16, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
2598 const h_file = try windows.CreateFileW(2602 const h_file = try windows.CreateFileW(
2599 pathname,2603 pathname,
2600 windows.GENERIC_READ,2604 windows.GENERIC_READ,
...@@ -2749,8 +2753,8 @@ pub fn sched_getaffinity(pid: pid_t) SchedGetAffinityError!cpu_set_t {...@@ -2749,8 +2753,8 @@ pub fn sched_getaffinity(pid: pid_t) SchedGetAffinityError!cpu_set_t {
27492753
2750/// Used to convert a slice to a null terminated slice on the stack.2754/// Used to convert a slice to a null terminated slice on the stack.
2751/// TODO https://github.com/ziglang/zig/issues/2872755/// TODO https://github.com/ziglang/zig/issues/287
2752pub fn toPosixPath(file_path: []const u8) ![PATH_MAX]u8 {2756pub fn toPosixPath(file_path: []const u8) ![PATH_MAX-1:0]u8 {
2753 var path_with_null: [PATH_MAX]u8 = undefined;2757 var path_with_null: [PATH_MAX-1:0]u8 = undefined;
2754 // >= rather than > to make room for the null byte2758 // >= rather than > to make room for the null byte
2755 if (file_path.len >= PATH_MAX) return error.NameTooLong;2759 if (file_path.len >= PATH_MAX) return error.NameTooLong;
2756 mem.copy(u8, &path_with_null, file_path);2760 mem.copy(u8, &path_with_null, file_path);
...@@ -2855,7 +2859,7 @@ pub const GetHostNameError = error{PermissionDenied} || UnexpectedError;...@@ -2855,7 +2859,7 @@ pub const GetHostNameError = error{PermissionDenied} || UnexpectedError;
2855pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 {2859pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 {
2856 if (builtin.link_libc) {2860 if (builtin.link_libc) {
2857 switch (errno(system.gethostname(name_buffer, name_buffer.len))) {2861 switch (errno(system.gethostname(name_buffer, name_buffer.len))) {
2858 0 => return mem.toSlice(u8, name_buffer),2862 0 => return mem.toSlice(u8, @ptrCast([*:0]u8, name_buffer)),
2859 EFAULT => unreachable,2863 EFAULT => unreachable,
2860 ENAMETOOLONG => unreachable, // HOST_NAME_MAX prevents this2864 ENAMETOOLONG => unreachable, // HOST_NAME_MAX prevents this
2861 EPERM => return error.PermissionDenied,2865 EPERM => return error.PermissionDenied,
lib/std/os/bits/darwin.zig+1-1
...@@ -1205,7 +1205,7 @@ pub const addrinfo = extern struct {...@@ -1205,7 +1205,7 @@ pub const addrinfo = extern struct {
1205 socktype: i32,1205 socktype: i32,
1206 protocol: i32,1206 protocol: i32,
1207 addrlen: socklen_t,1207 addrlen: socklen_t,
1208 canonname: ?[*]u8,1208 canonname: ?[*:0]u8,
1209 addr: ?*sockaddr,1209 addr: ?*sockaddr,
1210 next: ?*addrinfo,1210 next: ?*addrinfo,
1211};1211};
lib/std/os/bits/linux.zig+1-1
...@@ -1355,7 +1355,7 @@ pub const addrinfo = extern struct {...@@ -1355,7 +1355,7 @@ pub const addrinfo = extern struct {
1355 protocol: i32,1355 protocol: i32,
1356 addrlen: socklen_t,1356 addrlen: socklen_t,
1357 addr: ?*sockaddr,1357 addr: ?*sockaddr,
1358 canonname: ?[*]u8,1358 canonname: ?[*:0]u8,
1359 next: ?*addrinfo,1359 next: ?*addrinfo,
1360};1360};
13611361
lib/std/os/wasi.zig+2-2
...@@ -19,13 +19,13 @@ comptime {...@@ -19,13 +19,13 @@ comptime {
19pub const iovec_t = iovec;19pub const iovec_t = iovec;
20pub const ciovec_t = iovec_const;20pub const ciovec_t = iovec_const;
2121
22pub extern "wasi_unstable" fn args_get(argv: [*][*]u8, argv_buf: [*]u8) errno_t;22pub extern "wasi_unstable" fn args_get(argv: [*][*:0]u8, argv_buf: [*]u8) errno_t;
23pub extern "wasi_unstable" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t;23pub extern "wasi_unstable" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t;
2424
25pub extern "wasi_unstable" fn clock_res_get(clock_id: clockid_t, resolution: *timestamp_t) errno_t;25pub extern "wasi_unstable" fn clock_res_get(clock_id: clockid_t, resolution: *timestamp_t) errno_t;
26pub extern "wasi_unstable" fn clock_time_get(clock_id: clockid_t, precision: timestamp_t, timestamp: *timestamp_t) errno_t;26pub extern "wasi_unstable" fn clock_time_get(clock_id: clockid_t, precision: timestamp_t, timestamp: *timestamp_t) errno_t;
2727
28pub extern "wasi_unstable" fn environ_get(environ: [*]?[*]u8, environ_buf: [*]u8) errno_t;28pub extern "wasi_unstable" fn environ_get(environ: [*]?[*:0]u8, environ_buf: [*]u8) errno_t;
29pub extern "wasi_unstable" fn environ_sizes_get(environ_count: *usize, environ_buf_size: *usize) errno_t;29pub extern "wasi_unstable" fn environ_sizes_get(environ_count: *usize, environ_buf_size: *usize) errno_t;
3030
31pub extern "wasi_unstable" fn fd_advise(fd: fd_t, offset: filesize_t, len: filesize_t, advice: advice_t) errno_t;31pub extern "wasi_unstable" fn fd_advise(fd: fd_t, offset: filesize_t, len: filesize_t, advice: advice_t) errno_t;
lib/std/os/windows.zig+8-8
...@@ -192,7 +192,7 @@ pub const FindFirstFileError = error{...@@ -192,7 +192,7 @@ pub const FindFirstFileError = error{
192};192};
193193
194pub fn FindFirstFile(dir_path: []const u8, find_file_data: *WIN32_FIND_DATAW) FindFirstFileError!HANDLE {194pub fn FindFirstFile(dir_path: []const u8, find_file_data: *WIN32_FIND_DATAW) FindFirstFileError!HANDLE {
195 const dir_path_w = try sliceToPrefixedSuffixedFileW(dir_path, [_]u16{ '\\', '*', 0 });195 const dir_path_w = try sliceToPrefixedSuffixedFileW(dir_path, [_]u16{ '\\', '*'});
196 const handle = kernel32.FindFirstFileW(&dir_path_w, find_file_data);196 const handle = kernel32.FindFirstFileW(&dir_path_w, find_file_data);
197197
198 if (handle == INVALID_HANDLE_VALUE) {198 if (handle == INVALID_HANDLE_VALUE) {
...@@ -919,18 +919,18 @@ pub fn nanoSecondsToFileTime(ns: i64) FILETIME {...@@ -919,18 +919,18 @@ pub fn nanoSecondsToFileTime(ns: i64) FILETIME {
919 };919 };
920}920}
921921
922pub fn cStrToPrefixedFileW(s: [*]const u8) ![PATH_MAX_WIDE + 1]u16 {922pub fn cStrToPrefixedFileW(s: [*:0]const u8) ![PATH_MAX_WIDE:0]u16 {
923 return sliceToPrefixedFileW(mem.toSliceConst(u8, s));923 return sliceToPrefixedFileW(mem.toSliceConst(u8, s));
924}924}
925925
926pub fn sliceToPrefixedFileW(s: []const u8) ![PATH_MAX_WIDE + 1]u16 {926pub fn sliceToPrefixedFileW(s: []const u8) ![PATH_MAX_WIDE:0]u16 {
927 return sliceToPrefixedSuffixedFileW(s, [_]u16{0});927 return sliceToPrefixedSuffixedFileW(s, &[_]u16{});
928}928}
929929
930/// Assumes an absolute path.930/// Assumes an absolute path.
931pub fn wToPrefixedFileW(s: []const u16) ![PATH_MAX_WIDE + 1]u16 {931pub fn wToPrefixedFileW(s: []const u16) ![PATH_MAX_WIDE:0]u16 {
932 // TODO https://github.com/ziglang/zig/issues/2765932 // TODO https://github.com/ziglang/zig/issues/2765
933 var result: [PATH_MAX_WIDE + 1]u16 = undefined;933 var result: [PATH_MAX_WIDE:0]u16 = undefined;
934934
935 const start_index = if (mem.startsWith(u16, s, [_]u16{'\\', '?'})) 0 else blk: {935 const start_index = if (mem.startsWith(u16, s, [_]u16{'\\', '?'})) 0 else blk: {
936 const prefix = [_]u16{ '\\', '?', '?', '\\' };936 const prefix = [_]u16{ '\\', '?', '?', '\\' };
...@@ -945,9 +945,9 @@ pub fn wToPrefixedFileW(s: []const u16) ![PATH_MAX_WIDE + 1]u16 {...@@ -945,9 +945,9 @@ pub fn wToPrefixedFileW(s: []const u16) ![PATH_MAX_WIDE + 1]u16 {
945945
946}946}
947947
948pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16) ![PATH_MAX_WIDE + suffix.len]u16 {948pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16) ![PATH_MAX_WIDE + suffix.len:0]u16 {
949 // TODO https://github.com/ziglang/zig/issues/2765949 // TODO https://github.com/ziglang/zig/issues/2765
950 var result: [PATH_MAX_WIDE + suffix.len]u16 = undefined;950 var result: [PATH_MAX_WIDE + suffix.len:0]u16 = undefined;
951 // > File I/O functions in the Windows API convert "/" to "\" as part of951 // > File I/O functions in the Windows API convert "/" to "\" as part of
952 // > converting the name to an NT-style name, except when using the "\\?\"952 // > converting the name to an NT-style name, except when using the "\\?\"
953 // > prefix as detailed in the following sections.953 // > prefix as detailed in the following sections.
lib/std/process.zig+2-2
...@@ -77,7 +77,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {...@@ -77,7 +77,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
7777
78 // TODO: Verify that the documentation is incorrect78 // TODO: Verify that the documentation is incorrect
79 // https://github.com/WebAssembly/WASI/issues/2779 // https://github.com/WebAssembly/WASI/issues/27
80 var environ = try allocator.alloc(?[*]u8, environ_count + 1);80 var environ = try allocator.alloc(?[*:0]u8, environ_count + 1);
81 defer allocator.free(environ);81 defer allocator.free(environ);
82 var environ_buf = try std.heap.wasm_allocator.alloc(u8, environ_buf_size);82 var environ_buf = try std.heap.wasm_allocator.alloc(u8, environ_buf_size);
83 defer allocator.free(environ_buf);83 defer allocator.free(environ_buf);
...@@ -397,7 +397,7 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![][]u8 {...@@ -397,7 +397,7 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![][]u8 {
397 return os.unexpectedErrno(args_sizes_get_ret);397 return os.unexpectedErrno(args_sizes_get_ret);
398 }398 }
399399
400 var argv = try allocator.alloc([*]u8, count);400 var argv = try allocator.alloc([*:0]u8, count);
401 defer allocator.free(argv);401 defer allocator.free(argv);
402402
403 var argv_buf = try allocator.alloc(u8, buf_size);403 var argv_buf = try allocator.alloc(u8, buf_size);
src/analyze.cpp+1-1
...@@ -6550,7 +6550,7 @@ static bool const_values_equal_array(CodeGen *g, ConstExprValue *a, ConstExprVal...@@ -6550,7 +6550,7 @@ static bool const_values_equal_array(CodeGen *g, ConstExprValue *a, ConstExprVal
6550}6550}
65516551
6552bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {6552bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
6553 assert(a->type->id == b->type->id);6553 if (a->type->id != b->type->id) return false;
6554 assert(a->special == ConstValSpecialStatic);6554 assert(a->special == ConstValSpecialStatic);
6555 assert(b->special == ConstValSpecialStatic);6555 assert(b->special == ConstValSpecialStatic);
6556 if (a->type == b->type) {6556 if (a->type == b->type) {