Backed out changeset c358e102e573 (bug 1008091) for B2G mochitest failures.
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 09 Jan 2015 11:54:14 -0500
changeset 248856 78f910177388ec02fa8e5bc6d00397954431700d
parent 248855 f15e6350d86bbf7ee34a747eae649d50b300b950
child 248857 086396560012f598b2400b11c10bfe39be083429
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1008091
milestone37.0a1
backs outc358e102e57398c171bd754128e91a0bd9e11137
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset c358e102e573 (bug 1008091) for B2G mochitest failures. CLOSED TREE
netwerk/build/moz.build
netwerk/build/nsNetModule.cpp
netwerk/system/linux/moz.build
netwerk/system/linux/nsNotifyAddrListener_Linux.cpp
netwerk/system/linux/nsNotifyAddrListener_Linux.h
netwerk/system/moz.build
xpcom/glue/FileUtils.h
--- a/netwerk/build/moz.build
+++ b/netwerk/build/moz.build
@@ -53,21 +53,16 @@ if CONFIG['MOZ_ENABLE_QTNETWORK']:
         '../system/qt',
     ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     LOCAL_INCLUDES += [
         '../system/android',
     ]
 
-elif CONFIG['OS_ARCH'] == 'Linux':
-    LOCAL_INCLUDES += [
-        '../system/linux',
-    ]
-
 if CONFIG['NECKO_COOKIES']:
     LOCAL_INCLUDES += [
         '../cookie',
     ]
 
 if CONFIG['NECKO_WIFI']:
     LOCAL_INCLUDES += [
         '../wifi',
--- a/netwerk/build/nsNetModule.cpp
+++ b/netwerk/build/nsNetModule.cpp
@@ -371,19 +371,16 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsNo
 #include "nsNetworkLinkService.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsNetworkLinkService, Init)
 #elif defined(MOZ_ENABLE_QTNETWORK)
 #include "nsQtNetworkLinkService.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsQtNetworkLinkService, Init)
 #elif defined(MOZ_WIDGET_ANDROID)
 #include "nsAndroidNetworkLinkService.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAndroidNetworkLinkService)
-#elif defined(XP_LINUX)
-#include "nsNotifyAddrListener_Linux.h"
-NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsNotifyAddrListener, Init)
 #endif
 
 ///////////////////////////////////////////////////////////////////////////////
 
 #ifdef NECKO_PROTOCOL_ftp
 #include "nsFTPDirListingConv.h"
 nsresult NS_NewFTPDirListingConv(nsFTPDirListingConv** result);
 #endif
@@ -789,18 +786,16 @@ NS_DEFINE_NAMED_CID(NS_RTSPPROTOCOLHANDL
 #if defined(XP_WIN)
 NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
 #elif defined(MOZ_WIDGET_COCOA)
 NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
 #elif defined(MOZ_ENABLE_QTNETWORK)
 NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
 #elif defined(MOZ_WIDGET_ANDROID)
 NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
-#elif defined(XP_LINUX)
-NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
 #endif
 NS_DEFINE_NAMED_CID(NS_SERIALIZATION_HELPER_CID);
 NS_DEFINE_NAMED_CID(NS_REDIRECTCHANNELREGISTRAR_CID);
 NS_DEFINE_NAMED_CID(NS_CACHE_STORAGE_SERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_NETWORKPREDICTOR_CID);
 
 static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
     { &kNS_IOSERVICE_CID, false, nullptr, nsIOServiceConstructor },
@@ -935,18 +930,16 @@ static const mozilla::Module::CIDEntry k
 #if defined(XP_WIN)
     { &kNS_NETWORK_LINK_SERVICE_CID, false, nullptr, nsNotifyAddrListenerConstructor },
 #elif defined(MOZ_WIDGET_COCOA)
     { &kNS_NETWORK_LINK_SERVICE_CID, false, nullptr, nsNetworkLinkServiceConstructor },
 #elif defined(MOZ_ENABLE_QTNETWORK)
     { &kNS_NETWORK_LINK_SERVICE_CID, false, nullptr, nsQtNetworkLinkServiceConstructor },
 #elif defined(MOZ_WIDGET_ANDROID)
     { &kNS_NETWORK_LINK_SERVICE_CID, false, nullptr, nsAndroidNetworkLinkServiceConstructor },
-#elif defined(XP_LINUX)
-    { &kNS_NETWORK_LINK_SERVICE_CID, false, nullptr, nsNotifyAddrListenerConstructor },
 #endif
     { &kNS_SERIALIZATION_HELPER_CID, false, nullptr, nsSerializationHelperConstructor },
     { &kNS_REDIRECTCHANNELREGISTRAR_CID, false, nullptr, RedirectChannelRegistrarConstructor },
     { &kNS_CACHE_STORAGE_SERVICE_CID, false, nullptr, CacheStorageServiceConstructor },
     { &kNS_NETWORKPREDICTOR_CID, false, nullptr, mozilla::net::Predictor::Create },
     { nullptr }
 };
 
