Porting library to PS3 (psl1ght)
parent
ef0ca03565
commit
c7ad0762d8
|
@ -22,6 +22,10 @@
|
|||
#include "aros_compat.h"
|
||||
#endif
|
||||
|
||||
#ifdef PS3_PPU
|
||||
#include "ps3_compat.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <win32/win32_compat.h>
|
||||
#endif
|
||||
|
|
|
@ -26,6 +26,10 @@
|
|||
#include "aros_compat.h"
|
||||
#endif
|
||||
|
||||
#ifdef PS3_PPU
|
||||
#include "ps3_compat.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <win32/win32_compat.h>
|
||||
#endif
|
||||
|
@ -2167,9 +2171,11 @@ send_nfsd_probes(struct rpc_context *rpc, struct ifconf *ifc,
|
|||
if (ifr.ifr_addr.sa_family != AF_INET) {
|
||||
continue;
|
||||
}
|
||||
#ifndef PS3_PPU
|
||||
if (ioctl(rpc_get_fd(rpc), SIOCGIFFLAGS, &ifr) < 0) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
if (!(ifr.ifr_flags & IFF_UP)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -2179,9 +2185,11 @@ send_nfsd_probes(struct rpc_context *rpc, struct ifconf *ifc,
|
|||
if (!(ifr.ifr_flags & IFF_BROADCAST)) {
|
||||
continue;
|
||||
}
|
||||
#ifndef PS3_PPU
|
||||
if (ioctl(rpc_get_fd(rpc), SIOCGIFBRDADDR, &ifr) < 0) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (getnameinfo(&ifr.ifr_broadaddr, sizeof(struct sockaddr_in),
|
||||
&bcdd[0], sizeof(bcdd), NULL, 0,
|
||||
NI_NUMERICHOST) < 0) {
|
||||
|
@ -2233,11 +2241,13 @@ nfs_find_local_servers(void)
|
|||
ifc.ifc_len = size;
|
||||
ifc.ifc_buf = malloc(size);
|
||||
memset(ifc.ifc_buf, 0, size);
|
||||
#ifndef PS3_PPU
|
||||
if (ioctl(rpc_get_fd(rpc), SIOCGIFCONF, (caddr_t)&ifc) < 0) {
|
||||
rpc_destroy_context(rpc);
|
||||
free(ifc.ifc_buf);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
for (loop=0; loop<3; loop++) {
|
||||
|
|
|
@ -33,6 +33,10 @@
|
|||
#include "aros_compat.h"
|
||||
#endif
|
||||
|
||||
#ifdef PS3_PPU
|
||||
#include "ps3_compat.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
#include "aros_compat.h"
|
||||
#endif
|
||||
|
||||
#ifdef PS3_PPU
|
||||
#include "ps3_compat.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <win32/win32_compat.h>
|
||||
#endif
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
#include "aros_compat.h"
|
||||
#endif
|
||||
|
||||
#ifdef PS3_PPU
|
||||
#include "ps3_compat.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <win32/win32_compat.h>
|
||||
#endif
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
#include "aros_compat.h"
|
||||
#endif
|
||||
|
||||
#ifdef PS3_PPU
|
||||
#include "ps3_compat.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <win32/win32_compat.h>
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
#include "aros_compat.h"
|
||||
#endif
|
||||
|
||||
#ifdef PS3_PPU
|
||||
#include "ps3_compat.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <win32/win32_compat.h>
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
#include "aros_compat.h"
|
||||
#endif
|
||||
|
||||
#ifdef PS3_PPU
|
||||
#include "ps3_compat.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <win32/win32_compat.h>
|
||||
#endif
|
||||
|
@ -663,6 +667,7 @@ rpc_connect_sockaddr_async(struct rpc_context *rpc)
|
|||
sizeof(struct sockaddr_in);
|
||||
#endif
|
||||
break;
|
||||
#ifndef PS3_PPU
|
||||
case AF_INET6:
|
||||
sin6->sin6_port = port;
|
||||
sin6->sin6_family = AF_INET6;
|
||||
|
@ -671,6 +676,7 @@ rpc_connect_sockaddr_async(struct rpc_context *rpc)
|
|||
sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
rc = bind(rpc->fd, (struct sockaddr *)&ss,
|
||||
|
@ -719,6 +725,7 @@ rpc_set_sockaddr(struct rpc_context *rpc, const char *server, int port)
|
|||
sizeof(struct sockaddr_in);
|
||||
#endif
|
||||
break;
|
||||
#ifndef PS3_PPU
|
||||
case AF_INET6:
|
||||
((struct sockaddr_in6 *)&rpc->s)->sin6_family = ai->ai_family;
|
||||
((struct sockaddr_in6 *)&rpc->s)->sin6_port = htons(port);
|
||||
|
@ -729,6 +736,7 @@ rpc_set_sockaddr(struct rpc_context *rpc, const char *server, int port)
|
|||
sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
freeaddrinfo(ai);
|
||||
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
#include <win32/win32_compat.h>
|
||||
#endif/*WIN32*/
|
||||
|
||||
#ifdef PS3_PPU
|
||||
#include "ps3_compat.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "libnfs-zdr.h"
|
||||
|
|
|
@ -21,6 +21,10 @@
|
|||
#include <sys/stat.h>
|
||||
#endif/*WIN32*/
|
||||
|
||||
#ifdef PS3_PPU
|
||||
#include "ps3_compat.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
#include <sys/stat.h>
|
||||
#endif/*WIN32*/
|
||||
|
||||
#ifdef PS3_PPU
|
||||
#include "ps3_compat.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
#include <win32/win32_compat.h>
|
||||
#endif/*WIN32*/
|
||||
|
||||
#ifdef PS3_PPU
|
||||
#include "ps3_compat.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "libnfs-zdr.h"
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
#include <win32/win32_compat.h>
|
||||
#endif/*WIN32*/
|
||||
|
||||
#ifdef PS3_PPU
|
||||
#include "ps3_compat.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "libnfs-zdr.h"
|
||||
#include "libnfs.h"
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
#---------------------------------------------------------------------------------
|
||||
# Clear the implicit built in rules
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(PSL1GHT)),)
|
||||
$(error "Please set PSL1GHT in your environment. export PSL1GHT=<path>")
|
||||
endif
|
||||
|
||||
include $(PSL1GHT)/ppu_rules
|
||||
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(PLATFORM)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export BASEDIR := $(CURDIR)
|
||||
export DEPS := $(BASEDIR)/deps
|
||||
export LIBS := $(BASEDIR)/lib
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export LIBDIR := $(LIBS)/$(PLATFORM)
|
||||
export DEPSDIR := $(DEPS)/$(PLATFORM)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
TARGET := libnfs
|
||||
BUILD := build-ppu
|
||||
SOURCE := lib mount portmap nfs rquota nlm ps3_ppu
|
||||
INCLUDE := include include/nfsc ps3_ppu nfs mount portmap
|
||||
DATA := data
|
||||
LIBS :=
|
||||
|
||||
MACHDEP := -DPS3_PPU=1 -DHAVE_CONFIG_H -D_U_=" "
|
||||
|
||||
CFLAGS += -O2 -Wall -mcpu=cell $(MACHDEP) -fno-strict-aliasing $(INCLUDES)
|
||||
|
||||
LD := ppu-ld
|
||||
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
|
||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||
export VPATH := $(foreach dir,$(SOURCE),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
export BUILDDIR := $(CURDIR)/$(BUILD)
|
||||
export DEPSDIR := $(BUILDDIR)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCE),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CXXFILES := $(foreach dir,$(SOURCE),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCE),$(notdir $(wildcard $(dir)/*.S)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.bin)))
|
||||
|
||||
|
||||
export OFILES := $(CFILES:.c=.o) \
|
||||
$(CXXFILES:.cpp=.o) \
|
||||
$(SFILES:.S=.o) \
|
||||
$(BINFILES:.bin=.bin.o)
|
||||
|
||||
export BINFILES := $(BINFILES:.bin=.bin.h)
|
||||
|
||||
export INCLUDES = $(foreach dir,$(INCLUDE),-I$(CURDIR)/$(dir)) \
|
||||
-I$(CURDIR)/$(BUILD) -I$(PSL1GHT)/ppu/include -I$(PORTLIBS)/include
|
||||
|
||||
.PHONY: $(BUILD) install clean
|
||||
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/ps3_ppu/Makefile.PS3_PPU
|
||||
|
||||
install: $(BUILD)
|
||||
@echo Copying...
|
||||
@[ -d $(PORTLIBS)/include/smb2 ] || mkdir -p $(PORTLIBS)/include/smb2
|
||||
@cp -frv ../include/smb2/*.h $(PORTLIBS)/include/smb2
|
||||
@cp -frv *.a $(PORTLIBS)/lib
|
||||
@echo Done!
|
||||
|
||||
clean:
|
||||
@echo Clean...
|
||||
@rm -rf $(BUILD) $(OUTPUT).elf $(OUTPUT).self $(OUTPUT).a
|
||||
|
||||
else
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
$(OUTPUT).a: $(OFILES)
|
||||
$(OFILES): $(BINFILES)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
endif
|
|
@ -0,0 +1,77 @@
|
|||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
#define HAVE_NETDB_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
|
||||
/* Whether sockaddr struct has sa_len */
|
||||
#define HAVE_SOCKADDR_LEN 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the <utime.h> header file. */
|
||||
#define HAVE_UTIME_H 1
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "libnfs"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "ronniesahlberg@gmail.com"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "libnfs"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "libnfs 4.0.0"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "libnfs"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "4.0.0"
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "4.0.0"
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
Copyright (C) 2013 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
|
||||
|
||||
This program 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 program 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 program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "ps3_compat.h"
|
||||
|
||||
int getnameinfo(const struct sockaddr *sa, socklen_t salen,
|
||||
char *host, size_t hostlen,
|
||||
char *serv, size_t servlen, int flags)
|
||||
{
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||
|
||||
if (host) {
|
||||
snprintf(host, hostlen, inet_ntoa(sin->sin_addr));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getaddrinfo(const char *node, const char*service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res)
|
||||
{
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
sin = malloc(sizeof(struct sockaddr_in));
|
||||
sin->sin_len = sizeof(struct sockaddr_in);
|
||||
sin->sin_family=AF_INET;
|
||||
|
||||
/* Some error checking would be nice */
|
||||
sin->sin_addr.s_addr = inet_addr(node);
|
||||
|
||||
sin->sin_port=0;
|
||||
if (service) {
|
||||
sin->sin_port=htons(atoi(service));
|
||||
}
|
||||
|
||||
*res = malloc(sizeof(struct addrinfo));
|
||||
|
||||
(*res)->ai_family = AF_INET;
|
||||
(*res)->ai_addrlen = sizeof(struct sockaddr_in);
|
||||
(*res)->ai_addr = (struct sockaddr *)sin;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void freeaddrinfo(struct addrinfo *res)
|
||||
{
|
||||
free(res->ai_addr);
|
||||
free(res);
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
Copyright (C) 2013 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
|
||||
|
||||
This program 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 program 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 program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PS3_COMPAT_H
|
||||
#define PS3_COMPAT_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <netdb.h>
|
||||
#include <net/socket.h>
|
||||
#include <net/poll.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
|
||||
int getnameinfo(const struct sockaddr *sa, socklen_t salen,
|
||||
char *host, size_t hostlen,
|
||||
char *serv, size_t servlen, int flags);
|
||||
int getaddrinfo(const char *node, const char*service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res);
|
||||
void freeaddrinfo(struct addrinfo *res);
|
||||
|
||||
#define IFNAMSIZ 16
|
||||
|
||||
/* just pretend they are the same so we compile */
|
||||
#define sockaddr_in6 sockaddr_in
|
||||
|
||||
#define IPPORT_RESERVED 1024
|
||||
#define MSG_NOSIGNAL 0x20000
|
||||
#define O_NOFOLLOW 0400000
|
||||
#define MINORBITS 20
|
||||
#define MINORMASK ((1U << MINORBITS) - 1)
|
||||
|
||||
#define major(dev) ((unsigned int) ((dev) >> MINORBITS))
|
||||
#define minor(dev) ((unsigned int) ((dev) & MINORMASK))
|
||||
|
||||
#define IFF_UP 0x1 /* interface is up */
|
||||
#define IFF_BROADCAST 0x2 /* broadcast address valid */
|
||||
#define IFF_DEBUG 0x4 /* turn on debugging */
|
||||
#define IFF_LOOPBACK 0x8 /* is a loopback net */
|
||||
|
||||
|
||||
struct ifmap {
|
||||
unsigned long mem_start;
|
||||
unsigned long mem_end;
|
||||
unsigned short base_addr;
|
||||
unsigned char irq;
|
||||
unsigned char dma;
|
||||
unsigned char port;
|
||||
/* 3 bytes spare */
|
||||
};
|
||||
|
||||
struct ifreq {
|
||||
char ifr_name[IFNAMSIZ]; /* Interface name */
|
||||
union {
|
||||
struct sockaddr ifr_addr;
|
||||
struct sockaddr ifr_dstaddr;
|
||||
struct sockaddr ifr_broadaddr;
|
||||
struct sockaddr ifr_netmask;
|
||||
struct sockaddr ifr_hwaddr;
|
||||
short ifr_flags;
|
||||
int ifr_ifindex;
|
||||
int ifr_metric;
|
||||
int ifr_mtu;
|
||||
struct ifmap ifr_map;
|
||||
char ifr_slave[IFNAMSIZ];
|
||||
char ifr_newname[IFNAMSIZ];
|
||||
char *ifr_data;
|
||||
};
|
||||
};
|
||||
|
||||
struct ifconf {
|
||||
int ifc_len; /* size of buffer */
|
||||
union {
|
||||
char *ifc_buf; /* buffer address */
|
||||
struct ifreq *ifc_req; /* array of structures */
|
||||
};
|
||||
};
|
||||
|
||||
typedef uint32_t fsblkcnt_t;
|
||||
typedef uint32_t fsfilcnt_t;
|
||||
|
||||
struct statvfs {
|
||||
unsigned long f_bsize;
|
||||
unsigned long f_frsize;
|
||||
fsblkcnt_t f_blocks;
|
||||
fsblkcnt_t f_bfree;
|
||||
fsblkcnt_t f_bavail;
|
||||
fsfilcnt_t f_files;
|
||||
fsfilcnt_t f_ffree;
|
||||
fsfilcnt_t f_favail;
|
||||
unsigned long f_fsid;
|
||||
unsigned long f_flag;
|
||||
unsigned long f_namemax;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -18,6 +18,10 @@
|
|||
#include <win32/win32_compat.h>
|
||||
#endif/*WIN32*/
|
||||
|
||||
#ifdef PS3_PPU
|
||||
#include "ps3_compat.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
|
|
Loading…
Reference in New Issue