Skip to content

Commit

Permalink
add stop subcommand
Browse files Browse the repository at this point in the history
  • Loading branch information
txthinking committed Jul 22, 2024
1 parent 2a1e7c0 commit d676ab4
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 139 deletions.
219 changes: 82 additions & 137 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@ pub fn _main() !void {
\\ <id> print stdout and stderr of command
\\ z print stdout and stderr of z
\\
\\ stop stop z daemon
\\
\\v20240723 https://github.com/txthinking/z
\\v20240726 https://github.com/txthinking/z
\\
\\
;
Expand All @@ -70,156 +71,100 @@ pub fn _main() !void {
return;
}

if (std.mem.eql(u8, args[1], "start")) {
if (helper.getuid() != 0) {
return error.RootRequired;
}
const r = crontabL(allocator) catch null;
defer {
if (r) |r1| {
allocator.free(r1.b);
}
}
var cp = std.process.Child.init(&.{"crontab"}, allocator);
cp.stdin_behavior = .Pipe;
try cp.spawn();
if (!std.mem.eql(u8, args[1], "start")) {
var string = std.ArrayList(u8).init(allocator);
defer string.deinit();
try std.json.stringify(args[1..], .{}, string.writer());
const r = try client.send(allocator, string.items);
defer allocator.free(r.b);
try stdout.print("{s}", .{r.b[0..r.n]});
return;
}

if (helper.getuid() != 0) {
return error.RootRequired;
}

const r = crontabL(allocator) catch null;
defer {
if (r) |r1| {
var it = std.mem.splitScalar(u8, r1.b[0..r1.n], '\n');
while (it.next()) |v| {
if (v.len == 0 or std.mem.containsAtLeast(u8, v, 1, "z start")) {
continue;
}
errdefer _ = cp.wait() catch .Unknown;
try cp.stdin.?.writeAll(v);
try cp.stdin.?.writeAll("\n");
}
allocator.free(r1.b);
}
{
}
var cp = std.process.Child.init(&.{"crontab"}, allocator);
cp.stdin_behavior = .Pipe;
try cp.spawn();
if (r) |r1| {
var it = std.mem.splitScalar(u8, r1.b[0..r1.n], '\n');
while (it.next()) |v| {
if (v.len == 0 or std.mem.containsAtLeast(u8, v, 1, "z start")) {
continue;
}
errdefer _ = cp.wait() catch .Unknown;
try cp.stdin.?.writeAll("@reboot ");
const bz = try allocator.alloc(u8, 4 * 1024);
defer allocator.free(bz);
const bz1 = try std.fs.selfExePath(bz);
try cp.stdin.?.writeAll(bz1);
try cp.stdin.?.writeAll(" start\n");
cp.stdin.?.close();
cp.stdin = null;
try cp.stdin.?.writeAll(v);
try cp.stdin.?.writeAll("\n");
}
_ = try cp.wait();
}
{
errdefer _ = cp.wait() catch .Unknown;
try cp.stdin.?.writeAll("@reboot ");
const bz = try allocator.alloc(u8, 4 * 1024);
defer allocator.free(bz);
const bz1 = try std.fs.selfExePath(bz);
try cp.stdin.?.writeAll(bz1);
try cp.stdin.?.writeAll(" start\n");
cp.stdin.?.close();
cp.stdin = null;
}
_ = try cp.wait();

const b = try allocator.alloc(u8, 8);
defer allocator.free(b);
@memcpy(b, "[\"ping\"]");
const r1 = client.send(allocator, b) catch {
const pid1 = std.c.fork();
if (pid1 < 0) {
helper.syslog(error.Fork1Failed);
const b = try allocator.alloc(u8, 8);
defer allocator.free(b);
@memcpy(b, "[\"ping\"]");
const r1 = client.send(allocator, b) catch {
const pid1 = std.c.fork();
if (pid1 < 0) {
helper.syslog(error.Fork1Failed);
std.c.exit(-1);
}
if (pid1 > 0) {
std.c.exit(0);
}
if (pid1 == 0) {
if (helper.setsid() == -1) {
helper.syslog(error.SetsidFailed);
std.c.exit(-1);
}
if (pid1 > 0) {
const pid2 = std.c.fork();
if (pid2 < 0) {
helper.syslog(error.Fork2Failed);
std.c.exit(-1);
}
if (pid2 > 0) {
std.c.exit(0);
}
if (pid1 == 0) {
if (helper.setsid() == -1) {
helper.syslog(error.SetsidFailed);
std.c.exit(-1);
}
const pid2 = std.c.fork();
if (pid2 < 0) {
helper.syslog(error.Fork2Failed);
if (pid2 == 0) {
if (std.c.chdir("/") == -1) {
helper.syslog(error.ChdirFailed);
std.c.exit(-1);
}
if (pid2 > 0) {
std.c.exit(0);
}
if (pid2 == 0) {
if (std.c.chdir("/") == -1) {
helper.syslog(error.ChdirFailed);
std.c.exit(-1);
}
_ = std.c.umask(0);
const n = helper.getdtablesize();
for (0..@intCast(n)) |i| {
_ = std.c.close(@intCast(i));
}
var s = try Server.init(allocator);
defer s.deinit();
s.start() catch |err| {
s.e(err);
return err;
};
_ = std.c.umask(0);
const n = helper.getdtablesize();
for (0..@intCast(n)) |i| {
_ = std.c.close(@intCast(i));
}
}
return;
};
defer allocator.free(r1.b);
return error.MaybeZAlreadyRunning;
}

var l = try allocator.alloc([]u8, args.len - 1);
var done: ?usize = null;
defer {
if (done) |i| {
for (0..(i + 1)) |j| {
allocator.free(l[j]);
var s = try Server.init(allocator);
defer s.deinit();
s.start() catch |err| {
s.e(err);
return err;
};
}
}
allocator.free(l);
}
for (args[1..], 0..) |v, i| {
if (i == 0) {
const id: ?i64 = std.fmt.parseInt(i64, v, 10) catch null;
if (std.mem.eql(u8, v, "a") or std.mem.eql(u8, v, "s") or std.mem.eql(u8, v, "r") or std.mem.eql(u8, v, "d") or std.mem.eql(u8, v, "e") or std.mem.eql(u8, v, "z") or id != null) {
const b = try allocator.alloc(u8, v.len);
@memcpy(b, v);
l[i] = b;
done = i;
continue;
}
if (std.mem.startsWith(u8, v, ".") or std.mem.containsAtLeast(u8, v, 1, "/")) {
var ap: [std.fs.max_path_bytes]u8 = undefined;
const b0 = try std.posix.realpath(v, &ap);
const b = try allocator.alloc(u8, b0.len);
@memcpy(b, b0);
l[i] = b;
done = i;
continue;
}
// std.process.Child does not find exec on given env now, so find it first
var s1 = std.ArrayList(u8).init(allocator);
defer s1.deinit();
var s2 = std.ArrayList(u8).init(allocator);
defer s2.deinit();
var cp = std.process.Child.init(&.{ "which", v }, allocator);
cp.stdout_behavior = .Pipe;
cp.stderr_behavior = .Pipe;
try cp.spawn();
{
errdefer _ = cp.wait() catch .Unknown;
try cp.collectOutput(&s1, &s2, std.fs.max_path_bytes);
}
_ = try cp.wait();
if (s1.items.len == 0) {
return error.WhichCommandNotFound;
}
const b = try allocator.alloc(u8, s1.items.len - 1);
@memcpy(b, s1.items[0 .. s1.items.len - 1]);
l[i] = b;
done = i;
continue;
}
const b = try allocator.alloc(u8, v.len);
@memcpy(b, v);
l[i] = b;
done = i;
}

var string = std.ArrayList(u8).init(allocator);
defer string.deinit();
try std.json.stringify(l, .{}, string.writer());
const r = try client.send(allocator, string.items);
defer allocator.free(r.b);
try stdout.print("{s}", .{r.b[0..r.n]});
return;
};
defer allocator.free(r1.b);
return error.MaybeZAlreadyRunning;
}

fn crontabL(allocator: std.mem.Allocator) !?struct { b: []u8, n: usize } {
Expand Down
15 changes: 13 additions & 2 deletions src/server.zig
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,17 @@ fn _handle(self: *Server, conn: std.net.Server.Connection) !void {
try self.endHandle(conn);
return;
}
if (p.value.len == 1 and std.mem.eql(u8, p.value[0], "stop")) {
self.mutex.lock();
defer self.mutex.unlock();
for (self.processes.items) |v| {
_ = try v.process.kill();
}
try self.endHandle(conn);
std.time.sleep(2 * std.time.ns_per_s);
std.process.exit(0);
return;
}
if (p.value.len == 1 and std.mem.eql(u8, p.value[0], "a")) {
self.mutex.lock();
defer self.mutex.unlock();
Expand Down Expand Up @@ -218,9 +229,9 @@ fn _handle(self: *Server, conn: std.net.Server.Connection) !void {
for (self.processes.items) |v| {
if (v.id == id) {
_ = try v.process.kill();
std.time.sleep(2 * std.time.ns_per_s);
}
}
std.time.sleep(2 * std.time.ns_per_s);
var cmd: ?Command = null;
for (self.commands.items) |v| {
if (v.id == id) {
Expand All @@ -241,9 +252,9 @@ fn _handle(self: *Server, conn: std.net.Server.Connection) !void {
for (self.processes.items) |v| {
if (v.id == id) {
_ = try v.process.kill();
std.time.sleep(1 * std.time.ns_per_s);
}
}
std.time.sleep(1 * std.time.ns_per_s);
for (self.commands.items, 0..) |v, i| {
if (v.id == id) {
const cmd = self.commands.orderedRemove(i);
Expand Down

0 comments on commit d676ab4

Please sign in to comment.