Compare commits

...

58 Commits

Author SHA1 Message Date
Ryan C. Gordon 119f182c8b
Bumped version to 3.0.3! 2022-09-30 16:10:38 -04:00
Ryan C. Gordon aa4165c3c7 apple: macOS 12.0 deprecated things called "master" for "main".
Try to look for the new name in the process's namespace before falling back
to the old one (and giving up on CD-ROM detection if everything falls apart).

iOS has PHYSFS_NO_CDROM_SUPPORT defined, so this isn't used there.
2022-09-29 14:16:21 -04:00
Ozkan Sezer 8c02d53f69 fix version number in os/2 makefile. 2022-09-29 17:56:50 +03:00
Ryan C. Gordon c743450d86
atomic: __PHYSFS_ATOMIC_(DECR|INCR) should return final value.
Fixes #46.
2022-09-29 10:54:28 -04:00
Ryan C. Gordon ee956e0e5c
PHYSFS_mkdir() should allow symlinks in the mounted writeDir itself.
Fixes #47.
2022-09-29 10:28:41 -04:00
Ryan C. Gordon 2bb0d5c5f7
Bumped copyright for 2022. 2022-05-20 23:37:01 -04:00
Ryan C. Gordon 395cccbd24
cmake: Don't try to use readline if you don't also have curses.
Fixes #17.
2022-05-20 23:36:47 -04:00
Ryan C. Gordon ca34091863
zip: workaround Windows Explorer bug.
If you edit a zip file with Windows Explorer, it will rewrite the entire
central directory, setting all files version_needed field to 2.0/MS-DOS,
but it won't touch files that it doesn't plan to alter, so you might end
up with a local header that doesn't match the central directory details.

We aren't currently using the version_needed information, so now we just
favor the local header's copy of it in case we ever need it, and don't
complain if the central directory doesn't match.

Fixes #24.
2022-05-20 23:36:39 -04:00
Ozkan Sezer 9e2be90470
disable dllexport from static builds.
Closes https://github.com/icculus/physfs/pull/15 .
2022-05-20 23:36:26 -04:00
Ozkan Sezer d024ca24de
cmake: set os2 dll name to 'physfs'
not libphysfs, because of os2 limitation.
2022-05-20 23:35:57 -04:00
Ozkan Sezer 3bc65f1613
physfs_platform_os2.c: eliminated signedness warnings. 2022-05-20 23:35:39 -04:00
Ozkan Sezer 40ff5dba86
added __PHYSFS_ATOMIC_INCR and __PHYSFS_ATOMIC_DECR for watcom compiler 2022-05-20 23:35:29 -04:00
Ozkan Sezer 268d9e6266
added a watcom makefile targeting os2 2022-05-20 23:35:01 -04:00
Ozkan Sezer 4e91208cc3
fixed os2 symbol exports 2022-05-20 23:34:39 -04:00
Ozkan Sezer c27c67123c
fixed windows symbol exports 2022-05-20 23:34:17 -04:00
alfadur 7f4dbec16e
add 0x10000 properly 2022-05-20 23:33:27 -04:00
alfadur 4d66ea5946
add missing bit to UTF-16 surrogate pair conversion 2022-05-20 23:33:13 -04:00
pastdue 543a1ae037
physfs_platform_posix.c: Use O_CLOEXEC / FD_CLOEXEC 2022-05-20 23:31:33 -04:00
pastdue 3c32cd5600
physfs_platform_posix.c: Retry on EINTR 2022-05-20 23:31:24 -04:00
James Le Cuirot 52c3f19e17
Use the GNUInstallDirs CMake module to respect installation locations
Apparently use of LIB_SUFFIX is now discouraged. GNUInstallDirs does a
better job of setting a default.

