summaryrefslogtreecommitdiff
path: root/src/cmd/chdir.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/chdir.zig')
-rw-r--r--src/cmd/chdir.zig99
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 };
+ }
+ }
+};