Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb8505e7 authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change 3354

* changes:
  break dependency on utils/ZipEntry.h and utils/ZipFile.h, get rid of inet_address.h and Socket.h which were not used
parents 0d2037be 55e3d60d
Loading
Loading
Loading
Loading

include/utils/Socket.h

deleted100644 → 0
+0 −80
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2005 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//
// Socket class.  Modeled after Java classes.
//
#ifndef _RUNTIME_SOCKET_H
#define _RUNTIME_SOCKET_H

#include <utils/inet_address.h>
#include <sys/types.h>

namespace android {

/*
 * Basic socket class, needed to abstract away the differences between
 * BSD sockets and WinSock.  This establishes a streaming network
 * connection (TCP/IP) to somebody.
 */
class Socket {
public:
    Socket(void);
    ~Socket(void);

    // Create a connection to somewhere.
    // Return 0 on success.
    int connect(const char* host, int port);
    int connect(const InetAddress* addr, int port);


    // Close the socket.  Don't try to use this object again after
    // calling this.  Returns false on failure.
    bool close(void);

    // If we created the socket without an address, we can use these
    // to finish the connection.  Returns 0 on success.
    int bind(const SocketAddress& bindPoint);
    int connect(const SocketAddress& endPoint);

    // Here we deviate from the traditional object-oriented fanciness
    // and just provide read/write operators instead of getters for
    // objects that abstract a stream.
    //
    // Standard read/write semantics.
    int read(void* buf, ssize_t len) const;
    int write(const void* buf, ssize_t len) const;

    // This must be called once, at program startup.
    static bool bootInit(void);
    static void finalShutdown(void);

private:
    // Internal function that establishes a connection.
    int doConnect(const InetSocketAddress& addr);

    unsigned long   mSock;      // holds SOCKET or int

    static bool     mBootInitialized;
};


// debug -- unit tests
void TestSockets(void);

}; // namespace android

#endif // _RUNTIME_SOCKET_H

include/utils/inet_address.h

deleted100644 → 0
+0 −103
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2005 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//
// Internet address classes.  Modeled after Java classes.
//
#ifndef _RUNTIME_INET_ADDRESS_H
#define _RUNTIME_INET_ADDRESS_H

#ifdef HAVE_ANDROID_OS
#error DO NOT USE THIS FILE IN THE DEVICE BUILD
#endif


namespace android {

/*
 * This class holds Internet addresses.  Perhaps more useful is its
 * ability to look up addresses by name.
 *
 * Invoke one of the static factory methods to create a new object.
 */
class InetAddress {
public:
    virtual ~InetAddress(void);

    // create from w.x.y.z or foo.bar.com notation
    static InetAddress* getByName(const char* host);

    // copy-construction
    InetAddress(const InetAddress& orig);

    const void* getAddress(void) const { return mAddress; }
    int getAddressLength(void) const { return mLength; }
    const char* getHostName(void) const { return mName; }

private:
    InetAddress(void);
    // assignment (private)
    InetAddress& operator=(const InetAddress& addr);

    // use a void* here so we don't have to expose actual socket headers
    void*       mAddress;   // this is really a ptr to sockaddr_in
    int         mLength;
    char*       mName;
};


/*
 * Base class for socket addresses.
 */
class SocketAddress {
public:
    SocketAddress() {}
    virtual ~SocketAddress() {}
};


/*
 * Internet address class.  This combines an InetAddress with a port.
 */
class InetSocketAddress : public SocketAddress {
public:
    InetSocketAddress() :
        mAddress(0), mPort(-1)
        {}
    ~InetSocketAddress(void) {
        delete mAddress;
    }

    // Create an address with a host wildcard (useful for servers).
    bool create(int port);
    // Create an address with the specified host and port.
    bool create(const InetAddress* addr, int port);
    // Create an address with the specified host and port.  Does the
    // hostname lookup.
    bool create(const char* host, int port);

    const InetAddress* getAddress(void) const { return mAddress; }
    const int getPort(void) const { return mPort; }
    const char* getHostName(void) const { return mAddress->getHostName(); }

private:
    InetAddress* mAddress;
    int         mPort;
};

}; // namespace android

