summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSharvil Nanavati <sharvil@google.com>2016-06-20 19:16:12 -0700
committerZach Jang <zachjang@google.com>2016-06-22 16:28:31 -0700
commit472271b153c5dc53c28beac55480a8d8434b2d5c (patch)
tree9112405a19254acdd7e1b37b4d667135cc0e2764
parent514139f4b40cbb035bb92f3e24d5a389d75db9e6 (diff)
downloadandroid_system_bt-472271b153c5dc53c28beac55480a8d8434b2d5c.tar.gz
android_system_bt-472271b153c5dc53c28beac55480a8d8434b2d5c.tar.bz2
android_system_bt-472271b153c5dc53c28beac55480a8d8434b2d5c.zip
DO NOT MERGE Fix potential DoS caused by delivering signal to BT process
Bug: 28885210 Change-Id: I63866d894bfca47464d6e42e3fb0357c4f94d360 Conflicts: btif/co/bta_hh_co.c btif/src/btif_core.c Merge conflict resolution of ag/1161415 (referencing ag/1164670) - Directly into mnc-mr2-release
-rw-r--r--audio_a2dp_hw/audio_a2dp_hw.c22
-rw-r--r--btif/co/bta_hh_co.c11
-rw-r--r--btif/co/bta_hl_co.c3
-rw-r--r--btif/src/btif_core.c5
-rw-r--r--btif/src/btif_dm.c3
-rw-r--r--btif/src/btif_hh.c4
-rw-r--r--btif/src/btif_hl.c14
-rw-r--r--btif/src/btif_pan.c22
-rw-r--r--btif/src/btif_rc.c19
-rw-r--r--btif/src/btif_sock_l2cap.c10
-rw-r--r--btif/src/btif_sock_rfc.c14
-rw-r--r--btif/src/btif_sock_thread.c20
-rw-r--r--btif/src/btif_sock_util.c6
-rw-r--r--gki/ulinux/gki_ulinux.c2
-rw-r--r--hci/src/btsnoop.c6
-rw-r--r--hci/src/btsnoop_net.c6
-rw-r--r--hci/src/hci_hal_h4.c2
-rw-r--r--hci/src/hci_hal_mct.c2
-rw-r--r--hci/src/hci_layer.c3
-rw-r--r--hci/test/hci_hal_h4_test.cpp16
-rw-r--r--hci/test/hci_hal_mct_test.cpp8
-rw-r--r--osi/src/config.c90
-rw-r--r--osi/src/eager_reader.c4
-rw-r--r--osi/src/reactor.c2
-rw-r--r--osi/src/semaphore.c6
-rw-r--r--osi/src/socket.c10
-rw-r--r--osi/test/alarm_test.cpp2
-rw-r--r--osi/test/atomic_test.cpp6
-rw-r--r--osi/test/eager_reader_test.cpp4
-rw-r--r--osi/test/reactor_test.cpp4
-rw-r--r--test/suite/support/callbacks.h6
-rw-r--r--tools/hci/main.c9
-rw-r--r--udrv/ulinux/uipc.c20
33 files changed, 214 insertions, 147 deletions
diff --git a/audio_a2dp_hw/audio_a2dp_hw.c b/audio_a2dp_hw/audio_a2dp_hw.c
index 29803366e..a17b01cc1 100644
--- a/audio_a2dp_hw/audio_a2dp_hw.c
+++ b/audio_a2dp_hw/audio_a2dp_hw.c
@@ -244,7 +244,7 @@ static int skt_read(int fd, void *p, size_t len)
ts_log("skt_read recv", len, NULL);
- if ((read = recv(fd, p, len, MSG_NOSIGNAL)) == -1)
+ if ((read = TEMP_FAILURE_RETRY(recv(fd, p, len, MSG_NOSIGNAL))) == -1)
{
ERROR("write failed with errno=%d\n", errno);
return -1;
@@ -266,12 +266,12 @@ static int skt_write(int fd, const void *p, size_t len)
/* poll for 500 ms */
/* send time out */
- if (poll(&pfd, 1, 500) == 0)
+ if (TEMP_FAILURE_RETRY(poll(&pfd, 1, 500)) == 0)
return 0;
ts_log("skt_write", len, NULL);
- if ((sent = send(fd, p, len, MSG_NOSIGNAL)) == -1)
+ if ((sent = TEMP_FAILURE_RETRY(send(fd, p, len, MSG_NOSIGNAL))) == -1)
{
ERROR("write failed with errno=%d\n", errno);
return -1;
@@ -302,14 +302,14 @@ static int skt_disconnect(int fd)
static int a2dp_ctrl_receive(struct a2dp_stream_common *common, void* buffer, int length)
{
- int ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL);
+ int ret = TEMP_FAILURE_RETRY(recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL));
if (ret < 0)
{
ERROR("ack failed (%s)", strerror(errno));
if (errno == EINTR)
{
/* retry again */
- ret = recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL);
+ ret = TEMP_FAILURE_RETRY(recv(common->ctrl_fd, buffer, length, MSG_NOSIGNAL));
if (ret < 0)
{
ERROR("ack failed (%s)", strerror(errno));
@@ -336,7 +336,7 @@ static int a2dp_command(struct a2dp_stream_common *common, char cmd)
DEBUG("A2DP COMMAND %s", dump_a2dp_ctrl_event(cmd));
/* send command */
- if (send(common->ctrl_fd, &cmd, 1, MSG_NOSIGNAL) == -1)
+ if (TEMP_FAILURE_RETRY(send(common->ctrl_fd, &cmd, 1, MSG_NOSIGNAL)) == -1)
{
ERROR("cmd failed (%s)", strerror(errno));
skt_disconnect(common->ctrl_fd);
@@ -409,13 +409,13 @@ static void a2dp_open_ctrl_path(struct a2dp_stream_common *common)
break;
ERROR("error : a2dp not ready, wait 250 ms and retry");
- usleep(250000);
+ TEMP_FAILURE_RETRY(usleep(250000));
skt_disconnect(common->ctrl_fd);
common->ctrl_fd = AUDIO_SKT_DISCONNECTED;
}
/* ctrl channel not ready, wait a bit */
- usleep(250000);
+ TEMP_FAILURE_RETRY(usleep(250000));
}
}
@@ -578,7 +578,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
DEBUG("emulate a2dp write delay (%d us)", us_delay);
- usleep(us_delay);
+ TEMP_FAILURE_RETRY(usleep(us_delay));
pthread_mutex_unlock(&out->common.lock);
return -1;
}
@@ -985,7 +985,7 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer,
DEBUG("emulate a2dp read delay (%d us)", us_delay);
- usleep(us_delay);
+ TEMP_FAILURE_RETRY(usleep(us_delay));
pthread_mutex_unlock(&in->common.lock);
return -1;
}
@@ -1114,7 +1114,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
DEBUG("success");
/* Delay to ensure Headset is in proper state when START is initiated
from DUT immediately after the connection due to ongoing music playback. */
- usleep(250000);
+ TEMP_FAILURE_RETRY(usleep(250000));
return 0;
err_open:
diff --git a/btif/co/bta_hh_co.c b/btif/co/bta_hh_co.c
index bd6fd6f06..f689f24ea 100644
--- a/btif/co/bta_hh_co.c
+++ b/btif/co/bta_hh_co.c
@@ -58,8 +58,7 @@ void uhid_set_non_blocking(int fd)
/*Internal function to perform UHID write and error checking*/
static int uhid_write(int fd, const struct uhid_event *ev)
{
- ssize_t ret = write(fd, ev, sizeof(*ev));
-
+ ssize_t ret = TEMP_FAILURE_RETRY(write(fd, ev, sizeof(*ev)));
if (ret < 0){
int rtn = -errno;
APPL_TRACE_ERROR("%s: Cannot write to uhid:%s",
@@ -85,7 +84,7 @@ static int uhid_event(btif_hh_device_t *p_dev)
APPL_TRACE_ERROR("%s: Device not found",__FUNCTION__)
return -1;
}
- ret = read(p_dev->fd, &ev, sizeof(ev));
+ ret = TEMP_FAILURE_RETRY(read(p_dev->fd, &ev, sizeof(ev)));
if (ret == 0) {
APPL_TRACE_ERROR("%s: Read HUP on uhid-cdev %s", __FUNCTION__,
strerror(errno));
@@ -206,7 +205,7 @@ static void *btif_hh_poll_event_thread(void *arg)
uhid_set_non_blocking(p_dev->fd);
while(p_dev->hh_keep_polling){
- ret = poll(pfds, 1, 50);
+ ret = TEMP_FAILURE_RETRY(poll(pfds, 1, 50));
if (ret < 0) {
APPL_TRACE_ERROR("%s: Cannot poll for fds: %s\n", __FUNCTION__, strerror(errno));
break;
@@ -300,7 +299,7 @@ void bta_hh_co_open(UINT8 dev_handle, UINT8 sub_class, tBTA_HH_ATTR_MASK attr_ma
__FUNCTION__, p_dev->attr_mask, p_dev->sub_class, p_dev->app_id);
if(p_dev->fd<0) {
- p_dev->fd = open(dev_path, O_RDWR | O_CLOEXEC);
+ p_dev->fd = TEMP_FAILURE_RETRY(open(dev_path, O_RDWR | O_CLOEXEC));
if (p_dev->fd < 0){
APPL_TRACE_ERROR("%s: Error: failed to open uhid, err:%s",
__FUNCTION__,strerror(errno));
@@ -329,7 +328,7 @@ void bta_hh_co_open(UINT8 dev_handle, UINT8 sub_class, tBTA_HH_ATTR_MASK attr_ma
btif_hh_cb.device_num++;
// This is a new device,open the uhid driver now.
- p_dev->fd = open(dev_path, O_RDWR | O_CLOEXEC);
+ p_dev->fd = TEMP_FAILURE_RETRY(open(dev_path, O_RDWR | O_CLOEXEC));
if (p_dev->fd < 0){
APPL_TRACE_ERROR("%s: Error: failed to open uhid, err:%s",
__FUNCTION__,strerror(errno));
diff --git a/btif/co/bta_hl_co.c b/btif/co/bta_hl_co.c
index 9aa91f7a0..f1331459a 100644
--- a/btif/co/bta_hl_co.c
+++ b/btif/co/bta_hl_co.c
@@ -34,6 +34,7 @@
#include <fcntl.h>
#include <ctype.h>
#include <cutils/sockets.h>
+#include <unistd.h>
#include "bta_api.h"
#include "btm_api.h"
#include "bta_sys.h"
@@ -384,7 +385,7 @@ void bta_hl_co_put_rx_data (UINT8 app_id, tBTA_HL_MDL_HANDLE mdl_handle,
{
BTIF_TRACE_DEBUG("app_idx=%d mcl_idx=0x%x mdl_idx=0x%x data_size=%d",
app_idx, mcl_idx, mdl_idx, data_size);
- r = send(p_dcb->p_scb->socket_id[1], p_dcb->p_rx_pkt, data_size, 0);
+ r = TEMP_FAILURE_RETRY(send(p_dcb->p_scb->socket_id[1], p_dcb->p_rx_pkt, data_size, 0));
if (r == data_size)
{
diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c
index 0ff9651fb..1f28dc8ba 100644
--- a/btif/src/btif_core.c
+++ b/btif/src/btif_core.c
@@ -29,6 +29,7 @@
#include <ctype.h>
#include <cutils/properties.h>
#include <dirent.h>
+#include <errno.h>
#include <fcntl.h>
#include <hardware/bluetooth.h>
#include <stdlib.h>
@@ -344,10 +345,10 @@ static void btif_fetch_local_bdaddr(bt_bdaddr_t *local_addr)
BTIF_TRACE_DEBUG("%s, local bdaddr is stored in %s", __func__, val);
- if ((addr_fd = open(val, O_RDONLY)) != -1)
+ if ((addr_fd = TEMP_FAILURE_RETRY(open(val, O_RDONLY))) != -1)
{
memset(val, 0, sizeof(val));
- read(addr_fd, val, FACTORY_BT_BDADDR_STORAGE_LEN);
+ TEMP_FAILURE_RETRY(read(addr_fd, val, FACTORY_BT_BDADDR_STORAGE_LEN));
/* If this is not a reserved/special bda, then use it */
if ((string_to_bdaddr(val, local_addr)) &&
(memcmp(local_addr->address, null_bdaddr, BD_ADDR_LEN) != 0))
diff --git a/btif/src/btif_dm.c b/btif/src/btif_dm.c
index c7a5ffe47..c8d66a0fc 100644
--- a/btif/src/btif_dm.c
+++ b/btif/src/btif_dm.c
@@ -28,6 +28,7 @@
#define LOG_TAG "bt_btif_dm"
#include <assert.h>
+#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -1782,7 +1783,7 @@ static void btif_dm_upstreams_evt(UINT16 event, char* p_param)
BTIF_TRACE_ERROR("Received H/W Error. ");
/* Flush storage data */
btif_config_flush();
- usleep(100000); /* 100milliseconds */
+ TEMP_FAILURE_RETRY(usleep(100000)); /* 100milliseconds */
/* Killing the process to force a restart as part of fault tolerance */
kill(getpid(), SIGKILL);
break;
diff --git a/btif/src/btif_hh.c b/btif/src/btif_hh.c
index 8b977ae34..0d503209a 100644
--- a/btif/src/btif_hh.c
+++ b/btif/src/btif_hh.c
@@ -234,7 +234,7 @@ static void toggle_os_keylockstates(int fd, int changedlockstates)
BTIF_TRACE_DEBUG("%s: %x %x %x", __FUNCTION__,
hidreport[6], hidreport[7], hidreport[8]);
bta_hh_co_write(fd , hidreport, sizeof(hidreport));
- usleep(200000);
+ TEMP_FAILURE_RETRY(usleep(200000));
memset(hidreport,0,9);
hidreport[0]=1;
BTIF_TRACE_DEBUG("Writing hidreport #2 to os: "\
@@ -329,7 +329,7 @@ static void sync_lockstate_on_connect(btif_hh_device_t *p_dev)
BTIF_TRACE_DEBUG("%s: Sending hid report to kernel "\
"indicating lock key state 0x%x",__FUNCTION__,
keylockstates);
- usleep(200000);
+ TEMP_FAILURE_RETRY(usleep(200000));
toggle_os_keylockstates(p_dev->fd, keylockstates);
}
else
diff --git a/btif/src/btif_hl.c b/btif/src/btif_hl.c
index 9d0c0d730..995146e8e 100644
--- a/btif/src/btif_hl.c
+++ b/btif/src/btif_hl.c
@@ -4795,8 +4795,8 @@ void btif_hl_select_monitor_callback(fd_set *p_cur_set ,fd_set *p_org_set) {
}
p_dcb->p_tx_pkt = btif_hl_get_buf (p_dcb->mtu);
if (p_dcb) {
- int r = (int)recv(p_scb->socket_id[1], p_dcb->p_tx_pkt,
- p_dcb->mtu, MSG_DONTWAIT);
+ int r = (int)TEMP_FAILURE_RETRY(recv(p_scb->socket_id[1], p_dcb->p_tx_pkt,
+ p_dcb->mtu, MSG_DONTWAIT));
if (r > 0) {
BTIF_TRACE_DEBUG("btif_hl_select_monitor_callback send data r =%d", r);
p_dcb->tx_size = r;
@@ -4852,7 +4852,7 @@ static inline int btif_hl_select_wakeup_init(fd_set* set){
static inline int btif_hl_select_wakeup(void){
char sig_on = btif_hl_signal_select_wakeup;
BTIF_TRACE_DEBUG("btif_hl_select_wakeup");
- return send(signal_fds[1], &sig_on, sizeof(sig_on), 0);
+ return TEMP_FAILURE_RETRY(send(signal_fds[1], &sig_on, sizeof(sig_on), 0));
}
/*******************************************************************************
@@ -4867,7 +4867,7 @@ static inline int btif_hl_select_wakeup(void){
static inline int btif_hl_select_close_connected(void){
char sig_on = btif_hl_signal_select_close_connected;
BTIF_TRACE_DEBUG("btif_hl_select_close_connected");
- return send(signal_fds[1], &sig_on, sizeof(sig_on), 0);
+ return TEMP_FAILURE_RETRY(send(signal_fds[1], &sig_on, sizeof(sig_on), 0));
}
/*******************************************************************************
@@ -4884,7 +4884,7 @@ static inline int btif_hl_close_select_thread(void)
int result = 0;
char sig_on = btif_hl_signal_select_exit;
BTIF_TRACE_DEBUG("btif_hl_signal_select_exit");
- result = send(signal_fds[1], &sig_on, sizeof(sig_on), 0);
+ result = TEMP_FAILURE_RETRY(send(signal_fds[1], &sig_on, sizeof(sig_on), 0));
if (btif_is_enabled())
{
/* Wait for the select_thread_id to exit if BT is still enabled
@@ -4911,7 +4911,7 @@ static inline int btif_hl_select_wake_reset(void){
char sig_recv = 0;
BTIF_TRACE_DEBUG("btif_hl_select_wake_reset");
- recv(signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL);
+ TEMP_FAILURE_RETRY(recv(signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL));
return(int)sig_recv;
}
/*******************************************************************************
@@ -4972,7 +4972,7 @@ static void *btif_hl_select_thread(void *arg){
BTIF_TRACE_DEBUG("set curr_set = org_set ");
curr_set = org_set;
max_curr_s = max_org_s;
- int ret = select((max_curr_s + 1), &curr_set, NULL, NULL, NULL);
+ int ret = TEMP_FAILURE_RETRY(select((max_curr_s + 1), &curr_set, NULL, NULL, NULL));
BTIF_TRACE_DEBUG("select unblocked ret=%d", ret);
if (ret == -1)
{
diff --git a/btif/src/btif_pan.c b/btif/src/btif_pan.c
index cbb8d9745..6010ae2f0 100644
--- a/btif/src/btif_pan.c
+++ b/btif/src/btif_pan.c
@@ -312,7 +312,7 @@ static int tap_if_up(const char *devname, const bt_bdaddr_t *addr)
//set mac addr
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, devname, IFNAMSIZ - 1);
- err = ioctl(sk, SIOCGIFHWADDR, &ifr);
+ err = TEMP_FAILURE_RETRY(ioctl(sk, SIOCGIFHWADDR, &ifr));
if (err < 0)
{
BTIF_TRACE_ERROR("Could not get network hardware for interface:%s, errno:%s", devname, strerror(errno));
@@ -333,7 +333,7 @@ static int tap_if_up(const char *devname, const bt_bdaddr_t *addr)
ifr.ifr_hwaddr.sa_data[0] &= ~0x01;
}
- err = ioctl(sk, SIOCSIFHWADDR, (caddr_t)&ifr);
+ err = TEMP_FAILURE_RETRY(ioctl(sk, SIOCSIFHWADDR, (caddr_t)&ifr));
if (err < 0) {
BTIF_TRACE_ERROR("Could not set bt address for interface:%s, errno:%s", devname, strerror(errno));
@@ -348,7 +348,7 @@ static int tap_if_up(const char *devname, const bt_bdaddr_t *addr)
ifr.ifr_flags |= IFF_UP;
ifr.ifr_flags |= IFF_MULTICAST;
- err = ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr);
+ err = TEMP_FAILURE_RETRY(ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr));
if (err < 0) {
@@ -375,7 +375,7 @@ static int tap_if_down(const char *devname)
ifr.ifr_flags &= ~IFF_UP;
- ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr);
+ TEMP_FAILURE_RETRY(ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr));
close(sk);
@@ -401,7 +401,7 @@ int btpan_tap_open()
/* open the clone device */
- if ((fd = open(clonedev, O_RDWR)) < 0)
+ if ((fd = TEMP_FAILURE_RETRY(open(clonedev, O_RDWR))) < 0)
{
BTIF_TRACE_DEBUG("could not open %s, err:%d", clonedev, errno);
return fd;
@@ -413,7 +413,7 @@ int btpan_tap_open()
strncpy(ifr.ifr_name, TAP_IF_NAME, IFNAMSIZ);
/* try to create the device */
- if ((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0)
+ if ((err = TEMP_FAILURE_RETRY(ioctl(fd, TUNSETIFF, (void *) &ifr))) < 0)
{
BTIF_TRACE_DEBUG("ioctl error:%d, errno:%s", err, strerror(errno));
close(fd);
@@ -421,8 +421,8 @@ int btpan_tap_open()
}
if (tap_if_up(TAP_IF_NAME, controller_get_interface()->get_address()) == 0)
{
- int flags = fcntl(fd, F_GETFL, 0);
- fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+ int flags = TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL, 0));
+ TEMP_FAILURE_RETRY(fcntl(fd, F_SETFL, flags | O_NONBLOCK));
return fd;
}
BTIF_TRACE_ERROR("can not bring up tap interface:%s", TAP_IF_NAME);
@@ -451,7 +451,7 @@ int btpan_tap_send(int tap_fd, const BD_ADDR src, const BD_ADDR dst, UINT16 prot
memcpy(packet + sizeof(tETH_HDR), buf, len);
/* Send data to network interface */
- int ret = write(tap_fd, packet, len + sizeof(tETH_HDR));
+ int ret = TEMP_FAILURE_RETRY(write(tap_fd, packet, len + sizeof(tETH_HDR)));
BTIF_TRACE_DEBUG("ret:%d", ret);
return ret;
}
@@ -740,7 +740,7 @@ static void btu_exec_tap_fd_read(void *p_param) {
// We save it in the congest_packet right away in case we can't deliver it in this
// attempt.
if (!btpan_cb.congest_packet_size) {
- ssize_t ret = read(fd, btpan_cb.congest_packet, sizeof(btpan_cb.congest_packet));
+ ssize_t ret = TEMP_FAILURE_RETRY(read(fd, btpan_cb.congest_packet, sizeof(btpan_cb.congest_packet)));
switch (ret) {
case -1:
BTIF_TRACE_ERROR("%s unable to read from driver: %s", __func__, strerror(errno));
@@ -784,7 +784,7 @@ static void btu_exec_tap_fd_read(void *p_param) {
ufd.fd = fd;
ufd.events = POLLIN;
ufd.revents = 0;
- if (poll(&ufd, 1, 0) <= 0 || IS_EXCEPTION(ufd.revents))
+ if (TEMP_FAILURE_RETRY(poll(&ufd, 1, 0)) <= 0 || IS_EXCEPTION(ufd.revents))
break;
}
//add fd back to monitor thread
diff --git a/btif/src/btif_rc.c b/btif/src/btif_rc.c
index 6667ddb95..eeb4f0bff 100644
--- a/btif/src/btif_rc.c
+++ b/btif/src/btif_rc.c
@@ -24,6 +24,7 @@
* Description: Bluetooth AVRC implementation
*
*****************************************************************************/
+#include <errno.h>
#include <hardware/bluetooth.h>
#include <fcntl.h>
#include <string.h>
@@ -213,7 +214,7 @@ int send_event (int fd, uint16_t type, uint16_t code, int32_t value)
event.code = code;
event.value = value;
- return write(fd, &event, sizeof(event));
+ return TEMP_FAILURE_RETRY(write(fd, &event, sizeof(event)));
}
void send_key (int fd, uint16_t key, int pressed)
@@ -252,7 +253,7 @@ int uinput_create(char *name)
for(x=0; x < MAX_UINPUT_PATHS; x++)
{
- fd = open(uinput_dev_path[x], O_RDWR);
+ fd = TEMP_FAILURE_RETRY(open(uinput_dev_path[x], O_RDWR));
if (fd < 0)
continue;
break;
@@ -270,20 +271,20 @@ int uinput_create(char *name)
dev.id.product = 0x0000;
dev.id.version = 0x0000;
- if (write(fd, &dev, sizeof(dev)) < 0) {
+ if (TEMP_FAILURE_RETRY(write(fd, &dev, sizeof(dev))) < 0) {
BTIF_TRACE_ERROR("%s Unable to write device information", __FUNCTION__);
close(fd);
return -1;
}
- ioctl(fd, UI_SET_EVBIT, EV_KEY);
- ioctl(fd, UI_SET_EVBIT, EV_REL);
- ioctl(fd, UI_SET_EVBIT, EV_SYN);
+ TEMP_FAILURE_RETRY(ioctl(fd, UI_SET_EVBIT, EV_KEY));
+ TEMP_FAILURE_RETRY(ioctl(fd, UI_SET_EVBIT, EV_REL));
+ TEMP_FAILURE_RETRY(ioctl(fd, UI_SET_EVBIT, EV_SYN));
for (x = 0; key_map[x].name != NULL; x++)
- ioctl(fd, UI_SET_KEYBIT, key_map[x].mapped_id);
+ TEMP_FAILURE_RETRY(ioctl(fd, UI_SET_KEYBIT, key_map[x].mapped_id));
- if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) {
+ if (TEMP_FAILURE_RETRY(ioctl(fd, UI_DEV_CREATE, NULL)) < 0) {
BTIF_TRACE_ERROR("%s Unable to create uinput device", __FUNCTION__);
close(fd);
return -1;
@@ -311,7 +312,7 @@ void close_uinput (void)
{
BTIF_TRACE_DEBUG("%s", __FUNCTION__);
if (uinput_fd > 0) {
- ioctl(uinput_fd, UI_DEV_DESTROY);
+ TEMP_FAILURE_RETRY(ioctl(uinput_fd, UI_DEV_DESTROY));
close(uinput_fd);
uinput_fd = -1;
diff --git a/btif/src/btif_sock_l2cap.c b/btif/src/btif_sock_l2cap.c
index 04c5b676b..7b1a5cf02 100644
--- a/btif/src/btif_sock_l2cap.c
+++ b/btif/src/btif_sock_l2cap.c
@@ -968,7 +968,7 @@ static BOOLEAN flush_incoming_que_on_wr_signal_l(l2cap_socket *sock)
uint32_t len;
while (packet_get_head_l(sock, &buf, &len)) {
- int sent = send(sock->our_fd, buf, len, MSG_DONTWAIT);
+ int sent = TEMP_FAILURE_RETRY(send(sock->our_fd, buf, len, MSG_DONTWAIT));
if (sent == (signed)len)
osi_free(buf);
@@ -1002,7 +1002,7 @@ void btsock_l2cap_signaled(int fd, int flags, uint32_t user_id)
if (sock->connected) {
int size = 0;
- if (!(flags & SOCK_THREAD_FD_EXCEPTION) || (ioctl(sock->our_fd, FIONREAD, &size)
+ if (!(flags & SOCK_THREAD_FD_EXCEPTION) || (TEMP_FAILURE_RETRY(ioctl(sock->our_fd, FIONREAD, &size))
== 0 && size)) {
uint8_t *buffer = osi_malloc(L2CAP_MAX_SDU_LENGTH);
//uint8_t *buffer = (uint8_t*)GKI_getbuf(L2CAP_MAX_SDU_LENGTH);
@@ -1028,8 +1028,8 @@ void btsock_l2cap_signaled(int fd, int flags, uint32_t user_id)
* UPDATE: Since we are responsible for freeing the buffer in the
* write_complete_ind, it is OK to use malloc. */
- int count = recv(fd, buffer, L2CAP_MAX_SDU_LENGTH,
- MSG_NOSIGNAL | MSG_DONTWAIT);
+ int count = TEMP_FAILURE_RETRY(recv(fd, buffer, L2CAP_MAX_SDU_LENGTH,
+ MSG_NOSIGNAL | MSG_DONTWAIT));
APPL_TRACE_DEBUG("btsock_l2cap_signaled - %d bytes received from socket",
count);
if (sock->fixed_chan) {
@@ -1061,7 +1061,7 @@ void btsock_l2cap_signaled(int fd, int flags, uint32_t user_id)
}
if (drop_it || (flags & SOCK_THREAD_FD_EXCEPTION)) {
int size = 0;
- if (drop_it || ioctl(sock->our_fd, FIONREAD, &size) != 0 || size == 0)
+ if (drop_it || TEMP_FAILURE_RETRY(ioctl(sock->our_fd, FIONREAD, &size)) != 0 || size == 0)
btsock_l2cap_free_l(sock);
}
}
diff --git a/btif/src/btif_sock_rfc.c b/btif/src/btif_sock_rfc.c
index f80ed562f..605099e96 100644
--- a/btif/src/btif_sock_rfc.c
+++ b/btif/src/btif_sock_rfc.c
@@ -720,7 +720,7 @@ static sent_status_t send_data_to_app(int fd, BT_HDR *p_buf) {
if (p_buf->len == 0)
return SENT_ALL;
- ssize_t sent = send(fd, p_buf->data + p_buf->offset, p_buf->len, MSG_DONTWAIT);
+ ssize_t sent = TEMP_FAILURE_RETRY(send(fd, p_buf->data + p_buf->offset, p_buf->len, MSG_DONTWAIT));
if (sent == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
@@ -783,11 +783,9 @@ void btsock_rfc_signaled(UNUSED_ATTR int fd, int flags, uint32_t user_id) {
if (slot->f.connected) {
// Make sure there's data pending in case the peer closed the socket.
int size = 0;
- if (!(flags & SOCK_THREAD_FD_EXCEPTION) || (ioctl(slot->fd, FIONREAD, &size) == 0 && size))
- //unlock before BTA_JvRfcommWrite to avoid deadlock on concurrnet multi rfcomm connectoins
- //concurrnet multi rfcomm connectoins
- pthread_mutex_unlock(&slot_lock);
+ if (!(flags & SOCK_THREAD_FD_EXCEPTION) || (TEMP_FAILURE_RETRY(ioctl(slot->fd, FIONREAD, &size)) == 0 && size)) {
BTA_JvRfcommWrite(slot->rfc_handle, slot->id);
+ }
} else {
LOG_ERROR("%s socket signaled for read while disconnected, slot: %d, channel: %d", __func__, slot->id, slot->scn);
need_close = true;
@@ -805,7 +803,7 @@ void btsock_rfc_signaled(UNUSED_ATTR int fd, int flags, uint32_t user_id) {
if (need_close || (flags & SOCK_THREAD_FD_EXCEPTION)) {
// Clean up if there's no data pending.
int size = 0;
- if (need_close || ioctl(slot->fd, FIONREAD, &size) != 0 || !size)
+ if (need_close || TEMP_FAILURE_RETRY(ioctl(slot->fd, FIONREAD, &size)) != 0 || !size)
cleanup_rfc_slot(slot);
}
@@ -859,7 +857,7 @@ int bta_co_rfc_data_outgoing_size(void *user_data, int *size) {
if (!slot)
goto out;
- if (ioctl(slot->fd, FIONREAD, size) == 0) {
+ if (TEMP_FAILURE_RETRY(ioctl(slot->fd, FIONREAD, size)) == 0) {
ret = true;
} else {
LOG_ERROR("%s unable to determine bytes remaining to be read on fd %d: %s", __func__, slot->fd, strerror(errno));
@@ -880,7 +878,7 @@ int bta_co_rfc_data_outgoing(void *user_data, uint8_t *buf, uint16_t size) {
if (!slot)
goto out;
- int received = recv(slot->fd, buf, size, 0);
+ int received = TEMP_FAILURE_RETRY(recv(slot->fd, buf, size, 0));
if(received == size) {
ret = true;
} else {
diff --git a/btif/src/btif_sock_thread.c b/btif/src/btif_sock_thread.c
index 459aebac2..ebf636d36 100644
--- a/btif/src/btif_sock_thread.c
+++ b/btif/src/btif_sock_thread.c
@@ -114,12 +114,12 @@ static pthread_mutex_t thread_slot_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
static inline void set_socket_blocking(int s, int blocking)
{
int opts;
- opts = fcntl(s, F_GETFL);
+ opts = TEMP_FAILURE_RETRY(fcntl(s, F_GETFL));
if (opts<0) APPL_TRACE_ERROR("set blocking (%s)", strerror(errno));
if(blocking)
opts &= ~O_NONBLOCK;
else opts |= O_NONBLOCK;
- if (fcntl(s, F_SETFL, opts) < 0)
+ if (TEMP_FAILURE_RETRY(fcntl(s, F_SETFL, opts)) < 0)
APPL_TRACE_ERROR("set blocking (%s)", strerror(errno));
}
@@ -161,7 +161,7 @@ static inline int accept_server_socket(int s)
{
struct sockaddr_un client_address;
socklen_t clen;
- int fd = accept(s, (struct sockaddr*)&client_address, &clen);
+ int fd = TEMP_FAILURE_RETRY(accept(s, (struct sockaddr*)&client_address, &clen));
APPL_TRACE_DEBUG("accepted fd:%d for server fd:%d", fd, s);
return fd;
}
@@ -325,7 +325,7 @@ int btsock_thread_add_fd(int h, int fd, int type, int flags, uint32_t user_id)
}
sock_cmd_t cmd = {CMD_ADD_FD, fd, type, flags, user_id};
APPL_TRACE_DEBUG("adding fd:%d, flags:0x%x", fd, flags);
- return send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd);
+ return TEMP_FAILURE_RETRY(send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0)) == sizeof(cmd);
}
bool btsock_thread_remove_fd_and_close(int thread_handle, int fd)
@@ -342,7 +342,7 @@ bool btsock_thread_remove_fd_and_close(int thread_handle, int fd)
}
sock_cmd_t cmd = {CMD_REMOVE_FD, fd, 0, 0, 0};
- return send(ts[thread_handle].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd);
+ return TEMP_FAILURE_RETRY(send(ts[thread_handle].cmd_fdw, &cmd, sizeof(cmd), 0)) == sizeof(cmd);
}
int btsock_thread_post_cmd(int h, int type, const unsigned char* data, int size, uint32_t user_id)
@@ -376,7 +376,7 @@ int btsock_thread_post_cmd(int h, int type, const unsigned char* data, int size,
return FALSE;
}
}
- return send(ts[h].cmd_fdw, cmd_send, size_send, 0) == size_send;
+ return TEMP_FAILURE_RETRY(send(ts[h].cmd_fdw, cmd_send, size_send, 0)) == size_send;
}
int btsock_thread_wakeup(int h)
{
@@ -391,7 +391,7 @@ int btsock_thread_wakeup(int h)
return FALSE;
}
sock_cmd_t cmd = {CMD_WAKEUP, 0, 0, 0, 0};
- return send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd);
+ return TEMP_FAILURE_RETRY(send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0)) == sizeof(cmd);
}
int btsock_thread_exit(int h)
{
@@ -406,7 +406,7 @@ int btsock_thread_exit(int h)
return FALSE;
}
sock_cmd_t cmd = {CMD_EXIT, 0, 0, 0, 0};
- if(send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd))
+ if(TEMP_FAILURE_RETRY(send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0)) == sizeof(cmd))
{
pthread_join(ts[h].thread_id, 0);
pthread_mutex_lock(&thread_slot_lock);
@@ -501,7 +501,7 @@ static int process_cmd_sock(int h)
{
sock_cmd_t cmd = {-1, 0, 0, 0, 0};
int fd = ts[h].cmd_fdr;
- if(recv(fd, &cmd, sizeof(cmd), MSG_WAITALL) != sizeof(cmd))
+ if(TEMP_FAILURE_RETRY(recv(fd, &cmd, sizeof(cmd), MSG_WAITALL)) != sizeof(cmd))
{
APPL_TRACE_ERROR("recv cmd errno:%d", errno);
return FALSE;
@@ -608,7 +608,7 @@ static void *sock_poll_thread(void *arg)
for(;;)
{
prepare_poll_fds(h, pfds);
- int ret = poll(pfds, ts[h].poll_count, -1);
+ int ret = TEMP_FAILURE_RETRY(poll(pfds, ts[h].poll_count, -1));
if(ret == -1)
{
APPL_TRACE_ERROR("poll ret -1, exit the thread, errno:%d, err:%s", errno, strerror(errno));
diff --git a/btif/src/btif_sock_util.c b/btif/src/btif_sock_util.c
index baa3ed3d9..ead113f13 100644
--- a/btif/src/btif_sock_util.c
+++ b/btif/src/btif_sock_util.c
@@ -74,7 +74,7 @@ int sock_send_all(int sock_fd, const uint8_t* buf, int len)
int ret;
while(s)
{
- do ret = send(sock_fd, buf, s, 0);
+ do ret = TEMP_FAILURE_RETRY(send(sock_fd, buf, s, 0));
while(ret < 0 && errno == EINTR);
if(ret <= 0)
{
@@ -92,7 +92,7 @@ int sock_recv_all(int sock_fd, uint8_t* buf, int len)
int ret = -1;
while(r)
{
- do ret = recv(sock_fd, buf, r, MSG_WAITALL);
+ do ret = TEMP_FAILURE_RETRY(recv(sock_fd, buf, r, MSG_WAITALL));
while(ret < 0 && errno == EINTR);
if(ret <= 0)
{
@@ -140,7 +140,7 @@ int sock_send_fd(int sock_fd, const uint8_t* buf, int len, int send_fd)
msg.msg_iovlen = 1;
do {
- ret = sendmsg(sock_fd, &msg, MSG_NOSIGNAL);
+ ret = TEMP_FAILURE_RETRY(sendmsg(sock_fd, &msg, MSG_NOSIGNAL));
} while (ret < 0 && errno == EINTR);
if (ret < 0) {
diff --git a/gki/ulinux/gki_ulinux.c b/gki/ulinux/gki_ulinux.c
index 72ad479e0..703e99278 100644
--- a/gki/ulinux/gki_ulinux.c
+++ b/gki/ulinux/gki_ulinux.c
@@ -76,7 +76,7 @@ void GKI_delay(UINT32 timeout_ms) {
int err;
do {
- err = nanosleep(&delay, &delay);
+ err = TEMP_FAILURE_RETRY(nanosleep(&delay, &delay));
} while (err == -1 && errno == EINTR);
}
diff --git a/hci/src/btsnoop.c b/hci/src/btsnoop.c
index d859e6842..7b6b97f30 100644
--- a/hci/src/btsnoop.c
+++ b/hci/src/btsnoop.c
@@ -169,14 +169,14 @@ static void update_logging() {
LOG_ERROR("%s unable to rename '%s' to '%s': %s", __func__, log_path, last_log_path, strerror(errno));
}
- logfile_fd = open(log_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
+ logfile_fd = TEMP_FAILURE_RETRY(open(log_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH));
if (logfile_fd == INVALID_FD) {
LOG_ERROR("%s unable to open '%s': %s", __func__, log_path, strerror(errno));
is_logging = false;
return;
}
- write(logfile_fd, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16);
+ TEMP_FAILURE_RETRY(write(logfile_fd, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16));
} else {
if (logfile_fd != INVALID_FD)
close(logfile_fd);
@@ -188,7 +188,7 @@ static void update_logging() {
static void btsnoop_write(const void *data, size_t length) {
if (logfile_fd != INVALID_FD)
- write(logfile_fd, data, length);
+ TEMP_FAILURE_RETRY(write(logfile_fd, data, length));
btsnoop_net_write(data, length);
}
diff --git a/hci/src/btsnoop_net.c b/hci/src/btsnoop_net.c
index c6a9cd61a..1aff83290 100644
--- a/hci/src/btsnoop_net.c
+++ b/hci/src/btsnoop_net.c
@@ -77,7 +77,7 @@ void btsnoop_net_write(const void *data, size_t length) {
pthread_mutex_lock(&client_socket_lock_);
if (client_socket_ != -1) {
- if (send(client_socket_, data, length, 0) == -1 && errno == ECONNRESET) {
+ if (TEMP_FAILURE_RETRY(send(client_socket_, data, length, 0)) == -1 && errno == ECONNRESET) {
safe_close_(&client_socket_);
}
}
@@ -115,7 +115,7 @@ static void *listen_fn_(UNUSED_ATTR void *context) {
}
for (;;) {
- int client_socket = accept(listen_socket_, NULL, NULL);
+ int client_socket = TEMP_FAILURE_RETRY(accept(listen_socket_, NULL, NULL));
if (client_socket == -1) {
if (errno == EINVAL || errno == EBADF) {
break;
@@ -129,7 +129,7 @@ static void *listen_fn_(UNUSED_ATTR void *context) {
pthread_mutex_lock(&client_socket_lock_);
safe_close_(&client_socket_);
client_socket_ = client_socket;
- send(client_socket_, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16, 0);
+ TEMP_FAILURE_RETRY(send(client_socket_, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16, 0));
pthread_mutex_unlock(&client_socket_lock_);
}
diff --git a/hci/src/hci_hal_h4.c b/hci/src/hci_hal_h4.c
index 7a48c691d..fc0d27838 100644
--- a/hci/src/hci_hal_h4.c
+++ b/hci/src/hci_hal_h4.c
@@ -153,7 +153,7 @@ static uint16_t transmit_data(serial_data_type_t type, uint8_t *data, uint16_t l
uint16_t transmitted_length = 0;
while (length > 0) {
- ssize_t ret = write(uart_fd, data + transmitted_length, length);
+ ssize_t ret = TEMP_FAILURE_RETRY(write(uart_fd, data + transmitted_length, length));
switch (ret) {
case -1:
LOG_ERROR("In %s, error writing to the uart serial port: %s", __func__, strerror(errno));
diff --git a/hci/src/hci_hal_mct.c b/hci/src/hci_hal_mct.c
index 9b3707c7f..5219e039b 100644
--- a/hci/src/hci_hal_mct.c
+++ b/hci/src/hci_hal_mct.c
@@ -159,7 +159,7 @@ static uint16_t transmit_data_on(int fd, uint8_t *data, uint16_t length) {
uint16_t transmitted_length = 0;
while (length > 0) {
- ssize_t ret = write(fd, data + transmitted_length, length);
+ ssize_t ret = TEMP_FAILURE_RETRY(write(fd, data + transmitted_length, length));
switch (ret) {
case -1:
LOG_ERROR("In %s, error writing to the serial port with fd %d: %s", __func__, fd, strerror(errno));
diff --git a/hci/src/hci_layer.c b/hci/src/hci_layer.c
index 5138ce6e1..16f72c606 100644
--- a/hci/src/hci_layer.c
+++ b/hci/src/hci_layer.c
@@ -20,6 +20,7 @@
#include <assert.h>
#include <cutils/properties.h>
+#include <errno.h>
#include <string.h>
#include <signal.h>
#include <string.h>
@@ -517,7 +518,7 @@ static void command_timed_out(UNUSED_ATTR void *context) {
}
LOG_ERROR("%s restarting the bluetooth process.", __func__);
- usleep(10000);
+ TEMP_FAILURE_RETRY(usleep(10000));
kill(getpid(), SIGKILL);
}
diff --git a/hci/test/hci_hal_h4_test.cpp b/hci/test/hci_hal_h4_test.cpp
index d64e8c4d2..9ee8006c3 100644
--- a/hci/test/hci_hal_h4_test.cpp
+++ b/hci/test/hci_hal_h4_test.cpp
@@ -183,26 +183,26 @@ static void expect_socket_data(int fd, char first_byte, char *data) {
fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(fd, &read_fds);
- select(fd + 1, &read_fds, NULL, NULL, NULL);
+ TEMP_FAILURE_RETRY(select(fd + 1, &read_fds, NULL, NULL, NULL));
char byte;
- read(fd, &byte, 1);
+ TEMP_FAILURE_RETRY(read(fd, &byte, 1));
EXPECT_EQ(i == 0 ? first_byte : data[i - 1], byte);
}
}
static void write_packet(int fd, char first_byte, char *data) {
- write(fd, &first_byte, 1);
- write(fd, data, strlen(data));
+ TEMP_FAILURE_RETRY(write(fd, &first_byte, 1));
+ TEMP_FAILURE_RETRY(write(fd, data, strlen(data)));
}
static void write_packet_reentry(int fd, char first_byte, char *data) {
- write(fd, &first_byte, 1);
+ TEMP_FAILURE_RETRY(write(fd, &first_byte, 1));
int length = strlen(data);
for (int i = 0; i < length; i++) {
- write(fd, &data[i], 1);
+ TEMP_FAILURE_RETRY(write(fd, &data[i], 1));
semaphore_wait(reentry_semaphore);
}
}
@@ -252,7 +252,7 @@ TEST_F(HciHalH4Test, test_type_byte_only_must_not_signal_data_ready) {
reset_for(type_byte_only);
char byte = DATA_TYPE_ACL;
- write(sockfd[1], &byte, 1);
+ TEMP_FAILURE_RETRY(write(sockfd[1], &byte, 1));
fd_set read_fds;
@@ -265,6 +265,6 @@ TEST_F(HciHalH4Test, test_type_byte_only_must_not_signal_data_ready) {
timeout.tv_sec = 0;
timeout.tv_usec = 0;
- select(sockfd[0] + 1, &read_fds, NULL, NULL, &timeout);
+ TEMP_FAILURE_RETRY(select(sockfd[0] + 1, &read_fds, NULL, NULL, &timeout));
} while(FD_ISSET(sockfd[0], &read_fds));
}
diff --git a/hci/test/hci_hal_mct_test.cpp b/hci/test/hci_hal_mct_test.cpp
index 911aabcfd..a857629b3 100644
--- a/hci/test/hci_hal_mct_test.cpp
+++ b/hci/test/hci_hal_mct_test.cpp
@@ -186,23 +186,23 @@ static void expect_socket_data(int fd, char *data) {
fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(fd, &read_fds);
- select(fd + 1, &read_fds, NULL, NULL, NULL);
+ TEMP_FAILURE_RETRY(select(fd + 1, &read_fds, NULL, NULL, NULL));
char byte;
- read(fd, &byte, 1);
+ TEMP_FAILURE_RETRY(read(fd, &byte, 1));
EXPECT_EQ(data[i], byte);
}
}
static void write_packet(int fd, char *data) {
- write(fd, data, strlen(data));
+ TEMP_FAILURE_RETRY(write(fd, data, strlen(data)));
}
static void write_packet_reentry(int fd, char *data) {
int length = strlen(data);
for (int i = 0; i < length; i++) {
- write(fd, &data[i], 1);
+ TEMP_FAILURE_RETRY(write(fd, &data[i], 1));
semaphore_wait(reentry_semaphore);
}
}
diff --git a/osi/src/config.c b/osi/src/config.c
index c87f5310a..3d5d87ff3 100644
--- a/osi/src/config.c
+++ b/osi/src/config.c
@@ -21,10 +21,13 @@
#include <assert.h>
#include <ctype.h>
#include <errno.h>
+#include <fcntl.h>
+#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
+#include <sys/types.h>
#include "osi/include/allocator.h"
#include "osi/include/config.h"
@@ -275,16 +278,39 @@ bool config_save(const config_t *config, const char *filename) {
assert(filename != NULL);
assert(*filename != '\0');
- char *temp_filename = osi_calloc(strlen(filename) + 5);
- if (!temp_filename) {
- LOG_ERROR("%s unable to allocate memory for filename.", __func__);
- return false;
+ // Steps to ensure content of config file gets to disk:
+ //
+ // 1) Open and write to temp file (e.g. bt_config.conf.new).
+ // 2) Sync the temp file to disk with fsync().
+ // 3) Rename temp file to actual config file (e.g. bt_config.conf).
+ // This ensures atomic update.
+ // 4) Sync directory that has the conf file with fsync().
+ // This ensures directory entries are up-to-date.
+ int dir_fd = -1;
+ FILE *fp = NULL;
+
+ // Build temp config file based on config file (e.g. bt_config.conf.new).
+ static const char *temp_file_ext = ".new";
+ const int filename_len = strlen(filename);
+ const int temp_filename_len = filename_len + strlen(temp_file_ext) + 1;
+ char *temp_filename = osi_calloc(temp_filename_len);
+ snprintf(temp_filename, temp_filename_len, "%s%s", filename, temp_file_ext);
+
+ // Extract directory from file path (e.g. /data/misc/bluedroid).
+ char *temp_dirname = osi_strdup(filename);
+ const char *directoryname = dirname(temp_dirname);
+ if (!directoryname) {
+ LOG_ERROR("%s error extracting directory from '%s': %s", __func__, filename, strerror(errno));
+ goto error;
}
- strcpy(temp_filename, filename);
- strcat(temp_filename, ".new");
+ dir_fd = TEMP_FAILURE_RETRY(open(directoryname, O_RDONLY));
+ if (dir_fd < 0) {
+ LOG_ERROR("%s unable to open dir '%s': %s", __func__, directoryname, strerror(errno));
+ goto error;
+ }
- FILE *fp = fopen(temp_filename, "wt");
+ fp = fopen(temp_filename, "wt");
if (!fp) {
LOG_ERROR("%s unable to write file '%s': %s", __func__, temp_filename, strerror(errno));
goto error;
@@ -292,20 +318,38 @@ bool config_save(const config_t *config, const char *filename) {
for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) {
const section_t *section = (const section_t *)list_node(node);
- fprintf(fp, "[%s]\n", section->name);
+ if (fprintf(fp, "[%s]\n", section->name) < 0) {
+ LOG_ERROR("%s unable to write to file '%s': %s", __func__, temp_filename, strerror(errno));
+ goto error;
+ }
for (const list_node_t *enode = list_begin(section->entries); enode != list_end(section->entries); enode = list_next(enode)) {
const entry_t *entry = (const entry_t *)list_node(enode);
- fprintf(fp, "%s = %s\n", entry->key, entry->value);
+ if (fprintf(fp, "%s = %s\n", entry->key, entry->value) < 0) {
+ LOG_ERROR("%s unable to write to file '%s': %s", __func__, temp_filename, strerror(errno));
+ goto error;
+ }
}
// Only add a separating newline if there are more sections.
- if (list_next(node) != list_end(config->sections))
- fputc('\n', fp);
+ if (list_next(node) != list_end(config->sections)) {
+ if (fputc('\n', fp) == EOF) {
+ LOG_ERROR("%s unable to write to file '%s': %s", __func__, temp_filename, strerror(errno));
+ goto error;
+ }
+ }
}
- fflush(fp);
- fclose(fp);
+ // Sync written temp file out to disk. fsync() is blocking until data makes it to disk.
+ if (fsync(fileno(fp)) < 0) {
+ LOG_WARN("%s unable to fsync file '%s': %s", __func__, temp_filename, strerror(errno));
+ }
+
+ if (fclose(fp) == EOF) {
+ LOG_ERROR("%s unable to close file '%s': %s", __func__, temp_filename, strerror(errno));
+ goto error;
+ }
+ fp = NULL;
// Change the file's permissions to Read/Write by User and Group
if (chmod(temp_filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) == -1) {
@@ -313,17 +357,35 @@ bool config_save(const config_t *config, const char *filename) {
goto error;
}
+ // Rename written temp file to the actual config file.
if (rename(temp_filename, filename) == -1) {
LOG_ERROR("%s unable to commit file '%s': %s", __func__, filename, strerror(errno));
goto error;
}
+ // This should ensure the directory is updated as well.
+ if (fsync(dir_fd) < 0) {
+ LOG_WARN("%s unable to fsync dir '%s': %s", __func__, directoryname, strerror(errno));
+ }
+
+ if (close(dir_fd) < 0) {
+ LOG_ERROR("%s unable to close dir '%s': %s", __func__, directoryname, strerror(errno));
+ goto error;
+ }
+
osi_free(temp_filename);
+ osi_free(temp_dirname);
return true;
-error:;
+error:
+ // This indicates there is a write issue. Unlink as partial data is not acceptable.
unlink(temp_filename);
+ if (fp)
+ fclose(fp);
+ if (dir_fd != -1)
+ close(dir_fd);
osi_free(temp_filename);
+ osi_free(temp_dirname);
return false;
}
diff --git a/osi/src/eager_reader.c b/osi/src/eager_reader.c
index 3ca8ad13c..e93947d51 100644
--- a/osi/src/eager_reader.c
+++ b/osi/src/eager_reader.c
@@ -228,7 +228,7 @@ static bool has_byte(const eager_reader_t *reader) {
timeout.tv_sec = 0;
timeout.tv_usec = 0;
- select(reader->bytes_available_fd + 1, &read_fds, NULL, NULL, &timeout);
+ TEMP_FAILURE_RETRY(select(reader->bytes_available_fd + 1, &read_fds, NULL, NULL, &timeout));
return FD_ISSET(reader->bytes_available_fd, &read_fds);
}
@@ -244,7 +244,7 @@ static void inbound_data_waiting(void *context) {
buffer->length = 0;
buffer->offset = 0;
- int bytes_read = read(reader->inbound_fd, buffer->data, reader->buffer_size);
+ int bytes_read = TEMP_FAILURE_RETRY(read(reader->inbound_fd, buffer->data, reader->buffer_size));
if (bytes_read > 0) {
// Save the data for later
buffer->length = bytes_read;
diff --git a/osi/src/reactor.c b/osi/src/reactor.c
index 08b50982e..32bd1bef1 100644
--- a/osi/src/reactor.c
+++ b/osi/src/reactor.c
@@ -241,7 +241,7 @@ static reactor_status_t run_reactor(reactor_t *reactor, int iterations) {
int ret;
do {
- ret = epoll_wait(reactor->epoll_fd, events, MAX_EVENTS, -1);
+ ret = TEMP_FAILURE_RETRY(epoll_wait(reactor->epoll_fd, events, MAX_EVENTS, -1));
} while (ret == -1 && errno == EINTR);
if (ret == -1) {
diff --git a/osi/src/semaphore.c b/osi/src/semaphore.c
index 5ee992649..76fba0d55 100644
--- a/osi/src/semaphore.c
+++ b/osi/src/semaphore.c
@@ -73,12 +73,12 @@ bool semaphore_try_wait(semaphore_t *semaphore) {
assert(semaphore != NULL);
assert(semaphore->fd != INVALID_FD);
- int flags = fcntl(semaphore->fd, F_GETFL);
+ int flags = TEMP_FAILURE_RETRY(fcntl(semaphore->fd, F_GETFL));
if (flags == -1) {
LOG_ERROR("%s unable to get flags for semaphore fd: %s", __func__, strerror(errno));
return false;
}
- if (fcntl(semaphore->fd, F_SETFL, flags | O_NONBLOCK) == -1) {
+ if (TEMP_FAILURE_RETRY(fcntl(semaphore->fd, F_SETFL, flags | O_NONBLOCK)) == -1) {
LOG_ERROR("%s unable to set O_NONBLOCK for semaphore fd: %s", __func__, strerror(errno));
return false;
}
@@ -87,7 +87,7 @@ bool semaphore_try_wait(semaphore_t *semaphore) {
if (eventfd_read(semaphore->fd, &value) == -1)
return false;
- if (fcntl(semaphore->fd, F_SETFL, flags) == -1)
+ if (TEMP_FAILURE_RETRY(fcntl(semaphore->fd, F_SETFL, flags)) == -1)
LOG_ERROR("%s unable to resetore flags for semaphore fd: %s", __func__, strerror(errno));
return true;
}
diff --git a/osi/src/socket.c b/osi/src/socket.c
index 91f084e79..9905ae300 100644
--- a/osi/src/socket.c
+++ b/osi/src/socket.c
@@ -121,7 +121,7 @@ bool socket_listen(const socket_t *socket, port_t port) {
socket_t *socket_accept(const socket_t *socket) {
assert(socket != NULL);
- int fd = accept(socket->fd, NULL, NULL);
+ int fd = TEMP_FAILURE_RETRY(accept(socket->fd, NULL, NULL));
if (fd == INVALID_FD) {
LOG_ERROR("%s unable to accept socket: %s", __func__, strerror(errno));
return NULL;
@@ -142,14 +142,14 @@ ssize_t socket_read(const socket_t *socket, void *buf, size_t count) {
assert(socket != NULL);
assert(buf != NULL);
- return recv(socket->fd, buf, count, MSG_DONTWAIT);
+ return TEMP_FAILURE_RETRY(recv(socket->fd, buf, count, MSG_DONTWAIT));
}
ssize_t socket_write(const socket_t *socket, const void *buf, size_t count) {
assert(socket != NULL);
assert(buf != NULL);
- return send(socket->fd, buf, count, MSG_DONTWAIT);
+ return TEMP_FAILURE_RETRY(send(socket->fd, buf, count, MSG_DONTWAIT));
}
ssize_t socket_write_and_transfer_fd(const socket_t *socket, const void *buf, size_t count, int fd) {
@@ -179,7 +179,7 @@ ssize_t socket_write_and_transfer_fd(const socket_t *socket, const void *buf, si
header->cmsg_len = CMSG_LEN(sizeof(int));
*(int *)CMSG_DATA(header) = fd;
- ssize_t ret = sendmsg(socket->fd, &msg, MSG_DONTWAIT);
+ ssize_t ret = TEMP_FAILURE_RETRY(sendmsg(socket->fd, &msg, MSG_DONTWAIT));
close(fd);
return ret;
}
@@ -188,7 +188,7 @@ ssize_t socket_bytes_available(const socket_t *socket) {
assert(socket != NULL);
int size = 0;
- if (ioctl(socket->fd, FIONREAD, &size) == -1)
+ if (TEMP_FAILURE_RETRY(ioctl(socket->fd, FIONREAD, &size)) == -1)
return -1;
return size;
}
diff --git a/osi/test/alarm_test.cpp b/osi/test/alarm_test.cpp
index 287d40812..fec828f90 100644
--- a/osi/test/alarm_test.cpp
+++ b/osi/test/alarm_test.cpp
@@ -32,7 +32,7 @@ static int cb_counter;
static const uint64_t EPSILON_MS = 5;
static void msleep(uint64_t ms) {
- usleep(ms * 1000);
+ TEMP_FAILURE_RETRY(usleep(ms * 1000));
}
class AlarmTest : public AlarmTestHarness {
diff --git a/osi/test/atomic_test.cpp b/osi/test/atomic_test.cpp
index b0039ab3f..6cde546e5 100644
--- a/osi/test/atomic_test.cpp
+++ b/osi/test/atomic_test.cpp
@@ -17,7 +17,7 @@ struct atomic_test_s32_s {
void *atomic_thread(void *context) {
struct atomic_test_s32_s *at = (struct atomic_test_s32_s *)context;
for (int i = 0; i < at->max_val; i++) {
- usleep(1);
+ TEMP_FAILURE_RETRY(usleep(1));
atomic_inc_prefix_s32(&at->data[i]);
}
return NULL;
@@ -26,9 +26,9 @@ void *atomic_thread(void *context) {
void *atomic_thread_inc_dec(void *context) {
struct atomic_test_s32_s *at = (struct atomic_test_s32_s *)context;
for (int i = 0; i < at->max_val; i++) {
- usleep(1);
+ TEMP_FAILURE_RETRY(usleep(1));
atomic_inc_prefix_s32(&at->data[i]);
- usleep(1);
+ TEMP_FAILURE_RETRY(usleep(1));
atomic_dec_prefix_s32(&at->data[i]);
}
return NULL;
diff --git a/osi/test/eager_reader_test.cpp b/osi/test/eager_reader_test.cpp
index ad00e17b0..d979f42a6 100644
--- a/osi/test/eager_reader_test.cpp
+++ b/osi/test/eager_reader_test.cpp
@@ -126,7 +126,7 @@ TEST_F(EagerReaderTest, test_small_data) {
thread_t *read_thread = thread_new("read_thread");
eager_reader_register(reader, thread_get_reactor(read_thread), expect_data, (void *)small_data);
- write(pipefd[1], small_data, strlen(small_data));
+ TEMP_FAILURE_RETRY(write(pipefd[1], small_data, strlen(small_data)));
semaphore_wait(done);
eager_reader_free(reader);
@@ -139,7 +139,7 @@ TEST_F(EagerReaderTest, test_large_data_multibyte) {
thread_t *read_thread = thread_new("read_thread");
eager_reader_register(reader, thread_get_reactor(read_thread), expect_data_multibyte, (void *)large_data);
- write(pipefd[1], large_data, strlen(large_data));
+ TEMP_FAILURE_RETRY(write(pipefd[1], large_data, strlen(large_data)));
semaphore_wait(done);
eager_reader_free(reader);
diff --git a/osi/test/reactor_test.cpp b/osi/test/reactor_test.cpp
index 6e3a0092a..73a6ae07b 100644
--- a/osi/test/reactor_test.cpp
+++ b/osi/test/reactor_test.cpp
@@ -64,7 +64,7 @@ TEST_F(ReactorTest, reactor_start_wait_stop) {
reactor_t *reactor = reactor_new();
spawn_reactor_thread(reactor);
- usleep(50 * 1000);
+ TEMP_FAILURE_RETRY(usleep(50 * 1000));
EXPECT_TRUE(thread_running);
reactor_stop(reactor);
@@ -108,7 +108,7 @@ TEST_F(ReactorTest, reactor_unregister_from_separate_thread) {
reactor_object_t *object = reactor_register(reactor, fd, NULL, NULL, NULL);
spawn_reactor_thread(reactor);
- usleep(50 * 1000);
+ TEMP_FAILURE_RETRY(usleep(50 * 1000));
reactor_unregister(object);
reactor_stop(reactor);
diff --git a/test/suite/support/callbacks.h b/test/suite/support/callbacks.h
index e01de39a2..2ef35156c 100644
--- a/test/suite/support/callbacks.h
+++ b/test/suite/support/callbacks.h
@@ -20,12 +20,14 @@
#include "base.h"
+#include <errno.h>
#include <semaphore.h>
+#include <unistd.h>
#define WAIT(callback) \
do { \
sem_t *semaphore = callbacks_get_semaphore(#callback); \
- sem_wait(semaphore); \
+ TEMP_FAILURE_RETRY(sem_wait(semaphore)); \
} while (0)
#define CALL_AND_WAIT(expression, callback) \
@@ -33,7 +35,7 @@
sem_t *semaphore = callbacks_get_semaphore(#callback); \
while (!sem_trywait(semaphore)); \
expression; \
- sem_wait(semaphore); \
+ TEMP_FAILURE_RETRY(sem_wait(semaphore)); \
} while(0)
// To be called from every exit point of the callback. This macro
diff --git a/tools/hci/main.c b/tools/hci/main.c
index fc433bcda..97fbef1e7 100644
--- a/tools/hci/main.c
+++ b/tools/hci/main.c
@@ -1,3 +1,4 @@
+#include <errno.h>
#include <hardware/bluetooth.h>
#include <netinet/in.h>
#include <stdio.h>
@@ -149,16 +150,16 @@ static bool write_hci_command(hci_packet_t type, const void *packet, size_t leng
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(0x7F000001);
addr.sin_port = htons(8873);
- if (connect(sock, (const struct sockaddr *)&addr, sizeof(addr)) == -1)
+ if (TEMP_FAILURE_RETRY(connect(sock, (const struct sockaddr *)&addr, sizeof(addr))) == -1)
goto error;
- if (send(sock, &type, 1, 0) != 1)
+ if (TEMP_FAILURE_RETRY(send(sock, &type, 1, 0)) != 1)
goto error;
- if (send(sock, &length, 2, 0) != 2)
+ if (TEMP_FAILURE_RETRY(send(sock, &length, 2, 0)) != 2)
goto error;
- if (send(sock, packet, length, 0) != (ssize_t)length)
+ if (TEMP_FAILURE_RETRY(send(sock, packet, length, 0)) != (ssize_t)length)
goto error;
close(sock);
diff --git a/udrv/ulinux/uipc.c b/udrv/ulinux/uipc.c
index f3c746e09..5a94d73c8 100644
--- a/udrv/ulinux/uipc.c
+++ b/udrv/ulinux/uipc.c
@@ -184,7 +184,7 @@ static int accept_server_socket(int sfd)
pfd.fd = sfd;
pfd.events = POLLIN;
- if (poll(&pfd, 1, 0) == 0)
+ if (TEMP_FAILURE_RETRY(poll(&pfd, 1, 0)) == 0)
{
BTIF_TRACE_EVENT("accept poll timeout");
return -1;
@@ -192,7 +192,7 @@ static int accept_server_socket(int sfd)
//BTIF_TRACE_EVENT("poll revents 0x%x", pfd.revents);
- if ((fd = accept(sfd, (struct sockaddr *)&remote, &len)) == -1)
+ if ((fd = TEMP_FAILURE_RETRY(accept(sfd, (struct sockaddr *)&remote, &len))) == -1)
{
BTIF_TRACE_ERROR("sock accept failed (%s)", strerror(errno));
return -1;
@@ -330,7 +330,7 @@ static void uipc_check_interrupt_locked(void)
{
char sig_recv = 0;
//BTIF_TRACE_EVENT("UIPC INTERRUPT");
- recv(uipc_main.signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL);
+ TEMP_FAILURE_RETRY(recv(uipc_main.signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL));
}
}
@@ -338,7 +338,7 @@ static inline void uipc_wakeup_locked(void)
{
char sig_on = 1;
BTIF_TRACE_EVENT("UIPC SEND WAKE UP");
- send(uipc_main.signal_fds[1], &sig_on, sizeof(sig_on), 0);
+ TEMP_FAILURE_RETRY(send(uipc_main.signal_fds[1], &sig_on, sizeof(sig_on), 0));
}
static int uipc_setup_server_locked(tUIPC_CH_ID ch_id, char *name, tUIPC_RCV_CBACK *cback)
@@ -394,7 +394,7 @@ static void uipc_flush_ch_locked(tUIPC_CH_ID ch_id)
while (1)
{
- ret = poll(&pfd, 1, 1);
+ ret = TEMP_FAILURE_RETRY(poll(&pfd, 1, 1));
BTIF_TRACE_VERBOSE("%s() - polling fd %d, revents: 0x%x, ret %d",
__FUNCTION__, pfd.fd, pfd.revents, ret);
@@ -412,7 +412,7 @@ static void uipc_flush_ch_locked(tUIPC_CH_ID ch_id)
/* read sufficiently large buffer to ensure flush empties socket faster than
it is getting refilled */
- read(pfd.fd, &buf, UIPC_FLUSH_BUFFER_SIZE);
+ TEMP_FAILURE_RETRY(read(pfd.fd, &buf, UIPC_FLUSH_BUFFER_SIZE));
}
}
@@ -502,7 +502,7 @@ static void uipc_read_task(void *arg)
{
uipc_main.read_set = uipc_main.active_set;
- result = select(uipc_main.max_fd+1, &uipc_main.read_set, NULL, NULL, NULL);
+ result = TEMP_FAILURE_RETRY(select(uipc_main.max_fd+1, &uipc_main.read_set, NULL, NULL, NULL));
if (result == 0)
{
@@ -715,7 +715,7 @@ BOOLEAN UIPC_Send(tUIPC_CH_ID ch_id, UINT16 msg_evt, UINT8 *p_buf,
UIPC_LOCK();
- if (write(uipc_main.ch[ch_id].fd, p_buf, msglen) < 0)
+ if (TEMP_FAILURE_RETRY(write(uipc_main.ch[ch_id].fd, p_buf, msglen)) < 0)
{
BTIF_TRACE_ERROR("failed to write (%s)", strerror(errno));
}
@@ -784,7 +784,7 @@ UINT32 UIPC_Read(tUIPC_CH_ID ch_id, UINT16 *p_msg_evt, UINT8 *p_buf, UINT32 len)
/* make sure there is data prior to attempting read to avoid blocking
a read for more than poll timeout */
- if (poll(&pfd, 1, uipc_main.ch[ch_id].read_poll_tmo_ms) == 0)
+ if (TEMP_FAILURE_RETRY(poll(&pfd, 1, uipc_main.ch[ch_id].read_poll_tmo_ms)) == 0)
{
BTIF_TRACE_EVENT("poll timeout (%d ms)", uipc_main.ch[ch_id].read_poll_tmo_ms);
break;
@@ -801,7 +801,7 @@ UINT32 UIPC_Read(tUIPC_CH_ID ch_id, UINT16 *p_msg_evt, UINT8 *p_buf, UINT32 len)
return 0;
}
- n = recv(fd, p_buf+n_read, len-n_read, 0);
+ n = TEMP_FAILURE_RETRY(recv(fd, p_buf+n_read, len-n_read, 0));
//BTIF_TRACE_EVENT("read %d bytes", n);