-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add fork_func #487
Add fork_func #487
Conversation
e9ba002
to
9dfd1de
Compare
This PR includes #488. |
295e2de
to
04a8cb3
Compare
Having a separate file |
Testing with valgrind on macOS does require the sleep-sort values to be separated by more than 100ms. Empirically, when tested with 300ms and 400ms, the order was sometimes reversed (1 out of 2 attempts; I didn't try more tests to get a statistical estimate). I went with 200ms, because occasionally-failing tests are really annoying. |
{ | ||
pid_t pid; | ||
|
||
/* Fork */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is traditionally written with switch (pid = fork())
, see fork(2)
for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sigh, ok, I'll change it. I still think it's easier to leverage our normal "do something; did it fail?" idiom. Then if it did not fail, then figure out what type of success it had.
BTW, although I've seen the traditional switch
method before, it's not in the freebsd 12.4 man page, which has no EXAMPLES
section:
https://man.freebsd.org/cgi/man.cgi?query=fork&apropos=0&sektion=2&manpath=FreeBSD+12.4-RELEASE
Evidently that was only added in 13.1:
https://reviews.freebsd.org/D27626
util/fork_func.c
Outdated
warn0("pid %jd: stopped with %i", | ||
(intmax_t)pid, WSTOPSIG(status)); | ||
else | ||
warn0("pid %jd: stopped for unknown reason."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is "stopped" what you want here? I mean, stopped != exited.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, changed.
ece2651
to
469d76f
Compare
Updated with a REBASE commit. I also rebased onto master, to clear up the git conflict. |
tests/fork_func/check_exec.c
Outdated
|
||
(void)cookie; /* UNUSED */ | ||
|
||
if (execlp("true", "", NULL)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason you want to invoke true(1)
with an argv0 of ""?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope, fixed.
tests/fork_func/check_exit.c
Outdated
static int | ||
func_exit(void * cookie) | ||
{ | ||
int exitcode = *((int *)cookie); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would write this as
int *exitcodep = (int *)cookie;
return (*exitcodep);
Does the same thing, but we generally follow a convention of "pointer = cookie" at the start of callback functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
util/fork_func.c
Outdated
if (WIFSIGNALED(status)) | ||
warn0("pid %jd: signalled with %i", | ||
(intmax_t)pid, WTERMSIG(status)); | ||
else if (WIFSTOPPED(status)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we care about reporting processes which were stopped but not terminated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I figured that anything other than WIFEXITED
was unusual and worth reporting?
I mean, the overall point of fork_func_wait()
is "wait until the forked process is finished". I don't have a good sense of what to do if there's an error, so I figured that reporting it was a decent lower bound?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WIFSTOPPED(status)
True if the process has not terminated, but has stopped and can
be restarted. This macro can be true only if the wait call
specified the WUNTRACED option or if the child process is being
traced (see ptrace(2)).
Since we're not passing the WUNTRACED flag (or any flags at all for that matter), the only thing this would report to us is if the process is being traced... in which case the signal value isn't particularly useful anyway. So I would just handle this with the 'unknown reason' message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, removed
util/fork_func.c
Outdated
goto err0; | ||
case 0: | ||
/* In child process: Run the provided function, then exit. */ | ||
_exit((*func)(cookie)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We generally omit the *
when calling via a function pointer. (The C standard says it's optional.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
util/fork_func.c
Outdated
@@ -12,7 +12,7 @@ | |||
* Fork and run ${func} in a new process, with ${cookie} as the sole argument. | |||
*/ | |||
pid_t | |||
fork_func(int (* func)(void *), void * cookie) | |||
fork_func(int (*func)(void *), void * cookie) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wait, now I'm rethinking this one.
in events/*.c
, there's 6 function pointers defined as (*func)
with no spaces. There's only 2 instances of (* func)
, both of which in cpusupport code I wrote.
OTOH, when I grep for (*
, there's 56 hits, and at first glance, at least 90% of them are function pointers.
So I'm guessing that the desired style is:
int
foo(int (* func)(void *))
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, our STYLE says "space between * and variable name". Applies to function pointers just as much as any other pointers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed the bad commit, and made a separate PR for fixing the style of our function pointers.
I rebased the existing REBASE commits, but then added one more small change. |
/* Fork */ | ||
switch (pid = fork()) { | ||
case -1: | ||
warnp("fork"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency with the other case
s, I would add /* Error in fork system call. */
util/fork_func.c
Outdated
} else { | ||
/* Child ${pid} did not exit cleanly. */ | ||
|
||
/* Warn about the reason for the unclean exit. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Combine these into a single (multi-line) comment.
util/fork_func.c
Outdated
|
||
/* Warn about the reason for the unclean exit. */ | ||
if (WIFSIGNALED(status)) | ||
warn0("pid %jd: signalled with %i", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe "terminated by signal" would be clearer?
Also, any reason you used %i
instead of the more common %d
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hold-over from when I was a TA: "use %i for integer, and %f for float". (Because to a first-year engineering student, "decimal" means something like "1.23".)
Ok, I'll switch to %d
.
A few minor nits but generally looks good. Feel free to make changes and rebase unless there's something you're not sure about. |
Fixes made, rebased, ready for merge. |
No description provided.