#endif // _RUNTIME_INET_ADDRESS_H
+1 −22
Original line number Original line Diff line number Diff line
@@ -44,26 +44,13 @@ commonSources:= \
	misc.cpp \
	misc.cpp \
	LogSocket.cpp
	LogSocket.cpp


#
# The cpp files listed here do not belong in the device
# build.  Consult with the swetland before even thinking about
# putting them in commonSources.
#
# They're used by the simulator runtime and by host-side tools like
# aapt and the simulator front-end.
#
hostSources:= \
	InetAddress.cpp \
	Socket.cpp \
	ZipEntry.cpp \
	ZipFile.cpp


# For the host
# For the host
# =====================================================
# =====================================================


include $(CLEAR_VARS)
include $(CLEAR_VARS)


LOCAL_SRC_FILES:= $(commonSources) $(hostSources)
LOCAL_SRC_FILES:= $(commonSources)


ifeq ($(HOST_OS),linux)
ifeq ($(HOST_OS),linux)
# Use the futex based mutex and condition variable
# Use the futex based mutex and condition variable
@@ -100,10 +87,6 @@ LOCAL_SRC_FILES:= \
    BackupData.cpp \
    BackupData.cpp \
	BackupHelpers.cpp
	BackupHelpers.cpp


ifeq ($(TARGET_SIMULATOR),true)
LOCAL_SRC_FILES += $(hostSources)
endif

ifeq ($(TARGET_OS),linux)
ifeq ($(TARGET_OS),linux)
# Use the futex based mutex and condition variable
# Use the futex based mutex and condition variable
# implementation from android-arm because it's shared mem safe
# implementation from android-arm because it's shared mem safe
@@ -130,9 +113,5 @@ endif # linux-x86
endif # sim
endif # sim


LOCAL_MODULE:= libutils
LOCAL_MODULE:= libutils

#LOCAL_CFLAGS+=
#LOCAL_LDFLAGS:=

include $(BUILD_SHARED_LIBRARY)
include $(BUILD_SHARED_LIBRARY)

libs/utils/InetAddress.cpp

deleted100644 → 0
+0 −236
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2005 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//
// Internet address class.
//
#ifdef HAVE_WINSOCK
# include <winsock2.h>
#else
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
//# include <arpa/inet.h>
# include <netdb.h>
#endif

#include <utils/inet_address.h>
#include <utils/threads.h>
#include <utils/Log.h>

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

using namespace android;


/*
 * ===========================================================================
 *      InetAddress
 * ===========================================================================
 */

// lock for the next couple of functions; could tuck into InetAddress
static Mutex*   gGHBNLock;

/*
 * Lock/unlock access to the hostent struct returned by gethostbyname().
 */
static inline void lock_gethostbyname(void)
{
    if (gGHBNLock == NULL)
        gGHBNLock = new Mutex;
    gGHBNLock->lock();
}
static inline void unlock_gethostbyname(void)
{
    assert(gGHBNLock != NULL);
    gGHBNLock->unlock();
}


/*
 * Constructor -- just init members.  This is private so that callers
 * are required to use getByName().
 */
InetAddress::InetAddress(void)
    : mAddress(NULL), mLength(-1), mName(NULL)
{
}

/*
 * Destructor -- free address storage.
 */
InetAddress::~InetAddress(void)
{
    delete[] (char*) mAddress;
    delete[] mName;
}

/*
 * Copy constructor.
 */
InetAddress::InetAddress(const InetAddress& orig)
{
    *this = orig;   // use assignment code
}

/*
 * Assignment operator.
 */
InetAddress& InetAddress::operator=(const InetAddress& addr)
{
    // handle self-assignment
    if (this == &addr)
        return *this;
    // copy mLength and mAddress
    mLength = addr.mLength;
    if (mLength > 0) {
        mAddress = new char[mLength];
        memcpy(mAddress, addr.mAddress, mLength);
        LOG(LOG_DEBUG, "socket",
            "HEY: copied %d bytes in assignment operator\n", mLength);
    } else {
        mAddress = NULL;
    }
    // copy mName
    mName = new char[strlen(addr.mName)+1];
    strcpy(mName, addr.mName);

    return *this;
}

