Skip to content

Commit 22b8b33

Browse files
committed
add SockProtocol type for third argument of socket and socketpair
1 parent 64a5c6f commit 22b8b33

File tree

5 files changed

+58
-23
lines changed

5 files changed

+58
-23
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
1111

1212
### Changed
1313
- Renamed existing `ptrace` wrappers to encourage namespacing ([#692](https://github.com/nix-rust/nix/pull/692))
14+
- Changed function signature of `socket()` and `socketpair()`. The `protocol` argument
15+
has changed type from `c_int` to `SockProtocol`.
16+
It accepts a `None` value for default protocol that was specified with zero using `c_int`.
17+
([#647](https://github.com/nix-rust/nix/pull/647))
1418

1519
## [0.9.0] 2017-07-23
1620

src/sys/socket/mod.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,24 @@ pub enum SockType {
6060
Rdm = libc::SOCK_RDM,
6161
}
6262

63+
/// Constants used in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html)
64+
/// to specify the protocol to use.
65+
#[repr(i32)]
66+
pub enum SockProtocol {
67+
/// TCP protocol ([ip(7)](http://man7.org/linux/man-pages/man7/ip.7.html))
68+
Tcp = libc::IPPROTO_TCP,
69+
/// UDP protocol ([ip(7)](http://man7.org/linux/man-pages/man7/ip.7.html))
70+
Udp = libc::IPPROTO_UDP,
71+
/// Allows applications and other KEXTs to be notified when certain kernel events occur
72+
/// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
73+
#[cfg(any(target_os = "ios", target_os = "macos"))]
74+
KextEvent = libc::SYSPROTO_EVENT,
75+
/// Allows applications to configure and control a KEXT
76+
/// ([ref](https://developer.apple.com/library/content/documentation/Darwin/Conceptual/NKEConceptual/control/control.html))
77+
#[cfg(any(target_os = "ios", target_os = "macos"))]
78+
KextControl = libc::SYSPROTO_CONTROL,
79+
}
80+
6381
bitflags!(
6482
/// Extra flags - Supported by Linux 2.6.27, normalized on other platforms
6583
pub struct SockFlag: c_int {
@@ -381,9 +399,20 @@ pub fn recvmsg<'a, T>(fd: RawFd, iov: &[IoVec<&mut [u8]>], cmsg_buffer: Option<&
381399

382400
/// Create an endpoint for communication
383401
///
402+
/// The `protocol` specifies a particular protocol to be used with the
403+
/// socket. Normally only a single protocol exists to support a
404+
/// particular socket type within a given protocol family, in which case
405+
/// protocol can be specified as `None`. However, it is possible that many
406+
/// protocols may exist, in which case a particular protocol must be
407+
/// specified in this manner.
408+
///
384409
/// [Further reading](http://man7.org/linux/man-pages/man2/socket.2.html)
385-
pub fn socket(domain: AddressFamily, ty: SockType, flags: SockFlag, protocol: c_int) -> Result<RawFd> {
410+
pub fn socket<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: SockType, flags: SockFlag, protocol: T) -> Result<RawFd> {
386411
let mut ty = ty as c_int;
412+
let protocol = match protocol.into() {
413+
None => 0,
414+
Some(p) => p as c_int,
415+
};
387416
let feat_atomic = features::socket_atomic_cloexec();
388417

389418
if feat_atomic {
@@ -409,9 +438,13 @@ pub fn socket(domain: AddressFamily, ty: SockType, flags: SockFlag, protocol: c_
409438
/// Create a pair of connected sockets
410439
///
411440
/// [Further reading](http://man7.org/linux/man-pages/man2/socketpair.2.html)
412-
pub fn socketpair(domain: AddressFamily, ty: SockType, protocol: c_int,
441+
pub fn socketpair<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: SockType, protocol: T,
413442
flags: SockFlag) -> Result<(RawFd, RawFd)> {
414443
let mut ty = ty as c_int;
444+
let protocol = match protocol.into() {
445+
None => 0,
446+
Some(p) => p as c_int,
447+
};
415448
let feat_atomic = features::socket_atomic_cloexec();
416449

417450
if feat_atomic {

src/sys/socket/sockopt.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ mod test {
378378
fn can_get_peercred_on_unix_socket() {
379379
use super::super::*;
380380

381-
let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, 0, SockFlag::empty()).unwrap();
381+
let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()).unwrap();
382382
let a_cred = getsockopt(a, super::PeerCredentials).unwrap();
383383
let b_cred = getsockopt(b, super::PeerCredentials).unwrap();
384384
assert_eq!(a_cred, b_cred);
@@ -390,7 +390,7 @@ mod test {
390390
use super::super::*;
391391
use ::unistd::close;
392392

393-
let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, 0, SockFlag::empty()).unwrap();
393+
let (a, b) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty()).unwrap();
394394
let a_type = getsockopt(a, super::SockType).unwrap();
395395
assert!(a_type == SockType::Stream);
396396
close(a).unwrap();
@@ -402,7 +402,7 @@ mod test {
402402
use super::super::*;
403403
use ::unistd::close;
404404

405-
let s = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), 0).unwrap();
405+
let s = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), None).unwrap();
406406
let s_type = getsockopt(s, super::SockType).unwrap();
407407
assert!(s_type == SockType::Datagram);
408408
close(s).unwrap();
@@ -416,7 +416,7 @@ mod test {
416416
use super::super::*;
417417
use ::unistd::close;
418418

419-
let s = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), 0).unwrap();
419+
let s = socket(AddressFamily::Inet, SockType::Stream, SockFlag::empty(), None).unwrap();
420420
let s_listening = getsockopt(s, super::AcceptConn).unwrap();
421421
assert!(!s_listening);
422422
listen(s, 10).unwrap();

test/sys/test_socket.rs

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ pub fn test_getsockname() {
6969

7070
let tempdir = TempDir::new("test_getsockname").unwrap();
7171
let sockname = tempdir.path().join("sock");
72-
let sock = socket(AddressFamily::Unix, SockType::Stream, SockFlag::empty(),
73-
0).expect("socket failed");
72+
let sock = socket(AddressFamily::Unix, SockType::Stream, SockFlag::empty(), None)
73+
.expect("socket failed");
7474
let sockaddr = SockAddr::new_unix(&sockname).unwrap();
7575
bind(sock, &sockaddr).expect("bind failed");
7676
assert_eq!(sockaddr.to_str(),
@@ -82,8 +82,7 @@ pub fn test_socketpair() {
8282
use nix::unistd::{read, write};
8383
use nix::sys::socket::{socketpair, AddressFamily, SockType, SockFlag};
8484

85-
let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, 0,
86-
SockFlag::empty())
85+
let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
8786
.unwrap();
8887
write(fd1, b"hello").unwrap();
8988
let mut buf = [0;5];
@@ -101,8 +100,7 @@ pub fn test_scm_rights() {
101100
ControlMessage, CmsgSpace, MsgFlags,
102101
MSG_TRUNC, MSG_CTRUNC};
103102

104-
let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, 0,
105-
SockFlag::empty())
103+
let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
106104
.unwrap();
107105
let (r, w) = pipe().unwrap();
108106
let mut received_r: Option<RawFd> = None;
@@ -158,8 +156,7 @@ pub fn test_sendmsg_empty_cmsgs() {
158156
CmsgSpace, MsgFlags,
159157
MSG_TRUNC, MSG_CTRUNC};
160158

161-
let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, 0,
162-
SockFlag::empty())
159+
let (fd1, fd2) = socketpair(AddressFamily::Unix, SockType::Stream, None, SockFlag::empty())
163160
.unwrap();
164161

165162
{
@@ -194,14 +191,14 @@ pub fn test_unixdomain() {
194191
let tempdir = TempDir::new("test_unixdomain").unwrap();
195192
let sockname = tempdir.path().join("sock");
196193
let s1 = socket(AddressFamily::Unix, SockType::Stream,
197-
SockFlag::empty(), 0).expect("socket failed");
194+
SockFlag::empty(), None).expect("socket failed");
198195
let sockaddr = SockAddr::new_unix(&sockname).unwrap();
199196
bind(s1, &sockaddr).expect("bind failed");
200197
listen(s1, 10).expect("listen failed");
201198

202199
let thr = thread::spawn(move || {
203-
let s2 = socket(AddressFamily::Unix, SockType::Stream,
204-
SockFlag::empty(), 0).expect("socket failed");
200+
let s2 = socket(AddressFamily::Unix, SockType::Stream, SockFlag::empty(), None)
201+
.expect("socket failed");
205202
connect(s2, &sockaddr).expect("connect failed");
206203
write(s2, b"hello").expect("write failed");
207204
close(s2).unwrap();
@@ -223,11 +220,11 @@ pub fn test_unixdomain() {
223220
#[test]
224221
pub fn test_syscontrol() {
225222
use nix::{Errno, Error};
226-
use nix::sys::socket::{AddressFamily, SockType, SockFlag};
227-
use nix::sys::socket::{socket, SockAddr};
228-
use nix::sys::socket::SYSPROTO_CONTROL;
223+
use nix::sys::socket::{AddressFamily, socket, SockAddr, SockType, SockFlag, SockProtocol};
229224

230-
let fd = socket(AddressFamily::System, SockType::Datagram, SockFlag::empty(), SYSPROTO_CONTROL).expect("socket failed");
225+
let fd = socket(AddressFamily::System, SockType::Datagram,
226+
SockFlag::empty(), SockProtocol::KextControl)
227+
.expect("socket failed");
231228
let _sockaddr = SockAddr::new_sys_control(fd, "com.apple.net.utun_control", 0).expect("resolving sys_control name failed");
232229
assert_eq!(SockAddr::new_sys_control(fd, "foo.bar.lol", 0).err(), Some(Error::Sys(Errno::ENOENT)));
233230

test/sys/test_sockopt.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use rand::{thread_rng, Rng};
2-
use nix::sys::socket::{socket, sockopt, getsockopt, setsockopt, AddressFamily, SockType, SockFlag, SockLevel};
2+
use nix::sys::socket::{socket, sockopt, getsockopt, setsockopt, AddressFamily, SockType, SockFlag, SockProtocol};
33

44
#[test]
55
fn test_so_buf() {
6-
let fd = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), SockLevel::Udp as i32).unwrap();
6+
let fd = socket(AddressFamily::Inet, SockType::Datagram, SockFlag::empty(), SockProtocol::Udp)
7+
.unwrap();
78
let bufsize: usize = thread_rng().gen_range(4096, 131072);
89
setsockopt(fd, sockopt::SndBuf, &bufsize).unwrap();
910
let actual = getsockopt(fd, sockopt::SndBuf).unwrap();

0 commit comments

Comments
 (0)