@@ -1084,18 +1077,16 @@ static const mozilla::Module::ContractID
 #if defined(XP_WIN)
     { NS_NETWORK_LINK_SERVICE_CONTRACTID, &kNS_NETWORK_LINK_SERVICE_CID },
 #elif defined(MOZ_WIDGET_COCOA)
     { NS_NETWORK_LINK_SERVICE_CONTRACTID, &kNS_NETWORK_LINK_SERVICE_CID },
 #elif defined(MOZ_ENABLE_QTNETWORK)
     { NS_NETWORK_LINK_SERVICE_CONTRACTID, &kNS_NETWORK_LINK_SERVICE_CID },
 #elif defined(MOZ_WIDGET_ANDROID)
     { NS_NETWORK_LINK_SERVICE_CONTRACTID, &kNS_NETWORK_LINK_SERVICE_CID },
-#elif defined(XP_LINUX)
-    { NS_NETWORK_LINK_SERVICE_CONTRACTID, &kNS_NETWORK_LINK_SERVICE_CID },
 #endif
     { NS_SERIALIZATION_HELPER_CONTRACTID, &kNS_SERIALIZATION_HELPER_CID },
     { NS_REDIRECTCHANNELREGISTRAR_CONTRACTID, &kNS_REDIRECTCHANNELREGISTRAR_CID },
     { NS_CACHE_STORAGE_SERVICE_CONTRACTID, &kNS_CACHE_STORAGE_SERVICE_CID },
     { NS_CACHE_STORAGE_SERVICE_CONTRACTID2, &kNS_CACHE_STORAGE_SERVICE_CID },
     { NS_NETWORKPREDICTOR_CONTRACTID, &kNS_NETWORKPREDICTOR_CID },
     { nullptr }
 };
