So I am writing a shell. I was following along to ratfactor’s blog post about creating it in Zig. However, I am working on implementing some builtins like cd
to the shell. So I am taking in user input, and splitting it on whitespace with std.mem.splitSequence
. It works great. The problem is it is in []const u8
format. I am using std.os.chdirZ
to attempt to change directories. This takes [*.0]const u8
. Being a beginner I have no idea how to swap between these two types. Any help would be massively appreciated.
Hello @jjuel, welcome to the forum.
Types:
[*:0]const u8
is a sentinel terminated pointer, a pointer to0
terminated string ofu8
.[]const u8
is a slice, a pointer and a length.[:0]const u8
is a0
terminated sentinel slice, a pointer to0
terminated string and a length.
Convertions:
- To convert from a zero terminated pointer to a slice use:
std.mem.span
. - To convert from a
0
terminated sentinel slice to a zero terminated pointer call.ptr
// "Hello" is a zero terminated array of u8
const hello: [:0]const u8 = "Hello";
const ptr: [*:0]const u8 = hello.ptr;
- To convert from a non zero terminated slice to a zero terminated pointer use: std:mem.Allocator.dupeZ
@dimdin, I think we should make a Doc about this. I can get it started off of your post.
@dimdin’s answer is more general, but since you’re working with paths, there are other options:
First, it’s unclear why you’re choosing chdirZ
over chdir
when you don’t already have a sentinel-terminated slice.
But if you really want to call chdirZ
directly, you can use a stack-allocated buffer for the sentinel terminated slice instead of heap allocating. Using a stack allocated buffer is exactly what chdir
does via toPosixPath
:
where toPosixPath
looks like this:
This is great knowledge. Thank you. Honestly, the reason I wasn’ t using chdir
over chdirZ
was just not reading of it. As it turns out I did have sentinel-terminated slice I just didn’t realize I had it until after asking these questions. Thank you again. I am still learning Zig and systems programming.
Another thing to note that you dont need to construct paths generally in zig. You can instead tokenize the path and traverse the components directly with std.fs.Dir.openDir
this is actually sometimes required because filesystems may have max path limit, also relying on MAX_PATH especially is fragile