blob: 3f344afdf4d92bd76274da631a5d94bc87d06657 [file] [log] [blame]
Paul Stewartac1328e2012-07-20 11:55:40 -07001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Darin Petkov633ac6f2011-07-08 13:56:13 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Paul Stewartf65320c2011-10-13 14:34:52 -07005#include "shill/sockets.h"
6
7#include <errno.h>
8#include <fcntl.h>
9#include <net/if.h>
10#include <stdio.h>
Darin Petkove0a312e2011-07-20 13:45:28 -070011#include <sys/ioctl.h>
Darin Petkov633ac6f2011-07-08 13:56:13 -070012#include <sys/socket.h>
13#include <unistd.h>
14
Gary Morain41780232012-07-31 15:08:31 -070015#include <base/eintr_wrapper.h>
16
Christopher Wileyb691efd2012-08-09 13:51:51 -070017#include "shill/logging.h"
Darin Petkov633ac6f2011-07-08 13:56:13 -070018
19namespace shill {
20
21Sockets::~Sockets() {}
22
Gary Morain41780232012-07-31 15:08:31 -070023// Some system calls can be interrupted and return EINTR, but will succeed on
24// retry. The HANDLE_EINTR macro retries a call if it returns EINTR. For a
25// list of system calls that can return EINTR, see 'man 7 signal' under the
26// heading "Interruption of System Calls and Library Functions by Signal
27// Handlers".
28
Paul Stewartf65320c2011-10-13 14:34:52 -070029int Sockets::Accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
Gary Morain41780232012-07-31 15:08:31 -070030 return HANDLE_EINTR(accept(sockfd, addr, addrlen));
Paul Stewartf65320c2011-10-13 14:34:52 -070031}
32
Paul Stewartac1328e2012-07-20 11:55:40 -070033int Sockets::AttachFilter(int sockfd, struct sock_fprog *pf) {
34 return setsockopt(sockfd, SOL_SOCKET, SO_ATTACH_FILTER, pf, sizeof(*pf));
35}
36
Darin Petkov633ac6f2011-07-08 13:56:13 -070037int Sockets::Bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
38 return bind(sockfd, addr, addrlen);
39}
40
Paul Stewartf65320c2011-10-13 14:34:52 -070041int Sockets::BindToDevice(int sockfd, const std::string &device) {
42 char dev_name[IFNAMSIZ];
43 CHECK_GT(sizeof(dev_name), device.length());
44 memset(&dev_name, 0, sizeof(dev_name));
45 snprintf(dev_name, sizeof(dev_name), "%s", device.c_str());
Gary Morain41780232012-07-31 15:08:31 -070046 return HANDLE_EINTR(setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, &dev_name,
47 sizeof(dev_name)));
Paul Stewartf65320c2011-10-13 14:34:52 -070048}
49
Darin Petkov633ac6f2011-07-08 13:56:13 -070050int Sockets::Close(int fd) {
Gary Morain41780232012-07-31 15:08:31 -070051 return HANDLE_EINTR(close(fd));
Darin Petkov633ac6f2011-07-08 13:56:13 -070052}
53
Paul Stewartf65320c2011-10-13 14:34:52 -070054int Sockets::Connect(int sockfd, const struct sockaddr *addr,
55 socklen_t addrlen) {
Gary Morain41780232012-07-31 15:08:31 -070056 return HANDLE_EINTR(connect(sockfd, addr, addrlen));
Paul Stewartf65320c2011-10-13 14:34:52 -070057}
58
59int Sockets::Error() {
60 return errno;
61}
62
63std::string Sockets::ErrorString() {
64 return std::string(strerror(Error()));
65}
66
67int Sockets::GetSockName(int sockfd,
68 struct sockaddr *addr,
69 socklen_t *addrlen) {
70 return getsockname(sockfd, addr, addrlen);
71}
72
73
74int Sockets::GetSocketError(int sockfd) {
75 int error;
76 socklen_t optlen = sizeof(error);
77 if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &optlen) == 0) {
78 return error;
79 }
80 return -1;
81}
82
83
Darin Petkove0a312e2011-07-20 13:45:28 -070084int Sockets::Ioctl(int d, int request, void *argp) {
Gary Morain41780232012-07-31 15:08:31 -070085 return HANDLE_EINTR(ioctl(d, request, argp));
Darin Petkove0a312e2011-07-20 13:45:28 -070086}
87
Paul Stewartf65320c2011-10-13 14:34:52 -070088int Sockets::Listen(int sockfd, int backlog) {
89 return listen(sockfd, backlog);
90}
91
Paul Stewartac1328e2012-07-20 11:55:40 -070092ssize_t Sockets::RecvFrom(int sockfd, void *buf, size_t len, int flags,
93 struct sockaddr *src_addr, socklen_t *addrlen) {
Gary Morain41780232012-07-31 15:08:31 -070094 return HANDLE_EINTR(recvfrom(sockfd, buf, len, flags, src_addr, addrlen));
Paul Stewartac1328e2012-07-20 11:55:40 -070095}
96
Darin Petkov633ac6f2011-07-08 13:56:13 -070097ssize_t Sockets::Send(int sockfd, const void *buf, size_t len, int flags) {
Gary Morain41780232012-07-31 15:08:31 -070098 return HANDLE_EINTR(send(sockfd, buf, len, flags));
Darin Petkov633ac6f2011-07-08 13:56:13 -070099}
100
101ssize_t Sockets::SendTo(int sockfd, const void *buf, size_t len, int flags,
102 const struct sockaddr *dest_addr, socklen_t addrlen) {
Gary Morain41780232012-07-31 15:08:31 -0700103 return HANDLE_EINTR(sendto(sockfd, buf, len, flags, dest_addr, addrlen));
Darin Petkov633ac6f2011-07-08 13:56:13 -0700104}
105
Paul Stewartf65320c2011-10-13 14:34:52 -0700106int Sockets::SetNonBlocking(int sockfd) {
Gary Morain41780232012-07-31 15:08:31 -0700107 return HANDLE_EINTR(
108 fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK));
Paul Stewartf65320c2011-10-13 14:34:52 -0700109}
110
Darin Petkov633ac6f2011-07-08 13:56:13 -0700111int Sockets::Socket(int domain, int type, int protocol) {
112 return socket(domain, type, protocol);
113}
114
Darin Petkove0a312e2011-07-20 13:45:28 -0700115ScopedSocketCloser::ScopedSocketCloser(Sockets *sockets, int fd)
116 : sockets_(sockets),
117 fd_(fd) {}
118
119ScopedSocketCloser::~ScopedSocketCloser() {
120 sockets_->Close(fd_);
121 fd_ = -1;
122}
123
Darin Petkov633ac6f2011-07-08 13:56:13 -0700124} // namespace shill