// File: /workspace/github_c_makefile_star2_O2/alexgirao[P]aimant/subprocess.c
// Function: subprocess_terminate
int subprocess_terminate(struct subprocess *sp)
{
	DEBUG_INFO("subprocess_terminate(pid=%i)", sp->pid);

	assert(sp->waitpid_pid == 0); /* you can't terminated a terminated process */

	/* this is required to release children dictionary
	 */
	assert(subprocess_read_selfpipe() == 0);

	/* close child stdin (this clearly tells child that we don't
	 * want to produce anymore)
	 */
	subprocess_close_child_fdin(sp);

	/* close reading ends, so that child get a SIGPIPE
	 */
	subprocess_close_child_fdout(sp);
	subprocess_close_child_fderr(sp);

	if ((sp->waitpid_pid = waitpid(sp->pid, &sp->exit_status, WNOHANG))) {
		assert(sp->waitpid_pid == sp->pid);
	} else {
		assert(sp->waitpid_pid == 0);
		if (subprocess_wait(sp, 5000 /* 5 seconds */) == 0) {
			/* we tried to be nice, giving hints to subprocess to
			 * stop its job
			 */
			DEBUG_INFO("send SIGTERM to child pid %i", sp->pid);
			assert(kill(sp->pid, SIGTERM) == 0);
			if (subprocess_wait(sp, 5000 /* 5 seconds */) == 0) {
				/* still alive, this is the last resort, we must
				 * retry SIGKILL indefinitely
				 */
#ifdef DEBUG_INFO_ENABLED
				int tries = 0;
				DEBUG_INFO("still alive after 5 seconds with kill(child_pid=%i, SIGTERM)", sp->pid);
				DEBUG_INFO("send SIGKILL to child pid %i", sp->pid);
#endif
				for (;;) {
					/* we can't go, if we go, we
					 * run the risk of resource
					 * exhaustion for piling up
					 * immortal processes
					 */
					int r;
					assert(kill(sp->pid, SIGKILL) == 0);
					if ((r = subprocess_wait(sp, 10000 /* 10 seconds */))) {
						DEBUG_INFO("child %i is finally gone, after %i tries", r, tries);
						break;
					}
					DEBUG_INFO("still alive after 10 seconds with kill(child_pid=%i, SIGKILL), try number %i, i won't give up", sp->pid, ++tries);
				}
			}
		}

		/* the child has terminated, that's for sure, we do a
		 * waitpid here just to avoid zombie (defunct)
		 * processes and to get the proper exit status
		 */
		assert((sp->waitpid_pid = waitpid(sp->pid, &sp->exit_status, WNOHANG)) == sp->pid);
	}

	if (sp->is_gone == 0) {
		/* some SIGCHLD may be lost if they arrive at same
		 * time (see test-subprocess-13.c)
		 */
		struct child *c;

		DEBUG_INFO("selfpipe failed for pid %i", sp->pid);

		assert(c = children_search_by_pid(subprocesses, sp->pid));
		DEBUG_INFO("\x20\x20pid %i found at child %p", sp->pid, c);

		children_remove(subprocesses, c);

		child_free(c);
		c = NULL;

		sp->is_gone = 1;
	}

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
cmpl $0x0, 0x1c(%rdi)
jne 0x6c36
movq %rdi, %rbx
callq 0x5eb5
movq %rbx, %rdi
callq 0x5d7d
movq %rbx, %rdi
callq 0x5de5
movq %rbx, %rdi
callq 0x5e4d
movl 0x18(%rbx), %edi
leaq 0x14(%rbx), %r14
pushq $0x1
popq %rdx
movq %r14, %rsi
callq 0x22c0
movl %eax, 0x1c(%rbx)
testl %eax, %eax
je 0x6b5e
cmpl 0x18(%rbx), %eax
je 0x6bd1
leaq 0x4ae3(%rip), %rdi      # 0xb629
leaq 0x43cc(%rip), %rsi      # 0xaf19
leaq 0x4aa7(%rip), %rcx      # 0xb5fb
movl $0x3f3, %edx            # imm = 0x3F3
callq 0x21b0
movq %rbx, %rdi
movl $0x1388, %esi           # imm = 0x1388
callq 0x605d
testl %eax, %eax
jne 0x6bb7
movl 0x18(%rbx), %edi
pushq $0xf
popq %rsi
callq 0x2270
testl %eax, %eax
jne 0x6c93
movq %rbx, %rdi
movl $0x1388, %esi           # imm = 0x1388
callq 0x605d
testl %eax, %eax
jne 0x6bb7
pushq $0x9
popq %r15
movl 0x18(%rbx), %edi
movl %r15d, %esi
callq 0x2270
testl %eax, %eax
jne 0x6c17
movq %rbx, %rdi
movl $0x2710, %esi           # imm = 0x2710
callq 0x605d
testl %eax, %eax
je 0x6b97
movl 0x18(%rbx), %edi
pushq $0x1
popq %rdx
movq %r14, %rsi
callq 0x22c0
movl %eax, 0x1c(%rbx)
cmpl 0x18(%rbx), %eax
jne 0x6c74
cmpl $0x0, 0x34(%rbx)
jne 0x6c0a
movq 0x9c02(%rip), %r14      # 0x107e0
movq %r14, %rdi
movl %eax, %esi
callq 0x5b82
testq %rax, %rax
je 0x6c55
movq %rax, %r15
movq %r14, %rdi
movq %rax, %rsi
callq 0x5303
movq %r15, %rdi
callq 0x5b57
movl $0x1, 0x34(%rbx)
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0x4a42(%rip), %rdi      # 0xb660
leaq 0x42f4(%rip), %rsi      # 0xaf19
leaq 0x49cf(%rip), %rcx      # 0xb5fb
movl $0x40c, %edx            # imm = 0x40C
callq 0x21b0
leaq 0x4705(%rip), %rdi      # 0xb342
leaq 0x42d5(%rip), %rsi      # 0xaf19
leaq 0x49b0(%rip), %rcx      # 0xb5fb
movl $0x3e2, %edx            # imm = 0x3E2
callq 0x21b0
leaq 0x4a6b(%rip), %rdi      # 0xb6c7
leaq 0x42b6(%rip), %rsi      # 0xaf19
leaq 0x4991(%rip), %rcx      # 0xb5fb
movl $0x425, %edx            # imm = 0x425
callq 0x21b0
leaq 0x4a01(%rip), %rdi      # 0xb67c
leaq 0x4297(%rip), %rsi      # 0xaf19
leaq 0x4972(%rip), %rcx      # 0xb5fb
movl $0x41a, %edx            # imm = 0x41A
callq 0x21b0
leaq 0x49aa(%rip), %rdi      # 0xb644
leaq 0x4278(%rip), %rsi      # 0xaf19
leaq 0x4953(%rip), %rcx      # 0xb5fb
movl $0x3fb, %edx            # imm = 0x3FB
callq 0x21b0