/*
 * Create a new object from a name or a dotted-number IP notation.
 *
 * Returns NULL on failure.
 */
InetAddress*
InetAddress::getByName(const char* host)
{
    InetAddress* newAddr = NULL;
    struct sockaddr_in addr;
    struct hostent* he;
    DurationTimer hostTimer, lockTimer;

    // gethostbyname() isn't reentrant, so we need to lock things until
    // we can copy the data out.
    lockTimer.start();
    lock_gethostbyname();
    hostTimer.start();

    he = gethostbyname(host);
    if (he == NULL) {
        LOG(LOG_WARN, "socket", "WARNING: cannot resolve host %s\n", host);
        unlock_gethostbyname();
        return NULL;
    }

    memcpy(&addr.sin_addr, he->h_addr, he->h_length);
    addr.sin_family = he->h_addrtype;
    addr.sin_port = 0;

    // got it, unlock us
    hostTimer.stop();
    he = NULL;
    unlock_gethostbyname();

    lockTimer.stop();
    if ((long) lockTimer.durationUsecs() > 100000) {
        long lockTime = (long) lockTimer.durationUsecs();
        long hostTime = (long) hostTimer.durationUsecs();
        LOG(LOG_DEBUG, "socket",
            "Lookup of %s took %.3fs (gethostbyname=%.3fs lock=%.3fs)\n",
            host, lockTime / 1000000.0, hostTime / 1000000.0,
            (lockTime - hostTime) / 1000000.0);
    }

    // Alloc storage and copy it over.
    newAddr = new InetAddress();
    if (newAddr == NULL)
        return NULL;

    newAddr->mLength = sizeof(struct sockaddr_in);
    newAddr->mAddress = new char[sizeof(struct sockaddr_in)];
    if (newAddr->mAddress == NULL) {
        delete newAddr;
        return NULL;
    }
    memcpy(newAddr->mAddress, &addr, newAddr->mLength);

    // Keep this for debug messages.
    newAddr->mName = new char[strlen(host)+1];
    if (newAddr->mName == NULL) {
        delete newAddr;
        return NULL;
    }
    strcpy(newAddr->mName, host);

    return newAddr;
}


/*
 * ===========================================================================
 *      InetSocketAddress
 * ===========================================================================
 */

/*
 * Create an address with the host wildcard (INADDR_ANY).
 */
bool InetSocketAddress::create(int port)
{
    assert(mAddress == NULL);

    mAddress = InetAddress::getByName("0.0.0.0");
    if (mAddress == NULL)
        return false;
    mPort = port;
    return true;
}

/*
 * Create address with host and port specified.
 */
bool InetSocketAddress::create(const InetAddress* addr, int port)
{
    assert(mAddress == NULL);

    mAddress = new InetAddress(*addr);  // make a copy
    if (mAddress == NULL)
        return false;
    mPort = port;
    return true;
}

/*
 * Create address with host and port specified.
 */
bool InetSocketAddress::create(const char* host, int port)
{
    assert(mAddress == NULL);

    mAddress = InetAddress::getByName(host);
    if (mAddress == NULL)
        return false;
    mPort = port;
    return true;
}

libs/utils/Socket.cpp

deleted100644 → 0
+0 −388
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2005 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//
// Internet address class.
//

#ifdef HAVE_WINSOCK
// This needs to come first, or Cygwin gets concerned about a potential
// clash between WinSock and <sys/types.h>.
# include <winsock2.h>
#endif

#include <utils/Socket.h>
#include <utils/inet_address.h>
#include <utils/Log.h>
#include <utils/Timers.h>

#ifndef HAVE_WINSOCK
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
#endif

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <assert.h>

using namespace android;


/*
 * ===========================================================================
 *      Socket
 * ===========================================================================
 */

#ifndef INVALID_SOCKET
# define INVALID_SOCKET (-1)
#endif
#define UNDEF_SOCKET   ((unsigned long) INVALID_SOCKET)

