aboutsummaryrefslogtreecommitdiff
path: root/std
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-04-17 02:58:42 -0400
committerAndrew Kelley <superjoe30@gmail.com>2017-04-17 06:47:20 -0400
commit47336abae3992ef343bd9cb6099b89bad1dfb634 (patch)
tree4b05465b2d964d8110b9c912b81d82d6dfcada19 /std
parentd16ce67106796011706e9f3653bb843c21c9d708 (diff)
downloadzig-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.zig81
-rw-r--r--std/os/child_process.zig8
-rw-r--r--std/os/index.zig67
-rw-r--r--std/os/linux.zig8
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)
}