The libdir of ${prefix}/lib in the pkg-config file caused warnings,
and possibly even failures, when linking on multilib systems where
/usr/lib is for 32-bit libraries rather than 64-bit libraries.
2022-05-20 23:31:16 -04:00
Ryan C. Gordon 21b4ccfc53
cmake: fixed "dist" target to use git instead of Mercurial. 2022-05-20 23:31:07 -04:00
Ryan C. Gordon 751be263bf
Updated a URL to point to github.com 2022-05-20 23:31:01 -04:00
Ryan C. Gordon a4dc0a7129
Renamed .hgignore -> .gitignore 2022-05-20 23:30:27 -04:00
Matthew Albrecht 99d0fef19e
Include alloca.h on Solaris and Linux platforms. 2022-05-20 23:30:15 -04:00
Ryan C. Gordon f3eb059e57
Reformat LICENSE.txt so GitHub sees it as zlib. 2022-05-20 23:29:37 -04:00
Ryan C. Gordon 911e253e00 msvc: Move stdarg.h include ahead of __PHYSFS_msvc_vsnprintf declaration.
(transplanted from e0346f4349265b4e483b987a0694740474942bb0)
2021-04-29 15:00:16 -04:00
Ryan C. Gordon 48ffe8ddf5 7z: copy/paste error in error checking, found by static analysis.
This was clearly copied from a previous line but wasn't updated with the
correct condition to check, so if malloc() failed, it would dereference NULL
instead of reporting an error.
(transplanted from 1dc6e265fefcc1fec8d68f096a73e1dca4bf0691)
2020-05-17 01:26:31 -04:00
Ryan C. Gordon db2a4a5807 Move buildbot script changes to stable-3.0 branch. 2020-05-17 00:58:55 -04:00
Ryan C. Gordon 6421738346 Minor style fix in docs/INSTALL.txt
(transplanted from 9cf9cdc05779f08c6342d620977c1f1273313881)
2020-05-12 01:04:09 -04:00
Ryan C. Gordon 557d1c58d5 Updated copyright for 2020. 2020-05-12 00:54:52 -04:00
Ryan C. Gordon fcfc99941f extras: Cleaning up some scripts to work with the newly-recreated buildbot.
(transplanted from 8ca9a80a216ca06ea2f3c86dcbd242908e9f96db)
2020-05-12 00:32:00 -04:00
Ryan C. Gordon 0e38afca9b Corrected example code for PHYSFS_enumerate in physfs.h
(transplanted from d3929e6603725b968df778618204ca6c3869b446)
2019-08-24 21:06:54 -04:00
Ryan C. Gordon f5458fbc6c cmake: Minimum CMake version is now 2.8.12. 2019-05-20 23:38:12 -04:00
Kevin d'Orange 95fd951c57 CMake: made install step export the targets
(transplanted from b2abaf7d4e4b2af671763b9ef2887dd30b42d6da)
2019-04-19 12:33:08 +02:00
Ryan C. Gordon 2ae6fe8833 Tagging 3.0.2 release 2019-03-18 14:37:22 -04:00
Ryan C. Gordon f8f89035c4 Bumped version to 3.0.2! 2019-03-18 14:35:44 -04:00
Ryan C. Gordon 2dc2dd1b04 Fixed compiler warning.
(transplanted from b76a47b006f65ad81b54256080d485919abdce29)
2019-03-18 14:28:46 -04:00
Ryan C. Gordon 81bb11ddbc windows: Workaround for WinXP systems. 2019-03-18 13:36:16 -04:00
Ryan C. Gordon fa34bb479d Only flush file handles on close if they were opened for writing.
(transplanted from 89e1b79e10c6e9faf9e4c06dc357dee5ef2c7d4f)
2019-03-18 11:27:26 -04:00
Ryan C. Gordon 9a825fcd77 Updated copyright year for 2019.
(transplanted from 63df6e1d7f90fee339e7a2033df2f4885df89d16)
2019-02-10 15:56:21 -05:00
Ryan C. Gordon 3ba1e363d1 cmake: Special build target names ("dist" "docs" "uninstall") can be renamed.
(transplanted from ac7b9452fdd8ef87eb4cfa36a80999b9cfc66235)
2019-02-10 15:45:01 -05:00
Ryan C. Gordon 0d3d0afc9a Allow builds to opt-out or opt-in to specific archivers, whichever's easier.
(transplanted from ff8f4c2a60d8bea12e34c1ed5cb4f506efb39020)
2019-01-26 03:00:29 -05:00
Ryan C. Gordon 20da8fab65 PHYSFS_flush() shouldn't call PHYSFS_Io::flush().
The former is meant to send PhysicsFS-buffered data to the PHYSFS_Io's
implementation, the latter is meant to tell the OS to definitely make sure the
data is safely written to disk (or at least, that's what it does in practice).

This was making PHYSFS_setBuffer()'d handles _slower_, since they would end
up blocking whenever the buffer was full until the data made the full trip to
physical media, instead of just letting the OS do its own buffering.

Now we still PHYSFS_Io::flush() on PHYSFS_close(), like this has always
worked. That might also be overkill, but that remains a historical artifact
of trying to keep the underlying file handle usable if pending writes fail
for possibly-recoverable reasons (which isn't guaranteed if you just close()
it, at least as far as I remember).
(transplanted from 8b3cc36531c6ac09dbac98d3774921bdf14b240d)
2018-11-27 23:53:33 -05:00
Ryan C. Gordon 9ef9a06db3 windows: Workaround GetUserProfileDirectory's API change in Win10 build 1809. 2018-10-03 22:40:57 -04:00
Ryan C. Gordon 4a56820f1d PHYSFS_setWriteDir() shouldn't create an empty file if the dir doesn't exist.
(transplanted from 2653b3bc19c9ba7d1e6bf53566719e4e30935382)
2018-05-16 19:54:51 -04:00
Ryan C. Gordon b1c6c7f4a8 Fix up physfs.h for compilers that are sensitive about preprocessor defines. 2018-04-19 10:06:38 -04:00
Ryan C. Gordon a828a91feb apple: Patched to compile with older (mac 10.7) SDKs (thanks, Ken and Ryan!).
(transplanted from 46561a3098955aa3534c10e2dcd9e969e140bb3d)
2018-03-24 00:19:59 -04:00
Ryan C. Gordon be0afe31e3 ignorecase: Don't crash if enumeration returned a NULL pointer. 2018-03-09 14:50:37 -05:00
Ryan C. Gordon d08188c1e0 Updated copyright date.
(transplanted from f50073f637203bd545443b5a53326cc8e8dd0cd8)
2018-03-08 12:21:45 -05:00
Ryan C. Gordon e216897cb9 7zip: don't forget to destroy the PHYSFS_Io when closing the archive!
(transplanted from bc6cd61b76288298feb2d997b99f19deb75fd90c)
2018-03-08 11:47:42 -05:00
Ryan C. Gordon ac1ee1a3f2 Patched physfsrwops to compile against SDL 1.2 (thanks, Rob!). 2017-11-11 08:53:23 -05:00
Ryan C. Gordon 9ea364e46e Bumped version to 3.0.1! 2017-10-26 14:38:03 -04:00
Ryan C. Gordon 179bd1d40a Catch access to paths that are just "." or ".." without any path separator.
(transplanted from b6d25a1927c2274cf31166a74b87b24e2752e0e8)
2017-10-26 14:37:16 -04:00
Ryan C. Gordon a80261989e Fixed mounting a symlink to a real directory.
(transplanted from f3459eaad51bbbed4fc2768c0ec65b3005a7f490)
2017-10-26 14:21:36 -04:00
Ryan C. Gordon b8aa7dab87 Fixed some infinite loops that a maliciously-crafted .iso can trigger.
These bugs exposed by American Fuzzy Lop (AFL), a powerful fuzzer.

http://lcamtuf.coredump.cx/afl/
(transplanted from 4f1bf89597e5b76c1c317fbeb2b472481090b4e4)
2017-10-23 14:58:54 -04:00
Ryan C. Gordon b9fd9e8100 Don't allow NULL filenames to be mounted.
Regardless of what the 3.0.0 documentation says, PhysicsFS never handled this
correctly, so now we check for it so you can't get into crashy situations.

Corrected documentation to reflect reality.
(transplanted from 0bbfaf6c5508139ba3d417377c94d75ca921772a)
2017-10-23 12:40:59 -04:00
Ryan C. Gordon e290b8d0a0 Fixed crash when duplicating PHYSFS_Io for zipfiles.
(transplanted from 67ca4c4f043ecf050c395e767845733512c83de2)
2017-10-23 12:16:51 -04:00
Ryan C. Gordon 12b7a80640 Added some notes on API documentation.
(transplanted from 7ee477e62e86838eca158df16a724d417eef125f)
2017-09-27 16:13:00 -04:00
27 changed files with 457 additions and 273 deletions

View File

@ -1,2 +1,2 @@
syntax:glob
cmake-build

View File

@ -9,10 +9,12 @@
# compile, using preprocessor checks for platform-specific bits instead of
# testing in here.
cmake_minimum_required(VERSION 2.8.4)
cmake_minimum_required(VERSION 2.8.12)
project(PhysicsFS)
set(PHYSFS_VERSION 3.0.0)
set(PHYSFS_VERSION 3.0.3)
include(GNUInstallDirs)
# Increment this if/when we break backwards compatibility.
set(PHYSFS_SOVERSION 1)
@ -163,6 +165,10 @@ if(PHYSFS_BUILD_STATIC)
set_target_properties(physfs-static PROPERTIES VS_WINRT_COMPONENT True)
set_target_properties(physfs-static PROPERTIES STATIC_LIBRARY_FLAGS "/ignore:4264")
endif()
if(WIN32 OR WINRT OR OS2)
# no dll exports from the static library
target_compile_definitions(physfs-static PRIVATE "PHYSFS_STATIC")
endif()
set(PHYSFS_LIB_TARGET physfs-static)
set(PHYSFS_INSTALL_TARGETS ${PHYSFS_INSTALL_TARGETS} ";physfs-static")
@ -177,6 +183,9 @@ if(PHYSFS_BUILD_SHARED)
if(WINRT)
set_target_properties(physfs PROPERTIES VS_WINRT_COMPONENT True)
endif()
if(OS2) # OS/2 does not support a DLL name longer than 8 characters.
set_target_properties(physfs PROPERTIES OUTPUT_NAME "physfs")
endif()
target_link_libraries(physfs ${OPTIONAL_LIBRARY_LIBS} ${OTHER_LDFLAGS})
set(PHYSFS_LIB_TARGET physfs)
set(PHYSFS_INSTALL_TARGETS ${PHYSFS_INSTALL_TARGETS} ";physfs")
@ -199,13 +208,15 @@ if(PHYSFS_BUILD_TEST)
find_path(HISTORY_H readline/history.h)
if(READLINE_H AND HISTORY_H)
find_library(CURSES_LIBRARY NAMES curses ncurses)
set(CMAKE_REQUIRED_LIBRARIES ${CURSES_LIBRARY})
find_library(READLINE_LIBRARY readline)
if(READLINE_LIBRARY)
set(HAVE_SYSTEM_READLINE TRUE)
set(TEST_PHYSFS_LIBS ${TEST_PHYSFS_LIBS} ${READLINE_LIBRARY} ${CURSES_LIBRARY})
include_directories(SYSTEM ${READLINE_H} ${HISTORY_H})
add_definitions(-DPHYSFS_HAVE_READLINE=1)
if(CURSES_LIBRARY)
set(CMAKE_REQUIRED_LIBRARIES ${CURSES_LIBRARY})
find_library(READLINE_LIBRARY readline)
if(READLINE_LIBRARY)
set(HAVE_SYSTEM_READLINE TRUE)
set(TEST_PHYSFS_LIBS ${TEST_PHYSFS_LIBS} ${READLINE_LIBRARY} ${CURSES_LIBRARY})
include_directories(SYSTEM ${READLINE_H} ${HISTORY_H})
add_definitions(-DPHYSFS_HAVE_READLINE=1)
endif()
endif()
endif()
add_executable(test_physfs test/test_physfs.c)
@ -213,11 +224,18 @@ if(PHYSFS_BUILD_TEST)
set(PHYSFS_INSTALL_TARGETS ${PHYSFS_INSTALL_TARGETS} ";test_physfs")
endif()
install(TARGETS ${PHYSFS_INSTALL_TARGETS}
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib${LIB_SUFFIX}
ARCHIVE DESTINATION lib${LIB_SUFFIX})
install(FILES src/physfs.h DESTINATION include)
install(TARGETS ${PHYSFS_INSTALL_TARGETS} EXPORT PhysFSExport
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(FILES src/physfs.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(EXPORT PhysFSExport
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/PhysFS"
FILE PhysFSConfig.cmake
)
find_package(Doxygen)
if(DOXYGEN_FOUND)
@ -232,8 +250,9 @@ if(DOXYGEN_FOUND)
file(APPEND "${PHYSFS_OUTPUT_DOXYFILE}" "OUTPUT_DIRECTORY = \"${CMAKE_CURRENT_BINARY_DIR}/docs\"\n")
file(APPEND "${PHYSFS_OUTPUT_DOXYFILE}" "\n# End auto-generated section.\n\n")
set(PHYSFS_TARGETNAME_DOCS "docs" CACHE STRING "Name of 'docs' build target")
add_custom_target(
docs
${PHYSFS_TARGETNAME_DOCS}
${DOXYGEN_EXECUTABLE} "${PHYSFS_OUTPUT_DOXYFILE}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Building documentation in 'docs' directory..."
@ -243,15 +262,19 @@ else()
endif()
if(UNIX)
set(PHYSFS_TARBALL "${CMAKE_CURRENT_SOURCE_DIR}/../physfs-${PHYSFS_VERSION}.tar.bz2")
set(PHYSFS_TARBALL "${CMAKE_CURRENT_SOURCE_DIR}/../physfs-${PHYSFS_VERSION}.tar.gz")
set(PHYSFS_TARGETNAME_DIST "dist" CACHE STRING "Name of 'dist' build target")
add_custom_target(
dist
hg archive -t tbz2 "${PHYSFS_TARBALL}"
${PHYSFS_TARGETNAME_DIST}
git archive --prefix="physfs-${PHYSFS_VERSION}/" --output="${PHYSFS_TARBALL}" HEAD
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Building source tarball '${PHYSFS_TARBALL}'..."
)
set(PHYSFS_TARGETNAME_UNINSTALL "uninstall" CACHE STRING "Name of 'uninstall' build target")
add_custom_target(
uninstall
${PHYSFS_TARGETNAME_UNINSTALL}
"${CMAKE_CURRENT_SOURCE_DIR}/extras/uninstall.sh"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMENT "Uninstall the project..."
@ -266,7 +289,7 @@ if(NOT MSVC)
)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/extras/physfs.pc"
DESTINATION "lib${LIB_SUFFIX}/pkgconfig"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
)
endif()
@ -297,4 +320,3 @@ if(PHYSFS_BUILD_TEST)
endif()
# end of CMakeLists.txt ...

View File

@ -1,23 +1,17 @@
Copyright (c) 2001-2022 Ryan C. Gordon <icculus@icculus.org> and others.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Copyright (c) 2001-2017 Ryan C. Gordon and others.
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from
the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software in a
product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Ryan C. Gordon <icculus@icculus.org>
3. This notice may not be removed or altered from any source distribution.

View File

@ -6,6 +6,6 @@ The changelog is no longer maintained by hand. It made sense to have a single
If you want a list of changes, updated in real time, just point your web
browser here:
https://hg.icculus.org/icculus/physfs/
https://github.com/icculus/physfs/commits/

View File

@ -164,6 +164,9 @@ CMake fixes:
Bug fixes,
Rémi Verschelde
Bug fixes:
Rob Loach
Other stuff:
Your name here! Patches go to icculus@icculus.org ...

View File

@ -37,7 +37,7 @@ If this all worked for your specific project, you can stop reading now.
UNIX:
Unix:
You will need CMake (https://www.cmake.org/) 2.4 or later installed.

View File

@ -0,0 +1,18 @@
The API documentation is readable in a few ways:
- Read physfs.h; it's _heavily_ documented and the primary source of reference
documentation for the library.
- Run Doxygen over the header, which produces nicer-to-browse documentation in
HTML, LaTeX, manpage, etc formats. This is done for you if Doxygen is
installed and you build the "docs" target in whatever project files CMake
generated for you.
- Too much trouble? We generated the HTML reference for you, online here:
https://icculus.org/physfs/docs/
- We would love well-written tutorials for the latest version of PhysicsFS!
If you write one, we would love to list it here. Drop me a line about it:
icculus@icculus.org ... Thanks!
--ryan.

View File

@ -1,53 +1,14 @@
#!/bin/bash
# This is a script used by some Buildbot buildslaves to push the project
# This is a script used by some Buildbot workers to push the project
# through Clang's static analyzer and prepare the output to be uploaded
# back to the buildmaster. You might find it useful too.
# Install Clang (you already have it on Mac OS X, apt-get install clang
# on Ubuntu, etc),
# or download checker at http://clang-analyzer.llvm.org/ and unpack it in
# /usr/local ... update CHECKERDIR as appropriate.
# on Ubuntu, etc), Make sure "scan-build" is in your $PATH.
FINALDIR="$1"
CHECKERDIR="/usr/local/checker-279"
if [ ! -d "$CHECKERDIR" ]; then
echo "$CHECKERDIR not found. Trying /usr/share/clang ..." 1>&2
CHECKERDIR="/usr/share/clang/scan-build"
fi
if [ ! -d "$CHECKERDIR" ]; then
echo "$CHECKERDIR not found. Giving up." 1>&2
exit 1
fi
if [ -z "$MAKE" ]; then
OSTYPE=`uname -s`
if [ "$OSTYPE" == "Linux" ]; then
NCPU=`cat /proc/cpuinfo |grep vendor_id |wc -l`
let NCPU=$NCPU+1
elif [ "$OSTYPE" = "Darwin" ]; then
NCPU=`sysctl -n hw.ncpu`
elif [ "$OSTYPE" = "SunOS" ]; then
NCPU=`/usr/sbin/psrinfo |wc -l |sed -e 's/^ *//g;s/ *$//g'`
else
NCPU=1
fi
if [ -z "$NCPU" ]; then
NCPU=1
elif [ "$NCPU" = "0" ]; then
NCPU=1
fi
MAKE="make -j$NCPU"
fi
echo "\$MAKE is '$MAKE'"
MAKECMD="$MAKE"
unset MAKE # prevent warnings about jobserver mode.
set -x
set -e
@ -66,13 +27,10 @@ cd checker-buildbot
# The -Wno-liblto is new since our checker-279 upgrade, I think; checker otherwise warns "libLTO.dylib relative to clang installed dir not found"
# You might want to do this for CMake-backed builds instead...
PATH="$CHECKERDIR/bin:$PATH" scan-build -o analysis cmake -Wno-dev -DPHYSFS_BUILD_SHARED=False -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_FLAGS="-Wno-deprecated-declarations" -DCMAKE_EXE_LINKER_FLAGS="-Wno-liblto" ..
# ...or run configure without the scan-build wrapper...
#CC="$CHECKERDIR/libexec/ccc-analyzer" CFLAGS="-O0 -Wno-deprecated-declarations" LDFLAGS="-Wno-liblto" ../configure --enable-assertions=enabled
scan-build -o analysis cmake -G Ninja -Wno-dev -DPHYSFS_BUILD_SHARED=False -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_FLAGS="-Wno-deprecated-declarations" -DCMAKE_EXE_LINKER_FLAGS="-Wno-liblto" ..
rm -rf analysis
PATH="$CHECKERDIR/bin:$PATH" scan-build -o analysis $MAKECMD
scan-build -o analysis cmake --build . --config Debug
if [ `ls -A analysis |wc -l` == 0 ] ; then
mkdir analysis/zarro

View File

@ -1,7 +1,7 @@
#!/bin/bash
if [ -z "$SDKDIR" ]; then
SDKDIR="/emsdk_portable"
SDKDIR="/emsdk"
fi
ENVSCRIPT="$SDKDIR/emsdk_env.sh"
@ -20,32 +20,6 @@ cd `dirname "$0"`
cd ..
PHYSFSBASE=`pwd`
if [ -z "$MAKE" ]; then
OSTYPE=`uname -s`
if [ "$OSTYPE" == "Linux" ]; then
NCPU=`cat /proc/cpuinfo |grep vendor_id |wc -l`
let NCPU=$NCPU+1
elif [ "$OSTYPE" = "Darwin" ]; then
NCPU=`sysctl -n hw.ncpu`
elif [ "$OSTYPE" = "SunOS" ]; then
NCPU=`/usr/sbin/psrinfo |wc -l |sed -e 's/^ *//g;s/ *$//g'`
else
NCPU=1
fi
if [ -z "$NCPU" ]; then
NCPU=1
elif [ "$NCPU" = "0" ]; then
NCPU=1
fi
MAKE="make -j$NCPU"
fi
echo "\$MAKE is '$MAKE'"
MAKECMD="$MAKE"
unset MAKE # prevent warnings about jobserver mode.
echo "Setting up Emscripten SDK environment..."
source "$ENVSCRIPT"
@ -56,10 +30,10 @@ mkdir buildbot
cd buildbot
echo "Configuring..."
emcmake cmake -G "Unix Makefiles" -DPHYSFS_BUILD_SHARED=False -DCMAKE_BUILD_TYPE=MinSizeRel .. || exit $?
emcmake cmake -G "Ninja" -DPHYSFS_BUILD_SHARED=False -DCMAKE_BUILD_TYPE=MinSizeRel .. || exit $?
echo "Building..."
emmake $MAKECMD || exit $?
emmake cmake --build . --config MinSizeRel || exit $?
set -e
rm -rf "$TARBALL" physfs-emscripten

View File

@ -15,24 +15,7 @@ if [ -z $1 ]; then
TARBALL=physfs-raspberrypi.tar.xz
fi
OSTYPE=`uname -s`
if [ "$OSTYPE" != "Linux" ]; then
# !!! FIXME
echo "This only works on x86 or x64-64 Linux at the moment." 1>&2
exit 1
fi
if [ "x$MAKE" == "x" ]; then
NCPU=`cat /proc/cpuinfo |grep vendor_id |wc -l`
let NCPU=$NCPU+1
MAKE="make -j$NCPU"
fi
echo "\$MAKE is '$MAKE'"
MAKECMD="$MAKE"
unset MAKE # prevent warnings about jobserver mode.
BUILDBOTDIR="raspberrypi-buildbot"
BUILDBOTDIR="buildbot"
PARENTDIR="$PWD"
set -e
@ -42,8 +25,9 @@ rm -rf $BUILDBOTDIR
mkdir -p $BUILDBOTDIR
pushd $BUILDBOTDIR
# the '-G "Ninja"' can be '-G "Unix Makefiles"' if you prefer to use GNU Make.
SYSROOT="/opt/rpi-sysroot"
cmake -G "Unix Makefiles" \
cmake -G "Ninja" \
-DCMAKE_C_COMPILER="/opt/rpi-tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc" \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DCMAKE_SYSROOT="$SYSROOT" \
@ -55,7 +39,7 @@ cmake -G "Unix Makefiles" \
-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
..
$MAKECMD
cmake --build . --config MinSizeRel
rm -rf "$TARBALL" physfs-raspberrypi
mkdir -p physfs-raspberrypi

View File

@ -50,18 +50,22 @@ static int locateOneElement(char *buf)
ptr++; /* point past dirsep to entry itself. */
} /* else */
for (i = rc; *i != NULL; i++)
if (rc != NULL)
{
if (PHYSFS_utf8stricmp(*i, ptr) == 0)
for (i = rc; *i != NULL; i++)
{
strcpy(ptr, *i); /* found a match. Overwrite with this case. */
PHYSFS_freeList(rc);
return 1;
} /* if */
} /* for */
if (PHYSFS_utf8stricmp(*i, ptr) == 0)
{
strcpy(ptr, *i); /* found a match. Overwrite with this case. */
PHYSFS_freeList(rc);
return 1;
} /* if */
} /* for */
PHYSFS_freeList(rc);
} /* if */
/* no match at all... */
PHYSFS_freeList(rc);
return 0;
} /* locateOneElement */