/*static*/ bool Socket::mBootInitialized = false;

/*
 * Extract system-dependent error code.
 */
static inline int getSocketError(void) {
#ifdef HAVE_WINSOCK
    return WSAGetLastError();
#else
    return errno;
#endif
}

/*
 * One-time initialization for socket code.
 */
/*static*/ bool Socket::bootInit(void)
{
#ifdef HAVE_WINSOCK
    WSADATA wsaData;
    int err;

    err = WSAStartup(MAKEWORD(2, 0), &wsaData);
    if (err != 0) {
        LOG(LOG_ERROR, "socket", "Unable to start WinSock\n");
        return false;
    }

    LOG(LOG_INFO, "socket", "Using WinSock v%d.%d\n",
        LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
#endif

    mBootInitialized = true;
    return true;
}

/*
 * One-time shutdown for socket code.
 */
/*static*/ void Socket::finalShutdown(void)
{
#ifdef HAVE_WINSOCK
    WSACleanup();
#endif
    mBootInitialized = false;
}


/*
 * Simple constructor.  Allow the application to create us and then make
 * bind/connect calls.
 */
Socket::Socket(void)
    : mSock(UNDEF_SOCKET)
{
    if (!mBootInitialized)
        LOG(LOG_WARN, "socket", "WARNING: sockets not initialized\n");
}

/*
 * Destructor.  Closes the socket and resets our storage.
 */
Socket::~Socket(void)
{
    close();
}


/*
 * Create a socket and connect to the specified host and port.
 */
int Socket::connect(const char* host, int port)
{
    if (mSock != UNDEF_SOCKET) {
        LOG(LOG_WARN, "socket", "Socket already connected\n");
        return -1;
    }

    InetSocketAddress sockAddr;
    if (!sockAddr.create(host, port))
        return -1;

    //return doConnect(sockAddr);
    int foo;
    foo = doConnect(sockAddr);
    return foo;
}

/*
 * Create a socket and connect to the specified host and port.
 */
int Socket::connect(const InetAddress* addr, int port)
{
    if (mSock != UNDEF_SOCKET) {
        LOG(LOG_WARN, "socket", "Socket already connected\n");
        return -1;
    }

    InetSocketAddress sockAddr;
    if (!sockAddr.create(addr, port))
        return -1;

    return doConnect(sockAddr);
}

/*
 * Finish creating a socket by connecting to the remote host.
 *
 * Returns 0 on success.
 */
int Socket::doConnect(const InetSocketAddress& sockAddr)
{
#ifdef HAVE_WINSOCK
    SOCKET sock;
#else
    int sock;
#endif
    const InetAddress* addr = sockAddr.getAddress();
    int port = sockAddr.getPort();
    struct sockaddr_in inaddr;
    DurationTimer connectTimer;

    assert(sizeof(struct sockaddr_in) == addr->getAddressLength());
    memcpy(&inaddr, addr->getAddress(), addr->getAddressLength());
    inaddr.sin_port = htons(port);

    //fprintf(stderr, "--- connecting to %s:%d\n",
    //    sockAddr.getHostName(), port);

    sock = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock == INVALID_SOCKET) {
        int err = getSocketError();
        LOG(LOG_ERROR, "socket", "Unable to create socket (err=%d)\n", err);
        return (err != 0) ? err : -1;
    }

    connectTimer.start();

    if (::connect(sock, (struct sockaddr*) &inaddr, sizeof(inaddr)) != 0) {
        int err = getSocketError();
        LOG(LOG_WARN, "socket", "Connect to %s:%d failed: %d\n",
            sockAddr.getHostName(), port, err);
        return (err != 0) ? err : -1;
    }

    connectTimer.stop();
    if ((long) connectTimer.durationUsecs() > 100000) {
        LOG(LOG_INFO, "socket",
            "Connect to %s:%d took %.3fs\n", sockAddr.getHostName(),
            port, ((long) connectTimer.durationUsecs()) / 1000000.0);
    }

    mSock = (unsigned long) sock;
    LOG(LOG_VERBOSE, "socket",
        "--- connected to %s:%d\n", sockAddr.getHostName(), port);
    return 0;
}


