lua/js utils.get_env_list() uses `environ' which was ANSI, thus
it broke any unicode names/values.
mpv already has an internal utf8_environ for win32, but it's used
only at the getenv(..) wrapper and not exposed in itself, and also it
has lazy initialization - on first getenv() call.
Now `environ' maps to a function which ensures initialization while
keeping it an l-value (like posix expects).
The cost of this fuglyness is that files should include osdep/io.h
(which now declares environ as extern) rather than declaring it
themselves, or else the build will break on mingw.
I often watch sporting events. On many occasions I get files with the
same filename for each session. For example, for F1 I might have the
following directory structure:
F1/
FP1.mkv
FP2.mkv
FP3.mkv
Qualification.mkv
Race.mkv
Since usually one simply watches one race after the other, I usually
just rsync the new event's files over the old ones, so, for example,
Race.mkv will be replaced from the file for the last event with the file
from the new event.
One problem with this is that I like to use --resume-playback for other
kinds of media, so I have it on by default. That works great for, say, a
movie, but doesn't work so well with this scheme, because you can
trivially forget to pass --no-resume-playback on the command line and
end up 2 hours in, watching spoilers as the race results scroll down the
screen :-)
This patch adds a new option, --resume-playback-check-mtime, which
validates that the file's mtime hasn't changed since the watch_later
configuration was saved. It does this by setting the watch_later
configuration to have the same mtime as the file after it is saved.
Switching back and forth between checking mtime and not checking mtime
works fine, as we only choose whether to compare based on it, but we
update the watch_later configuration mtime regardless of its value.
Unused now. The old stream cache used it, but it was removed.
On a side note, the demuxer cache uses mp_mkostemps(). It looks like our
Windows open() emulation handles this correctly by using CREATE_NEW, so
no functionality gets lost by the "new" approach. On the other hand, the
demuxer cache does not set FILE_FLAG_DELETE_ON_CLOSE, but instead tries
to delete the file after opening (POSIX style), which probably won't
work on Windows. But I'm not sure how to make it use the DELETE_ON_CLOSE
flag, so whatever.
Supposed to follow the standard function.
The standard function is not standard, but a GNU extension. Adding some
ifdef mess is pointless too - it has no advantages other than having a
mess, and not spotting implementation bugs in the emulation due to
running it only on "obscure" platforms (like Windows, so most computers
actually, except the developer's platform).
There is mkstemp(), which at least is in POSIX 2008. But it's 100%
useless, except in some obscure cases: it doesn't set O_CLOEXEC, nor can
you pass it to it. Without O_CLOEXEC, we'd leak the temporary file to
all child processes. (The fact that the file, which is expected to reach
double or tripple digit GB sizes, will be deleted only once all
processes unreference the FD, makes this sort of a big deal. You could
ftruncate() it, but that doesn't fix all the other problems.)
Why did POSIX standardize mkstemp() and O_CLOEXEC apparently at the same
time, but provided no way to pass O_CLOEXEC to mkstemp()? With the
introduction of O_CLOEXEC, they acknowledged that there's a need to
atomically set the FD_CLOEXEC flag when creating file descriptors.
(FD_CLOEXEC was standard before that, but setting it with fcntl() is
racy.) You're much more likely to need a temp file that is CLOEXEC
rather than the opposite, and even if they were somehow opposed to
CLOEXEC by default (such as for compat. reasons), surely POSIX could
have standardized mkostemp() too or instead.
And then there's the fact that this whole O_CLOEXEC mess is stupid.
Surely there would have been a better way to handle this, instead of
requiring adding O_CLOEXEC to almost ALL instances of open() in all code
that has been written ever. The justification for this is that the
historic default was wrong, and you can't change it (e.g. this won't
work: changing the behavior of exec() and not inherit the FD to the
child process, unless a hypothetical O_KEEP_EXEC flag is set).
But on the other hand, surely you could have introduced an exec()
variant which does close all FDs, except a whitelist of FDs passed to
it. Let's call it execve2(). In fact, I'm going to argue that exec()
call sites are the most aware of whether (and which) FDs to inherit.
Some programs even tried to explicitly iterate over all opened FDs and
explicitly close "unwanted" FDs (which of course was problematic for
other reasons), and such an execve2() call would have been the ideal
solution.
Maybe this proposed solution would have had problems too. But surely
revisiting and reviewing every exec*() call would have been simpler than
reviewing every open() call. And more importantly, having to extend
every damn library function that either calls open() or creates FDs in
some other way, like mkstemp().
What argument are there going to be against this? That there will be
library code that can't keep working correctly with processes that use
the "old" exec? Well, what about all my legacy library code that uses
open() incorrectly, and that will break no matter what?
Well, I'm not going to claim that I can come up with better solutions
than POSIX (generally or in this case), but this situation is ABSOLUTELY
ATROCIOUS. It makes win32 programming look attractive compared to POSIX,
that standard pandering to dead people from the past. (Note: not trying
to insult dead people.)
I'm not sure what POSIX is even doing. Anything useful? Doesn't look
like it to me. Are they paid? Why? They didn't even fix the locale mess,
nor do they intend to. I bet they're proud of discussing compatibility
to 70ies code day in and day out iwtohut ever producing anything useful.
What a load of crap. They seriously got to do better than this.
Oh, and my wrapper is probably buggy. Fortunately that doesn't matter.
Also I'm dumping this into io.h. Originally, io.h was just supposed to
replace broken implementation of standard functions by MinGW (and then
by Android), but whatever, just give a dumping ground for shit code.
This sliences some warnings about unused values and statements with no
effect, but it also fixes a logic error with freelocale(), since
previously it would not work as expected when used in the body of an if
statement without braces.
Uses real functions, because with macros, I don't think there is a way
to silence the "statement with no effect" warnings in the case where the
return value of uselocale() is ignored.
As for replacing the these functions with working implementations, I
don't think this is possible for mpv's use-case, since MSVCRT does not
support UTF-8 locales, or any locale with multibyte characters that are
three or more bytes long. See:
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale
Directory-opening never worked on Windows because MSVCRT's open()
doesn't open directories and its fstat() doesn't recognise directory
handles. These are just MSVCRT restrictions, and the Windows API itself
has no problem with opening directories as file objects, so reimplement
mpv's mp_open and mp_stat to use the Windows API directly. This should
fix directory playback.
This also populates the st_dev and st_ino fields of struct stat, so
filesystem loop checking in demux_playlist.c should now work on Windows.
Fixes#4711
This fixes >2GiB files with at least API level 21.
See: https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md
for the gritty details.
* Based on libavformat's things, except we do not care about API
versions or NDKs without unistd.h, which contains all sorts of
things that we utilize.
* Redefines lseek to always point to the 64bit version.
* Redefines fseeko to always point towards an inlined static
implementation that utilizes the 64bit version of lseek underneath.
This currently is only limited to Android. Its stdlib contains the
things that mpv's POSIX check checks for, but unfortunately not
glob().
This fixes Android compilation broken in 70a70b9da .
This covers source files which were added in mplayer2 and mpv times
only, and where all code is covered by LGPL relicensing agreements.
There are probably more files to which this applies, but I'm being
conservative here.
A file named ao_sdl.c exists in MPlayer too, but the mpv one is a
complete rewrite, and was added some time after the original ao_sdl.c
was removed. The same applies to vo_sdl.c, for which the SDL2 API is
radically different in addition (MPlayer supports SDL 1.2 only).
common.c contains only code written by me. But common.h is a strange
case: although it originally was named mp_common.h and exists in MPlayer
too, by now it contains only definitions written by uau and me. The
exceptions are the CONTROL_ defines - thus not changing the license of
common.h yet.
codec_tags.c contained once large tables generated from MPlayer's
codecs.conf, but all of these tables were removed.
From demux_playlist.c I'm removing a code fragment from someone who was
not asked; this probably could be done later (see commit 15dccc37).
misc.c is a bit complicated to reason about (it was split off mplayer.c
and thus contains random functions out of this file), but actually all
functions have been added post-MPlayer. Except get_relative_time(),
which was written by uau, but looks similar to 3 different versions of
something similar in each of the Unix/win32/OSX timer source files. I'm
not sure what that means in regards to copyright, so I've just moved it
into another still-GPL source file for now.
screenshot.c once had some minor parts of MPlayer's vf_screenshot.c, but
they're all gone.
Revert "win32: more wchar_t -> WCHAR replacements"
Revert "win32: replace wchar_t with WCHAR"
Doing a "partial" port of this makes no sense anymore from my
perspective. Revert the changes, as they're confusing without
context, maintenance, and progress. These changes were a bit
premature anyway, and might actually cause other issues
(locale neutrality etc. as it was pointed out).
WCHAR is more portable. While at least MinGW, Cygwin, and MSVC actually
use 16 bit wchar_t, Midipix will have 32 bit wchar_t. In that context,
using WCHAR instead is more portable.
This affects only non-MinGW parts, so not all uses of wchar_t need to
be changed. For example, terminal-win.c won't be used on Midipix at
all. (Most of io.c won't either, so the search & replace here is more
than necessary, but also not harmful.)
(Midipix is not useable yet, so this is just preparation.)
Add a platform-specific entry-point for Windows. This will allow some
platform-specific initialization to be added without the need for ugly
ifdeffery in main.c.
As an immediate advantage, mpv can now use a unicode entry-point and
convert the command line arguments to UTF-8 before passing them to
mpv_main, so osdep_preinit can be simplified a little bit.
Makes all of overlay_add work on windows/mingw.
Since we now don't explicitly check for mmap() anymore (it's always
present), this also requires us to make af_export.c compile, but I
haven't tested it.
mp_stat() instead of stat() was used in the normal code (i.e. even
on Unix), because MinGW-w64 has an unbelievable macro-mess in place,
which prevents solving this elegantly.
Add some dirty workarounds to hide mp_stat() from the normal code
properly. This now requires replacing all functions that use the
struct stat type. This includes fstat, lstat, fstatat, and possibly
others. (mpv currently uses stat and fstat only.)
The Windows version of tmpfile is actually pretty broken. It tries to
create the file in the root directory of the current drive, which means
on Vista and up, it normally fails due to insufficient permissions.
Replace it with a version that uses GetTempPath.
Also remove the Windows-specific note about automatic deletion of the
cache file. FILE_FLAG_DELETE_ON_CLOSE is available in NT, and it should
be pretty reliable.
glob-win.c wasn't big, so it was easier to rewrite it. The new version
supports Unicode, handles directories properly, sorts the output and
puts all its allocations in the same talloc context to simplify the
implementation of globfree.
Notably, the old glob had error checking code, but didn't do anything
with the errors since the error reporting code was commented out. The
new glob doesn't copy this behaviour. It just treats errors as if there
were no more matching files, which shouldn't matter for mpv, since it
ignores glob errors too.
To match the other Windows I/O helper functions, the definition is moved
to osdep/io.h.
This is necessary to start mpv without forcing a console window,
but also breaks console usability. A workaround is to call mpv
from a wrapper process that uses the console subsystem and helps
redirecting the standard streams and WriteConsole output to where
they belong.
This is needed so that new processes (created with fork+exec) don't
inherit open files, which can be important for a number of reasons.
Since O_CLOEXEC is relatively new (POSIX.1-2008, before that Linux
specific), we #define it to 0 in io.h to prevent compilation errors on
older/crappy systems. At least this is the plan.
input.c creates a pipe. For that, add a mp_set_cloexec() function (which
is based on Weston's code in vo_wayland.c, but more correct). We could
use pipe2() instead, but that is Linux specific. Technically, we have a
race condition, but it won't matter.
Remove the ifdef hell from mp_find_user_config_file(). Move the win32
specific code (for MinGW and Cygwin) to path-win.c. The behavior should
be about the same, but I can't be sure due to lack of testing and
because the old path.c code was hard to follow. (I expect those who care
about windows will fix things, should issues pop up - sorry.)
One difference is that the new code will always force MPV_HOME. It looks
like the old code preferred the mpv config dir in the exe dir if it
exists.
Also, make sure MP_PATH_MAX has enough space, even if the equivalent
wchar_t string is not 0-terminated with PATH_MAX (because apparently the
winapi doesn't require this). (Actually, maybe we should just kill all
uses of PATH_MAX/MP_PATH_MAX.)
This is a bit "hard", because getenv() returns a static string, and we
can't just return an allocated string. We also want getenv() to be
thread-safe if possible. (If the mpv core is going to be more threaded,
we sure do want the lower layers to be thread-safe as well.)
I have no idea when or how this broke, but _wstati64() is the function
we want anyway (64 bit filesize). Possibly this was a mingw-w64 bug.
It's unknown why "wstat()" just doesn't work in this case, as it's not
defined by MSDN and could be defined by mingw as it needs.
Use the *W variants instead of the implicit *A functions. (One could
define the UNICODE macro to switch the functions without suffix from
A to W, but I'm too lazy to figure out how portable that is, etc.)
Also make sure io.h defines a unicode aware printf().
Windows uses a legacy codepage for char* / runtime functions accepting
char *. Using UTF-8 as the codepage with setlocale() is explicitly
forbidden.
Work this around by overriding the MSVCRT functions with wrapper
macros, that assume UTF-8 and use "proper" API calls like _wopen etc.
to deal with unicode filenames. All code that uses standard functions
that take or return filenames must now include osdep/io.h. stat()
can't be overridden, because MinGW-w64 itself defines "stat" as a
macro. Change code to use use mp_stat() instead.
This is not perfectly clean, but still somewhat sane, and much better
than littering the rest of the mplayer code with MinGW specific hacks.
It's also a bit fragile, but that's actually little different from the
previous situation. Also, MinGW is unlikely to ever include a nice way
of dealing with this.