View File

@ -1,7 +1,7 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
exec_prefix=@CMAKE_INSTALL_PREFIX@
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
Name: PhysicsFS
Description: PhysicsFS is a library to provide abstract access to various archives.

View File

@ -32,10 +32,16 @@
#endif
#if !TARGET_SDL2
#ifndef RW_SEEK_SET
#define RW_SEEK_SET SEEK_SET
#endif
#ifndef RW_SEEK_CUR
#define RW_SEEK_CUR SEEK_CUR
#endif
#ifndef RW_SEEK_END
#define RW_SEEK_END SEEK_END
#endif
#endif
#if TARGET_SDL2
static Sint64 SDLCALL physfsrwops_size(struct SDL_RWops *rw)

93
src/Makefile.os2 Normal file
View File

@ -0,0 +1,93 @@
# Open Watcom makefile to build PhysicsFS for OS/2
# wmake -f Makefile.os2
LIBNAME = physfs
VERSION = 3.0.3
LIBFILE = $(LIBNAME).lib
DLLFILE = $(LIBNAME).dll
LNKFILE = $(LIBNAME).lnk
TITLENAME = $(LIBNAME) $(VERSION)
SRCS = physfs.c &
physfs_byteorder.c &
physfs_unicode.c &
physfs_platform_os2.c &
physfs_archiver_dir.c &
physfs_archiver_unpacked.c &
physfs_archiver_grp.c &
physfs_archiver_hog.c &
physfs_archiver_7z.c &
physfs_archiver_mvl.c &
physfs_archiver_qpak.c &
physfs_archiver_wad.c &
physfs_archiver_zip.c &
physfs_archiver_slb.c &
physfs_archiver_iso9660.c &
physfs_archiver_vdf.c
OBJS = $(SRCS:.c=.obj)
CFLAGS_BASE = -bt=os2 -d0 -q -bm -5s -fp5 -fpi87 -sg -oeatxh -ei -j
CFLAGS_BASE+= -DNDEBUG
# warnings:
CFLAGS_BASE+= -wx
# newer OpenWatcom versions enable W303 by default
CFLAGS_BASE+= -wcd=303
# include paths:
CFLAGS_BASE+= -I"$(%WATCOM)/h/os2" -I"$(%WATCOM)/h"
CFLAGS = $(CFLAGS_BASE)
# to build a dll:
CFLAGS+= -bd
.extensions:
.extensions: .lib .dll .obj .c
all: $(DLLFILE) test_physfs.exe
.c: decoders
.c: examples
$(LIBFILE): $(DLLFILE)
@echo * Create library: $@...
wlib -b -n -q -c -pa -s -t -zld -ii -io $@ $(DLLFILE)
$(DLLFILE): $(OBJS) $(MODPLIB) $(TIMILIB) $(LNKFILE)
@echo * Link: $@
wlink @$(LNKFILE)
$(LNKFILE):
@%create $@
@%append $@ SYSTEM os2v2_dll INITINSTANCE TERMINSTANCE
@%append $@ NAME $(LIBNAME)
@for %i in ($(OBJS)) do @%append $@ FILE %i
@%append $@ OPTION QUIET
@%append $@ OPTION DESCRIPTION '@$#icculus org:$(VERSION)$#@PhysicsFS'
@%append $@ OPTION MAP=$^&.map
@%append $@ OPTION ELIMINATE
@%append $@ OPTION MANYAUTODATA
@%append $@ OPTION OSNAME='OS/2 and eComStation'
@%append $@ OPTION SHOWDEAD
.c.obj:
wcc386 $(CFLAGS) -fo=$^@ $<
test_physfs.obj: "../test/test_physfs.c"
wcc386 $(CFLAGS_BASE) -fo=$^@ $<
test_physfs.exe: $(LIBFILE) test_physfs.obj
@echo * Link: $@
wlink SYS os2v2 LIBR {$(LIBFILE)} op q op el F {test_physfs.obj} N test_physfs.exe
clean: .SYMBOLIC
@echo * Clean: $(TITLENAME)
@if exist *.obj rm *.obj
@if exist *.err rm *.err
@if exist $(LNKFILE) rm $(LNKFILE)
distclean: .SYMBOLIC clean
@if exist $(DLLFILE) rm $(DLLFILE)
@if exist $(LIBFILE) rm $(LIBFILE)
@if exist *.map rm *.map
@if exist *.exe rm *.exe

