mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-20 12:13:26 +01:00
More spm fixes
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
AM_CFLAGS = $(GLOBAL_CFLAGS)
|
||||
|
||||
noinst_LTLIBRARIES = libinternalcommon.la
|
||||
|
||||
libinternalcommon_la_LIBADD =
|
||||
libinternalcommon_la_SOURCES = \
|
||||
socket.c \
|
||||
thread.c \
|
||||
collection.c \
|
||||
socket.h \
|
||||
thread.h \
|
||||
collection.h
|
||||
|
||||
if WIN32
|
||||
libinternalcommon_la_LIBADD += -lws2_32
|
||||
endif
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* collection.c
|
||||
*
|
||||
* Copyright (C) 2009 Hector Martin <hector@marcansoft.com>
|
||||
* Copyright (C) 2009 Nikias Bassen <nikias@gmx.li>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "collection.h"
|
||||
|
||||
void collection_init(struct collection *col)
|
||||
{
|
||||
col->list = malloc(sizeof(void *));
|
||||
memset(col->list, 0, sizeof(void *));
|
||||
col->capacity = 1;
|
||||
}
|
||||
|
||||
void collection_free(struct collection *col)
|
||||
{
|
||||
free(col->list);
|
||||
col->list = NULL;
|
||||
col->capacity = 0;
|
||||
}
|
||||
|
||||
void collection_add(struct collection *col, void *element)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<col->capacity; i++) {
|
||||
if(!col->list[i]) {
|
||||
col->list[i] = element;
|
||||
return;
|
||||
}
|
||||
}
|
||||
col->list = realloc(col->list, sizeof(void*) * col->capacity * 2);
|
||||
memset(&col->list[col->capacity], 0, sizeof(void *) * col->capacity);
|
||||
col->list[col->capacity] = element;
|
||||
col->capacity *= 2;
|
||||
}
|
||||
|
||||
int collection_remove(struct collection *col, void *element)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<col->capacity; i++) {
|
||||
if(col->list[i] == element) {
|
||||
col->list[i] = NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "%s: WARNING: element %p not present in collection %p (cap %d)", __func__, element, col, col->capacity);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int collection_count(struct collection *col)
|
||||
{
|
||||
int i, cnt = 0;
|
||||
for(i=0; i<col->capacity; i++) {
|
||||
if(col->list[i])
|
||||
cnt++;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* collection.h
|
||||
*
|
||||
* Copyright (C) 2009 Hector Martin <hector@marcansoft.com>
|
||||
* Copyright (C) 2009 Nikias Bassen <nikias@gmx.li>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef COLLECTION_H
|
||||
#define COLLECTION_H
|
||||
|
||||
struct collection {
|
||||
void **list;
|
||||
int capacity;
|
||||
};
|
||||
|
||||
void collection_init(struct collection *col);
|
||||
void collection_add(struct collection *col, void *element);
|
||||
int collection_remove(struct collection *col, void *element);
|
||||
int collection_count(struct collection *col);
|
||||
void collection_free(struct collection *col);
|
||||
|
||||
#define FOREACH(var, col) \
|
||||
do { \
|
||||
int _iter; \
|
||||
for(_iter=0; _iter<(col)->capacity; _iter++) { \
|
||||
if(!(col)->list[_iter]) continue; \
|
||||
var = (col)->list[_iter];
|
||||
|
||||
#define ENDFOREACH \
|
||||
} \
|
||||
} while(0);
|
||||
|
||||
#endif
|
||||
497
Sources/libimobiledevice/dependencies/libusbmuxd/common/socket.c
Normal file
497
Sources/libimobiledevice/dependencies/libusbmuxd/common/socket.c
Normal file
@@ -0,0 +1,497 @@
|
||||
/*
|
||||
* socket.c
|
||||
*
|
||||
* Copyright (C) 2012-2018 Nikias Bassen <nikias@gmx.li>
|
||||
* Copyright (C) 2012 Martin Szulecki <m.szulecki@libimobiledevice.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
static int wsa_init = 0;
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#include "socket.h"
|
||||
|
||||
#define RECV_TIMEOUT 20000
|
||||
#define CONNECT_TIMEOUT 5000
|
||||
|
||||
#ifndef ECONNRESET
|
||||
#define ECONNRESET 108
|
||||
#endif
|
||||
|
||||
static int verbose = 0;
|
||||
|
||||
void socket_set_verbose(int level)
|
||||
{
|
||||
verbose = level;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
int socket_create_unix(const char *filename)
|
||||
{
|
||||
struct sockaddr_un name;
|
||||
int sock;
|
||||
#ifdef SO_NOSIGPIPE
|
||||
int yes = 1;
|
||||
#endif
|
||||
|
||||
// remove if still present
|
||||
unlink(filename);
|
||||
|
||||
/* Create the socket. */
|
||||
sock = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
perror("socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef SO_NOSIGPIPE
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (void*)&yes, sizeof(int)) == -1) {
|
||||
perror("setsockopt()");
|
||||
socket_close(sock);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Bind a name to the socket. */
|
||||
name.sun_family = AF_UNIX;
|
||||
strncpy(name.sun_path, filename, sizeof(name.sun_path));
|
||||
name.sun_path[sizeof(name.sun_path) - 1] = '\0';
|
||||
|
||||
if (bind(sock, (struct sockaddr*)&name, sizeof(name)) < 0) {
|
||||
perror("bind");
|
||||
socket_close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen(sock, 10) < 0) {
|
||||
perror("listen");
|
||||
socket_close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
int socket_connect_unix(const char *filename)
|
||||
{
|
||||
struct sockaddr_un name;
|
||||
int sfd = -1;
|
||||
struct stat fst;
|
||||
#ifdef SO_NOSIGPIPE
|
||||
int yes = 1;
|
||||
#endif
|
||||
int bufsize = 0x20000;
|
||||
|
||||
// check if socket file exists...
|
||||
if (stat(filename, &fst) != 0) {
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "%s: stat '%s': %s\n", __func__, filename,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
// ... and if it is a unix domain socket
|
||||
if (!S_ISSOCK(fst.st_mode)) {
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "%s: File '%s' is not a socket!\n", __func__,
|
||||
filename);
|
||||
return -1;
|
||||
}
|
||||
// make a new socket
|
||||
if ((sfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "%s: socket: %s\n", __func__, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(sfd, SOL_SOCKET, SO_SNDBUF, (void*)&bufsize, sizeof(int)) == -1) {
|
||||
perror("Could not set send buffer for socket");
|
||||
}
|
||||
|
||||
if (setsockopt(sfd, SOL_SOCKET, SO_RCVBUF, (void*)&bufsize, sizeof(int)) == -1) {
|
||||
perror("Could not set receive buffer for socket");
|
||||
}
|
||||
|
||||
#ifdef SO_NOSIGPIPE
|
||||
if (setsockopt(sfd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&yes, sizeof(int)) == -1) {
|
||||
perror("setsockopt()");
|
||||
socket_close(sfd);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
// and connect to 'filename'
|
||||
name.sun_family = AF_UNIX;
|
||||
strncpy(name.sun_path, filename, sizeof(name.sun_path));
|
||||
name.sun_path[sizeof(name.sun_path) - 1] = 0;
|
||||
|
||||
if (connect(sfd, (struct sockaddr*)&name, sizeof(name)) < 0) {
|
||||
socket_close(sfd);
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "%s: connect: %s\n", __func__,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sfd;
|
||||
}
|
||||
#endif
|
||||
|
||||
int socket_create(uint16_t port)
|
||||
{
|
||||
int sfd = -1;
|
||||
int yes = 1;
|
||||
#ifdef WIN32
|
||||
WSADATA wsa_data;
|
||||
if (!wsa_init) {
|
||||
if (WSAStartup(MAKEWORD(2,2), &wsa_data) != ERROR_SUCCESS) {
|
||||
fprintf(stderr, "WSAStartup failed!\n");
|
||||
ExitProcess(-1);
|
||||
}
|
||||
wsa_init = 1;
|
||||
}
|
||||
#endif
|
||||
struct sockaddr_in saddr;
|
||||
|
||||
if (0 > (sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) {
|
||||
perror("socket()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(int)) == -1) {
|
||||
perror("setsockopt()");
|
||||
socket_close(sfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef SO_NOSIGPIPE
|
||||
if (setsockopt(sfd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&yes, sizeof(int)) == -1) {
|
||||
perror("setsockopt()");
|
||||
socket_close(sfd);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
memset((void *) &saddr, 0, sizeof(saddr));
|
||||
saddr.sin_family = AF_INET;
|
||||
saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
saddr.sin_port = htons(port);
|
||||
|
||||
if (0 > bind(sfd, (struct sockaddr *) &saddr, sizeof(saddr))) {
|
||||
perror("bind()");
|
||||
socket_close(sfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen(sfd, 1) == -1) {
|
||||
perror("listen()");
|
||||
socket_close(sfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sfd;
|
||||
}
|
||||
|
||||
int socket_connect(const char *addr, uint16_t port)
|
||||
{
|
||||
int sfd = -1;
|
||||
int yes = 1;
|
||||
int bufsize = 0x20000;
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *result, *rp;
|
||||
char portstr[8];
|
||||
int res;
|
||||
#ifdef WIN32
|
||||
u_long l_yes = 1;
|
||||
u_long l_no = 0;
|
||||
WSADATA wsa_data;
|
||||
if (!wsa_init) {
|
||||
if (WSAStartup(MAKEWORD(2,2), &wsa_data) != ERROR_SUCCESS) {
|
||||
fprintf(stderr, "WSAStartup failed!\n");
|
||||
ExitProcess(-1);
|
||||
}
|
||||
wsa_init = 1;
|
||||
}
|
||||
#else
|
||||
int flags = 0;
|
||||
#endif
|
||||
|
||||
if (!addr) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&hints, '\0', sizeof(struct addrinfo));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = 0;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
sprintf(portstr, "%d", port);
|
||||
|
||||
res = getaddrinfo(addr, portstr, &hints, &result);
|
||||
if (res != 0) {
|
||||
fprintf(stderr, "%s: getaddrinfo: %s\n", __func__, gai_strerror(res));
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
||||
sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||
if (sfd == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(int)) == -1) {
|
||||
perror("setsockopt()");
|
||||
socket_close(sfd);
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
ioctlsocket(sfd, FIONBIO, &l_yes);
|
||||
#else
|
||||
fcntl(sfd, F_SETFL, O_NONBLOCK);
|
||||
#endif
|
||||
|
||||
if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1) {
|
||||
break;
|
||||
}
|
||||
#ifdef WIN32
|
||||
if (WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
#else
|
||||
if (errno == EINPROGRESS)
|
||||
#endif
|
||||
{
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(sfd, &fds);
|
||||
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = CONNECT_TIMEOUT / 1000;
|
||||
timeout.tv_usec = (CONNECT_TIMEOUT - (timeout.tv_sec * 1000)) * 1000;
|
||||
if (select(sfd + 1, NULL, &fds, NULL, &timeout) == 1) {
|
||||
int so_error;
|
||||
socklen_t len = sizeof(so_error);
|
||||
getsockopt(sfd, SOL_SOCKET, SO_ERROR, (void*)&so_error, &len);
|
||||
if (so_error == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
socket_close(sfd);
|
||||
}
|
||||
|
||||
freeaddrinfo(result);
|
||||
|
||||
if (rp == NULL) {
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "%s: Could not connect to %s:%d\n", __func__, addr, port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
ioctlsocket(sfd, FIONBIO, &l_no);
|
||||
#else
|
||||
flags = fcntl(sfd, F_GETFL, 0);
|
||||
fcntl(sfd, F_SETFL, flags & (~O_NONBLOCK));
|
||||
#endif
|
||||
|
||||
#ifdef SO_NOSIGPIPE
|
||||
if (setsockopt(sfd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&yes, sizeof(int)) == -1) {
|
||||
perror("setsockopt()");
|
||||
socket_close(sfd);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, (void*)&yes, sizeof(int)) == -1) {
|
||||
perror("Could not set TCP_NODELAY on socket");
|
||||
}
|
||||
|
||||
if (setsockopt(sfd, SOL_SOCKET, SO_SNDBUF, (void*)&bufsize, sizeof(int)) == -1) {
|
||||
perror("Could not set send buffer for socket");
|
||||
}
|
||||
|
||||
if (setsockopt(sfd, SOL_SOCKET, SO_RCVBUF, (void*)&bufsize, sizeof(int)) == -1) {
|
||||
perror("Could not set receive buffer for socket");
|
||||
}
|
||||
|
||||
return sfd;
|
||||
}
|
||||
|
||||
int socket_check_fd(int fd, fd_mode fdm, unsigned int timeout)
|
||||
{
|
||||
fd_set fds;
|
||||
int sret;
|
||||
int eagain;
|
||||
struct timeval to;
|
||||
struct timeval *pto;
|
||||
|
||||
if (fd < 0) {
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "ERROR: invalid fd in check_fd %d\n", fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
|
||||
sret = -1;
|
||||
|
||||
do {
|
||||
if (timeout > 0) {
|
||||
to.tv_sec = (time_t) (timeout / 1000);
|
||||
to.tv_usec = (time_t) ((timeout - (to.tv_sec * 1000)) * 1000);
|
||||
pto = &to;
|
||||
} else {
|
||||
pto = NULL;
|
||||
}
|
||||
eagain = 0;
|
||||
switch (fdm) {
|
||||
case FDM_READ:
|
||||
sret = select(fd + 1, &fds, NULL, NULL, pto);
|
||||
break;
|
||||
case FDM_WRITE:
|
||||
sret = select(fd + 1, NULL, &fds, NULL, pto);
|
||||
break;
|
||||
case FDM_EXCEPT:
|
||||
sret = select(fd + 1, NULL, NULL, &fds, pto);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sret < 0) {
|
||||
switch (errno) {
|
||||
case EINTR:
|
||||
// interrupt signal in select
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "%s: EINTR\n", __func__);
|
||||
eagain = 1;
|
||||
break;
|
||||
case EAGAIN:
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "%s: EAGAIN\n", __func__);
|
||||
break;
|
||||
default:
|
||||
if (verbose >= 2)
|
||||
fprintf(stderr, "%s: select failed: %s\n", __func__,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} while (eagain);
|
||||
|
||||
return sret;
|
||||
}
|
||||
|
||||
int socket_accept(int fd, uint16_t port)
|
||||
{
|
||||
#ifdef WIN32
|
||||
int addr_len;
|
||||
#else
|
||||
socklen_t addr_len;
|
||||
#endif
|
||||
int result;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
addr_len = sizeof(addr);
|
||||
result = accept(fd, (struct sockaddr*)&addr, &addr_len);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int socket_shutdown(int fd, int how)
|
||||
{
|
||||
return shutdown(fd, how);
|
||||
}
|
||||
|
||||
int socket_close(int fd) {
|
||||
#ifdef WIN32
|
||||
return closesocket(fd);
|
||||
#else
|
||||
return close(fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
int socket_receive(int fd, void *data, size_t length)
|
||||
{
|
||||
return socket_receive_timeout(fd, data, length, 0, RECV_TIMEOUT);
|
||||
}
|
||||
|
||||
int socket_peek(int fd, void *data, size_t length)
|
||||
{
|
||||
return socket_receive_timeout(fd, data, length, MSG_PEEK, RECV_TIMEOUT);
|
||||
}
|
||||
|
||||
int socket_receive_timeout(int fd, void *data, size_t length, int flags,
|
||||
unsigned int timeout)
|
||||
{
|
||||
int res;
|
||||
int result;
|
||||
|
||||
// check if data is available
|
||||
res = socket_check_fd(fd, FDM_READ, timeout);
|
||||
if (res <= 0) {
|
||||
return res;
|
||||
}
|
||||
// if we get here, there _is_ data available
|
||||
result = recv(fd, data, length, flags);
|
||||
if (res > 0 && result == 0) {
|
||||
// but this is an error condition
|
||||
if (verbose >= 3)
|
||||
fprintf(stderr, "%s: fd=%d recv returned 0\n", __func__, fd);
|
||||
return -ECONNRESET;
|
||||
}
|
||||
if (result < 0) {
|
||||
return -errno;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int socket_send(int fd, void *data, size_t length)
|
||||
{
|
||||
int flags = 0;
|
||||
#ifdef MSG_NOSIGNAL
|
||||
flags |= MSG_NOSIGNAL;
|
||||
#endif
|
||||
return send(fd, data, length, flags);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* socket.h
|
||||
*
|
||||
* Copyright (C) 2012 Martin Szulecki <m.szulecki@libimobiledevice.org>
|
||||
* Copyright (C) 2012 Nikias Bassen <nikias@gmx.li>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef SOCKET_SOCKET_H
|
||||
#define SOCKET_SOCKET_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
enum fd_mode {
|
||||
FDM_READ,
|
||||
FDM_WRITE,
|
||||
FDM_EXCEPT
|
||||
};
|
||||
typedef enum fd_mode fd_mode;
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#define SHUT_RD SD_READ
|
||||
#define SHUT_WR SD_WRITE
|
||||
#define SHUT_RDWR SD_BOTH
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
int socket_create_unix(const char *filename);
|
||||
int socket_connect_unix(const char *filename);
|
||||
#endif
|
||||
int socket_create(uint16_t port);
|
||||
int socket_connect(const char *addr, uint16_t port);
|
||||
int socket_check_fd(int fd, fd_mode fdm, unsigned int timeout);
|
||||
int socket_accept(int fd, uint16_t port);
|
||||
|
||||
int socket_shutdown(int fd, int how);
|
||||
int socket_close(int fd);
|
||||
|
||||
int socket_receive(int fd, void *data, size_t size);
|
||||
int socket_peek(int fd, void *data, size_t size);
|
||||
int socket_receive_timeout(int fd, void *data, size_t size, int flags,
|
||||
unsigned int timeout);
|
||||
|
||||
int socket_send(int fd, void *data, size_t size);
|
||||
|
||||
void socket_set_verbose(int level);
|
||||
|
||||
#endif /* SOCKET_SOCKET_H */
|
||||
140
Sources/libimobiledevice/dependencies/libusbmuxd/common/thread.c
Normal file
140
Sources/libimobiledevice/dependencies/libusbmuxd/common/thread.c
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* thread.c
|
||||
*
|
||||
* Copyright (c) 2012-2019 Nikias Bassen, All Rights Reserved.
|
||||
* Copyright (c) 2012 Martin Szulecki, All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include "thread.h"
|
||||
|
||||
int thread_new(THREAD_T *thread, thread_func_t thread_func, void* data)
|
||||
{
|
||||
#ifdef WIN32
|
||||
HANDLE th = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_func, data, 0, NULL);
|
||||
if (th == NULL) {
|
||||
return -1;
|
||||
}
|
||||
*thread = th;
|
||||
return 0;
|
||||
#else
|
||||
int res = pthread_create(thread, NULL, thread_func, data);
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
void thread_detach(THREAD_T thread)
|
||||
{
|
||||
#ifdef WIN32
|
||||
CloseHandle(thread);
|
||||
#else
|
||||
pthread_detach(thread);
|
||||
#endif
|
||||
}
|
||||
|
||||
void thread_free(THREAD_T thread)
|
||||
{
|
||||
#ifdef WIN32
|
||||
CloseHandle(thread);
|
||||
#endif
|
||||
}
|
||||
|
||||
int thread_join(THREAD_T thread)
|
||||
{
|
||||
/* wait for thread to complete */
|
||||
#ifdef WIN32
|
||||
return (int)WaitForSingleObject(thread, INFINITE);
|
||||
#else
|
||||
return pthread_join(thread, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
int thread_alive(THREAD_T thread)
|
||||
{
|
||||
#ifdef WIN32
|
||||
return WaitForSingleObject(thread, 0) == WAIT_TIMEOUT;
|
||||
#else
|
||||
return pthread_kill(thread, 0) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int thread_cancel(THREAD_T thread)
|
||||
{
|
||||
#ifdef WIN32
|
||||
return 0;
|
||||
#else
|
||||
#ifdef HAVE_PTHREAD_CANCEL
|
||||
return pthread_cancel(thread);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void mutex_init(mutex_t* mutex)
|
||||
{
|
||||
#ifdef WIN32
|
||||
InitializeCriticalSection(mutex);
|
||||
#else
|
||||
pthread_mutex_init(mutex, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void mutex_destroy(mutex_t* mutex)
|
||||
{
|
||||
#ifdef WIN32
|
||||
DeleteCriticalSection(mutex);
|
||||
#else
|
||||
pthread_mutex_destroy(mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void mutex_lock(mutex_t* mutex)
|
||||
{
|
||||
#ifdef WIN32
|
||||
EnterCriticalSection(mutex);
|
||||
#else
|
||||
pthread_mutex_lock(mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void mutex_unlock(mutex_t* mutex)
|
||||
{
|
||||
#ifdef WIN32
|
||||
LeaveCriticalSection(mutex);
|
||||
#else
|
||||
pthread_mutex_unlock(mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void thread_once(thread_once_t *once_control, void (*init_routine)(void))
|
||||
{
|
||||
#ifdef WIN32
|
||||
while (InterlockedExchange(&(once_control->lock), 1) != 0) {
|
||||
Sleep(1);
|
||||
}
|
||||
if (!once_control->state) {
|
||||
once_control->state = 1;
|
||||
init_routine();
|
||||
}
|
||||
InterlockedExchange(&(once_control->lock), 0);
|
||||
#else
|
||||
pthread_once(once_control, init_routine);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* thread.h
|
||||
*
|
||||
* Copyright (c) 2012-2019 Nikias Bassen, All Rights Reserved.
|
||||
* Copyright (c) 2012 Martin Szulecki, All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __THREAD_H
|
||||
#define __THREAD_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
typedef HANDLE THREAD_T;
|
||||
typedef CRITICAL_SECTION mutex_t;
|
||||
typedef volatile struct {
|
||||
LONG lock;
|
||||
int state;
|
||||
} thread_once_t;
|
||||
#define THREAD_ONCE_INIT {0, 0}
|
||||
#define THREAD_ID GetCurrentThreadId()
|
||||
#define THREAD_T_NULL (THREAD_T)NULL
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
typedef pthread_t THREAD_T;
|
||||
typedef pthread_mutex_t mutex_t;
|
||||
typedef pthread_once_t thread_once_t;
|
||||
#define THREAD_ONCE_INIT PTHREAD_ONCE_INIT
|
||||
#define THREAD_ID pthread_self()
|
||||
#define THREAD_T_NULL (THREAD_T)NULL
|
||||
#endif
|
||||
|
||||
typedef void* (*thread_func_t)(void* data);
|
||||
|
||||
int thread_new(THREAD_T* thread, thread_func_t thread_func, void* data);
|
||||
void thread_detach(THREAD_T thread);
|
||||
void thread_free(THREAD_T thread);
|
||||
int thread_join(THREAD_T thread);
|
||||
int thread_alive(THREAD_T thread);
|
||||
|
||||
int thread_cancel(THREAD_T thread);
|
||||
|
||||
#ifdef WIN32
|
||||
#undef HAVE_THREAD_CLEANUP
|
||||
#else
|
||||
#ifdef HAVE_PTHREAD_CANCEL
|
||||
#define HAVE_THREAD_CLEANUP 1
|
||||
#define thread_cleanup_push(routine, arg) pthread_cleanup_push(routine, arg)
|
||||
#define thread_cleanup_pop(execute) pthread_cleanup_pop(execute)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void mutex_init(mutex_t* mutex);
|
||||
void mutex_destroy(mutex_t* mutex);
|
||||
void mutex_lock(mutex_t* mutex);
|
||||
void mutex_unlock(mutex_t* mutex);
|
||||
|
||||
void thread_once(thread_once_t *once_control, void (*init_routine)(void));
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user