/*
 * Close the socket if it needs closing.
 */
bool Socket::close(void)
{
    if (mSock != UNDEF_SOCKET) {
        //fprintf(stderr, "--- closing socket %lu\n", mSock);
#ifdef HAVE_WINSOCK
        if (::closesocket((SOCKET) mSock) != 0)
            return false;
#else
        if (::close((int) mSock) != 0)
            return false;
#endif
    }

    mSock = UNDEF_SOCKET;

    return true;
}

/*
 * Read data from socket.
 *
 * Standard semantics: read up to "len" bytes into "buf".  Returns the
 * number of bytes read, or less than zero on error.
 */
int Socket::read(void* buf, ssize_t len) const
{
    if (mSock == UNDEF_SOCKET) {
        LOG(LOG_ERROR, "socket", "ERROR: read on invalid socket\n");
        return -500;
    }

#ifdef HAVE_WINSOCK
    SOCKET sock = (SOCKET) mSock;
#else
    int sock = (int) mSock;
#endif
    int cc;

    cc = recv(sock, (char*)buf, len, 0);
    if (cc < 0) {
        int err = getSocketError();
        return (err > 0) ? -err : -1;
    }

    return cc;
}

/*
 * Write data to a socket.
 *
 * Standard semantics: write up to "len" bytes into "buf".  Returns the
 * number of bytes written, or less than zero on error.
 */
int Socket::write(const void* buf, ssize_t len) const
{
    if (mSock == UNDEF_SOCKET) {
        LOG(LOG_ERROR, "socket", "ERROR: write on invalid socket\n");
        return -500;
    }

#ifdef HAVE_WINSOCK
    SOCKET sock = (SOCKET) mSock;
#else
    int sock = (int) mSock;
#endif
    int cc;

    cc = send(sock, (const char*)buf, len, 0);
    if (cc < 0) {
        int err = getSocketError();
        return (err > 0) ? -err : -1;
    }

    return cc;
}


/*
 * ===========================================================================
 *      Socket tests
 * ===========================================================================
 */

/*
 * Read all data from the socket.  The data is read into a buffer that
 * expands as needed.
 *
 * On exit, the buffer is returned, and the length of the data is stored
 * in "*sz".  A null byte is added to the end, but is not included in
 * the length.
 */
static char* socketReadAll(const Socket& s, int *sz)
{
    int max, r;
    char *data, *ptr, *tmp;

    data = (char*) malloc(max = 32768);
    if (data == NULL)
        return NULL;

    ptr = data;
    
    for (;;) {
        if ((ptr - data) == max) {
            tmp = (char*) realloc(data, max *= 2);
            if(tmp == 0) {
                free(data);
                return 0;
            }
        }
        r = s.read(ptr, max - (ptr - data));
        if (r == 0)
            break;
        if (r < 0) {
            LOG(LOG_WARN, "socket", "WARNING: socket read failed (res=%d)\n",r);
            break;
        }
        ptr += r;
    }

    if ((ptr - data) == max) {
        tmp = (char*) realloc(data, max + 1);
        if (tmp == NULL) {
            free(data);
            return NULL;
        }
    }
    *ptr = '\0';
    *sz = (ptr - data);
    return data;
}

/*
 * Exercise the Socket class.
 */
void android::TestSockets(void)
{
    printf("----- SOCKET TEST ------\n");
    Socket::bootInit();

    char* buf = NULL;
    int len, cc;
    const char* kTestStr =
        "GET / HTTP/1.0\n"
        "Connection: close\n"
        "\n";

    Socket sock;
    if (sock.connect("www.google.com", 80) != 0) {
        fprintf(stderr, "socket connected failed\n");
        goto bail;
    }

    cc = sock.write(kTestStr, strlen(kTestStr));
    if (cc != (int) strlen(kTestStr)) {
        fprintf(stderr, "write failed, res=%d\n", cc);
        goto bail;
    }
    buf = socketReadAll(sock, &len);

    printf("GOT '%s'\n", buf);

bail:
    sock.close();
    free(buf);
}
Loading