示例#1
0
osd_file::error osd_file::remove(std::string const &filename)
{
	if (::unlink(filename.c_str()) < -1)
		return errno_to_file_error(errno);
	else
		return error::NONE;
}
示例#2
0
osd_file::error osd_get_full_path(std::string &dst, std::string const &path)
{
	try
	{
#if defined(WIN32)
		std::vector<char> path_buffer(MAX_PATH);
		if (::_fullpath(&path_buffer[0], path.c_str(), MAX_PATH))
		{
			dst = &path_buffer[0];
			return osd_file::error::NONE;
		}
		else
		{
			return osd_file::error::FAILURE;
		}
#else
		std::unique_ptr<char, void (*)(void *)> canonical(::realpath(path.c_str(), nullptr), &std::free);
		if (canonical)
		{
			dst = canonical.get();
			return osd_file::error::NONE;
		}

		std::vector<char> path_buffer(PATH_MAX);
		if (::realpath(path.c_str(), &path_buffer[0]))
		{
			dst = &path_buffer[0];
			return osd_file::error::NONE;
		}
		else if (path[0] == PATHSEPCH)
		{
			dst = path;
			return osd_file::error::NONE;
		}
		else
		{
			while (!::getcwd(&path_buffer[0], path_buffer.size()))
			{
				if (errno != ERANGE)
					return errno_to_file_error(errno);
				else
					path_buffer.resize(path_buffer.size() * 2);
			}
			dst.assign(&path_buffer[0]).push_back(PATHSEPCH);
			dst.append(path);
			return osd_file::error::NONE;
		}
#endif
	}
	catch (...)
	{
		return osd_file::error::OUT_OF_MEMORY;
	}
}
示例#3
0
osd_file::error osd_file::open(std::string const &path, std::uint32_t openflags, ptr &file, std::uint64_t &filesize)
{
	std::string dst;
	if (posix_check_socket_path(path))
		return posix_open_socket(path, openflags, file, filesize);
	else if (posix_check_ptty_path(path))
		return posix_open_ptty(openflags, file, filesize, dst);

	// select the file open modes
	int access;
	if (openflags & OPEN_FLAG_WRITE)
	{
		access = (openflags & OPEN_FLAG_READ) ? O_RDWR : O_WRONLY;
		access |= (openflags & OPEN_FLAG_CREATE) ? (O_CREAT | O_TRUNC) : 0;
	}
	else if (openflags & OPEN_FLAG_READ)
	{
		access = O_RDONLY;
	}
	else
	{
		return error::INVALID_ACCESS;
	}
#if defined(WIN32)
	access |= O_BINARY;
#endif

	// convert the path into something compatible
	dst = path;
#if defined(WIN32)
	for (auto it = dst.begin(); it != dst.end(); ++it)
		*it = (INVPATHSEPCH == *it) ? PATHSEPCH : *it;
#endif
	osd_subst_env(dst, dst);

	// attempt to open the file
	int fd = -1;
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) || defined(__HAIKU__) || defined(WIN32) || defined(SDLMAME_NO64BITIO) || defined(__ANDROID__)
	fd = ::open(dst.c_str(), access, 0666);
#else
	fd = ::open64(dst.c_str(), access, 0666);
#endif

	if (fd < 0)
	{
		// create the path if necessary
		if ((openflags & OPEN_FLAG_CREATE) && (openflags & OPEN_FLAG_CREATE_PATHS))
		{
			auto const pathsep = dst.rfind(PATHSEPCH);
			if (pathsep != std::string::npos)
			{
				// create the path up to the file
				osd_file::error const error = create_path_recursive(dst.substr(0, pathsep));

				// attempt to reopen the file
				if (error == osd_file::error::NONE)
				{
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) || defined(__HAIKU__) || defined(WIN32) || defined(SDLMAME_NO64BITIO) || defined(__ANDROID__)
					fd = ::open(dst.c_str(), access, 0666);
#else
					fd = ::open64(dst.c_str(), access, 0666);
#endif
				}
			}
		}

		// if we still failed, clean up and osd_free
		if (fd < 0)
		{
			return errno_to_file_error(errno);
		}
	}

	// get the file size
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) || defined(__HAIKU__) || defined(WIN32) || defined(SDLMAME_NO64BITIO) || defined(__ANDROID__)
	struct stat st;
	if (::fstat(fd, &st) < 0)
#else
	struct stat64 st;
	if (::fstat64(fd, &st) < 0)
#endif
	{
		int const error = errno;
		::close(fd);
		return errno_to_file_error(error);
	}
	filesize = std::uint64_t(std::make_unsigned_t<decltype(st.st_size)>(st.st_size));

	try
	{
		file = std::make_unique<posix_osd_file>(fd);
		return error::NONE;
	}
	catch (...)
	{
		::close(fd);
		return error::OUT_OF_MEMORY;
	}
}
示例#4
0
osd_file::error posix_open_socket(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize)
{
	char hostname[256];
	int port;
	std::sscanf(&path[strlen(posixfile_socket_identifier)], "%255[^:]:%d", hostname, &port);

	struct hostent const *const localhost = ::gethostbyname(hostname);
	if (!localhost)
		return osd_file::error::NOT_FOUND;

	struct sockaddr_in sai;
	memset(&sai, 0, sizeof(sai));
	sai.sin_family = AF_INET;
	sai.sin_port = htons(port);
	sai.sin_addr = *reinterpret_cast<struct in_addr *>(localhost->h_addr);

	int const sock = ::socket(AF_INET, SOCK_STREAM, 0);
	if (sock < 0)
		return errno_to_file_error(errno);

	int const flag = 1;
	if (::setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<const char *>(&flag), sizeof(flag)) < 0)
	{
		int const err = errno;
		::close(sock);
		return errno_to_file_error(err);
	}

	if (::setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<const char *>(&flag), sizeof(flag)) < 0)
	{
		int const err = errno;
		::close(sock);
		return errno_to_file_error(err);
	}


	// listening socket support
	if (openflags & OPEN_FLAG_CREATE)
	{
		//printf("Listening for client at '%s' on port '%d'\n", hostname, port);
		// bind socket...
		if (::bind(sock, reinterpret_cast<struct sockaddr const *>(&sai), sizeof(struct sockaddr)) < 0)
		{
			int const err = errno;
			::close(sock);
			return errno_to_file_error(err);
		}

		// start to listen...
		if (::listen(sock, 1) < 0)
		{
			int const err = errno;
			::close(sock);
			return errno_to_file_error(err);
		}

		// mark socket as "listening"
		try
		{
			file = std::make_unique<posix_osd_socket>(sock, true);
			filesize = 0;
			return osd_file::error::NONE;
		}
		catch (...)
		{
			::close(sock);
			return osd_file::error::OUT_OF_MEMORY;
		}
	}
	else
	{
		//printf("Connecting to server '%s' on port '%d'\n", hostname, port);
		if (::connect(sock, reinterpret_cast<struct sockaddr const *>(&sai), sizeof(struct sockaddr)) < 0)
		{
			::close(sock);
			return osd_file::error::ACCESS_DENIED; // have to return this value or bitb won't try to bind on connect failure
		}
		try
		{
			file = std::make_unique<posix_osd_socket>(sock, false);
			filesize = 0;
			return osd_file::error::NONE;
		}
		catch (...)
		{
			::close(sock);
			return osd_file::error::OUT_OF_MEMORY;
		}
	}
}