deleted file mode 100644
--- a/netwerk/system/linux/moz.build
+++ /dev/null
@@ -1,14 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-if CONFIG['OS_ARCH'] == 'Linux':
-    SOURCES += [
-        'nsNotifyAddrListener_Linux.cpp',
-    ]
-
-FAIL_ON_WARNINGS = True
-
-FINAL_LIBRARY = 'xul'
deleted file mode 100644
--- a/netwerk/system/linux/nsNotifyAddrListener_Linux.cpp
+++ /dev/null
@@ -1,318 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim:set et sw=4 ts=4: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include <stdarg.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <errno.h>
-
-#include "nsThreadUtils.h"
-#include "nsIObserverService.h"
-#include "nsServiceManagerUtils.h"
-#include "nsNotifyAddrListener_Linux.h"
-#include "nsString.h"
-#include "nsAutoPtr.h"
-#include "prlog.h"
-
-#include "mozilla/Services.h"
-#include "mozilla/Preferences.h"
-#include "mozilla/FileUtils.h"
-
-#ifdef MOZ_WIDGET_GONK
-#include <cutils/properties.h>
-#endif
-
-/* a shorter name that better explains what it does */
-#define EINTR_RETRY(x) MOZ_TEMP_FAILURE_RETRY(x)
-
-using namespace mozilla;
-
-#if defined(PR_LOGGING)
-static PRLogModuleInfo *gNotifyAddrLog = nullptr;
-#define LOG(args) PR_LOG(gNotifyAddrLog, PR_LOG_DEBUG, args)
-#else
-#define LOG(args)
-#endif
-
-#define NETWORK_NOTIFY_CHANGED_PREF "network.notify.changed"
-
-NS_IMPL_ISUPPORTS(nsNotifyAddrListener,
-                  nsINetworkLinkService,
-                  nsIRunnable,
-                  nsIObserver)
-
-nsNotifyAddrListener::nsNotifyAddrListener()
-    : mLinkUp(true)  // assume true by default
-    , mStatusKnown(false)
-    , mAllowChangedEvent(true)
-    , mChildThreadShutdown(false)
-{
-    mShutdownPipe[0] = -1;
-    mShutdownPipe[1] = -1;
-}
-
-nsNotifyAddrListener::~nsNotifyAddrListener()
-{
-    MOZ_ASSERT(!mThread, "nsNotifyAddrListener thread shutdown failed");
-
-    if (mShutdownPipe[0] != -1) {
-        EINTR_RETRY(close(mShutdownPipe[0]));
-    }
-    if (mShutdownPipe[1] != -1) {
-        EINTR_RETRY(close(mShutdownPipe[1]));
-    }
-}
-
-NS_IMETHODIMP
-nsNotifyAddrListener::GetIsLinkUp(bool *aIsUp)
-{
-    // XXX This function has not yet been implemented for this platform
-    *aIsUp = mLinkUp;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsNotifyAddrListener::GetLinkStatusKnown(bool *aIsUp)
-{
-    // XXX This function has not yet been implemented for this platform
-    *aIsUp = mStatusKnown;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsNotifyAddrListener::GetLinkType(uint32_t *aLinkType)
-{
-  NS_ENSURE_ARG_POINTER(aLinkType);
-
-  // XXX This function has not yet been implemented for this platform
-  *aLinkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN;
-  return NS_OK;
-}
-
-void nsNotifyAddrListener::OnNetlinkMessage(int aNetlinkSocket)
-{
-    struct  nlmsghdr *nlh;
-    struct  rtmsg *route_entry;
-
-    // The buffer size below, (4095) was chosen partly based on testing and
-    // partly on existing sample source code using this size. It needs to be
-    // large enough to hold the netlink messages from the kernel.
-    char buffer[4095];
-
-    // Receiving netlink socket data
-    ssize_t rc = EINTR_RETRY(recv(aNetlinkSocket, buffer, sizeof(buffer), 0));
-    if (rc < 0) {
-        return;
-    }
-    size_t netlink_bytes = rc;
-
-    nlh = reinterpret_cast<struct nlmsghdr *>(buffer);
-
-    bool networkChange = false;
-
-    for (; NLMSG_OK(nlh, netlink_bytes);
-         nlh = NLMSG_NEXT(nlh, netlink_bytes)) {
-
-        if (NLMSG_DONE == nlh->nlmsg_type) {
-            break;
-        }
-
-        switch(nlh->nlmsg_type) {
-        case RTM_DELROUTE:
-        case RTM_NEWROUTE:
-            // Get the route data
-            route_entry = static_cast<struct rtmsg *>(NLMSG_DATA(nlh));
-
-            // We are just intrested in main routing table
-            if (route_entry->rtm_table != RT_TABLE_MAIN)
-                continue;
-
-            networkChange = true;
-            break;
-
-        case RTM_NEWADDR:
-            networkChange = true;
-            break;
-
-        default:
-            continue;
-        }
-    }
-
-    if (networkChange && mAllowChangedEvent) {
-        SendEvent(NS_NETWORK_LINK_DATA_CHANGED);
-    }
-}
-
-NS_IMETHODIMP
-nsNotifyAddrListener::Run()
-{
-    PR_SetCurrentThreadName("Link Monitor");
-
-    int netlinkSocket = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
-    if (netlinkSocket < 0) {
-        return NS_ERROR_FAILURE;
-    }
-
-    struct sockaddr_nl addr;
-    memset(&addr, 0, sizeof(addr));   // clear addr
-
-    addr.nl_family = AF_NETLINK;
-    addr.nl_groups = RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR |
-        RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE;
-
-    if (bind(netlinkSocket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
-        // failure!
-        EINTR_RETRY(close(netlinkSocket));
-        return NS_ERROR_FAILURE;
-    }
-
-    // switch the socket into non-blocking
-    int flags = fcntl(netlinkSocket, F_GETFL, 0);
-    (void)fcntl(netlinkSocket, F_SETFL, flags | O_NONBLOCK);
-
-    struct pollfd fds[2];
-    fds[0].fd = mShutdownPipe[0];
-    fds[0].events = POLLIN;
-    fds[0].revents = 0;
-
-    fds[1].fd = netlinkSocket;
-    fds[1].events = POLLIN;
-    fds[1].revents = 0;
-
-    // when in b2g emulator, work around bug 1112499
-    int pollTimeout = -1;
-#ifdef MOZ_WIDGET_GONK
-    char propQemu[PROPERTY_VALUE_MAX];
-    property_get("ro.kernel.qemu", propQemu, "");
-    pollTimeout = !strncmp(propQemu, "1", 1) ? 100 : -1;
-#endif
-
-    nsresult rv = NS_OK;
-    bool shutdown = false;
-    while (!shutdown) {
-        int rc = EINTR_RETRY(poll(fds, 2, pollTimeout));
-
-        if (rc > 0) {
-            if (fds[0].revents & POLLIN) {
-                // shutdown, abort the loop!
-                LOG(("thread shutdown received, dying...\n"));
-                shutdown = true;
-            } else if (fds[1].revents & POLLIN) {
-                LOG(("netlink message received, handling it...\n"));
-                OnNetlinkMessage(netlinkSocket);
-            }
-        } else if (rc < 0) {
-            rv = NS_ERROR_FAILURE;
-            break;
-        }
-        if (mChildThreadShutdown) {
-            LOG(("thread shutdown via variable, dying...\n"));
-            shutdown = true;
-        }
-    }
-
-    EINTR_RETRY(close(netlinkSocket));
-
-    return rv;
-}
-
-NS_IMETHODIMP
-nsNotifyAddrListener::Observe(nsISupports *subject,
-                              const char *topic,
-                              const char16_t *data)
-{
-    if (!strcmp("xpcom-shutdown-threads", topic)) {
-        Shutdown();
-    }
-
-    return NS_OK;
-}
-
-nsresult
-nsNotifyAddrListener::Init(void)
-{
-#if defined(PR_LOGGING)
-    if (!gNotifyAddrLog)
-        gNotifyAddrLog = PR_NewLogModule("nsNotifyAddr");
-#endif
-
-    nsCOMPtr<nsIObserverService> observerService =
-        mozilla::services::GetObserverService();
-    if (!observerService)
-        return NS_ERROR_FAILURE;
-
-    nsresult rv = observerService->AddObserver(this, "xpcom-shutdown-threads",
-                                               false);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    Preferences::AddBoolVarCache(&mAllowChangedEvent,
-                                 NETWORK_NOTIFY_CHANGED_PREF, true);
-
-    rv = NS_NewThread(getter_AddRefs(mThread), this);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    if (-1 == pipe(mShutdownPipe)) {
-        return NS_ERROR_FAILURE;
-    }
-
-    return NS_OK;
-}
-
-nsresult
-nsNotifyAddrListener::Shutdown(void)
-{
-    // remove xpcom shutdown observer
-    nsCOMPtr<nsIObserverService> observerService =
-        mozilla::services::GetObserverService();
-    if (observerService)
-        observerService->RemoveObserver(this, "xpcom-shutdown-threads");
-
-    LOG(("write() to signal thread shutdown\n"));
-
-    // awake the thread to make it terminate
-    ssize_t rc = EINTR_RETRY(write(mShutdownPipe[1], "1", 1));
-    LOG(("write() returned %d, errno == %d\n", (int)rc, errno));
-
-    mChildThreadShutdown = true;
-
-    nsresult rv = mThread->Shutdown();
-
-    // Have to break the cycle here, otherwise nsNotifyAddrListener holds
-    // onto the thread and the thread holds onto the nsNotifyAddrListener
-    // via its mRunnable
-    mThread = nullptr;
-
-    return rv;
-}
-
-/* Sends the given event.  Assumes aEventID never goes out of scope (static
- * strings are ideal).
- */
-nsresult
-nsNotifyAddrListener::SendEvent(const char *aEventID)
-{
-    if (!aEventID)
-        return NS_ERROR_NULL_POINTER;
-
-    nsresult rv = NS_OK;
-    nsCOMPtr<nsIRunnable> event = new ChangeEvent(this, aEventID);
-    if (NS_FAILED(rv = NS_DispatchToMainThread(event)))
-        NS_WARNING("Failed to dispatch ChangeEvent");
-    return rv;
-}
-
-NS_IMETHODIMP
-nsNotifyAddrListener::ChangeEvent::Run()
-{
-    nsCOMPtr<nsIObserverService> observerService =
-        mozilla::services::GetObserverService();
-    if (observerService)
-        observerService->NotifyObservers(
-                mService, NS_NETWORK_LINK_TOPIC,
-                NS_ConvertASCIItoUTF16(mEventID).get());
-    return NS_OK;
-}
deleted file mode 100644
--- a/netwerk/system/linux/nsNotifyAddrListener_Linux.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim:set et sw=4 ts=4: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef NSNOTIFYADDRLISTENER_LINUX_H_
-#define NSNOTIFYADDRLISTENER_LINUX_H_
-
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-
-#include "nsINetworkLinkService.h"
-#include "nsIRunnable.h"
-#include "nsIObserver.h"
-#include "nsThreadUtils.h"
-#include "nsCOMPtr.h"
-#include "mozilla/TimeStamp.h"
-
-class nsNotifyAddrListener : public nsINetworkLinkService,
-                             public nsIRunnable,
-                             public nsIObserver
-{
-    virtual ~nsNotifyAddrListener();
-
-public:
-    NS_DECL_THREADSAFE_ISUPPORTS
-    NS_DECL_NSINETWORKLINKSERVICE
-    NS_DECL_NSIRUNNABLE
-    NS_DECL_NSIOBSERVER
-
-    nsNotifyAddrListener();
-    nsresult Init(void);
-
-private:
-    class ChangeEvent : public nsRunnable {
-    public:
-        NS_DECL_NSIRUNNABLE
-        ChangeEvent(nsINetworkLinkService *aService, const char *aEventID)
-            : mService(aService), mEventID(aEventID) {
-        }
-    private:
-        nsCOMPtr<nsINetworkLinkService> mService;
-        const char *mEventID;
-    };
-
-    // Called when xpcom-shutdown-threads is received.
-    nsresult Shutdown(void);
-
-    // Sends the network event.
-    nsresult SendEvent(const char *aEventID);
-
-    // Deals with incoming NETLINK messages.
-    void OnNetlinkMessage(int NetlinkSocket);
-
-    nsCOMPtr<nsIThread> mThread;
-
-    // The network is up.
-    bool mLinkUp;
-
-    // The network's up/down status is known.
-    bool mStatusKnown;
-
-    // A pipe to signal shutdown with.
-    int mShutdownPipe[2];
-
-    // Network changed events are enabled
-    bool mAllowChangedEvent;
-
-    // Flag to signal child thread kill with
-    bool mChildThreadShutdown;
-};
-
-#endif /* NSNOTIFYADDRLISTENER_LINUX_H_ */
--- a/netwerk/system/moz.build
+++ b/netwerk/system/moz.build
@@ -11,10 +11,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'coco
     DIRS += ['mac']
 
 if CONFIG['MOZ_ENABLE_QTNETWORK']:
     DIRS += ['qt']
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     DIRS += ['android']
 
-elif CONFIG['OS_ARCH'] == 'Linux':
-    DIRS += ['linux']
--- a/xpcom/glue/FileUtils.h
+++ b/xpcom/glue/FileUtils.h
@@ -156,35 +156,33 @@ void ReadAheadFile(pathstr_t aFilePath, 
  * (on Windows, file must be opened with FILE_FLAG_SEQUENTIAL_SCAN)
  * @param aOffset Offset into the file to begin preloading
  * @param aCount Number of bytes to preload (SIZE_MAX implies file size)
  */
 void ReadAhead(filedesc_t aFd, const size_t aOffset = 0,
                const size_t aCount = SIZE_MAX);
 
 
-#if defined(MOZ_WIDGET_GONK) || defined(XP_UNIX)
-#define MOZ_TEMP_FAILURE_RETRY(exp) (__extension__({ \
-  typeof (exp) _rc; \
-  do { \
-    _rc = (exp); \
-  } while (_rc == -1 && errno == EINTR); \
-  _rc; \
-}))
-#endif
-
 /* Define ReadSysFile() only on GONK to avoid unnecessary lubxul bloat.
 Also define it in debug builds, so that unit tests for it can be written
 and run in non-GONK builds. */
 #if (defined(MOZ_WIDGET_GONK) || defined(DEBUG)) && defined(XP_UNIX)
 
 #ifndef ReadSysFile_PRESENT
 #define ReadSysFile_PRESENT
 #endif /* ReadSysFile_PRESENT */
 
+#define MOZ_TEMP_FAILURE_RETRY(exp) (__extension__({ \
+  typeof (exp) _rc; \
+  do { \
+    _rc = (exp); \
+  } while (_rc == -1 && errno == EINTR); \
+  _rc; \
+}))
+
 /**
  * Read the contents of a file.
  * This function is intended for reading a single-lined text files from
  * /sys/. If the file ends with a newline ('\n') then it will be discarded.
  * The output buffer will always be '\0'-terminated on successful completion.
  * If aBufSize == 0, then this function will return true if the file exists
  * and is readable (it will not attempt to read anything from it).
  * On failure the contents of aBuf after this call will be undefined and the