// File: davmac314[P]dinit/src/dinit-monitor.cc
// Function: issue_command(char const*, char const*, char const*, std::vector<stringview, std::allocator<stringview>>&, bool)
static void issue_command(const char* name, const char* value, const char* event, std::vector<stringview> &command_parts, bool is_env) {
    std::vector<std::string> final_cmd_parts;
    std::vector<const char *> final_cmd_parts_cstr;

    for (stringview cmd_part : command_parts) {
        std::string cmd_part_str;
        cmd_part_str.reserve(cmd_part.len);

        for (size_t i = 0; i < cmd_part.len; ++i) {
            if (cmd_part.str[i] == '%') {
                ++i;
                if (i >= cmd_part.len) {
                    cmd_part_str.append(1, '%');
                    break;
                }
                if (cmd_part.str[i] == 'n') {
                    cmd_part_str.append(name);
                }
                else if (cmd_part.str[i] == 'v') {
                    if (value) cmd_part_str.append(value);
                }
                else if (cmd_part.str[i] == 's') {
                    cmd_part_str.append(event);
                }
                else {
                    // invalid specifier, just output as is
                    cmd_part_str.append(1, '%');
                    cmd_part_str.append(1, cmd_part_str[i]);
                }
            }
            else if (cmd_part.str[i] == '"') {
                // consume.
            }
            else {
                cmd_part_str.append(1, cmd_part.str[i]);
            }
        }

        final_cmd_parts.emplace_back(std::move(cmd_part_str));
    }

    for (const std::string &cmd_part : final_cmd_parts) {
        final_cmd_parts_cstr.push_back(cmd_part.c_str());
    }
    final_cmd_parts_cstr.push_back(nullptr);

    pid_t child_pid = fork();
    if (child_pid == 0) {
        // we are the child
        char **argv = const_cast<char **>(final_cmd_parts_cstr.data());
        execvp(argv[0], argv);
        perror("dinit-monitor: exec");
    }
    else if (child_pid == -1) {
        perror("dinit-monitor: fork");
    }
    else {
        int wstatus;
        if (wait(&wstatus) != -1) {
            if (wstatus != 0) {
                if (WIFEXITED(wstatus)) {
                    std::cerr << "dinit-monitor: notification command terminated with exit status "
                            << WEXITSTATUS(wstatus) << "\n";
                }
                if (WIFSIGNALED(wstatus)) {
                    std::cerr << "dinit-monitor: notification command terminated due to signal "
                            << WTERMSIG(wstatus) << "\n";
                }
            }
        }

        // Don't bother clearing any pending SIGCHLD. POSIX says that:
        // - either SIGCHLD doesn't queue, in which case we're only leaving one pending signal
        // - or, it does queue, but wait() removes it from the queue.
    }

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movb %r8b, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
andb $0x1, %al
movb %al, -0x21(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x7e80
leaq -0x58(%rbp), %rdi
callq 0x5b30
movq -0x20(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rdi
callq 0x7ea0
movq %rax, -0x68(%rbp)
movq -0x60(%rbp), %rdi
callq 0x7ed0
movq %rax, -0x70(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x7f00
testb $0x1, %al
jne 0x524d
jmp 0x5473
leaq -0x68(%rbp), %rdi
callq 0x7f40
movups (%rax), %xmm0
movaps %xmm0, -0x80(%rbp)
leaq -0xa0(%rbp), %rdi
movq %rdi, -0x108(%rbp)
callq 0x3420
movq -0x108(%rbp), %rdi
movq -0x78(%rbp), %rsi
callq 0x34a0
jmp 0x5282
movq $0x0, -0xb8(%rbp)
movq -0xb8(%rbp), %rax
cmpq -0x78(%rbp), %rax
jae 0x5447
movq -0x80(%rbp), %rax
movq -0xb8(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x25, %eax
jne 0x53f2
movq -0xb8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rax
cmpq -0x78(%rbp), %rax
jb 0x5315
leaq -0xa0(%rbp), %rdi
movl $0x1, %esi
movl $0x25, %edx
callq 0x32e0
jmp 0x52ed
jmp 0x5447
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x3190
jmp 0x56b2
movq -0x80(%rbp), %rax
movq -0xb8(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x6e, %eax
jne 0x5340
movq -0x8(%rbp), %rsi
leaq -0xa0(%rbp), %rdi
callq 0x3530
jmp 0x533b
jmp 0x53f0
movq -0x80(%rbp), %rax
movq -0xb8(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x76, %eax
jne 0x5371
cmpq $0x0, -0x10(%rbp)
je 0x536f
movq -0x10(%rbp), %rsi
leaq -0xa0(%rbp), %rdi
callq 0x3530
jmp 0x536d
jmp 0x536f
jmp 0x53ee
movq -0x80(%rbp), %rax
movq -0xb8(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x73, %eax
jne 0x5399
movq -0x18(%rbp), %rsi
leaq -0xa0(%rbp), %rdi
callq 0x3530
jmp 0x5397
jmp 0x53ec
leaq -0xa0(%rbp), %rdi
movl $0x1, %esi
movl $0x25, %edx
callq 0x32e0
jmp 0x53b1
movq -0xb8(%rbp), %rsi
leaq -0xa0(%rbp), %rdi
callq 0x3550
movq %rax, -0x110(%rbp)
jmp 0x53cd
movq -0x110(%rbp), %rax
movsbl (%rax), %edx
leaq -0xa0(%rbp), %rdi
movl $0x1, %esi
callq 0x32e0
jmp 0x53ea
jmp 0x53ec
jmp 0x53ee
jmp 0x53f0
jmp 0x542e
movq -0x80(%rbp), %rax
movq -0xb8(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x22, %eax
jne 0x5408
jmp 0x542c
movq -0x80(%rbp), %rax
movq -0xb8(%rbp), %rcx
movsbl (%rax,%rcx), %edx
leaq -0xa0(%rbp), %rdi
movl $0x1, %esi
callq 0x32e0
jmp 0x542a
jmp 0x542c
jmp 0x542e
jmp 0x5430
movq -0xb8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xb8(%rbp)
jmp 0x528d
leaq -0x40(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x7f60
jmp 0x5459
leaq -0xa0(%rbp), %rdi
callq 0x3190
leaq -0x68(%rbp), %rdi
callq 0x7fe0
jmp 0x5237
leaq -0x40(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0xc0(%rbp), %rdi
callq 0x8000
movq %rax, -0xc8(%rbp)
movq -0xc0(%rbp), %rdi
callq 0x8030
movq %rax, -0xd0(%rbp)
leaq -0xc8(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x8060
testb $0x1, %al
jne 0x54bd
jmp 0x551c
leaq -0xc8(%rbp), %rdi
callq 0x80a0
movq %rax, -0xd8(%rbp)
movq -0xd8(%rbp), %rdi
callq 0x30e0
movq %rax, -0xe0(%rbp)
leaq -0x58(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x80c0
jmp 0x54f5
jmp 0x54f7
leaq -0xc8(%rbp), %rdi
callq 0x80f0
jmp 0x54a4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
jmp 0x56b2
movq $0x0, -0xe8(%rbp)
leaq -0x58(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x80c0
jmp 0x5539
callq 0x3080
movl %eax, -0xec(%rbp)
cmpl $0x0, -0xec(%rbp)
jne 0x557f
leaq -0x58(%rbp), %rdi
callq 0x8110
movq %rax, -0xf8(%rbp)
movq -0xf8(%rbp), %rsi
movq (%rsi), %rdi
callq 0x31e0
leaq 0x93ef(%rip), %rdi      # 0xe962
callq 0x3230
jmp 0x557a
jmp 0x5697
cmpl $-0x1, -0xec(%rbp)
jne 0x559b
leaq 0x93e7(%rip), %rdi      # 0xe976
callq 0x3230
jmp 0x5596
jmp 0x5695
leaq -0xfc(%rbp), %rdi
callq 0x3380
movl %eax, -0x114(%rbp)
jmp 0x55af
movl -0x114(%rbp), %eax
cmpl $-0x1, %eax
je 0x5693
cmpl $0x0, -0xfc(%rbp)
je 0x5691
movl -0xfc(%rbp), %eax
andl $0x7f, %eax
cmpl $0x0, %eax
jne 0x5628
movq 0x10a10(%rip), %rdi     # 0x15ff0
leaq 0x93a3(%rip), %rsi      # 0xe98a
callq 0x32a0
movq %rax, -0x120(%rbp)
jmp 0x55f5
movq -0x120(%rbp), %rdi
movzbl -0xfb(%rbp), %esi
callq 0x34f0
movq %rax, -0x128(%rbp)
jmp 0x5611
movq -0x128(%rbp), %rdi
leaq 0x92a4(%rip), %rsi      # 0xe8c3
callq 0x32a0
jmp 0x5626
jmp 0x5628
movl -0xfc(%rbp), %eax
andl $0x7f, %eax
addl $0x1, %eax
movsbl %al, %eax
sarl %eax
cmpl $0x0, %eax
jle 0x568f
movq 0x109ab(%rip), %rdi     # 0x15ff0
leaq 0x937f(%rip), %rsi      # 0xe9cb
callq 0x32a0
movq %rax, -0x130(%rbp)
jmp 0x565a
movq -0x130(%rbp), %rdi
movl -0xfc(%rbp), %esi
andl $0x7f, %esi
callq 0x34f0
movq %rax, -0x138(%rbp)
jmp 0x5678
movq -0x138(%rbp), %rdi
leaq 0x923d(%rip), %rsi      # 0xe8c3
callq 0x32a0
jmp 0x568d
jmp 0x568f
jmp 0x5691
jmp 0x5693
jmp 0x5695
jmp 0x5697
leaq -0x58(%rbp), %rdi
callq 0x68c0
leaq -0x40(%rbp), %rdi
callq 0x8130
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
leaq -0x58(%rbp), %rdi
callq 0x68c0
leaq -0x40(%rbp), %rdi
callq 0x8130
movq -0xa8(%rbp), %rdi
callq 0x3500