mirror of
https://github.com/libretro/libretro-common.git
synced 2024-11-27 10:20:53 +00:00
Resync
This commit is contained in:
parent
fe8ba5671b
commit
74753e8840
@ -112,7 +112,7 @@ static int file_archive_extract_cb(const char *name, const char *valid_exts,
|
||||
}
|
||||
|
||||
if (userdata->extraction_directory)
|
||||
fill_pathname_join(new_path, userdata->extraction_directory,
|
||||
fill_pathname_join_special(new_path, userdata->extraction_directory,
|
||||
path_basename(name), sizeof(new_path));
|
||||
else
|
||||
fill_pathname_resolve_relative(new_path, userdata->archive_path,
|
||||
|
147
file/file_path.c
147
file/file_path.c
@ -30,7 +30,6 @@
|
||||
|
||||
#include <boolean.h>
|
||||
#include <file/file_path.h>
|
||||
#include <retro_assert.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <string/stdstring.h>
|
||||
#include <time/rtime.h>
|
||||
@ -278,8 +277,10 @@ bool path_is_compressed_file(const char* path)
|
||||
* out_path = "/foo/bar/baz/boo.asm"
|
||||
* E.g.: in_path = "/foo/bar/baz/boo.c", replace = "" =>
|
||||
* out_path = "/foo/bar/baz/boo"
|
||||
*
|
||||
* @return Length of the string copied into @out
|
||||
*/
|
||||
void fill_pathname(char *out_path, const char *in_path,
|
||||
size_t fill_pathname(char *out_path, const char *in_path,
|
||||
const char *replace, size_t size)
|
||||
{
|
||||
char tmp_path[PATH_MAX_LENGTH];
|
||||
@ -289,7 +290,7 @@ void fill_pathname(char *out_path, const char *in_path,
|
||||
*tok = '\0';
|
||||
|
||||
strlcpy(out_path, tmp_path, size);
|
||||
strlcat(out_path, replace, size);
|
||||
return strlcat(out_path, replace, size);
|
||||
}
|
||||
|
||||
|
||||
@ -516,8 +517,10 @@ size_t fill_dated_filename(char *out_filename,
|
||||
*
|
||||
* E.g.:
|
||||
* out_filename = "RetroArch-{year}{month}{day}-{Hour}{Minute}{Second}.{@ext}"
|
||||
*
|
||||
* @return Length of the string copied into @out_path
|
||||
**/
|
||||
void fill_str_dated_filename(char *out_filename,
|
||||
size_t fill_str_dated_filename(char *out_filename,
|
||||
const char *in_str, const char *ext, size_t size)
|
||||
{
|
||||
char format[NAME_MAX_LENGTH];
|
||||
@ -530,14 +533,11 @@ void fill_str_dated_filename(char *out_filename,
|
||||
if (string_is_empty(ext))
|
||||
{
|
||||
strftime(format, sizeof(format), "-%y%m%d-%H%M%S", &tm_);
|
||||
strlcat(out_filename, format, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
strftime(format, sizeof(format), "-%y%m%d-%H%M%S.", &tm_);
|
||||
strlcat(out_filename, format, size);
|
||||
strlcat(out_filename, ext, size);
|
||||
return strlcat(out_filename, format, size);
|
||||
}
|
||||
strftime(format, sizeof(format), "-%y%m%d-%H%M%S.", &tm_);
|
||||
strlcat(out_filename, format, size);
|
||||
return strlcat(out_filename, ext, size);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -829,6 +829,8 @@ end:
|
||||
* Both @path and @base are assumed to be absolute paths without "." or "..".
|
||||
*
|
||||
* E.g. path /a/b/e/f.cg with base /a/b/c/d/ turns into ../../e/f.cg
|
||||
*
|
||||
* @return Length of the string copied into @out
|
||||
**/
|
||||
size_t path_relative_to(char *out,
|
||||
const char *path, const char *base, size_t size)
|
||||
@ -906,13 +908,44 @@ void fill_pathname_resolve_relative(char *out_path,
|
||||
* Joins a directory (@dir) and path (@path) together.
|
||||
* Makes sure not to get two consecutive slashes
|
||||
* between directory and path.
|
||||
*
|
||||
* Deprecated. Use fill_pathname_join_special() instead
|
||||
* if you can ensure @dir and @out_path won't overlap.
|
||||
*
|
||||
* @return Length of the string copied into @out_path
|
||||
**/
|
||||
size_t fill_pathname_join(char *out_path,
|
||||
const char *dir, const char *path, size_t size)
|
||||
{
|
||||
size_t len = 0;
|
||||
if (out_path != dir)
|
||||
len = strlcpy(out_path, dir, size);
|
||||
strlcpy(out_path, dir, size);
|
||||
if (*out_path)
|
||||
fill_pathname_slash(out_path, size);
|
||||
return strlcat(out_path, path, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* fill_pathname_join_special:
|
||||
* @out_path : output path
|
||||
* @dir : directory. Cannot be identical to @out_path
|
||||
* @path : path
|
||||
* @size : size of output path
|
||||
*
|
||||
*
|
||||
* Specialized version of fill_pathname_join.
|
||||
* Unlike fill_pathname_join(),
|
||||
* @dir and @out_path CANNOT be identical.
|
||||
*
|
||||
* Joins a directory (@dir) and path (@path) together.
|
||||
* Makes sure not to get two consecutive slashes
|
||||
* between directory and path.
|
||||
*
|
||||
* @return Length of the string copied into @out_path
|
||||
**/
|
||||
size_t fill_pathname_join_special(char *out_path,
|
||||
const char *dir, const char *path, size_t size)
|
||||
{
|
||||
size_t len = strlcpy(out_path, dir, size);
|
||||
|
||||
if (*out_path)
|
||||
{
|
||||
@ -927,7 +960,10 @@ size_t fill_pathname_join(char *out_path,
|
||||
}
|
||||
}
|
||||
else
|
||||
strlcat(out_path, PATH_DEFAULT_SLASH(), size);
|
||||
{
|
||||
out_path[len] = PATH_DEFAULT_SLASH_C();
|
||||
out_path[len+1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return strlcat(out_path, path, size);
|
||||
@ -975,59 +1011,35 @@ size_t fill_pathname_join_delim(char *out_path, const char *dir,
|
||||
return copied;
|
||||
}
|
||||
|
||||
void fill_pathname_expand_special(char *out_path,
|
||||
size_t fill_pathname_expand_special(char *out_path,
|
||||
const char *in_path, size_t size)
|
||||
{
|
||||
#if !defined(RARCH_CONSOLE) && defined(RARCH_INTERNAL)
|
||||
char *app_dir = NULL;
|
||||
if (in_path[0] == '~')
|
||||
{
|
||||
char *home_dir = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
fill_pathname_home_dir(home_dir,
|
||||
PATH_MAX_LENGTH * sizeof(char));
|
||||
|
||||
if (*home_dir)
|
||||
{
|
||||
size_t src_size = strlcpy(out_path, home_dir, size);
|
||||
retro_assert(src_size < size);
|
||||
|
||||
out_path += src_size;
|
||||
size -= src_size;
|
||||
|
||||
if (!PATH_CHAR_IS_SLASH(out_path[-1]))
|
||||
{
|
||||
src_size = strlcpy(out_path, PATH_DEFAULT_SLASH(), size);
|
||||
retro_assert(src_size < size);
|
||||
|
||||
out_path += src_size;
|
||||
size -= src_size;
|
||||
}
|
||||
|
||||
in_path += 2;
|
||||
}
|
||||
|
||||
free(home_dir);
|
||||
app_dir = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
fill_pathname_home_dir(app_dir, PATH_MAX_LENGTH * sizeof(char));
|
||||
}
|
||||
else if (in_path[0] == ':')
|
||||
{
|
||||
char *application_dir = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
app_dir = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
app_dir[0] = '\0';
|
||||
fill_pathname_application_dir(app_dir, PATH_MAX_LENGTH * sizeof(char));
|
||||
}
|
||||
|
||||
application_dir[0] = '\0';
|
||||
|
||||
fill_pathname_application_dir(application_dir,
|
||||
PATH_MAX_LENGTH * sizeof(char));
|
||||
|
||||
if (*application_dir)
|
||||
if (app_dir)
|
||||
{
|
||||
if (*app_dir)
|
||||
{
|
||||
size_t src_size = strlcpy(out_path, application_dir, size);
|
||||
retro_assert(src_size < size);
|
||||
size_t src_size = strlcpy(out_path, app_dir, size);
|
||||
|
||||
out_path += src_size;
|
||||
size -= src_size;
|
||||
out_path += src_size;
|
||||
size -= src_size;
|
||||
|
||||
if (!PATH_CHAR_IS_SLASH(out_path[-1]))
|
||||
{
|
||||
src_size = strlcpy(out_path, PATH_DEFAULT_SLASH(), size);
|
||||
retro_assert(src_size < size);
|
||||
src_size = strlcpy(out_path, PATH_DEFAULT_SLASH(), size);
|
||||
|
||||
out_path += src_size;
|
||||
size -= src_size;
|
||||
@ -1036,14 +1048,13 @@ void fill_pathname_expand_special(char *out_path,
|
||||
in_path += 2;
|
||||
}
|
||||
|
||||
free(application_dir);
|
||||
free(app_dir);
|
||||
}
|
||||
#endif
|
||||
|
||||
retro_assert(strlcpy(out_path, in_path, size) < size);
|
||||
return strlcpy(out_path, in_path, size);
|
||||
}
|
||||
|
||||
void fill_pathname_abbreviate_special(char *out_path,
|
||||
size_t fill_pathname_abbreviate_special(char *out_path,
|
||||
const char *in_path, size_t size)
|
||||
{
|
||||
#if !defined(RARCH_CONSOLE) && defined(RARCH_INTERNAL)
|
||||
@ -1080,8 +1091,6 @@ void fill_pathname_abbreviate_special(char *out_path,
|
||||
{
|
||||
size_t src_size = strlcpy(out_path, notations[i], size);
|
||||
|
||||
retro_assert(src_size < size);
|
||||
|
||||
out_path += src_size;
|
||||
size -= src_size;
|
||||
in_path += strlen(candidates[i]);
|
||||
@ -1096,10 +1105,8 @@ void fill_pathname_abbreviate_special(char *out_path,
|
||||
break; /* Don't allow more abbrevs to take place. */
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
retro_assert(strlcpy(out_path, in_path, size) < size);
|
||||
return strlcpy(out_path, in_path, size);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1174,8 +1181,10 @@ static int get_pathname_num_slashes(const char *in_path)
|
||||
* If lengths of abbreviated and relative paths are the same,
|
||||
* the relative path will be used
|
||||
* @in_path can be an absolute, relative or abbreviated path
|
||||
*
|
||||
* @return Length of the string copied into @out_path
|
||||
**/
|
||||
void fill_pathname_abbreviated_or_relative(char *out_path,
|
||||
size_t fill_pathname_abbreviated_or_relative(char *out_path,
|
||||
const char *in_refpath, const char *in_path, size_t size)
|
||||
{
|
||||
char in_path_conformed[PATH_MAX_LENGTH];
|
||||
@ -1220,9 +1229,8 @@ void fill_pathname_abbreviated_or_relative(char *out_path,
|
||||
/* Use the shortest path, preferring the relative path*/
|
||||
if ( get_pathname_num_slashes(relative_path) <=
|
||||
get_pathname_num_slashes(abbreviated_path))
|
||||
retro_assert(strlcpy(out_path, relative_path, size) < size);
|
||||
else
|
||||
retro_assert(strlcpy(out_path, abbreviated_path, size) < size);
|
||||
return strlcpy(out_path, relative_path, size);
|
||||
return strlcpy(out_path, abbreviated_path, size);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1306,8 +1314,9 @@ void fill_pathname_application_path(char *s, size_t len)
|
||||
char resolved_bundle_dir_buf[PATH_MAX_LENGTH] = {0};
|
||||
if (realpath(s, resolved_bundle_dir_buf))
|
||||
{
|
||||
strlcpy(s, resolved_bundle_dir_buf, len - 1);
|
||||
strlcat(s, "/", len);
|
||||
size_t _len = strlcpy(s, resolved_bundle_dir_buf, len - 1);
|
||||
s[_len ] = '/';
|
||||
s[_len+1] = '\0';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1317,7 +1326,7 @@ void fill_pathname_application_path(char *s, size_t len)
|
||||
#ifndef HAVE_COCOATOUCH
|
||||
/* Not sure what this does but it breaks
|
||||
* stuff for iOS, so skipping */
|
||||
retro_assert(strlcat(s, "nobin", len) < len);
|
||||
strlcat(s, "nobin", len);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
@ -225,6 +225,8 @@ char *path_resolve_realpath(char *buf, size_t size, bool resolve_symlinks);
|
||||
* Both @path and @base are assumed to be absolute paths without "." or "..".
|
||||
*
|
||||
* E.g. path /a/b/e/f.cgp with base /a/b/c/d/ turns into ../../e/f.cgp
|
||||
*
|
||||
* @return Length of the string copied into @out
|
||||
**/
|
||||
size_t path_relative_to(char *out, const char *path, const char *base,
|
||||
size_t size);
|
||||
@ -264,8 +266,10 @@ bool path_is_absolute(const char *path);
|
||||
* - calls strlcpy 2x
|
||||
* - calls strrchr
|
||||
* - calls strlcat
|
||||
*
|
||||
* @return Length of the string copied into @out
|
||||
*/
|
||||
void fill_pathname(char *out_path, const char *in_path,
|
||||
size_t fill_pathname(char *out_path, const char *in_path,
|
||||
const char *replace, size_t size);
|
||||
|
||||
/**
|
||||
@ -309,8 +313,10 @@ size_t fill_dated_filename(char *out_filename,
|
||||
* - Calls string_is_empty()
|
||||
* - Calls strftime
|
||||
* - Calls strlcat at least 2x
|
||||
*
|
||||
* @return Length of the string copied into @out_path
|
||||
**/
|
||||
void fill_str_dated_filename(char *out_filename,
|
||||
size_t fill_str_dated_filename(char *out_filename,
|
||||
const char *in_str, const char *ext, size_t size);
|
||||
|
||||
/**
|
||||
@ -451,12 +457,43 @@ void fill_pathname_resolve_relative(char *out_path, const char *in_refpath,
|
||||
*
|
||||
* Hidden non-leaf function cost:
|
||||
* - calls strlcpy
|
||||
* - calls find_last_slash()
|
||||
* - calls fill_pathname_slash()
|
||||
* - calls strlcat
|
||||
*
|
||||
* Deprecated. Use fill_pathname_join_special() instead
|
||||
* if you can ensure @dir != @out_path
|
||||
*
|
||||
* @return Length of the string copied into @out_path
|
||||
**/
|
||||
size_t fill_pathname_join(char *out_path, const char *dir,
|
||||
const char *path, size_t size);
|
||||
|
||||
/**
|
||||
* fill_pathname_join_special:
|
||||
* @out_path : output path
|
||||
* @dir : directory. Cannot be identical to @out_path
|
||||
* @path : path
|
||||
* @size : size of output path
|
||||
*
|
||||
*
|
||||
* Specialized version of fill_pathname_join.
|
||||
* Unlike fill_pathname_join(),
|
||||
* @dir and @out_path CANNOT be identical.
|
||||
*
|
||||
* Joins a directory (@dir) and path (@path) together.
|
||||
* Makes sure not to get two consecutive slashes
|
||||
* between directory and path.
|
||||
*
|
||||
* Hidden non-leaf function cost:
|
||||
* - calls strlcpy
|
||||
* - calls find_last_slash()
|
||||
* - calls strlcat
|
||||
*
|
||||
* @return Length of the string copied into @out_path
|
||||
**/
|
||||
size_t fill_pathname_join_special(char *out_path,
|
||||
const char *dir, const char *path, size_t size);
|
||||
|
||||
size_t fill_pathname_join_special_ext(char *out_path,
|
||||
const char *dir, const char *path,
|
||||
const char *last, const char *ext,
|
||||
@ -481,10 +518,10 @@ size_t fill_pathname_join_special_ext(char *out_path,
|
||||
size_t fill_pathname_join_delim(char *out_path, const char *dir,
|
||||
const char *path, const char delim, size_t size);
|
||||
|
||||
void fill_pathname_expand_special(char *out_path,
|
||||
size_t fill_pathname_expand_special(char *out_path,
|
||||
const char *in_path, size_t size);
|
||||
|
||||
void fill_pathname_abbreviate_special(char *out_path,
|
||||
size_t fill_pathname_abbreviate_special(char *out_path,
|
||||
const char *in_path, size_t size);
|
||||
|
||||
/**
|
||||
@ -496,8 +533,10 @@ void fill_pathname_abbreviate_special(char *out_path,
|
||||
* If lengths of abbreviated and relative paths are the same,
|
||||
* the relative path will be used
|
||||
* @in_path can be an absolute, relative or abbreviated path
|
||||
*
|
||||
* @return Length of the string copied into @out_path
|
||||
**/
|
||||
void fill_pathname_abbreviated_or_relative(char *out_path,
|
||||
size_t fill_pathname_abbreviated_or_relative(char *out_path,
|
||||
const char *in_refpath, const char *in_path, size_t size);
|
||||
|
||||
/**
|
||||
|
@ -20,33 +20,30 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LIBRETRO_SDK_NET_COMPAT_H__
|
||||
#define LIBRETRO_SDK_NET_COMPAT_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#ifndef _LIBRETRO_SDK_NET_COMPAT_H
|
||||
#define _LIBRETRO_SDK_NET_COMPAT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <boolean.h>
|
||||
#include <retro_inline.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#ifndef MSG_NOSIGNAL
|
||||
#define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
|
||||
#if _WIN32_WINNT >= 0x0600
|
||||
#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600
|
||||
#define NETWORK_HAVE_POLL 1
|
||||
#endif
|
||||
|
||||
@ -56,43 +53,11 @@
|
||||
#include <xtl.h>
|
||||
#include <io.h>
|
||||
|
||||
#define socklen_t int
|
||||
|
||||
#ifndef SO_KEEPALIVE
|
||||
#define SO_KEEPALIVE 0 /* verify if correct */
|
||||
#endif
|
||||
|
||||
struct hostent
|
||||
{
|
||||
char *h_name;
|
||||
char **h_aliases;
|
||||
int h_addrtype;
|
||||
int h_length;
|
||||
char **h_addr_list;
|
||||
char *h_addr;
|
||||
char *h_end;
|
||||
};
|
||||
|
||||
#elif defined(GEKKO)
|
||||
#include <network.h>
|
||||
|
||||
#define NETWORK_HAVE_POLL 1
|
||||
|
||||
#define pollfd pollsd
|
||||
|
||||
#define socket(a,b,c) net_socket(a,b,c)
|
||||
#define getsockopt(a,b,c,d,e) net_getsockopt(a,b,c,d,e)
|
||||
#define setsockopt(a,b,c,d,e) net_setsockopt(a,b,c,d,e)
|
||||
#define bind(a,b,c) net_bind(a,b,c)
|
||||
#define listen(a,b) net_listen(a,b)
|
||||
#define accept(a,b,c) net_accept(a,b,c)
|
||||
#define connect(a,b,c) net_connect(a,b,c)
|
||||
#define send(a,b,c,d) net_send(a,b,c,d)
|
||||
#define sendto(a,b,c,d,e,f) net_sendto(a,b,c,d,e,f)
|
||||
#define recv(a,b,c,d) net_recv(a,b,c,d)
|
||||
#define recvfrom(a,b,c,d,e,f) net_recvfrom(a,b,c,d,e,f)
|
||||
#define select(a,b,c,d,e) net_select(a,b,c,d,e)
|
||||
#define gethostbyname(a) net_gethostbyname(a)
|
||||
#define socklen_t unsigned int
|
||||
|
||||
#elif defined(VITA)
|
||||
#include <psp2/net/net.h>
|
||||
@ -136,8 +101,9 @@ struct hostent
|
||||
#define POLLHUP SCE_NET_EPOLLHUP
|
||||
#define POLLNVAL 0
|
||||
|
||||
#define sockaddr_in SceNetSockaddrIn
|
||||
#define sockaddr SceNetSockaddr
|
||||
#define sockaddr_in SceNetSockaddrIn
|
||||
#define in_addr SceNetInAddr
|
||||
#define socklen_t unsigned int
|
||||
|
||||
#define socket(a,b,c) sceNetSocket("unknown",a,b,c)
|
||||
@ -156,34 +122,36 @@ struct hostent
|
||||
#define ntohl sceNetNtohl
|
||||
#define htons sceNetHtons
|
||||
#define ntohs sceNetNtohs
|
||||
#define inet_ntop sceNetInetNtop
|
||||
#define inet_pton sceNetInetPton
|
||||
|
||||
struct pollfd
|
||||
{
|
||||
int fd;
|
||||
unsigned events;
|
||||
unsigned revents;
|
||||
unsigned __pad; /* Align to 64-bits boundary */
|
||||
};
|
||||
#elif defined(GEKKO)
|
||||
#include <network.h>
|
||||
|
||||
struct hostent
|
||||
{
|
||||
char *h_name;
|
||||
char **h_aliases;
|
||||
int h_addrtype;
|
||||
int h_length;
|
||||
char **h_addr_list;
|
||||
char *h_addr;
|
||||
char *h_end;
|
||||
};
|
||||
#define NETWORK_HAVE_POLL 1
|
||||
|
||||
struct SceNetInAddr inet_aton(const char *ip_addr);
|
||||
#define pollfd pollsd
|
||||
|
||||
#define socket(a,b,c) net_socket(a,b,c)
|
||||
#define getsockopt(a,b,c,d,e) net_getsockopt(a,b,c,d,e)
|
||||
#define setsockopt(a,b,c,d,e) net_setsockopt(a,b,c,d,e)
|
||||
#define bind(a,b,c) net_bind(a,b,c)
|
||||
#define listen(a,b) net_listen(a,b)
|
||||
#define accept(a,b,c) net_accept(a,b,c)
|
||||
#define connect(a,b,c) net_connect(a,b,c)
|
||||
#define send(a,b,c,d) net_send(a,b,c,d)
|
||||
#define sendto(a,b,c,d,e,f) net_sendto(a,b,c,d,e,f)
|
||||
#define recv(a,b,c,d) net_recv(a,b,c,d)
|
||||
#define recvfrom(a,b,c,d,e,f) net_recvfrom(a,b,c,d,e,f)
|
||||
#define select(a,b,c,d,e) net_select(a,b,c,d,e)
|
||||
#define gethostbyname(a) net_gethostbyname(a)
|
||||
|
||||
#else
|
||||
#include <sys/select.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#ifndef __PSL1GHT__
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
@ -199,17 +167,16 @@ struct SceNetInAddr inet_aton(const char *ip_addr);
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIIU
|
||||
#define WIIU_RCVBUF (128 * 2 * 1024)
|
||||
#define WIIU_SNDBUF (128 * 2 * 1024)
|
||||
#endif
|
||||
|
||||
#if defined(__PSL1GHT__)
|
||||
#include <net/poll.h>
|
||||
|
||||
#define NETWORK_HAVE_POLL 1
|
||||
|
||||
#elif !defined(WIIU) && !defined(__PS3__)
|
||||
#elif defined(WIIU)
|
||||
#define WIIU_RCVBUF 0x40000
|
||||
#define WIIU_SNDBUF 0x40000
|
||||
|
||||
#elif !defined(__PS3__)
|
||||
#include <poll.h>
|
||||
|
||||
#define NETWORK_HAVE_POLL 1
|
||||
@ -217,13 +184,6 @@ struct SceNetInAddr inet_aton(const char *ip_addr);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef MSG_NOSIGNAL
|
||||
#define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
@ -242,18 +202,55 @@ struct SceNetInAddr inet_aton(const char *ip_addr);
|
||||
#define NET_POLL_HAS_EVENT(sockev, sockfds) ((sockfds)->revents & (sockev))
|
||||
#endif
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
/* Compatibility layer for legacy or incomplete BSD socket implementations.
|
||||
* Only for IPv4. Mostly useful for the consoles which do not support
|
||||
* anything reasonably modern on the socket API side of things. */
|
||||
#ifdef HAVE_SOCKET_LEGACY
|
||||
|
||||
#define sockaddr_storage sockaddr_in
|
||||
#define addrinfo addrinfo_retro__
|
||||
|
||||
#ifndef AI_PASSIVE
|
||||
#define AI_PASSIVE 1
|
||||
#ifdef AI_PASSIVE
|
||||
#undef AI_PASSIVE
|
||||
#endif
|
||||
#ifdef AI_CANONNAME
|
||||
#undef AI_CANONNAME
|
||||
#endif
|
||||
#ifdef AI_NUMERICHOST
|
||||
#undef AI_NUMERICHOST
|
||||
#endif
|
||||
#ifdef AI_NUMERICSERV
|
||||
#undef AI_NUMERICSERV
|
||||
#endif
|
||||
|
||||
#ifdef NI_NUMERICHOST
|
||||
#undef NI_NUMERICHOST
|
||||
#endif
|
||||
#ifdef NI_NUMERICSERV
|
||||
#undef NI_NUMERICSERV
|
||||
#endif
|
||||
#ifdef NI_NOFQDN
|
||||
#undef NI_NOFQDN
|
||||
#endif
|
||||
#ifdef NI_NAMEREQD
|
||||
#undef NI_NAMEREQD
|
||||
#endif
|
||||
#ifdef NI_DGRAM
|
||||
#undef NI_DGRAM
|
||||
#endif
|
||||
|
||||
#define AI_PASSIVE 1
|
||||
#define AI_CANONNAME 2
|
||||
#define AI_NUMERICHOST 4
|
||||
#define AI_NUMERICSERV 8
|
||||
|
||||
#define NI_NUMERICHOST 1
|
||||
#define NI_NUMERICSERV 2
|
||||
#define NI_NOFQDN 4
|
||||
#define NI_NAMEREQD 8
|
||||
#define NI_DGRAM 16
|
||||
|
||||
#ifndef __PS3__
|
||||
struct addrinfo
|
||||
{
|
||||
int ai_flags;
|
||||
@ -265,50 +262,137 @@ struct addrinfo
|
||||
char *ai_canonname;
|
||||
struct addrinfo *ai_next;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* gai_strerror() not used, so we skip that. */
|
||||
|
||||
#else
|
||||
/* Ensure that getaddrinfo and getnameinfo flags are always defined. */
|
||||
#ifndef AI_PASSIVE
|
||||
#define AI_PASSIVE 0
|
||||
#endif
|
||||
#ifndef AI_CANONNAME
|
||||
#define AI_CANONNAME 0
|
||||
#endif
|
||||
#ifndef AI_NUMERICHOST
|
||||
#define AI_NUMERICHOST 0
|
||||
#endif
|
||||
#ifndef AI_NUMERICSERV
|
||||
#define AI_NUMERICSERV 0
|
||||
#endif
|
||||
|
||||
static INLINE bool isagain(int bytes)
|
||||
#ifndef NI_NUMERICHOST
|
||||
#define NI_NUMERICHOST 0
|
||||
#endif
|
||||
#ifndef NI_NUMERICSERV
|
||||
#define NI_NUMERICSERV 0
|
||||
#endif
|
||||
#ifndef NI_NOFQDN
|
||||
#define NI_NOFQDN 0
|
||||
#endif
|
||||
#ifndef NI_NAMEREQD
|
||||
#define NI_NAMEREQD 0
|
||||
#endif
|
||||
#ifndef NI_DGRAM
|
||||
#define NI_DGRAM 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_XBOX)
|
||||
struct hostent
|
||||
{
|
||||
char *h_name;
|
||||
char **h_aliases;
|
||||
int h_addrtype;
|
||||
int h_length;
|
||||
char **h_addr_list;
|
||||
char *h_addr;
|
||||
char *h_end;
|
||||
};
|
||||
|
||||
#elif defined(VITA)
|
||||
struct pollfd
|
||||
{
|
||||
int fd;
|
||||
unsigned events;
|
||||
unsigned revents;
|
||||
unsigned __pad; /* Align to 64-bits boundary */
|
||||
};
|
||||
|
||||
struct hostent
|
||||
{
|
||||
char *h_name;
|
||||
char **h_aliases;
|
||||
int h_addrtype;
|
||||
int h_length;
|
||||
char **h_addr_list;
|
||||
char *h_addr;
|
||||
char *h_end;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static INLINE bool isagain(int val)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return (bytes == SOCKET_ERROR) && (WSAGetLastError() == WSAEWOULDBLOCK);
|
||||
return (val == SOCKET_ERROR) && (WSAGetLastError() == WSAEWOULDBLOCK);
|
||||
#elif !defined(__PSL1GHT__) && defined(__PS3__)
|
||||
return (sys_net_errno == SYS_NET_EAGAIN) || (sys_net_errno == SYS_NET_EWOULDBLOCK);
|
||||
#elif defined(VITA)
|
||||
return (bytes == SCE_NET_ERROR_EAGAIN) || (bytes == SCE_NET_ERROR_EWOULDBLOCK);
|
||||
return (val == SCE_NET_ERROR_EAGAIN) || (val == SCE_NET_ERROR_EWOULDBLOCK);
|
||||
#elif defined(WIIU)
|
||||
return (bytes == -1) && (socketlasterr() == SO_SUCCESS || socketlasterr() == SO_EWOULDBLOCK);
|
||||
return (val == -1) && (socketlasterr() == SO_SUCCESS || socketlasterr() == SO_EWOULDBLOCK);
|
||||
#else
|
||||
return (bytes < 0) && (errno == EAGAIN || errno == EWOULDBLOCK);
|
||||
return (val < 0) && (errno == EAGAIN || errno == EWOULDBLOCK);
|
||||
#endif
|
||||
}
|
||||
|
||||
static INLINE bool isinprogress(int bytes)
|
||||
static INLINE bool isinprogress(int val)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return (bytes == SOCKET_ERROR) && (WSAGetLastError() == WSAEWOULDBLOCK);
|
||||
return (val == SOCKET_ERROR) && (WSAGetLastError() == WSAEWOULDBLOCK);
|
||||
#elif !defined(__PSL1GHT__) && defined(__PS3__)
|
||||
return (sys_net_errno == SYS_NET_EINPROGRESS);
|
||||
#elif defined(VITA)
|
||||
return (bytes == SCE_NET_ERROR_EINPROGRESS);
|
||||
return (val == SCE_NET_ERROR_EINPROGRESS);
|
||||
#elif defined(WIIU)
|
||||
return (bytes == -1) && (socketlasterr() == SO_SUCCESS || socketlasterr() == SO_EWOULDBLOCK);
|
||||
return (val == -1) && (socketlasterr() == SO_EINPROGRESS);
|
||||
#else
|
||||
return (bytes < 0) && (errno == EINPROGRESS);
|
||||
return (val < 0) && (errno == EINPROGRESS);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t inet_htons(uint16_t hostshort);
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600
|
||||
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
|
||||
int inet_pton(int af, const char *src, void *dst);
|
||||
#endif
|
||||
|
||||
int inet_ptrton(int af, const char *src, void *dst);
|
||||
#elif defined(_XBOX)
|
||||
struct hostent *gethostbyname(const char *name);
|
||||
|
||||
#elif defined(VITA)
|
||||
char *inet_ntoa(struct in_addr in);
|
||||
int inet_aton(const char *cp, struct in_addr *inp);
|
||||
uint32_t inet_addr(const char *cp);
|
||||
|
||||
struct hostent *gethostbyname(const char *name);
|
||||
|
||||
#elif defined(GEKKO)
|
||||
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
|
||||
int inet_pton(int af, const char *src, void *dst);
|
||||
|
||||
#endif
|
||||
|
||||
int getaddrinfo_retro(const char *node, const char *service,
|
||||
struct addrinfo *hints, struct addrinfo **res);
|
||||
|
||||
void freeaddrinfo_retro(struct addrinfo *res);
|
||||
|
||||
int getnameinfo_retro(const struct sockaddr *addr, socklen_t addrlen,
|
||||
char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags);
|
||||
|
||||
bool addr_6to4(struct sockaddr_storage *addr);
|
||||
|
||||
/**
|
||||
@ -320,15 +404,6 @@ bool addr_6to4(struct sockaddr_storage *addr);
|
||||
**/
|
||||
bool network_init(void);
|
||||
|
||||
/**
|
||||
* network_deinit:
|
||||
*
|
||||
* Deinitialize platform specific socket libraries.
|
||||
**/
|
||||
void network_deinit(void);
|
||||
|
||||
const char *inet_ntop_compat(int af, const void *src, char *dst, socklen_t cnt);
|
||||
|
||||
bool udp_send_packet(const char *host, uint16_t port, const char *msg);
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
@ -137,7 +137,7 @@ static int dir_list_read(const char *dir,
|
||||
continue;
|
||||
}
|
||||
|
||||
fill_pathname_join(file_path, dir, name, sizeof(file_path));
|
||||
fill_pathname_join_special(file_path, dir, name, sizeof(file_path));
|
||||
|
||||
if (retro_dirent_is_dir(entry, NULL))
|
||||
{
|
||||
|
845
net/net_compat.c
845
net/net_compat.c
@ -20,20 +20,98 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <compat/strl.h>
|
||||
#include <retro_timers.h>
|
||||
|
||||
#include <net/net_compat.h>
|
||||
#include <net/net_socket.h>
|
||||
#include <retro_timers.h>
|
||||
#include <compat/strl.h>
|
||||
|
||||
#if defined(_XBOX)
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600
|
||||
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
|
||||
switch (af)
|
||||
{
|
||||
case AF_INET:
|
||||
memcpy(&((struct sockaddr_in*)&addr)->sin_addr, src,
|
||||
sizeof(struct in_addr));
|
||||
break;
|
||||
#ifdef HAVE_INET6
|
||||
case AF_INET6:
|
||||
memcpy(&((struct sockaddr_in6*)&addr)->sin6_addr, src,
|
||||
sizeof(struct in6_addr));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
addr.ss_family = af;
|
||||
if (getnameinfo((struct sockaddr*)&addr, sizeof(addr), dst, size, NULL, 0,
|
||||
NI_NUMERICHOST))
|
||||
return NULL;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
int inet_pton(int af, const char *src, void *dst)
|
||||
{
|
||||
struct addrinfo *addr = NULL;
|
||||
struct addrinfo hints = {0};
|
||||
|
||||
switch (af)
|
||||
{
|
||||
case AF_INET:
|
||||
#ifdef HAVE_INET6
|
||||
case AF_INET6:
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
hints.ai_family = af;
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
switch (getaddrinfo(src, NULL, &hints, &addr))
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case EAI_NONAME:
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!addr)
|
||||
return -1;
|
||||
|
||||
switch (af)
|
||||
{
|
||||
case AF_INET:
|
||||
memcpy(dst, &((struct sockaddr_in*)addr->ai_addr)->sin_addr,
|
||||
sizeof(struct in_addr));
|
||||
break;
|
||||
#ifdef HAVE_INET6
|
||||
case AF_INET6:
|
||||
memcpy(dst, &((struct sockaddr_in6*)addr->ai_addr)->sin6_addr,
|
||||
sizeof(struct in6_addr));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
freeaddrinfo(addr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif defined(_XBOX)
|
||||
struct hostent *gethostbyname(const char *name)
|
||||
{
|
||||
static struct in_addr addr = {0};
|
||||
@ -76,40 +154,27 @@ done:
|
||||
}
|
||||
|
||||
#elif defined(VITA)
|
||||
#define COMPAT_NET_INIT_SIZE 512*1024
|
||||
#define MAX_NAME 512
|
||||
#define COMPAT_NET_INIT_SIZE 0x80000
|
||||
|
||||
typedef uint32_t in_addr_t;
|
||||
|
||||
struct in_addr
|
||||
{
|
||||
in_addr_t s_addr;
|
||||
};
|
||||
|
||||
static void *_net_compat_net_memory = NULL;
|
||||
|
||||
char *inet_ntoa(struct SceNetInAddr in)
|
||||
char *inet_ntoa(struct in_addr in)
|
||||
{
|
||||
static char ip_addr[16];
|
||||
|
||||
if (!inet_ntop_compat(AF_INET, &in, ip_addr, sizeof(ip_addr)))
|
||||
strlcpy(ip_addr, "Invalid", sizeof(ip_addr));
|
||||
sceNetInetNtop(AF_INET, &in, ip_addr, sizeof(ip_addr));
|
||||
|
||||
return ip_addr;
|
||||
}
|
||||
|
||||
struct SceNetInAddr inet_aton(const char *ip_addr)
|
||||
int inet_aton(const char *cp, struct in_addr *inp)
|
||||
{
|
||||
SceNetInAddr inaddr;
|
||||
|
||||
inet_ptrton(AF_INET, ip_addr, &inaddr);
|
||||
|
||||
return inaddr;
|
||||
return sceNetInetPton(AF_INET, cp, inp);
|
||||
}
|
||||
|
||||
unsigned int inet_addr(const char *cp)
|
||||
uint32_t inet_addr(const char *cp)
|
||||
{
|
||||
return inet_aton(cp).s_addr;
|
||||
struct in_addr in;
|
||||
|
||||
return (sceNetInetPton(AF_INET, cp, &in) == 1) ? in.s_addr : INADDR_NONE;
|
||||
}
|
||||
|
||||
struct hostent *gethostbyname(const char *name)
|
||||
@ -144,33 +209,58 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#elif defined(GEKKO)
|
||||
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
|
||||
{
|
||||
const char *addr_str = inet_ntoa(*(struct in_addr*)src);
|
||||
|
||||
if (addr_str)
|
||||
{
|
||||
strlcpy(dst, addr_str, size);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int inet_pton(int af, const char *src, void *dst)
|
||||
{
|
||||
if (inet_aton(src, (struct in_addr*)dst))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(WIIU)
|
||||
#include <malloc.h>
|
||||
|
||||
static int _net_compat_thread_entry(int argc, const char **argv)
|
||||
{
|
||||
void *buf = memalign(128, WIIU_RCVBUF + WIIU_SNDBUF);
|
||||
|
||||
if (!buf)
|
||||
return -1;
|
||||
|
||||
somemopt(1, buf, WIIU_RCVBUF + WIIU_SNDBUF, 0);
|
||||
|
||||
free(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _net_compat_thread_cleanup(OSThread *thread, void *stack)
|
||||
{
|
||||
free(stack);
|
||||
}
|
||||
|
||||
#elif defined(_3DS)
|
||||
#include <malloc.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/services/soc.h>
|
||||
|
||||
#define SOC_ALIGN 0x1000
|
||||
#define SOC_BUFFERSIZE 0x100000
|
||||
|
||||
static u32* _net_compat_net_memory = NULL;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
int inet_aton(const char *cp, struct in_addr *inp)
|
||||
{
|
||||
uint32_t addr = 0;
|
||||
#ifndef _XBOX
|
||||
if (cp == 0 || inp == 0)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
addr = inet_addr(cp);
|
||||
if (addr == INADDR_NONE || addr == INADDR_ANY)
|
||||
return -1;
|
||||
|
||||
inp->s_addr = addr;
|
||||
return 1;
|
||||
}
|
||||
#define SOC_ALIGN 0x1000
|
||||
#define SOC_BUFFERSIZE 0x100000
|
||||
#endif
|
||||
|
||||
int getaddrinfo_retro(const char *node, const char *service,
|
||||
@ -192,30 +282,55 @@ int getaddrinfo_retro(const char *node, const char *service,
|
||||
{
|
||||
struct addrinfo *info = (struct addrinfo*)calloc(1, sizeof(*info));
|
||||
struct sockaddr_in *addr = (struct sockaddr_in*)malloc(sizeof(*addr));
|
||||
struct hostent *host = gethostbyname(node);
|
||||
|
||||
if (!info || !addr || !host || !host->h_addr)
|
||||
{
|
||||
free(addr);
|
||||
free(info);
|
||||
|
||||
return -1;
|
||||
}
|
||||
if (!info || !addr)
|
||||
goto failure;
|
||||
|
||||
info->ai_family = AF_INET;
|
||||
info->ai_socktype = hints->ai_socktype;
|
||||
info->ai_protocol = hints->ai_protocol;
|
||||
info->ai_addrlen = sizeof(*addr);
|
||||
info->ai_addr = (struct sockaddr*)addr;
|
||||
/* We ignore AI_CANONNAME; ai_canonname is always NULL. */
|
||||
|
||||
addr->sin_family = AF_INET;
|
||||
|
||||
addr->sin_family = AF_INET;
|
||||
if (service)
|
||||
addr->sin_port = inet_htons((uint16_t)strtoul(service, NULL, 10));
|
||||
memcpy(&addr->sin_addr, host->h_addr, sizeof(addr->sin_addr));
|
||||
{
|
||||
/* We can only handle numeric ports; ignore AI_NUMERICSERV. */
|
||||
char *service_end = NULL;
|
||||
uint16_t port = (uint16_t)strtoul(service, &service_end, 10);
|
||||
|
||||
if (service_end == service || *service_end)
|
||||
goto failure;
|
||||
|
||||
addr->sin_port = htons(port);
|
||||
}
|
||||
|
||||
if (hints->ai_flags & AI_NUMERICHOST)
|
||||
{
|
||||
if (!inet_aton(node, &addr->sin_addr))
|
||||
goto failure;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct hostent *host = gethostbyname(node);
|
||||
|
||||
if (!host || !host->h_addr)
|
||||
goto failure;
|
||||
|
||||
memcpy(&addr->sin_addr, host->h_addr, sizeof(addr->sin_addr));
|
||||
}
|
||||
|
||||
*res = info;
|
||||
|
||||
return 0;
|
||||
|
||||
failure:
|
||||
free(addr);
|
||||
free(info);
|
||||
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
return getaddrinfo(node, service, hints, res);
|
||||
@ -235,193 +350,37 @@ void freeaddrinfo_retro(struct addrinfo *res)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(WIIU)
|
||||
#include <malloc.h>
|
||||
|
||||
static OSThread wiiu_net_cmpt_thread;
|
||||
|
||||
static void wiiu_net_cmpt_thread_cleanup(OSThread *thread, void *stack)
|
||||
int getnameinfo_retro(const struct sockaddr *addr, socklen_t addrlen,
|
||||
char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags)
|
||||
{
|
||||
free(stack);
|
||||
}
|
||||
#ifdef HAVE_SOCKET_LEGACY
|
||||
const struct sockaddr_in *addr4 = (const struct sockaddr_in*)addr;
|
||||
|
||||
static int wiiu_net_cmpt_thread_entry(int argc, const char** argv)
|
||||
{
|
||||
const int buf_size = WIIU_RCVBUF + WIIU_SNDBUF;
|
||||
void* buf = memalign(128, buf_size);
|
||||
if (!buf) return -1;
|
||||
/* We cannot perform reverse DNS lookups here; ignore the following flags:
|
||||
NI_NAMEREQD
|
||||
NI_NOFQDN
|
||||
NI_NUMERICHOST (always enforced)
|
||||
*/
|
||||
if (host && hostlen)
|
||||
{
|
||||
const char *_host = inet_ntoa(addr4->sin_addr);
|
||||
|
||||
somemopt(1, buf, buf_size, 0);
|
||||
if (!_host)
|
||||
return -1;
|
||||
|
||||
strlcpy(host, _host, hostlen);
|
||||
}
|
||||
|
||||
/* We cannot get service names here; ignore the following flags:
|
||||
NI_DGRAM
|
||||
NI_NUMERICSERV (always enforced)
|
||||
*/
|
||||
if (serv && servlen)
|
||||
snprintf(serv, servlen, "%hu", (unsigned short)addr4->sin_port);
|
||||
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GEKKO)
|
||||
static char localip[16] = {0};
|
||||
static char gateway[16] = {0};
|
||||
static char netmask[16] = {0};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* network_init:
|
||||
*
|
||||
* Platform specific socket library initialization.
|
||||
*
|
||||
* @return true if successful, otherwise false.
|
||||
**/
|
||||
bool network_init(void)
|
||||
{
|
||||
static bool inited = false;
|
||||
|
||||
#if defined(_WIN32)
|
||||
WSADATA wsaData;
|
||||
#elif defined(__PSL1GHT__) || defined(__PS3__)
|
||||
int timeout_count = 10;
|
||||
#elif defined(WIIU)
|
||||
void* stack;
|
||||
#endif
|
||||
|
||||
if (inited)
|
||||
return true;
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData))
|
||||
goto failure;
|
||||
#elif defined(__PSL1GHT__) || defined(__PS3__)
|
||||
sysModuleLoad(SYSMODULE_NET);
|
||||
netInitialize();
|
||||
if (netCtlInit() < 0)
|
||||
goto failure;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int state;
|
||||
|
||||
if (netCtlGetState(&state) < 0)
|
||||
goto failure;
|
||||
if (state == NET_CTL_STATE_IPObtained)
|
||||
break;
|
||||
|
||||
if (!(timeout_count--))
|
||||
goto failure;
|
||||
|
||||
retro_sleep(500);
|
||||
}
|
||||
#elif defined(VITA)
|
||||
if (sceNetShowNetstat() == SCE_NET_ERROR_ENOTINIT)
|
||||
{
|
||||
SceNetInitParam param;
|
||||
|
||||
_net_compat_net_memory = malloc(COMPAT_NET_INIT_SIZE);
|
||||
if (!_net_compat_net_memory)
|
||||
goto failure;
|
||||
|
||||
param.memory = _net_compat_net_memory;
|
||||
param.size = COMPAT_NET_INIT_SIZE;
|
||||
param.flags = 0;
|
||||
if (sceNetInit(¶m) < 0)
|
||||
goto failure;
|
||||
if (sceNetCtlInit() < 0)
|
||||
goto failure;
|
||||
}
|
||||
#elif defined(GEKKO)
|
||||
if (if_config(localip, netmask, gateway, true, 10) < 0)
|
||||
goto failure;
|
||||
#elif defined(WIIU)
|
||||
stack = malloc(4096);
|
||||
if (!stack)
|
||||
goto failure;
|
||||
|
||||
socket_lib_init();
|
||||
|
||||
if (OSCreateThread(&wiiu_net_cmpt_thread, wiiu_net_cmpt_thread_entry,
|
||||
0, NULL, stack+4096, 4096, 3,
|
||||
OS_THREAD_ATTRIB_AFFINITY_ANY))
|
||||
{
|
||||
OSSetThreadName(&wiiu_net_cmpt_thread, "Network compat thread");
|
||||
OSSetThreadDeallocator(&wiiu_net_cmpt_thread,
|
||||
wiiu_net_cmpt_thread_cleanup);
|
||||
OSResumeThread(&wiiu_net_cmpt_thread);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(stack);
|
||||
goto failure;
|
||||
}
|
||||
#elif defined(_3DS)
|
||||
_net_compat_net_memory = (u32*)memalign(SOC_ALIGN, SOC_BUFFERSIZE);
|
||||
if (!_net_compat_net_memory)
|
||||
goto failure;
|
||||
|
||||
/* WIFI init */
|
||||
if (socInit(_net_compat_net_memory, SOC_BUFFERSIZE))
|
||||
goto failure;
|
||||
#else
|
||||
signal(SIGPIPE, SIG_IGN); /* Do not like SIGPIPE killing our app. */
|
||||
#endif
|
||||
|
||||
inited = true;
|
||||
|
||||
return true;
|
||||
|
||||
#if defined(_WIN32) || defined(__PSL1GHT__) || defined(__PS3__) || defined(VITA) || defined(GEKKO) || defined(WIIU) || defined(_3DS)
|
||||
failure:
|
||||
network_deinit();
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* network_deinit:
|
||||
*
|
||||
* Deinitialize platform specific socket libraries.
|
||||
**/
|
||||
void network_deinit(void)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
WSACleanup();
|
||||
#elif defined(__PSL1GHT__) || defined(__PS3__)
|
||||
netCtlTerm();
|
||||
netFinalizeNetwork();
|
||||
sysModuleUnload(SYSMODULE_NET);
|
||||
#elif defined(VITA)
|
||||
sceNetCtlTerm();
|
||||
sceNetTerm();
|
||||
|
||||
free(_net_compat_net_memory);
|
||||
_net_compat_net_memory = NULL;
|
||||
#elif defined(GEKKO) && !defined(HW_DOL)
|
||||
net_deinit();
|
||||
#elif defined(_3DS)
|
||||
socExit();
|
||||
|
||||
free(_net_compat_net_memory);
|
||||
_net_compat_net_memory = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t inet_htons(uint16_t hostshort)
|
||||
{
|
||||
#if defined(VITA)
|
||||
return sceNetHtons(hostshort);
|
||||
#else
|
||||
return htons(hostshort);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int inet_ptrton(int af, const char *src, void *dst)
|
||||
{
|
||||
#if defined(VITA)
|
||||
return sceNetInetPton(af, src, dst);
|
||||
#elif defined(GEKKO) || defined(_WIN32)
|
||||
/* TODO/FIXME - should use InetPton on Vista and later */
|
||||
return inet_aton(src, (struct in_addr*)dst);
|
||||
#else
|
||||
return inet_pton(af, src, dst);
|
||||
return getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -454,6 +413,7 @@ bool addr_6to4(struct sockaddr_storage *addr)
|
||||
port = addr6->sin6_port;
|
||||
|
||||
memset(addr, 0, sizeof(*addr));
|
||||
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = port;
|
||||
memcpy(&addr4->sin_addr, &address, sizeof(addr4->sin_addr));
|
||||
@ -462,271 +422,188 @@ bool addr_6to4(struct sockaddr_storage *addr)
|
||||
return true;
|
||||
}
|
||||
|
||||
struct in_addr6_compat
|
||||
{
|
||||
unsigned char ip_addr[16];
|
||||
};
|
||||
|
||||
#ifdef _XBOX
|
||||
|
||||
#ifndef IM_IN6ADDRSZ
|
||||
#define IM_IN6ADDRSZ 16
|
||||
#endif
|
||||
|
||||
#ifndef IM_INT16SZ
|
||||
#define IM_INT16SZ 2
|
||||
#endif
|
||||
|
||||
#ifndef IM_INADDRSZ
|
||||
#define IM_INADDRSZ 4
|
||||
#endif
|
||||
/* Taken from https://github.com/skywind3000/easenet/blob/master/inetbase.c
|
||||
*/
|
||||
|
||||
/**
|
||||
* inet_ntop4x:
|
||||
* network_init:
|
||||
*
|
||||
* Convert presentation format to network format.
|
||||
**/
|
||||
static const char *
|
||||
inet_ntop4x(const unsigned char *src, char *dst, size_t size)
|
||||
{
|
||||
char tmp[64];
|
||||
size_t len = snprintf(tmp,
|
||||
sizeof(tmp),
|
||||
"%u.%u.%u.%u", src[0], src[1], src[2], src[3]);
|
||||
|
||||
if (len >= size)
|
||||
goto error;
|
||||
|
||||
memcpy(dst, tmp, len + 1);
|
||||
return dst;
|
||||
|
||||
error:
|
||||
errno = ENOSPC;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* inet_ntop6x:
|
||||
* Platform specific socket library initialization.
|
||||
*
|
||||
* Convert presentation format to network format.
|
||||
* @return true if successful, otherwise false.
|
||||
**/
|
||||
static const char *
|
||||
inet_ntop6x(const unsigned char *src, char *dst, size_t size)
|
||||
bool network_init(void)
|
||||
{
|
||||
char tmp[64], *tp;
|
||||
int i, inc;
|
||||
struct { int base, len; } best, cur;
|
||||
unsigned int words[IM_IN6ADDRSZ / IM_INT16SZ];
|
||||
#if defined(_WIN32)
|
||||
static bool initialized = false;
|
||||
|
||||
memset(words, '\0', sizeof(words));
|
||||
best.base = best.len = 0;
|
||||
cur.base = cur.len = 0;
|
||||
|
||||
for (i = 0; i < IM_IN6ADDRSZ; i++)
|
||||
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
|
||||
for (i = 0; i < (IM_IN6ADDRSZ / IM_INT16SZ); i++)
|
||||
if (!initialized)
|
||||
{
|
||||
if (words[i] == 0)
|
||||
{
|
||||
if (cur.base == -1)
|
||||
{
|
||||
cur.base = i;
|
||||
cur.len = 1;
|
||||
}
|
||||
else cur.len++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cur.base != -1)
|
||||
{
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
cur.base = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cur.base != -1)
|
||||
{
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
}
|
||||
if (best.base != -1 && best.len < 2)
|
||||
best.base = -1;
|
||||
WSADATA wsaData;
|
||||
|
||||
tp = tmp;
|
||||
for (i = 0; i < (IM_IN6ADDRSZ / IM_INT16SZ); i++)
|
||||
{
|
||||
if (best.base != -1 && i >= best.base &&
|
||||
i < (best.base + best.len))
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData))
|
||||
{
|
||||
if (i == best.base)
|
||||
*tp++ = ':';
|
||||
continue;
|
||||
WSACleanup();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (i != 0)
|
||||
*tp++ = ':';
|
||||
if (i == 6 && best.base == 0 &&
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
#elif defined(__PSL1GHT__) || defined(__PS3__)
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
int tries;
|
||||
|
||||
sysModuleLoad(SYSMODULE_NET);
|
||||
|
||||
netInitialize();
|
||||
if (netCtlInit() < 0)
|
||||
goto failure;
|
||||
|
||||
for (tries = 10;;)
|
||||
{
|
||||
if (!inet_ntop4x(src+12, tp, sizeof(tmp) - (tp - tmp)))
|
||||
return NULL;
|
||||
tp += strlen(tp);
|
||||
break;
|
||||
int state;
|
||||
|
||||
if (netCtlGetState(&state) < 0)
|
||||
goto failure;
|
||||
if (state == NET_CTL_STATE_IPObtained)
|
||||
break;
|
||||
|
||||
if (!(--tries))
|
||||
goto failure;
|
||||
|
||||
retro_sleep(500);
|
||||
}
|
||||
inc = sprintf(tp, "%x", words[i]);
|
||||
tp += inc;
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
if (best.base != -1 && (best.base + best.len) ==
|
||||
(IM_IN6ADDRSZ / IM_INT16SZ))
|
||||
*tp++ = ':';
|
||||
return true;
|
||||
|
||||
*tp++ = '\0';
|
||||
failure:
|
||||
netCtlTerm();
|
||||
netFinalizeNetwork();
|
||||
|
||||
if ((size_t)(tp - tmp) > size)
|
||||
goto error;
|
||||
sysModuleUnload(SYSMODULE_NET);
|
||||
|
||||
memcpy(dst, tmp, tp - tmp);
|
||||
return dst;
|
||||
|
||||
error:
|
||||
errno = ENOSPC;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* isockaddr_ntop:
|
||||
*
|
||||
* Convert network format to presentation format.
|
||||
* Another inet_ntop, supports AF_INET/AF_INET6
|
||||
**/
|
||||
static const char *isockaddr_ntop(int af,
|
||||
const void *src, char *dst, size_t size)
|
||||
{
|
||||
switch (af)
|
||||
return false;
|
||||
#elif defined(VITA)
|
||||
if (sceNetShowNetstat() == SCE_NET_ERROR_ENOTINIT)
|
||||
{
|
||||
case AF_INET:
|
||||
return inet_ntop4x((const unsigned char*)src, dst, size);
|
||||
#ifdef AF_INET6
|
||||
case AF_INET6:
|
||||
return inet_ntop6x((const unsigned char*)src, dst, size);
|
||||
#endif
|
||||
default:
|
||||
if (af == -6)
|
||||
return inet_ntop6x((const unsigned char*)src, dst, size);
|
||||
errno = EAFNOSUPPORT;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
SceNetInitParam param;
|
||||
void *net_compat_memory = malloc(COMPAT_NET_INIT_SIZE);
|
||||
|
||||
const char *inet_ntop_compat(int af, const void *src, char *dst, socklen_t cnt)
|
||||
{
|
||||
#if defined(VITA)
|
||||
return sceNetInetNtop(af,src,dst,cnt);
|
||||
#elif defined(WIIU)
|
||||
return inet_ntop(af, src, dst, cnt);
|
||||
#elif defined(GEKKO)
|
||||
if (af == AF_INET)
|
||||
{
|
||||
const char *addr_str = inet_ntoa(*(struct in_addr*)src);
|
||||
if (!net_compat_memory)
|
||||
return false;
|
||||
|
||||
if (addr_str)
|
||||
{
|
||||
strlcpy(dst, addr_str, cnt);
|
||||
param.memory = net_compat_memory;
|
||||
param.size = COMPAT_NET_INIT_SIZE;
|
||||
param.flags = 0;
|
||||
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
if (sceNetInit(¶m) < 0)
|
||||
goto failure;
|
||||
if (sceNetCtlInit() < 0)
|
||||
goto failure;
|
||||
|
||||
return NULL;
|
||||
#elif defined(_XBOX)
|
||||
return isockaddr_ntop(af, src, dst, cnt);
|
||||
#elif defined(_WIN32)
|
||||
if (af == AF_INET)
|
||||
{
|
||||
struct sockaddr_in in;
|
||||
memset(&in, 0, sizeof(in));
|
||||
in.sin_family = AF_INET;
|
||||
memcpy(&in.sin_addr, src, sizeof(struct in_addr));
|
||||
getnameinfo((struct sockaddr *)&in, sizeof(struct
|
||||
sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST);
|
||||
return dst;
|
||||
}
|
||||
#if defined(AF_INET6) && !defined(HAVE_SOCKET_LEGACY)
|
||||
else if (af == AF_INET6)
|
||||
{
|
||||
struct sockaddr_in6 in;
|
||||
memset(&in, 0, sizeof(in));
|
||||
in.sin6_family = AF_INET6;
|
||||
memcpy(&in.sin6_addr, src, sizeof(struct in_addr6_compat));
|
||||
getnameinfo((struct sockaddr *)&in, sizeof(struct
|
||||
sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);
|
||||
return dst;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return NULL;
|
||||
#else
|
||||
return inet_ntop(af, src, dst, cnt);
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
|
||||
bool udp_send_packet(const char *host,
|
||||
uint16_t port, const char *msg)
|
||||
{
|
||||
char port_buf[16] = {0};
|
||||
struct addrinfo hints = {0};
|
||||
struct addrinfo *res = NULL;
|
||||
const struct addrinfo *tmp = NULL;
|
||||
int fd = -1;
|
||||
bool ret = true;
|
||||
failure:
|
||||
sceNetCtlTerm();
|
||||
sceNetTerm();
|
||||
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
free(net_compat_memory);
|
||||
|
||||
snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port);
|
||||
|
||||
if (getaddrinfo_retro(host, port_buf, &hints, &res) != 0)
|
||||
return false;
|
||||
|
||||
/* Send to all possible targets.
|
||||
* "localhost" might resolve to several different IPs. */
|
||||
tmp = (const struct addrinfo*)res;
|
||||
while (tmp)
|
||||
{
|
||||
ssize_t len, ret_len;
|
||||
|
||||
fd = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol);
|
||||
if (fd < 0)
|
||||
{
|
||||
ret = false;
|
||||
goto end;
|
||||
}
|
||||
|
||||
len = strlen(msg);
|
||||
ret_len = sendto(fd, msg, len, 0, tmp->ai_addr, tmp->ai_addrlen);
|
||||
|
||||
if (ret_len < len)
|
||||
{
|
||||
ret = false;
|
||||
goto end;
|
||||
}
|
||||
|
||||
socket_close(fd);
|
||||
fd = -1;
|
||||
tmp = tmp->ai_next;
|
||||
}
|
||||
|
||||
end:
|
||||
freeaddrinfo_retro(res);
|
||||
if (fd >= 0)
|
||||
socket_close(fd);
|
||||
return ret;
|
||||
return true;
|
||||
#elif defined(GEKKO)
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
char localip[16] = {0};
|
||||
char netmask[16] = {0};
|
||||
char gateway[16] = {0};
|
||||
|
||||
if (if_config(localip, netmask, gateway, true, 10) < 0)
|
||||
{
|
||||
net_deinit();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
#elif defined(WIIU)
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
OSThread net_compat_thread;
|
||||
void *stack = malloc(0x1000);
|
||||
|
||||
if (!stack)
|
||||
return false;
|
||||
|
||||
socket_lib_init();
|
||||
|
||||
if (!OSCreateThread(&net_compat_thread, _net_compat_thread_entry,
|
||||
0, NULL, (void*)((size_t)stack + 0x1000), 0x1000, 3,
|
||||
OS_THREAD_ATTRIB_AFFINITY_ANY))
|
||||
{
|
||||
free(stack);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
OSSetThreadName(&net_compat_thread, "Network compat thread");
|
||||
OSSetThreadDeallocator(&net_compat_thread, _net_compat_thread_cleanup);
|
||||
OSResumeThread(&net_compat_thread);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
#elif defined(_3DS)
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
u32 *net_compat_memory = (u32*)memalign(SOC_ALIGN, SOC_BUFFERSIZE);
|
||||
|
||||
if (!net_compat_memory)
|
||||
return false;
|
||||
|
||||
/* WIFI init */
|
||||
if (socInit(net_compat_memory, SOC_BUFFERSIZE))
|
||||
{
|
||||
socExit();
|
||||
|
||||
free(net_compat_memory);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
/* Do not like SIGPIPE killing our app. */
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ bool net_ifinfo_new(net_ifinfo_t *list)
|
||||
|
||||
do
|
||||
{
|
||||
if (getnameinfo(unicast_addr->Address.lpSockaddr,
|
||||
if (getnameinfo_retro(unicast_addr->Address.lpSockaddr,
|
||||
unicast_addr->Address.iSockaddrLength,
|
||||
entry->host, sizeof(entry->host), NULL, 0, NI_NUMERICHOST))
|
||||
continue;
|
||||
@ -304,7 +304,7 @@ failure:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (getnameinfo(addr->ifa_addr, addrlen,
|
||||
if (getnameinfo_retro(addr->ifa_addr, addrlen,
|
||||
entry->host, sizeof(entry->host), NULL, 0, NI_NUMERICHOST))
|
||||
continue;
|
||||
|
||||
|
@ -68,6 +68,7 @@ int socket_init(void **address, uint16_t port, const char *server,
|
||||
return -1;
|
||||
|
||||
snprintf(port_buf, sizeof(port_buf), "%hu", (unsigned short)port);
|
||||
hints.ai_flags |= AI_NUMERICSERV;
|
||||
|
||||
if (getaddrinfo_retro(server, port_buf, &hints, addrinfo))
|
||||
return -1;
|
||||
@ -686,7 +687,7 @@ int socket_connect(int fd, void *data, bool timeout_enable)
|
||||
int sendsz = WIIU_SNDBUF;
|
||||
|
||||
setsockopt(fd, SOL_SOCKET, SO_TCPSACK, &op, sizeof(op));
|
||||
setsockopt(fd, SOL_SOCKET, 0x10000, &op, sizeof(op));
|
||||
setsockopt(fd, SOL_SOCKET, SO_RUSRBUF, &op, sizeof(op));
|
||||
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &recvsz, sizeof(recvsz));
|
||||
setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sendsz, sizeof(sendsz));
|
||||
}
|
||||
@ -716,7 +717,7 @@ bool socket_connect_with_timeout(int fd, void *data, int timeout)
|
||||
int sendsz = WIIU_SNDBUF;
|
||||
|
||||
setsockopt(fd, SOL_SOCKET, SO_TCPSACK, &op, sizeof(op));
|
||||
setsockopt(fd, SOL_SOCKET, 0x10000, &op, sizeof(op));
|
||||
setsockopt(fd, SOL_SOCKET, SO_RUSRBUF, &op, sizeof(op));
|
||||
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &recvsz, sizeof(recvsz));
|
||||
setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sendsz, sizeof(sendsz));
|
||||
}
|
||||
@ -809,6 +810,9 @@ void socket_set_target(void *data, socket_target_t *in_addr)
|
||||
{
|
||||
struct sockaddr_in *out_target = (struct sockaddr_in*)data;
|
||||
|
||||
#ifdef GEKKO
|
||||
out_target->sin_len = 8;
|
||||
#endif
|
||||
switch (in_addr->domain)
|
||||
{
|
||||
case SOCKET_DOMAIN_INET:
|
||||
@ -818,13 +822,6 @@ void socket_set_target(void *data, socket_target_t *in_addr)
|
||||
out_target->sin_family = 0;
|
||||
break;
|
||||
}
|
||||
#ifndef VITA
|
||||
#ifdef GEKKO
|
||||
out_target->sin_len = 8;
|
||||
#endif
|
||||
inet_ptrton(AF_INET, in_addr->server, &out_target->sin_addr);
|
||||
#else
|
||||
out_target->sin_addr = inet_aton(in_addr->server);
|
||||
#endif
|
||||
out_target->sin_port = inet_htons(in_addr->port);
|
||||
out_target->sin_port = htons(in_addr->port);
|
||||
inet_pton(AF_INET, in_addr->server, &out_target->sin_addr);
|
||||
}
|
||||
|
@ -52,7 +52,5 @@ int main(void)
|
||||
net_http_delete(http1);
|
||||
net_http_delete(http3);
|
||||
|
||||
network_deinit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -157,10 +157,8 @@ int main(int argc, char *argv[])
|
||||
rand_str(tmp_str, sizeof(tmp_str) - 1);
|
||||
tmp_str[0] = '.';
|
||||
|
||||
out_file_path[0] = '\0';
|
||||
|
||||
if (!string_is_empty(in_file_dir))
|
||||
fill_pathname_join(out_file_path, in_file_dir,
|
||||
fill_pathname_join_special(out_file_path, in_file_dir,
|
||||
tmp_str, sizeof(out_file_path));
|
||||
else
|
||||
strlcpy(out_file_path, tmp_str, sizeof(out_file_path));
|
||||
|
@ -1158,7 +1158,7 @@ bool retro_vfs_dirent_is_dir_impl(libretro_vfs_implementation_dir *rdir)
|
||||
return false;
|
||||
#endif
|
||||
/* dirent struct doesn't have d_type, do it the slow way ... */
|
||||
fill_pathname_join(path, rdir->orig_path, retro_vfs_dirent_get_name_impl(rdir), sizeof(path));
|
||||
fill_pathname_join_special(path, rdir->orig_path, retro_vfs_dirent_get_name_impl(rdir), sizeof(path));
|
||||
if (stat(path, &buf) < 0)
|
||||
return false;
|
||||
return S_ISDIR(buf.st_mode);
|
||||
|
Loading…
Reference in New Issue
Block a user