View File

@ -12,8 +12,6 @@
#include "physfs_internal.h"
#if defined(_MSC_VER)
#include <stdarg.h>
/* this code came from https://stackoverflow.com/a/8712996 */
int __PHYSFS_msvc_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
{
@ -101,8 +99,8 @@ static inline int __PHYSFS_atomicAdd(int *ptrval, const int val)
{
int retval;
__PHYSFS_platformGrabMutex(stateLock);
*ptrval += val;
retval = *ptrval;
*ptrval = retval + val;
__PHYSFS_platformReleaseMutex(stateLock);
return retval;
} /* __PHYSFS_atomicAdd */
@ -879,13 +877,20 @@ static DirHandle *openDirectory(PHYSFS_Io *io, const char *d, int forWriting)
if (io == NULL)
{
/* file doesn't exist, etc? Just fail out. */
PHYSFS_Stat statbuf;
BAIL_IF_ERRPASS(!__PHYSFS_platformStat(d, &statbuf, 1), NULL);
/* DIR gets first shot (unlike the rest, it doesn't deal with files). */
retval = tryOpenDir(io, &__PHYSFS_Archiver_DIR, d, forWriting, &claimed);
if (retval || claimed)
return retval;
if (statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY)
{
retval = tryOpenDir(io, &__PHYSFS_Archiver_DIR, d, forWriting, &claimed);
if (retval || claimed)
return retval;
} /* if */
io = __PHYSFS_createNativeIo(d, forWriting ? 'w' : 'r');
BAIL_IF_ERRPASS(!io, 0);
BAIL_IF_ERRPASS(!io, NULL);
created_io = 1;
} /* if */
@ -939,6 +944,10 @@ static int sanitizePlatformIndependentPath(const char *src, char *dst)
while (*src == '/') /* skip initial '/' chars... */
src++;
/* Make sure the entire string isn't "." or ".." */
if ((strcmp(src, ".") == 0) || (strcmp(src, "..") == 0))
BAIL(PHYSFS_ERR_BAD_FILENAME, 0);
prev = dst;
do
{
@ -1012,6 +1021,8 @@ static DirHandle *createDirHandle(PHYSFS_Io *io, const char *newDir,
DirHandle *dirHandle = NULL;
char *tmpmntpnt = NULL;
assert(newDir != NULL); /* should have caught this higher up. */
if (mountPoint != NULL)
{
const size_t len = strlen(mountPoint) + 1;
@ -1025,15 +1036,9 @@ static DirHandle *createDirHandle(PHYSFS_Io *io, const char *newDir,
dirHandle = openDirectory(io, newDir, forWriting);
GOTO_IF_ERRPASS(!dirHandle, badDirHandle);
if (newDir == NULL)
dirHandle->dirName = NULL;
else
{
dirHandle->dirName = (char *) allocator.Malloc(strlen(newDir) + 1);
if (!dirHandle->dirName)
GOTO(PHYSFS_ERR_OUT_OF_MEMORY, badDirHandle);
strcpy(dirHandle->dirName, newDir);
} /* else */
dirHandle->dirName = (char *) allocator.Malloc(strlen(newDir) + 1);
GOTO_IF(!dirHandle->dirName, PHYSFS_ERR_OUT_OF_MEMORY, badDirHandle);
strcpy(dirHandle->dirName, newDir);
if ((mountPoint != NULL) && (*mountPoint != '\0'))
{
@ -1599,7 +1604,7 @@ const char *PHYSFS_getPrefDir(const char *org, const char *app)
assert(*endstr == dirsep);
*endstr = '\0'; /* mask out the final dirsep for now. */
if (!__PHYSFS_platformStat(prefDir, &statbuf))
if (!__PHYSFS_platformStat(prefDir, &statbuf, 1))
{
for (ptr = strchr(prefDir, dirsep); ptr; ptr = strchr(ptr+1, dirsep))
{
@ -1684,21 +1689,20 @@ static int doMount(PHYSFS_Io *io, const char *fname,
DirHandle *prev = NULL;
DirHandle *i;
BAIL_IF(!fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
if (mountPoint == NULL)
mountPoint = "/";
__PHYSFS_platformGrabMutex(stateLock);
if (fname != NULL)
for (i = searchPath; i != NULL; i = i->next)
{
for (i = searchPath; i != NULL; i = i->next)
{
/* already in search path? */
if ((i->dirName != NULL) && (strcmp(fname, i->dirName) == 0))
BAIL_MUTEX_ERRPASS(stateLock, 1);
prev = i;
} /* for */
} /* if */
/* already in search path? */
if ((i->dirName != NULL) && (strcmp(fname, i->dirName) == 0))
BAIL_MUTEX_ERRPASS(stateLock, 1);
prev = i;
} /* for */
dh = createDirHandle(io, fname, mountPoint, 0);
BAIL_IF_MUTEX_ERRPASS(!dh, stateLock, 0);
@ -1725,6 +1729,7 @@ int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname,
const char *mountPoint, int appendToPath)
{
BAIL_IF(!io, PHYSFS_ERR_INVALID_ARGUMENT, 0);
BAIL_IF(!fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
BAIL_IF(io->version != 0, PHYSFS_ERR_UNSUPPORTED, 0);
return doMount(io, fname, mountPoint, appendToPath);
} /* PHYSFS_mountIo */
@ -1738,6 +1743,7 @@ int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len, void (*del)(void *),
PHYSFS_Io *io = NULL;
BAIL_IF(!buf, PHYSFS_ERR_INVALID_ARGUMENT, 0);
BAIL_IF(!fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
io = __PHYSFS_createMemoryIo(buf, len, del);
BAIL_IF_ERRPASS(!io, 0);
@ -1760,7 +1766,8 @@ int PHYSFS_mountHandle(PHYSFS_File *file, const char *fname,
int retval = 0;
PHYSFS_Io *io = NULL;
BAIL_IF(file == NULL, PHYSFS_ERR_INVALID_ARGUMENT, 0);
BAIL_IF(!file, PHYSFS_ERR_INVALID_ARGUMENT, 0);
BAIL_IF(!fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
io = __PHYSFS_createHandleIo(file);
BAIL_IF_ERRPASS(!io, 0);
@ -1785,7 +1792,7 @@ int PHYSFS_mount(const char *newDir, const char *mountPoint, int appendToPath)
int PHYSFS_addToSearchPath(const char *newDir, int appendToPath)
{
return doMount(NULL, newDir, NULL, appendToPath);
return PHYSFS_mount(newDir, NULL, appendToPath);
} /* PHYSFS_addToSearchPath */
@ -2101,7 +2108,12 @@ static int doMkdir(const char *_dname, char *dname)
const int rc = h->funcs->stat(h->opaque, dname, &statbuf);
if ((!rc) && (currentErrorCode() == PHYSFS_ERR_NOT_FOUND))
exists = 0;
retval = ((rc) && (statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY));
/* verifyPath made sure that (dname) doesn't have symlinks if they aren't
allowed, but it's possible the mounted writeDir itself has symlinks in it,
(for example "/var" on iOS is a symlink, and the prefpath will be somewhere
under that)...if we mounted that writeDir, we must allow those symlinks here
unconditionally. */
retval = ( (rc) && ((statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY) || (statbuf.filetype == PHYSFS_FILETYPE_SYMLINK)) );
} /* if */
if (!exists)
@ -2660,7 +2672,6 @@ static int closeHandleInOpenList(FileHandle **list, FileHandle *handle)
{
FileHandle *prev = NULL;
FileHandle *i;
int rc = 1;
for (i = *list; i != NULL; i = i->next)
{
@ -2668,9 +2679,19 @@ static int closeHandleInOpenList(FileHandle **list, FileHandle *handle)
{
PHYSFS_Io *io = handle->io;
PHYSFS_uint8 *tmp = handle->buffer;
rc = PHYSFS_flush((PHYSFS_File *) handle);
if (!rc)
return -1;
/* send our buffer to io... */
if (!handle->forReading)
{
if (!PHYSFS_flush((PHYSFS_File *) handle))
return -1;
/* ...then have io send it to the disk... */
else if (io->flush && !io->flush(io))
return -1;
} /* if */
/* ...then close the underlying file. */
io->destroy(io);
if (tmp != NULL) /* free any associated buffer. */
@ -2968,7 +2989,7 @@ int PHYSFS_flush(PHYSFS_File *handle)
rc = io->write(io, fh->buffer + fh->bufpos, fh->buffill - fh->bufpos);
BAIL_IF_ERRPASS(rc <= 0, 0);
fh->bufpos = fh->buffill = 0;
return io->flush ? io->flush(io) : 1;
return 1;
} /* PHYSFS_flush */

View File

@ -225,11 +225,13 @@ extern "C" {
#if defined(PHYSFS_DECL)
/* do nothing. */
#elif (defined _MSC_VER)
#elif defined(PHYSFS_STATIC)
#define PHYSFS_DECL /**/
#elif defined(_WIN32) || defined(__OS2__)
#define PHYSFS_DECL __declspec(dllexport)
#elif (defined __SUNPRO_C)
#elif defined(__SUNPRO_C)
#define PHYSFS_DECL __global
#elif ((__GNUC__ >= 3) && (!__EMX__) && (!sun))
#elif ((__GNUC__ >= 3) && (!defined(__EMX__)) && (!defined(sun)))
#define PHYSFS_DECL __attribute__((visibility("default")))
#else
#define PHYSFS_DECL
@ -434,7 +436,7 @@ typedef struct PHYSFS_Version
#ifndef DOXYGEN_SHOULD_IGNORE_THIS
#define PHYSFS_VER_MAJOR 3
#define PHYSFS_VER_MINOR 0
#define PHYSFS_VER_PATCH 0
#define PHYSFS_VER_PATCH 3
#endif /* DOXYGEN_SHOULD_IGNORE_THIS */
@ -2176,11 +2178,15 @@ PHYSFS_DECL int PHYSFS_setAllocator(const PHYSFS_Allocator *allocator);
* or each other, for example.
*
* The mountpoint does not need to exist prior to mounting, which is different
* than those familiar with the Unix concept of "mounting" may not expect.
* than those familiar with the Unix concept of "mounting" may expect.
* As well, more than one archive can be mounted to the same mountpoint, or
* mountpoints and archive contents can overlap...the interpolation mechanism
* still functions as usual.
*
* Specifying a symbolic link to an archive or directory is allowed here,
* regardless of the state of PHYSFS_permitSymbolicLinks(). That function
* only deals with symlinks inside the mounted directory or archive.
*
* \param newDir directory or archive to add to the path, in
* platform-dependent notation.
* \param mountPoint Location in the interpolated tree that this archive
@ -2698,10 +2704,10 @@ typedef PHYSFS_EnumerateCallbackResult (*PHYSFS_EnumerateCallback)(void *data,
*
* \code
*
* static int printDir(void *data, const char *origdir, const char *fname)
* static PHYSFS_EnumerateCallbackResult printDir(void *data, const char *origdir, const char *fname)
* {
* printf(" * We've got [%s] in [%s].\n", fname, origdir);
* return 1; // give me more data, please.
* return PHYSFS_ENUM_OK; // give me more data, please.
* }
*
* // ...
@ -2760,6 +2766,12 @@ PHYSFS_DECL int PHYSFS_enumerate(const char *dir, PHYSFS_EnumerateCallback c,
* This call will fail (and fail to remove from the path) if the element still
* has files open in it.
*
* \warning This function wants the path to the archive or directory that was
* mounted (the same string used for the "newDir" argument of
* PHYSFS_addToSearchPath or any of the mount functions), not the
* path where it is mounted in the tree (the "mountPoint" argument
* to any of the mount functions).
*
* \param oldDir dir/archive to remove.
* \return nonzero on success, zero on failure. Use
* PHYSFS_getLastErrorCode() to obtain the specific error.
@ -3188,7 +3200,7 @@ typedef struct PHYSFS_Io
/**
* \fn int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname, const char *mountPoint, int appendToPath)
* \fn int PHYSFS_mountIo(PHYSFS_Io *io, const char *newDir, const char *mountPoint, int appendToPath)
* \brief Add an archive, built on a PHYSFS_Io, to the search path.
*
* \warning Unless you have some special, low-level need, you should be using
@ -3198,11 +3210,14 @@ typedef struct PHYSFS_Io
* instead of a pathname. Behind the scenes, PHYSFS_mount() calls this
* function with a physical-filesystem-based PHYSFS_Io.
*
* (filename) is only used here to optimize archiver selection (if you name it
* XXXXX.zip, we might try the ZIP archiver first, for example). It doesn't
* need to refer to a real file at all, and can even be NULL. If the filename
* isn't helpful, the system will try every archiver until one works or none
* of them do.
* (newDir) must be a unique string to identify this archive. It is used
* to optimize archiver selection (if you name it XXXXX.zip, we might try
* the ZIP archiver first, for example, or directly choose an archiver that
* can only trust the data is valid by filename extension). It doesn't
* need to refer to a real file at all. If the filename extension isn't
* helpful, the system will try every archiver until one works or none
* of them do. This filename must be unique, as the system won't allow you
* to have two archives with the same name.
*
* (io) must remain until the archive is unmounted. When the archive is
* unmounted, the system will call (io)->destroy(io), which will give you
@ -3211,7 +3226,7 @@ typedef struct PHYSFS_Io
* If this function fails, (io)->destroy(io) is not called.
*
* \param io i/o instance for archive to add to the path.
* \param fname Filename that can represent this stream. Can be NULL.
* \param newDir Filename that can represent this stream.
* \param mountPoint Location in the interpolated tree that this archive
* will be "mounted", in platform-independent notation.
* NULL or "" is equivalent to "/".
@ -3224,12 +3239,12 @@ typedef struct PHYSFS_Io
* \sa PHYSFS_getSearchPath
* \sa PHYSFS_getMountPoint
*/
PHYSFS_DECL int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname,
PHYSFS_DECL int PHYSFS_mountIo(PHYSFS_Io *io, const char *newDir,
const char *mountPoint, int appendToPath);
/**
* \fn int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len, void (*del)(void *), const char *fname, const char *mountPoint, int appendToPath)
* \fn int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len, void (*del)(void *), const char *newDir, const char *mountPoint, int appendToPath)
* \brief Add an archive, contained in a memory buffer, to the search path.
*
* \warning Unless you have some special, low-level need, you should be using
@ -3239,11 +3254,14 @@ PHYSFS_DECL int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname,
* instead of a pathname. This buffer contains all the data of the archive,
* and is used instead of a real file in the physical filesystem.
*
* (filename) is only used here to optimize archiver selection (if you name it
* XXXXX.zip, we might try the ZIP archiver first, for example). It doesn't
* need to refer to a real file at all, and can even be NULL. If the filename
* isn't helpful, the system will try every archiver until one works or none
* of them do.
* (newDir) must be a unique string to identify this archive. It is used
* to optimize archiver selection (if you name it XXXXX.zip, we might try
* the ZIP archiver first, for example, or directly choose an archiver that
* can only trust the data is valid by filename extension). It doesn't
* need to refer to a real file at all. If the filename extension isn't
* helpful, the system will try every archiver until one works or none
* of them do. This filename must be unique, as the system won't allow you
* to have two archives with the same name.
*
* (ptr) must remain until the archive is unmounted. When the archive is
* unmounted, the system will call (del)(ptr), which will notify you that
@ -3256,7 +3274,7 @@ PHYSFS_DECL int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname,
* \param buf Address of the memory buffer containing the archive data.
* \param len Size of memory buffer, in bytes.
* \param del A callback that triggers upon unmount. Can be NULL.
* \param fname Filename that can represent this stream. Can be NULL.
* \param newDir Filename that can represent this stream.
* \param mountPoint Location in the interpolated tree that this archive
* will be "mounted", in platform-independent notation.
* NULL or "" is equivalent to "/".
@ -3269,12 +3287,12 @@ PHYSFS_DECL int PHYSFS_mountIo(PHYSFS_Io *io, const char *fname,
* \sa PHYSFS_getMountPoint
*/
PHYSFS_DECL int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len,
void (*del)(void *), const char *fname,
void (*del)(void *), const char *newDir,
const char *mountPoint, int appendToPath);
/**
* \fn int PHYSFS_mountHandle(PHYSFS_File *file, const char *fname, const char *mountPoint, int appendToPath)
* \fn int PHYSFS_mountHandle(PHYSFS_File *file, const char *newDir, const char *mountPoint, int appendToPath)
* \brief Add an archive, contained in a PHYSFS_File handle, to the search path.
*
* \warning Unless you have some special, low-level need, you should be using
@ -3297,11 +3315,14 @@ PHYSFS_DECL int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len,
* but isn't necessarily. The most popular use for this is likely to mount
* archives stored inside other archives.
*
* (filename) is only used here to optimize archiver selection (if you name it
* XXXXX.zip, we might try the ZIP archiver first, for example). It doesn't
* need to refer to a real file at all, and can even be NULL. If the filename
* isn't helpful, the system will try every archiver until one works or none
* of them do.
* (newDir) must be a unique string to identify this archive. It is used
* to optimize archiver selection (if you name it XXXXX.zip, we might try
* the ZIP archiver first, for example, or directly choose an archiver that
* can only trust the data is valid by filename extension). It doesn't
* need to refer to a real file at all. If the filename extension isn't
* helpful, the system will try every archiver until one works or none
* of them do. This filename must be unique, as the system won't allow you
* to have two archives with the same name.
*
* (file) must remain until the archive is unmounted. When the archive is
* unmounted, the system will call PHYSFS_close(file). If you need this
@ -3311,7 +3332,7 @@ PHYSFS_DECL int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len,
* If this function fails, PHYSFS_close(file) is not called.
*
* \param file The PHYSFS_File handle containing archive data.
* \param fname Filename that can represent this stream. Can be NULL.
* \param newDir Filename that can represent this stream.
* \param mountPoint Location in the interpolated tree that this archive
* will be "mounted", in platform-independent notation.
* NULL or "" is equivalent to "/".
@ -3323,7 +3344,7 @@ PHYSFS_DECL int PHYSFS_mountMemory(const void *buf, PHYSFS_uint64 len,
* \sa PHYSFS_getSearchPath
* \sa PHYSFS_getMountPoint
*/
PHYSFS_DECL int PHYSFS_mountHandle(PHYSFS_File *file, const char *fname,
PHYSFS_DECL int PHYSFS_mountHandle(PHYSFS_File *file, const char *newDir,
const char *mountPoint, int appendToPath);

View File

@ -203,6 +203,8 @@ static void SZIP_closeArchive(void *opaque)
SZIPinfo *info = (SZIPinfo *) opaque;
if (info)
{
if (info->io)
info->io->destroy(info->io);
SzArEx_Free(&info->db, &SZIP_SzAlloc);
__PHYSFS_DirTreeDeinit(&info->tree);
allocator.Free(info);
@ -288,7 +290,7 @@ static PHYSFS_Io *SZIP_openRead(void *opaque, const char *path)
io = NULL;
buf = allocator.Malloc(outSizeProcessed);
GOTO_IF(rc != SZ_OK, PHYSFS_ERR_OUT_OF_MEMORY, SZIP_openRead_failed);
GOTO_IF(buf == NULL, PHYSFS_ERR_OUT_OF_MEMORY, SZIP_openRead_failed);
memcpy(buf, outBuffer + offset, outSizeProcessed);
alloc->Free(alloc, outBuffer);

View File

@ -49,7 +49,8 @@ static void *DIR_openArchive(PHYSFS_Io *io, const char *name,
const size_t seplen = 1;
assert(io == NULL); /* shouldn't create an Io for these. */
BAIL_IF_ERRPASS(!__PHYSFS_platformStat(name, &st), NULL);
BAIL_IF_ERRPASS(!__PHYSFS_platformStat(name, &st, 1), NULL);
if (st.filetype != PHYSFS_FILETYPE_DIRECTORY)
BAIL(PHYSFS_ERR_UNSUPPORTED, NULL);
@ -97,7 +98,7 @@ static PHYSFS_Io *doOpen(void *opaque, const char *name, const int mode)
{
const PHYSFS_ErrorCode err = PHYSFS_getLastErrorCode();
PHYSFS_Stat statbuf;
__PHYSFS_platformStat(f, &statbuf);
__PHYSFS_platformStat(f, &statbuf, 0); /* !!! FIXME: why are we stating here? */
PHYSFS_setErrorCode(err);
} /* if */
@ -164,7 +165,7 @@ static int DIR_stat(void *opaque, const char *name, PHYSFS_Stat *stat)
CVT_TO_DEPENDENT(d, opaque, name);
BAIL_IF_ERRPASS(!d, 0);
retval = __PHYSFS_platformStat(d, stat);
retval = __PHYSFS_platformStat(d, stat, 0);
__PHYSFS_smallFree(d);
return retval;
} /* DIR_stat */

View File

@ -151,18 +151,25 @@ static int iso9660LoadEntries(PHYSFS_Io *io, const int joliet,
/* recordlen = 0 -> no more entries or fill entry */
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &recordlen, 1), 0);
if (recordlen == 0)
if (recordlen > 0)
readpos += recordlen; /* ready to seek to next record. */
else
{
PHYSFS_uint64 nextpos;
/* if we are in the last sector of the directory & it's 0 -> end */
if ((dirend - 2048) <= (readpos - 1))
break; /* finished */
/* else skip to the next sector & continue; */
readpos = (((readpos - 1) / 2048) + 1) * 2048;
continue;
} /* if */
nextpos = (((readpos - 1) / 2048) + 1) * 2048;
readpos += recordlen; /* ready to seek to next record. */
/* whoops, can't make forward progress! */
BAIL_IF(nextpos == readpos, PHYSFS_ERR_CORRUPT, 0);
readpos = nextpos;
continue; /* start back at upper loop. */
} /* else */
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &extattrlen, 1), 0);
BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &extent, 4), 0);
@ -203,6 +210,10 @@ static int iso9660LoadEntries(PHYSFS_Io *io, const int joliet,
timestamp = (PHYSFS_sint64) mktime(&t);
extent += extattrlen; /* skip extended attribute record. */
/* infinite loop, corrupt file? */
BAIL_IF((extent * 2048) == dirstart, PHYSFS_ERR_CORRUPT, 0);
if (!iso9660AddEntry(io, joliet, isdir, base, fname, fnamelen,
timestamp, extent * 2048, datalen, unpkarc))
{

View File

@ -455,6 +455,7 @@ static PHYSFS_Io *ZIP_duplicate(PHYSFS_Io *io)
finfo->io = zip_get_io(origfinfo->io, NULL, finfo->entry);
GOTO_IF_ERRPASS(!finfo->io, failed);
initializeZStream(&finfo->stream);
if (finfo->entry->compression_method != COMPMETH_NONE)
{
finfo->buffer = (PHYSFS_uint8 *) allocator.Malloc(ZIP_READBUFSIZE);
@ -832,7 +833,10 @@ static int zip_parse_local(PHYSFS_Io *io, ZIPentry *entry)
BAIL_IF_ERRPASS(!readui32(io, &ui32), 0);
BAIL_IF(ui32 != ZIP_LOCAL_FILE_SIG, PHYSFS_ERR_CORRUPT, 0);
BAIL_IF_ERRPASS(!readui16(io, &ui16), 0);
BAIL_IF(ui16 != entry->version_needed, PHYSFS_ERR_CORRUPT, 0);
/* Windows Explorer might rewrite the entire central directory, setting
this field to 2.0/MS-DOS for all files, so favor the local version,
which it leaves intact if it didn't alter that specific file. */
entry->version_needed = ui16;
BAIL_IF_ERRPASS(!readui16(io, &ui16), 0); /* general bits. */
BAIL_IF_ERRPASS(!readui16(io, &ui16), 0);
BAIL_IF(ui16 != entry->compression_method, PHYSFS_ERR_CORRUPT, 0);

View File

@ -38,7 +38,7 @@
#include <malloc.h>
#endif
#ifdef PHYSFS_PLATFORM_SOLARIS
#if defined(PHYSFS_PLATFORM_SOLARIS) || defined(PHYSFS_PLATFORM_LINUX)
#include <alloca.h>
#endif
@ -69,7 +69,7 @@ extern "C" {
All file-private symbols need to be marked "static".
Everything shared between PhysicsFS sources needs to be in this
file between the visibility pragma blocks. */
#if PHYSFS_MINIMUM_GCC_VERSION(4,0) || defined(__clang__)
#if !defined(_WIN32) && (PHYSFS_MINIMUM_GCC_VERSION(4,0) || defined(__clang__))
#define PHYSFS_HAVE_PRAGMA_VISIBILITY 1
#endif
@ -95,6 +95,7 @@ extern const PHYSFS_Archiver __PHYSFS_Archiver_VDF;
/* a real C99-compliant snprintf() is in Visual Studio 2015,
but just use this everywhere for binary compatibility. */
#if defined(_MSC_VER)
#include <stdarg.h>
int __PHYSFS_msvc_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap);
int __PHYSFS_msvc_snprintf(char *outBuf, size_t size, const char *format, ...);
#define vsnprintf __PHYSFS_msvc_vsnprintf
@ -108,14 +109,24 @@ const void *__PHYSFS_winrtCalcPrefDir(void);
#endif
/* atomic operations. */
/* increment/decrement operations return the final incremented/decremented value. */
#if defined(_MSC_VER) && (_MSC_VER >= 1500)
#include <intrin.h>
__PHYSFS_COMPILE_TIME_ASSERT(LongEqualsInt, sizeof (int) == sizeof (long));
#define __PHYSFS_ATOMIC_INCR(ptrval) _InterlockedIncrement((long*)(ptrval))
#define __PHYSFS_ATOMIC_DECR(ptrval) _InterlockedDecrement((long*)(ptrval))
#elif defined(__clang__) || (defined(__GNUC__) && (((__GNUC__ * 10000) + (__GNUC_MINOR__ * 100)) >= 40100))
#define __PHYSFS_ATOMIC_INCR(ptrval) __sync_fetch_and_add(ptrval, 1)
#define __PHYSFS_ATOMIC_DECR(ptrval) __sync_fetch_and_add(ptrval, -1)
#define __PHYSFS_ATOMIC_INCR(ptrval) __sync_add_and_fetch(ptrval, 1)
#define __PHYSFS_ATOMIC_DECR(ptrval) __sync_add_and_fetch(ptrval, -1)
#elif defined(__WATCOMC__) && defined(__386__)
extern __inline int _xadd_watcom(volatile int *a, int v);
#pragma aux _xadd_watcom = \
"lock xadd [ecx], eax" \
parm [ecx] [eax] \
value [eax] \
modify exact [eax];
#define __PHYSFS_ATOMIC_INCR(ptrval) (_xadd_watcom(ptrval, 1)+1)
#define __PHYSFS_ATOMIC_DECR(ptrval) (_xadd_watcom(ptrval, -1)-1)
#else
#define PHYSFS_NEED_ATOMIC_OP_FALLBACK 1
int __PHYSFS_ATOMIC_INCR(int *ptrval);
@ -162,35 +173,44 @@ void __PHYSFS_smallFree(void *ptr);
#define free(x) Do not use free() directly.
/* !!! FIXME: add alloca check here. */
/* by default, enable things, so builds can opt out of a few things they
want to avoid. But you can build with this #defined to 0 if you would
like to turn off everything except a handful of things you opt into. */
#ifndef PHYSFS_SUPPORTS_DEFAULT
#define PHYSFS_SUPPORTS_DEFAULT 1
#endif
#ifndef PHYSFS_SUPPORTS_ZIP
#define PHYSFS_SUPPORTS_ZIP 1
#define PHYSFS_SUPPORTS_ZIP PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_7Z
#define PHYSFS_SUPPORTS_7Z 1
#define PHYSFS_SUPPORTS_7Z PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_GRP
#define PHYSFS_SUPPORTS_GRP 1
#define PHYSFS_SUPPORTS_GRP PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_HOG
#define PHYSFS_SUPPORTS_HOG 1
#define PHYSFS_SUPPORTS_HOG PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_MVL
#define PHYSFS_SUPPORTS_MVL 1
#define PHYSFS_SUPPORTS_MVL PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_WAD
#define PHYSFS_SUPPORTS_WAD 1
#define PHYSFS_SUPPORTS_WAD PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_QPAK
#define PHYSFS_SUPPORTS_QPAK 1
#define PHYSFS_SUPPORTS_QPAK PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_SLB
#define PHYSFS_SUPPORTS_SLB 1
#define PHYSFS_SUPPORTS_SLB PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_ISO9660
#define PHYSFS_SUPPORTS_ISO9660 1
#define PHYSFS_SUPPORTS_ISO9660 PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_VDF
#define PHYSFS_SUPPORTS_VDF 1
#define PHYSFS_SUPPORTS_VDF PHYSFS_SUPPORTS_DEFAULT
#endif
#if PHYSFS_SUPPORTS_7Z
@ -549,11 +569,12 @@ PHYSFS_sint64 __PHYSFS_platformFileLength(void *handle);
*
* This needs to fill in all the fields of (stat). For fields that might not
* mean anything on a platform (access time, perhaps), choose a reasonable
* default.
* default. if (follow), we want to follow symlinks and stat what they
* link to and not the link itself.
*
* Return zero on failure, non-zero on success.
*/
int __PHYSFS_platformStat(const char *fn, PHYSFS_Stat *stat);
int __PHYSFS_platformStat(const char *fn, PHYSFS_Stat *stat, const int follow);
/*
* Flush any pending writes to disk. (opaque) should be cast to whatever data

View File

@ -12,6 +12,7 @@
#ifdef PHYSFS_PLATFORM_APPLE
#include <Foundation/Foundation.h>
#include <dlfcn.h>
#include "physfs_internal.h"
@ -50,7 +51,7 @@ char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, TRUE);
BAIL_IF(!paths, PHYSFS_ERR_OS_ERROR, NULL);
NSString *path = (NSString *) paths[0];
NSString *path = (NSString *) [paths objectAtIndex:0];
BAIL_IF(!path, PHYSFS_ERR_OS_ERROR, NULL);
size_t len = [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
const size_t applen = strlen(app);
@ -99,7 +100,7 @@ static int darwinIsWholeMedia(io_service_t service)
} /* darwinIsWholeMedia */
static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort)
static int darwinIsMountedDisc(char *bsdName, mach_port_t mainPort)
{
int retval = 0;
CFMutableDictionaryRef matchingDict;
@ -107,10 +108,10 @@ static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort)
io_iterator_t iter;
io_service_t service;
if ((matchingDict = IOBSDNameMatching(masterPort, 0, bsdName)) == NULL)
if ((matchingDict = IOBSDNameMatching(mainPort, 0, bsdName)) == NULL)
return 0;
rc = IOServiceGetMatchingServices(masterPort, matchingDict, &iter);
rc = IOServiceGetMatchingServices(mainPort, matchingDict, &iter);
if ((rc != KERN_SUCCESS) || (!iter))
return 0;
@ -158,13 +159,25 @@ static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort)
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
#if !defined(PHYSFS_NO_CDROM_SUPPORT)
/* macOS 12.0 changed "master" names to "main". */
typedef kern_return_t (*ioMainPortFn)(mach_port_t, mach_port_t *);
static ioMainPortFn ioMainPort = NULL;
const char *devPrefix = "/dev/";
const int prefixLen = strlen(devPrefix);
mach_port_t masterPort = 0;
mach_port_t mainPort = 0;
struct statfs *mntbufp;
int i, mounts;
if (IOMasterPort(MACH_PORT_NULL, &masterPort) != KERN_SUCCESS)
if (ioMainPort == NULL)
{
ioMainPort = (ioMainPortFn) dlsym(RTLD_DEFAULT, "IOMainPort");
if (!ioMainPort)
ioMainPort = (ioMainPortFn) dlsym(RTLD_DEFAULT, "IOMasterPort");
if (!ioMainPort)
return; /* oh well, no CD-ROMs for you. */
} /* if */
if (ioMainPort(MACH_PORT_NULL, &mainPort) != KERN_SUCCESS)
BAIL(PHYSFS_ERR_OS_ERROR, ) /*return void*/;
mounts = getmntinfo(&mntbufp, MNT_WAIT); /* NOT THREAD SAFE! */
@ -176,7 +189,7 @@ void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
continue;
dev += prefixLen;
if (darwinIsMountedDisc(dev, masterPort))
if (darwinIsMountedDisc(dev, mainPort))
cb(data, mnt);
} /* for */
#endif /* !defined(PHYSFS_NO_CDROM_SUPPORT) */

View File

@ -222,7 +222,7 @@ static char *cvtPathToCorrectCase(char *buf)
if (ptr != NULL) /* isolate element to find (fname is the start). */
*ptr = '\0';
rc = DosFindFirst((unsigned char *) spec, &hdir, FILE_DIRECTORY,
rc = DosFindFirst(spec, &hdir, FILE_DIRECTORY,
&fb, sizeof (fb), &count, FIL_STANDARD);
if (rc == NO_ERROR)
{
@ -331,7 +331,7 @@ static int isCdRomDrive(ULONG drive)
ULONG ul1, ul2;
APIRET rc;
HFILE hfile = NULLHANDLE;
unsigned char drivename[3] = { 0, ':', '\0' };
char drivename[3] = { 0, ':', '\0' };
drivename[0] = 'A' + drive;
@ -443,7 +443,7 @@ PHYSFS_EnumerateCallbackResult __PHYSFS_platformEnumerate(const char *dirname,
__PHYSFS_smallFree(utf8);
BAIL_IF_ERRPASS(!cpspec, PHYSFS_ENUM_ERROR);
rc = DosFindFirst((unsigned char *) cpspec, &hdir,
rc = DosFindFirst(cpspec, &hdir,
FILE_DIRECTORY | FILE_ARCHIVED |
FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM,
&fb, sizeof (fb), &count, FIL_STANDARD);
@ -535,7 +535,7 @@ int __PHYSFS_platformMkDir(const char *filename)
APIRET rc;
char *cpstr = cvtUtf8ToCodepage(filename);
BAIL_IF_ERRPASS(!cpstr, 0);
rc = DosCreateDir((unsigned char *) cpstr, NULL);
rc = DosCreateDir(cpstr, NULL);
allocator.Free(cpstr);
BAIL_IF(rc != NO_ERROR, errcodeFromAPIRET(rc), 0);
return 1;
@ -721,7 +721,7 @@ PHYSFS_sint64 os2TimeToUnixTime(const FDATE *date, const FTIME *time)
} /* os2TimeToUnixTime */
int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *stat)
int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *stat, const int follow)
{
char *cpfname = cvtUtf8ToCodepage(filename);
FILESTATUS3 fs;

View File

@ -6,8 +6,6 @@
* This file written by Ryan C. Gordon.
*/
/* !!! FIXME: check for EINTR? */
#define __PHYSICSFS_INTERNAL__
#include "physfs_platforms.h"
@ -162,14 +160,30 @@ static void *doOpen(const char *filename, int mode)
const int appending = (mode & O_APPEND);
int fd;
int *retval;
int flags;
flags = -1;
errno = 0;
/* O_APPEND doesn't actually behave as we'd like. */
mode &= ~O_APPEND;
#ifdef O_CLOEXEC
/* Add O_CLOEXEC if defined */
mode |= O_CLOEXEC;
#endif
fd = open(filename, mode, S_IRUSR | S_IWUSR);
do {
fd = open(filename, mode, S_IRUSR | S_IWUSR);
} while ((fd < 0) && (errno == EINTR));
BAIL_IF(fd < 0, errcodeFromErrno(), NULL);
#if !defined(O_CLOEXEC) && defined(FD_CLOEXEC)
flags = fcntl(fd, F_GETFD);
if (flags != -1) {
fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
}
#endif
if (appending)
{
if (lseek(fd, 0, SEEK_END) < 0)
@ -219,7 +233,9 @@ PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
if (!__PHYSFS_ui64FitsAddressSpace(len))
BAIL(PHYSFS_ERR_INVALID_ARGUMENT, -1);
rc = read(fd, buffer, (size_t) len);
do {
rc = read(fd, buffer, (size_t) len);
} while ((rc == -1) && (errno == EINTR));
BAIL_IF(rc == -1, errcodeFromErrno(), -1);
assert(rc >= 0);
assert(rc <= len);
@ -236,7 +252,9 @@ PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
if (!__PHYSFS_ui64FitsAddressSpace(len))
BAIL(PHYSFS_ERR_INVALID_ARGUMENT, -1);
rc = write(fd, (void *) buffer, (size_t) len);
do {
rc = write(fd, (void *) buffer, (size_t) len);
} while ((rc == -1) && (errno == EINTR));
BAIL_IF(rc == -1, errcodeFromErrno(), rc);
assert(rc >= 0);
assert(rc <= len);
@ -275,8 +293,13 @@ PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
int __PHYSFS_platformFlush(void *opaque)
{
const int fd = *((int *) opaque);
if ((fcntl(fd, F_GETFL) & O_ACCMODE) != O_RDONLY)
BAIL_IF(fsync(fd) == -1, errcodeFromErrno(), 0);
int rc = -1;
if ((fcntl(fd, F_GETFL) & O_ACCMODE) != O_RDONLY) {
do {
rc = fsync(fd);
} while ((rc == -1) && (errno == EINTR));
BAIL_IF(rc == -1, errcodeFromErrno(), 0);
}
return 1;
} /* __PHYSFS_platformFlush */
@ -284,7 +307,10 @@ int __PHYSFS_platformFlush(void *opaque)
void __PHYSFS_platformClose(void *opaque)
{
const int fd = *((int *) opaque);
(void) close(fd); /* we don't check this. You should have used flush! */
int rc = -1;
do {
rc = close(fd); /* we don't check this. You should have used flush! */
} while ((rc == -1) && (errno == EINTR));
allocator.Free(opaque);
} /* __PHYSFS_platformClose */
@ -296,11 +322,11 @@ int __PHYSFS_platformDelete(const char *path)
} /* __PHYSFS_platformDelete */
int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
int __PHYSFS_platformStat(const char *fname, PHYSFS_Stat *st, const int follow)
{
struct stat statbuf;
BAIL_IF(lstat(filename, &statbuf) == -1, errcodeFromErrno(), 0);
const int rc = follow ? stat(fname, &statbuf) : lstat(fname, &statbuf);
BAIL_IF(rc == -1, errcodeFromErrno(), 0);
if (S_ISREG(statbuf.st_mode))
{
@ -330,7 +356,7 @@ int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
st->createtime = statbuf.st_ctime;
st->accesstime = statbuf.st_atime;
st->readonly = (access(filename, W_OK) == -1);
st->readonly = (access(fname, W_OK) == -1);
return 1;
} /* __PHYSFS_platformStat */

View File

@ -566,18 +566,26 @@ char *__PHYSFS_platformCalcUserDir(void)
else
{
DWORD psize = 0;
WCHAR dummy = 0;
LPWSTR wstr = NULL;
BOOL rc = 0;
/*
* Should fail. Will write the size of the profile path in
* psize. Also note that the second parameter can't be
* NULL or the function fails.
* NULL or the function fails on Windows XP, but has to be NULL on
* Windows 10 or it will fail. :(
*/
rc = pGetDir(accessToken, &dummy, &psize);
rc = pGetDir(accessToken, NULL, &psize);
GOTO_IF(rc, PHYSFS_ERR_OS_ERROR, done); /* should have failed! */
if (psize == 0) /* probably on Windows XP, try a different way. */
{
WCHAR x = 0;
rc = pGetDir(accessToken, &x, &psize);
GOTO_IF(rc, PHYSFS_ERR_OS_ERROR, done); /* should have failed! */
GOTO_IF(!psize, PHYSFS_ERR_OS_ERROR, done); /* Uhoh... */
} /* if */
/* Allocate memory for the profile directory */
wstr = (LPWSTR) __PHYSFS_smallAlloc((psize + 1) * sizeof (WCHAR));
if (wstr != NULL)
@ -960,7 +968,7 @@ static int isSymlink(const WCHAR *wpath, const DWORD attr)
} /* isSymlink */
int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st, const int follow)
{
WIN32_FILE_ATTRIBUTE_DATA winstat;
WCHAR *wstr = NULL;
@ -975,7 +983,7 @@ int __PHYSFS_platformStat(const char *filename, PHYSFS_Stat *st)
if (!rc)
err = GetLastError();
else /* check for symlink while wstr is still available */
issymlink = isSymlink(wstr, winstat.dwFileAttributes);
issymlink = !follow && isSymlink(wstr, winstat.dwFileAttributes);
__PHYSFS_smallFree(wstr);
BAIL_IF(!rc, errcodeFromWinApiError(err), 0);

View File

@ -210,7 +210,7 @@ static PHYSFS_uint32 utf16codepoint(const PHYSFS_uint16 **_str)
else
{
src++; /* eat the other surrogate. */
cp = (((cp - 0xD800) << 10) | (pair - 0xDC00));
cp = 0x10000 + (((cp - 0xD800) << 10) | (pair - 0xDC00));
} /* else */
} /* else if */

View File

@ -32,7 +32,7 @@
#define TEST_VERSION_MAJOR 3
#define TEST_VERSION_MINOR 0
#define TEST_VERSION_PATCH 0
#define TEST_VERSION_PATCH 3
static FILE *history_file = NULL;
static PHYSFS_uint32 do_buffer_size = 0;