Skip to content
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 waitid and related constants and types. #489

Merged
merged 7 commits into from
Jan 10, 2017
Merged

Conversation

zackw
Copy link
Contributor

@zackw zackw commented Jan 6, 2017

waitid is a variation on waitpid with a marginally more convenient way of reporting the status, and a couple of handy
additional features, such as the ability to peek at an exit status without consuming it. It's in POSIX.1-2008 and should be available on all supported Unixes.

Along with it come the type idtype_t and the constants WEXITED, WSTOPPED, WCONTINUED, and WNOWAIT. The constants were already defined for unix/notbsd platforms.

The patch is currently incomplete: I'm pushing it to get CI to test platforms I don't have. Todo list is

  • Add a definition of siginfo_t to all platforms that don't have it.
  • Verify that the new constants are consistent for all *BSD platforms.
  • Verify that idtype_t is consistent across the board.
  • Add link_name annotations for waitid if/as necessary.

waitid() is a variation on waitpid() with a marginally more
convenient way of reporting the status, and a couple of handy
additional features, such as the ability to peek at an exit
status without consuming it.  It's in POSIX.1-2008 and should
be available on all supported Unixes.

Along with it come the type 'idtype_t' and the constants
WEXITED, WSTOPPED, WCONTINUED, and WNOWAIT.  Theconstants
were alre dy defined for unix/notbsd platforms.

Patch incomplete: several targets are going to have to add
definitions of siginfo_t, but I'm not sure which ones yet.
@rust-highfive
Copy link

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @alexcrichton (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@alexcrichton
Copy link
Member

Nice! We tend to avoid literal enum types so could that be expanded to a list of constants?

@zackw
Copy link
Contributor Author

zackw commented Jan 6, 2017

@alexcrichton The trouble is that idtype_t is actually specified as an enum on the C side. Is it even possible to express that any other way? (See http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_wait.h.html )

@alexcrichton
Copy link
Member

Sure yeah, but C enums are different than Rust enums, they're extensible.

 * idtype_t no longer an enum.
 * Darwin/x86-32 needs the $UNIX2003 thing.
 * Darwin, FreeBSD, and NetBSD all have different values for the new constants.
 * OpenBSD doesn't have this feature at all.  (Hopefully we can get away
   with defining idtype_t anyway.)
@@ -447,6 +458,11 @@ extern {
link_name = "waitpid$UNIX2003")]
pub fn waitpid(pid: pid_t, status: *mut ::c_int, options: ::c_int)
-> pid_t;
#[cfg(not(target_os = "openbsd"))] // " if " -- appease style checker
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could the definition here be pushed down into the various modules to avoid the #[cfg]?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we defer that conversation until after I have something that works everywhere, please? I don't think the right tradeoff among tidiness, consistency with other stuff, and minimization of repetition will be apparent till then.

