// File: /workspace/github_c_makefile_star2_O0/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
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
cmpl $0x0, 0x1c(%rax)
jne 0x9ee8
jmp 0x9f07
leaq 0x74d2(%rip), %rdi      # 0x113c1
leaq 0x70a2(%rip), %rsi      # 0x10f98
movl $0x3e2, %edx            # imm = 0x3E2
leaq 0x778e(%rip), %rcx      # 0x11690
callq 0x21a0
callq 0x93a0
cmpl $0x0, %eax
jne 0x9f13
jmp 0x9f32
leaq 0x6a79(%rip), %rdi      # 0x10993
leaq 0x7077(%rip), %rsi      # 0x10f98
movl $0x3e6, %edx            # imm = 0x3E6
leaq 0x7763(%rip), %rcx      # 0x11690
callq 0x21a0
movq -0x8(%rbp), %rdi
callq 0x91d0
movq -0x8(%rbp), %rdi
callq 0x9280
movq -0x8(%rbp), %rdi
callq 0x9310
movq -0x8(%rbp), %rax
movl 0x18(%rax), %edi
movq -0x8(%rbp), %rsi
addq $0x14, %rsi
movl $0x1, %edx
callq 0x22d0
movq -0x8(%rbp), %rcx
movl %eax, 0x1c(%rcx)
cmpl $0x0, %eax
je 0x9fa8
movq -0x8(%rbp), %rax
movl 0x1c(%rax), %eax
movq -0x8(%rbp), %rcx
cmpl 0x18(%rcx), %eax
jne 0x9f84
jmp 0x9fa3
leaq 0x7733(%rip), %rdi      # 0x116be
leaq 0x7006(%rip), %rsi      # 0x10f98
movl $0x3f3, %edx            # imm = 0x3F3
leaq 0x76f2(%rip), %rcx      # 0x11690
callq 0x21a0
jmp 0xa0d7
movq -0x8(%rbp), %rax
cmpl $0x0, 0x1c(%rax)
jne 0x9fb4
jmp 0x9fd3
leaq 0x7406(%rip), %rdi      # 0x113c1
leaq 0x6fd6(%rip), %rsi      # 0x10f98
movl $0x3f5, %edx            # imm = 0x3F5
leaq 0x76c2(%rip), %rcx      # 0x11690
callq 0x21a0
movq -0x8(%rbp), %rdi
movl $0x1388, %esi           # imm = 0x1388
callq 0x9410
cmpl $0x0, %eax
jne 0xa08b
movq -0x8(%rbp), %rax
movl 0x18(%rax), %edi
movl $0xf, %esi
callq 0x2270
cmpl $0x0, %eax
jne 0xa002
jmp 0xa021
leaq 0x76d0(%rip), %rdi      # 0x116d9
leaq 0x6f88(%rip), %rsi      # 0x10f98
movl $0x3fb, %edx            # imm = 0x3FB
leaq 0x7674(%rip), %rcx      # 0x11690
callq 0x21a0
movq -0x8(%rbp), %rdi
movl $0x1388, %esi           # imm = 0x1388
callq 0x9410
cmpl $0x0, %eax
jne 0xa089
jmp 0xa036
movq -0x8(%rbp), %rax
movl 0x18(%rax), %edi
movl $0x9, %esi
callq 0x2270
cmpl $0x0, %eax
jne 0xa04e
jmp 0xa06d
leaq 0x76a0(%rip), %rdi      # 0x116f5
leaq 0x6f3c(%rip), %rsi      # 0x10f98
movl $0x40c, %edx            # imm = 0x40C
leaq 0x7628(%rip), %rcx      # 0x11690
callq 0x21a0
movq -0x8(%rbp), %rdi
movl $0x2710, %esi           # imm = 0x2710
callq 0x9410
movl %eax, -0xc(%rbp)
cmpl $0x0, %eax
je 0xa085
jmp 0xa087
jmp 0xa036
jmp 0xa089
jmp 0xa08b
movq -0x8(%rbp), %rax
movl 0x18(%rax), %edi
movq -0x8(%rbp), %rsi
addq $0x14, %rsi
movl $0x1, %edx
callq 0x22d0
movq -0x8(%rbp), %rcx
movl %eax, 0x1c(%rcx)
movq -0x8(%rbp), %rcx
cmpl 0x18(%rcx), %eax
jne 0xa0b6
jmp 0xa0d5
leaq 0x7654(%rip), %rdi      # 0x11711
leaq 0x6ed4(%rip), %rsi      # 0x10f98
movl $0x41a, %edx            # imm = 0x41A
leaq 0x75c0(%rip), %rcx      # 0x11690
callq 0x21a0
jmp 0xa0d7
movq -0x8(%rbp), %rax
cmpl $0x0, 0x34(%rax)
jne 0xa14b
movq 0xc728(%rip), %rdi      # 0x16810
movq -0x8(%rbp), %rax
movl 0x18(%rax), %esi
callq 0x8f00
movq %rax, -0x18(%rbp)
cmpq $0x0, %rax
je 0xa100
jmp 0xa11f
leaq 0x7655(%rip), %rdi      # 0x1175c
leaq 0x6e8a(%rip), %rsi      # 0x10f98
movl $0x425, %edx            # imm = 0x425
leaq 0x7576(%rip), %rcx      # 0x11690
callq 0x21a0
movq 0xc6ea(%rip), %rdi      # 0x16810
movq -0x18(%rbp), %rsi
callq 0x78d0
movq -0x18(%rbp), %rdi
callq 0x8ea0
movq $0x0, -0x18(%rbp)
movq -0x8(%rbp), %rax
movl $0x1, 0x34(%rax)
xorl %eax, %eax
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)