// File: /workspace/github_c_makefile_star2_O1/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 0x7787
movq %rdi, %rbx
callq 0x6a8d
movq %rbx, %rdi
callq 0x694c
movq %rbx, %rdi
callq 0x69b7
movq %rbx, %rdi
callq 0x6a22
movl 0x18(%rbx), %edi
leaq 0x14(%rbx), %r14
movq %r14, %rsi
movl $0x1, %edx
callq 0x22d0
movl %eax, 0x1c(%rbx)
testl %eax, %eax
je 0x767e
cmpl 0x18(%rbx), %eax
je 0x76af
leaq 0x4fd0(%rip), %rdi      # 0xc636
leaq 0x48b9(%rip), %rsi      # 0xbf26
leaq 0x4f94(%rip), %rcx      # 0xc608
movl $0x3f3, %edx            # imm = 0x3F3
callq 0x21b0
movq %rbx, %rdi
movl $0x1388, %esi           # imm = 0x1388
callq 0x6c2c
testl %eax, %eax
je 0x7723
movl 0x18(%rbx), %edi
movq %r14, %rsi
movl $0x1, %edx
callq 0x22d0
movl %eax, 0x1c(%rbx)
cmpl 0x18(%rbx), %eax
jne 0x77c5
cmpl $0x0, 0x34(%rbx)
jne 0x7716
movq 0xa124(%rip), %rdi      # 0x117e0
movq (%rdi), %r14
leaq 0x8(%rdi), %rax
cmpq %rax, %r14
je 0x76e8
movl 0x18(%rbx), %ecx
movq 0x10(%r14), %rdx
cmpl %ecx, 0x18(%rdx)
je 0x76eb
jle 0x76db
movq (%r14), %r14
jmp 0x76e3
movq 0x8(%r14), %r14
andq $-0x2, %r14
cmpq %rax, %r14
jne 0x76cb
xorl %r14d, %r14d
testq %r14, %r14
je 0x77a6
movq %r14, %rsi
callq 0x5dd3
movq 0x10(%r14), %rax
movl $0x1, %r15d
movl %r15d, 0x34(%rax)
movq %r14, %rdi
callq 0x2060
movl %r15d, 0x34(%rbx)
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
movl 0x18(%rbx), %edi
movl $0xf, %esi
callq 0x2280
testl %eax, %eax
jne 0x77e4
movq %rbx, %rdi
movl $0x1388, %esi           # imm = 0x1388
callq 0x6c2c
testl %eax, %eax
jne 0x7693
movl 0x18(%rbx), %edi
movl $0x9, %esi
callq 0x2280
testl %eax, %eax
jne 0x7768
movq %rbx, %rdi
movl $0x2710, %esi           # imm = 0x2710
jmp 0x7740
leaq 0x4efe(%rip), %rdi      # 0xc66d
leaq 0x47b0(%rip), %rsi      # 0xbf26
leaq 0x4e8b(%rip), %rcx      # 0xc608
movl $0x40c, %edx            # imm = 0x40C
callq 0x21b0
leaq 0x4bc1(%rip), %rdi      # 0xc34f
leaq 0x4791(%rip), %rsi      # 0xbf26
leaq 0x4e6c(%rip), %rcx      # 0xc608
movl $0x3e2, %edx            # imm = 0x3E2
callq 0x21b0
leaq 0x4f27(%rip), %rdi      # 0xc6d4
leaq 0x4772(%rip), %rsi      # 0xbf26
leaq 0x4e4d(%rip), %rcx      # 0xc608
movl $0x425, %edx            # imm = 0x425
callq 0x21b0
leaq 0x4ebd(%rip), %rdi      # 0xc689
leaq 0x4753(%rip), %rsi      # 0xbf26
leaq 0x4e2e(%rip), %rcx      # 0xc608
movl $0x41a, %edx            # imm = 0x41A
callq 0x21b0
leaq 0x4e66(%rip), %rdi      # 0xc651
leaq 0x4734(%rip), %rsi      # 0xbf26
leaq 0x4e0f(%rip), %rcx      # 0xc608
movl $0x3fb, %edx            # imm = 0x3FB
callq 0x21b0