// File: /workspace/github_c_makefile_star2_O3/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 0x755b
movq %rdi, %rbx
callq 0x6872
movq %rbx, %rdi
callq 0x6731
movq %rbx, %rdi
callq 0x679c
movq %rbx, %rdi
callq 0x6807
movl 0x18(%rbx), %edi
leaq 0x14(%rbx), %r14
movq %r14, %rsi
movl $0x1, %edx
callq 0x22c0
movl %eax, 0x1c(%rbx)
testl %eax, %eax
je 0x7441
cmpl 0x18(%rbx), %eax
je 0x7472
leaq 0x5200(%rip), %rdi      # 0xc629
leaq 0x4ae9(%rip), %rsi      # 0xbf19
leaq 0x51c4(%rip), %rcx      # 0xc5fb
movl $0x3f3, %edx            # imm = 0x3F3
callq 0x21b0
movq %rbx, %rdi
movl $0x1388, %esi           # imm = 0x1388
callq 0x69ed
testl %eax, %eax
je 0x74d8
movl 0x18(%rbx), %edi
movq %r14, %rsi
movl $0x1, %edx
callq 0x22c0
movl %eax, 0x1c(%rbx)
cmpl 0x18(%rbx), %eax
jne 0x757a
cmpl $0x0, 0x34(%rbx)
jne 0x74cb
movq 0xa361(%rip), %rdi      # 0x117e0
movq (%rdi), %r14
leaq 0x8(%rdi), %rcx
cmpq %rcx, %r14
je 0x751d
movq 0x10(%r14), %rdx
cmpl %eax, 0x18(%rdx)
je 0x74a9
jle 0x749f
movq (%r14), %r14
jmp 0x7486
movq 0x8(%r14), %r14
andq $-0x2, %r14
jmp 0x7486
movq %r14, %rsi
callq 0x5bdf
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 0x2270
testl %eax, %eax
jne 0x7599
movq %rbx, %rdi
movl $0x1388, %esi           # imm = 0x1388
callq 0x69ed
testl %eax, %eax
jne 0x7456
movl 0x18(%rbx), %edi
movl $0x9, %esi
callq 0x2270
testl %eax, %eax
jne 0x753c
movq %rbx, %rdi
movl $0x2710, %esi           # imm = 0x2710
jmp 0x74f5
leaq 0x51a3(%rip), %rdi      # 0xc6c7
leaq 0x49ee(%rip), %rsi      # 0xbf19
leaq 0x50c9(%rip), %rcx      # 0xc5fb
movl $0x425, %edx            # imm = 0x425
callq 0x21b0
leaq 0x511d(%rip), %rdi      # 0xc660
leaq 0x49cf(%rip), %rsi      # 0xbf19
leaq 0x50aa(%rip), %rcx      # 0xc5fb
movl $0x40c, %edx            # imm = 0x40C
callq 0x21b0
leaq 0x4de0(%rip), %rdi      # 0xc342
leaq 0x49b0(%rip), %rsi      # 0xbf19
leaq 0x508b(%rip), %rcx      # 0xc5fb
movl $0x3e2, %edx            # imm = 0x3E2
callq 0x21b0
leaq 0x50fb(%rip), %rdi      # 0xc67c
leaq 0x4991(%rip), %rsi      # 0xbf19
leaq 0x506c(%rip), %rcx      # 0xc5fb
movl $0x41a, %edx            # imm = 0x41A
callq 0x21b0
leaq 0x50a4(%rip), %rdi      # 0xc644
leaq 0x4972(%rip), %rsi      # 0xbf19
leaq 0x504d(%rip), %rcx      # 0xc5fb
movl $0x3fb, %edx            # imm = 0x3FB
callq 0x21b0