diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-04-17 02:58:42 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-04-17 06:47:20 -0400 |
| commit | 47336abae3992ef343bd9cb6099b89bad1dfb634 (patch) | |
| tree | 4b05465b2d964d8110b9c912b81d82d6dfcada19 /std | |
| parent | d16ce67106796011706e9f3653bb843c21c9d708 (diff) | |
| download | zig-47336abae3992ef343bd9cb6099b89bad1dfb634.tar.gz zig-47336abae3992ef343bd9cb6099b89bad1dfb634.zip | |
improvements to zig build system and unwrap error safety
* zig build system: create standard dynamic library sym links
* unwrapping an error results in a panic message that contains
the error name
* rename error.SysResources to error.SystemResources
* add std.os.symLink
* add std.os.deleteFile
Diffstat (limited to 'std')
| -rw-r--r-- | std/build.zig | 81 | ||||
| -rw-r--r-- | std/os/child_process.zig | 8 | ||||
| -rw-r--r-- | std/os/index.zig | 67 | ||||
| -rw-r--r-- | std/os/linux.zig | 8 |
4 files changed, 117 insertions, 47 deletions
diff --git a/std/build.zig b/std/build.zig index 44b3ddd12c..ae62efdf83 100644 --- a/std/build.zig +++ b/std/build.zig @@ -395,6 +395,33 @@ pub const Builder = struct { return self.invalid_user_input; } + + fn spawnChild(self: &Builder, exe_path: []const u8, args: []const []const u8) { + if (self.verbose) { + %%io.stderr.printf("{}", exe_path); + for (args) |arg| { + %%io.stderr.printf(" {}", arg); + } + %%io.stderr.printf("\n"); + } + + var child = os.ChildProcess.spawn(exe_path, args, &self.env_map, + StdIo.Ignore, StdIo.Inherit, StdIo.Inherit, self.allocator) + %% |err| debug.panic("Unable to spawn {}: {}\n", exe_path, @errorName(err)); + + const term = %%child.wait(); + switch (term) { + Term.Clean => |code| { + if (code != 0) { + debug.panic("Process {} exited with error code {}\n", exe_path, code); + } + }, + else => { + debug.panic("Process {} terminated unexpectedly\n", exe_path); + }, + }; + + } }; const Version = struct { @@ -568,14 +595,7 @@ const Exe = struct { %return zig_args.append(lib_path); } - if (builder.verbose) { - printInvocation(builder.zig_exe, zig_args); - } - // TODO issue #301 - var child = os.ChildProcess.spawn(builder.zig_exe, zig_args.toSliceConst(), &builder.env_map, - StdIo.Ignore, StdIo.Inherit, StdIo.Inherit, builder.allocator) - %% |err| debug.panic("Unable to spawn zig compiler: {}\n", @errorName(err)); - %return waitForCleanExit(&child); + builder.spawnChild(builder.zig_exe, zig_args.toSliceConst()); } }; @@ -700,14 +720,7 @@ const CLibrary = struct { %%cc_args.append(dir); } - if (builder.verbose) { - printInvocation(cc, cc_args); - } - - var child = os.ChildProcess.spawn(cc, cc_args.toSliceConst(), &builder.env_map, - StdIo.Ignore, StdIo.Inherit, StdIo.Inherit, builder.allocator) - %% |err| debug.panic("Unable to spawn compiler: {}\n", @errorName(err)); - %return waitForCleanExit(&child); + builder.spawnChild(cc, cc_args.toSliceConst()); %%self.object_files.append(o_file); } @@ -732,14 +745,18 @@ const CLibrary = struct { %%cc_args.append(object_file); } - if (builder.verbose) { - printInvocation(cc, cc_args); - } + builder.spawnChild(cc, cc_args.toSliceConst()); - var child = os.ChildProcess.spawn(cc, cc_args.toSliceConst(), &builder.env_map, - StdIo.Ignore, StdIo.Inherit, StdIo.Inherit, builder.allocator) - %% |err| debug.panic("Unable to spawn compiler: {}\n", @errorName(err)); - %return waitForCleanExit(&child); + // sym link for libfoo.so.1 to libfoo.so.1.2.3 + const major_only = %%fmt.allocPrint(builder.allocator, "lib{}.so.{d}", self.name, self.version.major); + defer builder.allocator.free(major_only); + _ = os.deleteFile(builder.allocator, major_only); + %%os.symLink(builder.allocator, self.out_filename, major_only); + // sym link for libfoo.so to libfoo.so.1 + const name_only = %%fmt.allocPrint(builder.allocator, "lib{}.so", self.name); + defer builder.allocator.free(name_only); + _ = os.deleteFile(builder.allocator, name_only); + %%os.symLink(builder.allocator, major_only, name_only); } } @@ -848,14 +865,7 @@ const CExecutable = struct { %%cc_args.append(dir); } - if (builder.verbose) { - printInvocation(cc, cc_args); - } - - var child = os.ChildProcess.spawn(cc, cc_args.toSliceConst(), &builder.env_map, - StdIo.Ignore, StdIo.Inherit, StdIo.Inherit, builder.allocator) - %% |err| debug.panic("Unable to spawn compiler: {}\n", @errorName(err)); - %return waitForCleanExit(&child); + builder.spawnChild(cc, cc_args.toSliceConst()); %%self.object_files.append(o_file); } @@ -879,14 +889,7 @@ const CExecutable = struct { %%cc_args.append(full_path_lib); } - if (builder.verbose) { - printInvocation(cc, cc_args); - } - - var child = os.ChildProcess.spawn(cc, cc_args.toSliceConst(), &builder.env_map, - StdIo.Ignore, StdIo.Inherit, StdIo.Inherit, builder.allocator) - %% |err| debug.panic("Unable to spawn compiler: {}\n", @errorName(err)); - %return waitForCleanExit(&child); + builder.spawnChild(cc, cc_args.toSliceConst()); } pub fn setTarget(self: &CExecutable, target_arch: Arch, target_os: Os, target_environ: Environ) { diff --git a/std/os/child_process.zig b/std/os/child_process.zig index 019f9460de..f3d9a112e3 100644 --- a/std/os/child_process.zig +++ b/std/os/child_process.zig @@ -142,7 +142,7 @@ pub const ChildProcess = struct { const pid_err = posix.getErrno(pid); if (pid_err > 0) { return switch (pid_err) { - errno.EAGAIN, errno.ENOMEM, errno.ENOSYS => error.SysResources, + errno.EAGAIN, errno.ENOMEM, errno.ENOSYS => error.SystemResources, else => error.Unexpected, }; } @@ -210,7 +210,7 @@ fn makePipe() -> %[2]i32 { const err = posix.getErrno(posix.pipe(&fds)); if (err > 0) { return switch (err) { - errno.EMFILE, errno.ENFILE => error.SysResources, + errno.EMFILE, errno.ENFILE => error.SystemResources, else => error.Unexpected, } } @@ -242,7 +242,7 @@ fn writeIntFd(fd: i32, value: ErrInt) -> %void { switch (err) { errno.EINTR => continue, errno.EINVAL => unreachable, - else => return error.SysResources, + else => return error.SystemResources, } } index += amt_written; @@ -260,7 +260,7 @@ fn readIntFd(fd: i32) -> %ErrInt { switch (err) { errno.EINTR => continue, errno.EINVAL => unreachable, - else => return error.SysResources, + else => return error.SystemResources, } } index += amt_written; diff --git a/std/os/index.zig b/std/os/index.zig index 68f33828e6..2b40f5e8ed 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -25,13 +25,16 @@ const BufMap = @import("../buf_map.zig").BufMap; const cstr = @import("../cstr.zig"); error Unexpected; -error SysResources; +error SystemResources; error AccessDenied; error InvalidExe; error FileSystem; error IsDir; error FileNotFound; error FileBusy; +error LinkPathAlreadyExists; +error SymLinkLoop; +error ReadOnlyFileSystem; /// Fills `buf` with random bytes. If linking against libc, this calls the /// appropriate OS-specific library call. Otherwise it uses the zig standard @@ -174,7 +177,7 @@ pub fn posixOpen(path: []const u8, flags: usize, perm: usize, allocator: ?&Alloc errno.ENFILE => error.SystemFdQuotaExceeded, errno.ENODEV => error.NoDevice, errno.ENOENT => error.PathNotFound, - errno.ENOMEM => error.NoMem, + errno.ENOMEM => error.SystemResources, errno.ENOSPC => error.NoSpaceLeft, errno.ENOTDIR => error.NotDir, errno.EPERM => error.BadPerm, @@ -191,7 +194,7 @@ pub fn posixDup2(old_fd: i32, new_fd: i32) -> %void { if (err > 0) { return switch (err) { errno.EBUSY, errno.EINTR => continue, - errno.EMFILE => error.SysResources, + errno.EMFILE => error.SystemResources, errno.EINVAL => unreachable, else => error.Unexpected, }; @@ -305,7 +308,7 @@ fn posixExecveErrnoToErr(err: usize) -> error { assert(err > 0); return switch (err) { errno.EFAULT => unreachable, - errno.E2BIG, errno.EMFILE, errno.ENAMETOOLONG, errno.ENFILE, errno.ENOMEM => error.SysResources, + errno.E2BIG, errno.EMFILE, errno.ENAMETOOLONG, errno.ENFILE, errno.ENOMEM => error.SystemResources, errno.EACCES, errno.EPERM => error.AccessDenied, errno.EINVAL, errno.ENOEXEC => error.InvalidExe, errno.EIO, errno.ELOOP => error.FileSystem, @@ -381,3 +384,59 @@ pub fn getCwd(allocator: &Allocator) -> %[]u8 { return buf; } } + +pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void { + const full_buf = %return allocator.alloc(u8, existing_path.len + new_path.len + 2); + defer allocator.free(full_buf); + + const existing_buf = full_buf; + mem.copy(u8, existing_buf, existing_path); + existing_buf[existing_path.len] = 0; + + const new_buf = full_buf[existing_path.len + 1...]; + mem.copy(u8, new_buf, new_path); + new_buf[new_path.len] = 0; + + const err = posix.getErrno(posix.symlink(existing_buf.ptr, new_buf.ptr)); + if (err > 0) { + return switch (err) { + errno.EFAULT, errno.EINVAL => unreachable, + errno.EACCES, errno.EPERM => error.AccessDenied, + errno.EDQUOT => error.DiskQuota, + errno.EEXIST => error.LinkPathAlreadyExists, + errno.EIO => error.FileSystem, + errno.ELOOP => error.SymLinkLoop, + errno.ENAMETOOLONG => error.NameTooLong, + errno.ENOENT, errno.ENOTDIR => error.FileNotFound, + errno.ENOMEM => error.SystemResources, + errno.ENOSPC => error.NoSpaceLeft, + errno.EROFS => error.ReadOnlyFileSystem, + else => error.Unexpected, + }; + } +} + +pub fn deleteFile(allocator: &Allocator, path: []const u8) -> %void { + const buf = %return allocator.alloc(u8, path.len + 1); + defer allocator.free(buf); + + mem.copy(u8, buf, path); + buf[path.len] = 0; + + const err = posix.getErrno(posix.unlink(buf.ptr)); + if (err > 0) { + return switch (err) { + errno.EACCES, errno.EPERM => error.AccessDenied, + errno.EBUSY => error.FileBusy, + errno.EFAULT, errno.EINVAL => unreachable, + errno.EIO => error.FileSystem, + errno.EISDIR => error.IsDir, + errno.ELOOP => error.SymLinkLoop, + errno.ENAMETOOLONG => error.NameTooLong, + errno.ENOENT, errno.ENOTDIR => error.FileNotFound, + errno.ENOMEM => error.SystemResources, + errno.EROFS => error.ReadOnlyFileSystem, + else => error.Unexpected, + }; + } +} diff --git a/std/os/linux.zig b/std/os/linux.zig index 640a915b77..2214fb8dd1 100644 --- a/std/os/linux.zig +++ b/std/os/linux.zig @@ -287,6 +287,10 @@ pub fn read(fd: i32, buf: &u8, count: usize) -> usize { arch.syscall3(arch.SYS_read, usize(fd), usize(buf), count) } +pub fn symlink(existing: &const u8, new: &const u8) -> usize { + arch.syscall2(arch.SYS_symlink, usize(existing), usize(new)) +} + pub fn pread(fd: i32, buf: &u8, count: usize, offset: usize) -> usize { arch.syscall4(arch.SYS_pread, usize(fd), usize(buf), count, offset) } @@ -340,6 +344,10 @@ pub fn kill(pid: i32, sig: i32) -> usize { arch.syscall2(arch.SYS_kill, usize(pid), usize(sig)) } +pub fn unlink(path: &const u8) -> usize { + arch.syscall1(arch.SYS_unlink, usize(path)) +} + pub fn waitpid(pid: i32, status: &i32, options: i32) -> usize { arch.syscall4(arch.SYS_wait4, usize(pid), usize(status), usize(options), 0) } |
