File: fork_func.c

package info (click to toggle)
spiped 1.6.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,328 kB
  • sloc: ansic: 11,951; sh: 1,081; makefile: 629; perl: 121
file content (78 lines) | stat: -rw-r--r-- 1,478 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <sys/wait.h>

#include <stdint.h>
#include <unistd.h>

#include "warnp.h"

#include "fork_func.h"

/**
 * fork_func(func, cookie):
 * Fork and run ${func} in a new process, with ${cookie} as the sole argument.
 */
pid_t
fork_func(int (* func)(void *), void * cookie)
{
	pid_t pid;

	/* Fork */
	switch (pid = fork()) {
	case -1:
		/* Error in fork system call. */
		warnp("fork");
		goto err0;
	case 0:
		/* In child process: Run the provided function, then exit. */
		_exit(func(cookie));
	default:
		/* In parent process: do nothing else. */
		break;
	}

	/* Success! */
	return (pid);

err0:
	/* Failure! */
	return (-1);
}

/**
 * fork_func_wait(pid):
 * Wait for the process ${pid} to finish.  Print any error arising from ${pid}.
 * If ${pid} exited cleanly, return its exit code; otherwise, return -1.
 */
int
fork_func_wait(pid_t pid)
{
	int status;
	int rc = -1;

	/* Wait for the process to finish. */
	if (waitpid(pid, &status, 0) == -1) {
		warnp("waitpid");
		goto err0;
	}

	/* Print the error status, if applicable. */
	if (WIFEXITED(status)) {
		/* Child ${pid} exited cleanly. */
		rc = WEXITSTATUS(status);
	} else {
		/*
		 * Child ${pid} did not exit cleanly; warn about the reason
		 * for the unclean exit.
		 */
		if (WIFSIGNALED(status))
			warn0("pid %jd: terminated with signal %d",
			    (intmax_t)pid, WTERMSIG(status));
		else
			warn0("pid %jd: exited for an unknown reason",
			    (intmax_t)pid);
	}

err0:
	/* Done! */
	return (rc);
}