// [ http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_wait.h.html ]
// However, FFI doesn't currently know how to ABI-match a C enum
// (rust#28925, rust#34641) and *probably* the underlying type will be
// c_uint everywhere since all of the enumerators are representable by c_uint.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's ok to remove this FIXME, I don't think it's possible to fix such a fixme.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the new rev, it still says this, but not as a FIXME. I think it's valuable to document that we are manually matching a C enum here. Especially as, it turns out, the underlying type differs on Android.

 * OpenBSD doesn't have idtype_t or the P_* constants either
 * FreeBSD has different values for the P_* constants
 * Android gives idtype_t a different signedness
 * Disable waitid on NetBSD as it causes a link failure - I think this
   may be a problem with the test environment
} else if #[cfg(target_os = "android")] {
pub type idtype_t = ::c_int;
} else {
pub type idtype_t = ::c_uint;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of a cfg_if! block here, could the definition of this just get pushed down into respective modules?

@@ -204,6 +218,22 @@ pub const PRIO_MIN: ::c_int = -20;
pub const PRIO_MAX: ::c_int = 20;

cfg_if! {
if #[cfg(target_os = "openbsd")] {
// P_* constants are not available
} else if #[cfg(target_os = "freebsd")] {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to above, could this cfg_if! be avoided to push the definitions into lower modules? (duplication is fine)

@alexcrichton
Copy link
Member

@zackw oh if you're writing for a green bill of health on Travis before worrying about organization no worries! Feel free to just ping me when it's all working and I'll come take a look at the style.

It turns out that *only* FreeBSD and NetBSD proper have waitid, and that
Solaris' additional W* constants are totally different from everyone
else's, which tips me over from 'find some way to shoehorn this into
the top-level unix/mod.rs' to 'put it in the submodules, live with the
code duplication'.
@zackw
Copy link
Contributor Author

zackw commented Jan 8, 2017

@alexcrichton This is ready to be reviewed now. I did wind up pushing stuff down into submodules - the cross-platform variance is bigger than I thought it was. You probably want to look only at the diff versus master; let me know if you want a squashed version.

There's still a weird problem with NetBSD (which is why the actual function prototype is commented out in that file), and I'm a little surprised not to have had to add any definitions of siginfo_t.

// idtype_t is specified as a C enum:
// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_wait.h.html
// However, FFI doesn't currently know how to ABI-match a C enum
// (rust#28925, rust#34641).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's ok to avoid repeating this comment in all locations, we tend to not have a lot of comments in libc due to the large amount of duplication.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, the trouble is that there isn't an obvious "top" or "first" place to put it. I think I'll leave it in bsd/apple/mod.rs, which is alphabetically first, and remove it from the others; does that sound good?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I think it's safe to just elide the comment in general. All the relevant properties of the typedef are already checked against the C representation, so it's basically never going to change, so it's ok to omit the comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, done.

// This should work, but it causes the netbsd CI build to fail with an
// intra-libc.a undefined reference to `wait6`.
//pub fn waitid(idtype: idtype_t, id: id_t, infop: *mut ::siginfo_t,
// options: ::c_int) -> ::c_int;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may just need a #[link_name] of some form, but otherwise it's ok to just delete this for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, OK. To be clear, though, I'm pretty sure this is a bug within (possibly just the rumprun version of) NetBSD libc. The actual error is

/usr/local/rumprun-x86_64/lib/libc.a(waitid.o): In function `_waitid':
/build/rumprun/src-netbsd/lib/libc/gen/waitid.c:52: undefined reference to `wait6'

I don't think there's any way to work around that from within our code.

// (rust#28925, rust#34641).
cfg_if! {
if #[cfg(target_os = "android")] {
pub type idtype_t = ::c_int;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be pushed into the two lower modules as well to avoid the cfg_if!?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

@zackw
Copy link
Contributor Author

zackw commented Jan 10, 2017

So I think this is fully baked now; do you want it rebased and squashed?

@alexcrichton
Copy link
Member

@bors: r+

Thanks!

@bors
Copy link
Contributor

bors commented Jan 10, 2017

📌 Commit 84bce94 has been approved by alexcrichton

@bors
Copy link
Contributor

bors commented Jan 10, 2017

⌛ Testing commit 84bce94 with merge 7012cd6...

bors added a commit that referenced this pull request Jan 10, 2017
Add waitid and related constants and types.

[`waitid`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/waitid.html) is a variation on `waitpid` with a marginally more convenient way of reporting the status, and a couple of handy
additional features, such as the ability to peek at an exit status without consuming it.  It's in POSIX.1-2008 and should be available on all supported Unixes.

Along with it come the type `idtype_t` and the constants `WEXITED`, `WSTOPPED`, `WCONTINUED`, and `WNOWAIT`.  The constants were already defined for unix/notbsd platforms.

The patch is currently incomplete: I'm pushing it to get CI to test platforms I don't have.  Todo list is

* [x] Add a definition of `siginfo_t` to all platforms that don't have it.
* [x] Verify that the new constants are consistent for all \*BSD platforms.
* [x] Verify that `idtype_t` is consistent across the board.
* [x] Add `link_name` annotations for `waitid` if/as necessary.
@alexcrichton
Copy link
Member

Nah it's ok, we can go ahead and merge if CI passes

@bors
Copy link
Contributor

bors commented Jan 10, 2017

💔 Test failed - status-travis

@alexcrichton
Copy link
Member

alexcrichton commented Jan 10, 2017 via email

@bors
Copy link
Contributor

bors commented Jan 10, 2017

⌛ Testing commit 84bce94 with merge cb7f667...

bors added a commit that referenced this pull request Jan 10, 2017
Add waitid and related constants and types.

[`waitid`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/waitid.html) is a variation on `waitpid` with a marginally more convenient way of reporting the status, and a couple of handy
additional features, such as the ability to peek at an exit status without consuming it.  It's in POSIX.1-2008 and should be available on all supported Unixes.

Along with it come the type `idtype_t` and the constants `WEXITED`, `WSTOPPED`, `WCONTINUED`, and `WNOWAIT`.  The constants were already defined for unix/notbsd platforms.

The patch is currently incomplete: I'm pushing it to get CI to test platforms I don't have.  Todo list is

* [x] Add a definition of `siginfo_t` to all platforms that don't have it.
* [x] Verify that the new constants are consistent for all \*BSD platforms.
* [x] Verify that `idtype_t` is consistent across the board.
* [x] Add `link_name` annotations for `waitid` if/as necessary.
@bors
Copy link
Contributor

bors commented Jan 10, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: alexcrichton
Pushing cb7f667 to master...

@bors bors merged commit 84bce94 into rust-lang:master Jan 10, 2017
@zackw zackw deleted the add-waitid branch January 20, 2017 13:15
Susurrus pushed a commit to Susurrus/libc that referenced this pull request Mar 26, 2017
Fix ControlMessage::encode_into when encoding multiple messages

copy_bytes updates dst so that it points after the bytes that were just
copied into it. encode_into did not advance the buffer in the same way
when encoding the data.

See rust-lang#473
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants