diff options
Diffstat (limited to 'src/cmd/chdir.zig')
-rw-r--r-- | src/cmd/chdir.zig | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/cmd/chdir.zig b/src/cmd/chdir.zig new file mode 100644 index 0000000..fa2da83 --- /dev/null +++ b/src/cmd/chdir.zig @@ -0,0 +1,99 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const print = std.debug.print; + +const paths = @import("../paths.zig"); +const formatDosPath = paths.formatDosPath; + +const types = @import("./types.zig"); +const CommandStatus = types.CommandStatus; +const OutputCapture = types.OutputCapture; +const InputSource = types.InputSource; + +pub const Chdir = struct { + path: []const u8, + + pub fn eval(chdir: Chdir, allocator: Allocator, output_capture: ?*OutputCapture, input_source: ?*InputSource) !CommandStatus { + _ = input_source; + + if (chdir.path.len == 0) { + // No arguments - display current directory + const cwd = std.fs.cwd().realpathAlloc(allocator, ".") catch { + const error_msg = "Unable to determine current directory\n"; + if (output_capture) |capture| { + try capture.write(error_msg); + } else { + print("{s}", .{error_msg}); + } + return CommandStatus{ .Code = 1 }; + }; + defer allocator.free(cwd); + + const formatted_path = try formatDosPath(allocator, cwd); + defer allocator.free(formatted_path); + + const output = try std.fmt.allocPrint(allocator, "{s}\n", .{formatted_path}); + defer allocator.free(output); + + if (output_capture) |capture| { + try capture.write(output); + } else { + print("{s}", .{output}); + } + return CommandStatus{ .Code = 0 }; + } else { + // Change directory + const target_path = chdir.path; + + // Handle special cases + if (std.mem.eql(u8, target_path, "..")) { + // Go to parent directory + std.process.changeCurDir("..") catch { + const error_msg = "The system cannot find the path specified.\n"; + if (output_capture) |capture| { + try capture.write(error_msg); + } else { + print("{s}", .{error_msg}); + } + return CommandStatus{ .Code = 1 }; + }; + } else if (std.mem.eql(u8, target_path, "\\") or std.mem.eql(u8, target_path, "/")) { + // Go to root directory - simplified to just go to "/" + std.process.changeCurDir("/") catch { + const error_msg = "The system cannot find the path specified.\n"; + if (output_capture) |capture| { + try capture.write(error_msg); + } else { + print("{s}", .{error_msg}); + } + return CommandStatus{ .Code = 1 }; + }; + } else { + // Regular directory change + // Make sure the path doesn't contain null bytes + for (target_path) |ch| { + if (ch == 0) { + const error_msg = "Invalid path: contains null character\n"; + if (output_capture) |capture| { + try capture.write(error_msg); + } else { + print("{s}", .{error_msg}); + } + return CommandStatus{ .Code = 1 }; + } + } + + std.process.changeCurDir(target_path) catch { + const error_msg = "The system cannot find the path specified.\n"; + if (output_capture) |capture| { + try capture.write(error_msg); + } else { + print("{s}", .{error_msg}); + } + return CommandStatus{ .Code = 1 }; + }; + } + return CommandStatus{ .Code = 0 }; + } + } +}; |