Compare commits

...

5 commits

Author SHA1 Message Date
Andrew Eikum
63b32e09f6 proton: Better handle broken symlinks 2022-03-14 10:22:16 -05:00
Andrew Eikum
bc57d557cf proton: Add file_exists helper function
To make desired handling of symlinks more clear at the callsite.
2022-03-14 10:22:16 -05:00
Andrew Eikum
8f5a92e619 media-converter: Don't panic on unknown tags for read-only DBs
CW-Bug-Id: #19516
2022-03-14 10:22:16 -05:00
Andrew Eikum
ec7e70b0c0 media-converter: Add Cargo.lock 2022-02-15 14:45:18 -06:00
Zebediah Figura
80cba82d25 proton: Always check if the prefix config changed.
In particular, make sure that we update builtin dlls for the first process that runs.
2021-06-16 14:39:13 -05:00
5 changed files with 721 additions and 47 deletions

659
media-converter/Cargo.lock generated Normal file
View file

@ -0,0 +1,659 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "anyhow"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
[[package]]
name = "array-init"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f30bbe2f5e3d117f55bd8c7a1f9191e4a5deba9f15f595bbea4f670c59c765db"
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits",
"time",
"winapi",
]
[[package]]
name = "crc32fast"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "futures-channel"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c2dd2df839b57db9ab69c2c9d8f3e8c81984781937fe2807dc6dcf3b2ad2939"
dependencies = [
"futures-core",
]
[[package]]
name = "futures-core"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94"
[[package]]
name = "futures-executor"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "891a4b7b96d84d5940084b2a37632dd65deeae662c114ceaa2c879629c9c0ad1"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-macro"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea405816a5139fb39af82c2beb921d52143f556038378d6db21183a5c37fbfb7"
dependencies = [
"proc-macro-hack",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "futures-task"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa189ef211c15ee602667a6fcfe1c1fd9e07d42250d2156382820fba33c9df80"
[[package]]
name = "futures-util"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1"
dependencies = [
"futures-core",
"futures-macro",
"futures-task",
"pin-project-lite",
"pin-utils",
"proc-macro-hack",
"proc-macro-nested",
"slab",
]
[[package]]
name = "glib"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c685013b7515e668f1b57a165b009d4d28cb139a8a989bbd699c10dad29d0c5"
dependencies = [
"bitflags",
"futures-channel",
"futures-core",
"futures-executor",
"futures-task",
"futures-util",
"glib-macros",
"glib-sys",
"gobject-sys",
"libc",
"once_cell",
]
[[package]]
name = "glib-macros"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41486a26d1366a8032b160b59065a59fb528530a46a49f627e7048fb8c064039"
dependencies = [
"anyhow",
"heck",
"itertools",
"proc-macro-crate",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "glib-sys"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7e9b997a66e9a23d073f2b1abb4dbfc3925e0b8952f67efd8d9b6e168e4cdc1"
dependencies = [
"libc",
"system-deps",
]
[[package]]
name = "gobject-sys"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "952133b60c318a62bf82ee75b93acc7e84028a093e06b9e27981c2b6fe68218c"
dependencies = [
"glib-sys",
"libc",
"system-deps",
]
[[package]]
name = "gst-plugin-version-helper"
version = "0.2.0"
source = "git+https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs?tag=0.6.0#634d231269ab9b68c722c5037d1c94bed97ba45c"
dependencies = [
"chrono",
]
[[package]]
name = "gstreamer"
version = "0.16.2"
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs?tag=0.16.2#4e57412fa365ef524971180f203a04abfc358112"
dependencies = [
"bitflags",
"cfg-if 0.1.10",
"futures-channel",
"futures-core",
"futures-util",
"glib",
"glib-sys",
"gobject-sys",
"gstreamer-sys",
"libc",
"muldiv",
"num-rational",
"once_cell",
"paste",
"pretty-hex",
"thiserror",
]
[[package]]
name = "gstreamer-audio"
version = "0.16.2"
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs?tag=0.16.2#4e57412fa365ef524971180f203a04abfc358112"
dependencies = [
"array-init",
"bitflags",
"glib",
"glib-sys",
"gobject-sys",
"gstreamer",
"gstreamer-audio-sys",
"gstreamer-base",
"gstreamer-base-sys",
"gstreamer-sys",
"libc",
"once_cell",
]
[[package]]
name = "gstreamer-audio-sys"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b614d5e478ad2ff6f5699757d03f11f2868ea43164c651c60449bd0e3c6b7d75"
dependencies = [
"glib-sys",
"gobject-sys",
"gstreamer-base-sys",
"gstreamer-sys",
"libc",
"system-deps",
]
[[package]]
name = "gstreamer-base"
version = "0.16.2"
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs?tag=0.16.2#4e57412fa365ef524971180f203a04abfc358112"
dependencies = [
"bitflags",
"glib",
"glib-sys",
"gobject-sys",
"gstreamer",
"gstreamer-base-sys",
"gstreamer-sys",
"libc",
]
[[package]]
name = "gstreamer-base-sys"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4b7b6dc2d6e160a1ae28612f602bd500b3fa474ce90bf6bb2f08072682beef5"
dependencies = [
"glib-sys",
"gobject-sys",
"gstreamer-sys",
"libc",
"system-deps",
]
[[package]]
name = "gstreamer-sys"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc1f154082d01af5718c5f8a8eb4f565a4ea5586ad8833a8fc2c2aa6844b601d"
dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
]
[[package]]
name = "gstreamer-video"
version = "0.16.2"
source = "git+https://gitlab.freedesktop.org/gstreamer/gstreamer-rs?tag=0.16.2#4e57412fa365ef524971180f203a04abfc358112"
dependencies = [
"bitflags",
"futures-channel",
"futures-util",
"glib",
"glib-sys",
"gobject-sys",
"gstreamer",
"gstreamer-base",
"gstreamer-base-sys",
"gstreamer-sys",
"gstreamer-video-sys",
"libc",
"once_cell",
]
[[package]]
name = "gstreamer-video-sys"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92347e46438007d6a2386302125f62cb9df6769cdacb931af5c0f12c1ee21de4"
dependencies = [
"glib-sys",
"gobject-sys",
"gstreamer-base-sys",
"gstreamer-sys",
"libc",
"system-deps",
]
[[package]]
name = "heck"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "itertools"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
dependencies = [
"either",
]
[[package]]
name = "libc"
version = "0.2.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7"
[[package]]
name = "muldiv"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0419348c027fa7be448d2ae7ea0e4e04c2334c31dc4e74ab29f00a2a7ca69204"
[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
[[package]]
name = "paste"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880"
dependencies = [
"paste-impl",
"proc-macro-hack",
]
[[package]]
name = "paste-impl"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6"
dependencies = [
"proc-macro-hack",
]
[[package]]
name = "pin-project-lite"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkg-config"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
[[package]]
name = "pretty-hex"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be91bcc43e73799dc46a6c194a55e7aae1d86cc867c860fd4a436019af21bd8c"
[[package]]
name = "proc-macro-crate"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785"
dependencies = [
"toml",
]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro-hack"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro-nested"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "proton-media-converter"
version = "1.0.0"
dependencies = [
"crc32fast",
"futures-channel",
"futures-core",
"futures-executor",
"futures-macro",
"futures-task",
"futures-util",
"glib",
"gst-plugin-version-helper",
"gstreamer",
"gstreamer-audio",
"gstreamer-base",
"gstreamer-video",
"once_cell",
]
[[package]]
name = "quote"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "serde"
version = "1.0.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
[[package]]
name = "slab"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
[[package]]
name = "strum"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57bd81eb48f4c437cadc685403cad539345bf703d78e63707418431cecd4522b"
[[package]]
name = "strum_macros"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "syn"
version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "system-deps"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f3ecc17269a19353b3558b313bba738b25d82993e30d62a18406a24aba4649b"
dependencies = [
"heck",
"pkg-config",
"strum",
"strum_macros",
"thiserror",
"toml",
"version-compare",
]
[[package]]
name = "thiserror"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "time"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi",
"winapi",
]
[[package]]
name = "toml"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
dependencies = [
"serde",
]
[[package]]
name = "unicode-segmentation"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "version-compare"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d63556a25bae6ea31b52e640d7c41d1ab27faba4ccb600013837a3d0b3994ca1"
[[package]]
name = "version_check"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View file

@ -198,7 +198,7 @@ static DUMP_FOZDB: Lazy<Mutex<Option<fossilize::StreamArchive>>> = Lazy::new(||
return Mutex::new(None); return Mutex::new(None);
} }
match fossilize::StreamArchive::new(&dump_file_path, OpenOptions::new().write(true).read(true).create(true), AUDIOCONV_FOZ_NUM_TAGS) { match fossilize::StreamArchive::new(&dump_file_path, OpenOptions::new().write(true).read(true).create(true), false /* read-only? */, AUDIOCONV_FOZ_NUM_TAGS) {
Ok(newdb) => Mutex::new(Some(newdb)), Ok(newdb) => Mutex::new(Some(newdb)),
Err(_) => Mutex::new(None), Err(_) => Mutex::new(None),
} }
@ -454,7 +454,7 @@ impl AudioConvState {
gst_loggable_error!(CAT, "MEDIACONV_AUDIO_TRANSCODED_FILE is not set!") gst_loggable_error!(CAT, "MEDIACONV_AUDIO_TRANSCODED_FILE is not set!")
})?; })?;
let read_fozdb = match fossilize::StreamArchive::new(&read_fozdb_path, OpenOptions::new().read(true), AUDIOCONV_FOZ_NUM_TAGS) { let read_fozdb = match fossilize::StreamArchive::new(&read_fozdb_path, OpenOptions::new().read(true), true /* read-only? */, AUDIOCONV_FOZ_NUM_TAGS) {
Ok(s) => Some(s), Ok(s) => Some(s),
Err(_) => None, Err(_) => None,
}; };

View file

@ -197,6 +197,7 @@ impl PayloadEntry {
pub struct StreamArchive { pub struct StreamArchive {
file: fs::File, file: fs::File,
read_only: bool,
seen_blobs: Vec<HashMap<FossilizeHash, PayloadEntry>>, seen_blobs: Vec<HashMap<FossilizeHash, PayloadEntry>>,
@ -210,7 +211,7 @@ pub enum CRCCheck {
impl StreamArchive { impl StreamArchive {
pub fn new<P: AsRef<std::path::Path>>(filename: P, fileopts: &OpenOptions, num_tags: usize) -> Result<Self, Error> { pub fn new<P: AsRef<std::path::Path>>(filename: P, fileopts: &OpenOptions, read_only: bool, num_tags: usize) -> Result<Self, Error> {
let file = fileopts.open(filename)?; let file = fileopts.open(filename)?;
@ -221,6 +222,7 @@ impl StreamArchive {
let mut ret = Self { let mut ret = Self {
file, file,
read_only,
seen_blobs, seen_blobs,
write_pos: 0, write_pos: 0,
}; };
@ -269,6 +271,10 @@ impl StreamArchive {
match res { match res {
Ok(p) => { Ok(p) => {
self.write_pos = p; self.write_pos = p;
if tag >= self.seen_blobs.len() && self.read_only {
/* ignore unknown tags for read-only DBs, otherwise panic */
continue;
}
self.seen_blobs[tag].insert(hash, payload_entry); self.seen_blobs[tag].insert(hash, payload_entry);
}, },

View file

@ -124,7 +124,7 @@ static DUMP_FOZDB: Lazy<Mutex<Option<fossilize::StreamArchive>>> = Lazy::new(||
return Mutex::new(None); return Mutex::new(None);
} }
match fossilize::StreamArchive::new(&dump_file_path, OpenOptions::new().write(true).read(true).create(true), VIDEOCONV_FOZ_NUM_TAGS) { match fossilize::StreamArchive::new(&dump_file_path, OpenOptions::new().write(true).read(true).create(true), false /* read-only? */, VIDEOCONV_FOZ_NUM_TAGS) {
Ok(newdb) => Mutex::new(Some(newdb)), Ok(newdb) => Mutex::new(Some(newdb)),
Err(_) => Mutex::new(None), Err(_) => Mutex::new(None),
} }
@ -237,7 +237,7 @@ impl VideoConvState {
gst_loggable_error!(CAT, "MEDIACONV_VIDEO_TRANSCODED_FILE is not set!") gst_loggable_error!(CAT, "MEDIACONV_VIDEO_TRANSCODED_FILE is not set!")
})?; })?;
let read_fozdb = match fossilize::StreamArchive::new(&read_fozdb_path, OpenOptions::new().read(true), VIDEOCONV_FOZ_NUM_TAGS) { let read_fozdb = match fossilize::StreamArchive::new(&read_fozdb_path, OpenOptions::new().read(true), true /* read-only? */, VIDEOCONV_FOZ_NUM_TAGS) {
Ok(s) => Some(s), Ok(s) => Some(s),
Err(_) => None, Err(_) => None,
}; };

93
proton
View file

@ -25,6 +25,13 @@ CURRENT_PREFIX_VERSION="5.13-1"
PFX="Proton: " PFX="Proton: "
ld_path_var = "LD_LIBRARY_PATH" ld_path_var = "LD_LIBRARY_PATH"
def file_exists(s, *, follow_symlinks):
if follow_symlinks:
#'exists' returns False on broken symlinks
return os.path.exists(s)
#'lexists' returns True on broken symlinks
return os.path.lexists(s)
def nonzero(s): def nonzero(s):
return len(s) > 0 and s != "0" return len(s) > 0 and s != "0"
@ -50,7 +57,7 @@ def file_is_wine_builtin_dll(path):
if os.path.dirname(contents).endswith(('/lib/wine', '/lib/wine/fakedlls', '/lib64/wine', '/lib64/wine/fakedlls')): if os.path.dirname(contents).endswith(('/lib/wine', '/lib/wine/fakedlls', '/lib64/wine', '/lib64/wine/fakedlls')):
# This may be a broken link to a dll in a removed Proton install # This may be a broken link to a dll in a removed Proton install
return True return True
if not os.path.exists(path): if not file_exists(path, follow_symlinks=True):
return False return False
try: try:
sfile = open(path, "rb") sfile = open(path, "rb")
@ -62,6 +69,9 @@ def file_is_wine_builtin_dll(path):
def makedirs(path): def makedirs(path):
try: try:
#replace broken symlinks with a new directory
if os.path.islink(path) and not file_exists(path, follow_symlinks=True):
os.remove(path)
os.makedirs(path) os.makedirs(path)
except OSError: except OSError:
#already exists #already exists
@ -71,11 +81,11 @@ def try_copy(src, dst, add_write_perm=True):
try: try:
if os.path.isdir(dst): if os.path.isdir(dst):
dstfile = dst + "/" + os.path.basename(src) dstfile = dst + "/" + os.path.basename(src)
if os.path.lexists(dstfile): if file_exists(dstfile, follow_symlinks=False):
os.remove(dstfile) os.remove(dstfile)
else: else:
dstfile = dst dstfile = dst
if os.path.lexists(dst): if file_exists(dst, follow_symlinks=False):
os.remove(dst) os.remove(dst)
shutil.copy(src, dst) shutil.copy(src, dst)
@ -95,9 +105,9 @@ def try_copyfile(src, dst):
try: try:
if os.path.isdir(dst): if os.path.isdir(dst):
dstfile = dst + "/" + os.path.basename(src) dstfile = dst + "/" + os.path.basename(src)
if os.path.lexists(dstfile): if file_exists(dstfile, follow_symlinks=False):
os.remove(dstfile) os.remove(dstfile)
elif os.path.lexists(dst): elif file_exists(dst, follow_symlinks=False):
os.remove(dst) os.remove(dst)
shutil.copyfile(src, dst) shutil.copyfile(src, dst)
except PermissionError as e: except PermissionError as e:
@ -166,18 +176,18 @@ class Proton:
def need_tarball_extraction(self): def need_tarball_extraction(self):
'''Checks if the proton_dist tarball archive must be extracted. Returns true if extraction is needed, false otherwise''' '''Checks if the proton_dist tarball archive must be extracted. Returns true if extraction is needed, false otherwise'''
return not os.path.exists(self.dist_dir) or \ return not file_exists(self.dist_dir, follow_symlinks=True) or \
not os.path.exists(self.path("dist/version")) or \ not file_exists(self.path("dist/version"), follow_symlinks=True) or \
not filecmp.cmp(self.version_file, self.path("dist/version")) not filecmp.cmp(self.version_file, self.path("dist/version"))
def extract_tarball(self): def extract_tarball(self):
with self.dist_lock: with self.dist_lock:
if self.need_tarball_extraction(): if self.need_tarball_extraction():
if os.path.exists(self.dist_dir): if file_exists(self.dist_dir, follow_symlinks=True):
shutil.rmtree(self.dist_dir) shutil.rmtree(self.dist_dir)
tar = None tar = None
for sf in ["", ".xz", ".bz2", ".gz"]: for sf in ["", ".xz", ".bz2", ".gz"]:
if os.path.exists(self.path("proton_dist.tar" + sf)): if file_exists(self.path("proton_dist.tar" + sf), follow_symlinks=True):
tar = tarfile.open(self.path("proton_dist.tar" + sf), mode="r:*") tar = tarfile.open(self.path("proton_dist.tar" + sf), mode="r:*")
break break
if not tar: if not tar:
@ -214,7 +224,7 @@ class CompatData:
return self.base_dir + d return self.base_dir + d
def remove_tracked_files(self): def remove_tracked_files(self):
if not os.path.exists(self.tracked_files_file): if not file_exists(self.tracked_files_file, follow_symlinks=True):
log("Prefix has no tracked_files??") log("Prefix has no tracked_files??")
return return
@ -222,7 +232,7 @@ class CompatData:
dirs = [] dirs = []
for f in tracked_files: for f in tracked_files:
path = self.prefix_dir + f.strip() path = self.prefix_dir + f.strip()
if os.path.exists(path): if file_exists(path, follow_symlinks=False):
if os.path.isfile(path) or os.path.islink(path): if os.path.isfile(path) or os.path.islink(path):
os.remove(path) os.remove(path)
else: else:
@ -262,21 +272,21 @@ class CompatData:
(int(new_proton_maj) == int(old_proton_maj) and \ (int(new_proton_maj) == int(old_proton_maj) and \
int(new_proton_min) < int(old_proton_min)): int(new_proton_min) < int(old_proton_min)):
log("Removing newer prefix") log("Removing newer prefix")
if old_proton_ver == "3.7" and not os.path.exists(self.tracked_files_file): if old_proton_ver == "3.7" and not file_exists(self.tracked_files_file, follow_symlinks=True):
#proton 3.7 did not generate tracked_files, so copy it into place first #proton 3.7 did not generate tracked_files, so copy it into place first
try_copy(g_proton.path("proton_3.7_tracked_files"), self.tracked_files_file) try_copy(g_proton.path("proton_3.7_tracked_files"), self.tracked_files_file)
self.remove_tracked_files() self.remove_tracked_files()
return return
if old_proton_ver == "3.7" and old_prefix_ver == "1": if old_proton_ver == "3.7" and old_prefix_ver == "1":
if not os.path.exists(self.prefix_dir + "/drive_c/windows/syswow64/kernel32.dll"): if not file_exists(self.prefix_dir + "/drive_c/windows/syswow64/kernel32.dll", follow_symlinks=True):
#shipped a busted 64-bit-only installation on 20180822. detect and wipe clean #shipped a busted 64-bit-only installation on 20180822. detect and wipe clean
log("Detected broken 64-bit-only installation, re-creating prefix.") log("Detected broken 64-bit-only installation, re-creating prefix.")
shutil.rmtree(self.prefix_dir) shutil.rmtree(self.prefix_dir)
return return
#replace broken .NET installations with wine-mono support #replace broken .NET installations with wine-mono support
if os.path.exists(self.prefix_dir + "/drive_c/windows/Microsoft.NET/NETFXRepair.exe") and \ if file_exists(self.prefix_dir + "/drive_c/windows/Microsoft.NET/NETFXRepair.exe", follow_symlinks=True) and \
file_is_wine_builtin_dll(self.prefix_dir + "/drive_c/windows/system32/mscoree.dll"): file_is_wine_builtin_dll(self.prefix_dir + "/drive_c/windows/system32/mscoree.dll"):
log("Broken .NET installation detected, switching to wine-mono.") log("Broken .NET installation detected, switching to wine-mono.")
#deleting this directory allows wine-mono to work #deleting this directory allows wine-mono to work
@ -334,18 +344,18 @@ class CompatData:
if len(rel_dir) > 0: if len(rel_dir) > 0:
rel_dir = rel_dir + "/" rel_dir = rel_dir + "/"
dst_dir = src_dir.replace(g_proton.default_pfx_dir, self.prefix_dir, 1) dst_dir = src_dir.replace(g_proton.default_pfx_dir, self.prefix_dir, 1)
if not os.path.exists(dst_dir): if not file_exists(dst_dir, follow_symlinks=True):
os.makedirs(dst_dir) makedirs(dst_dir)
tracked_files.write(rel_dir + "\n") tracked_files.write(rel_dir + "\n")
for dir_ in dirs: for dir_ in dirs:
src_file = os.path.join(src_dir, dir_) src_file = os.path.join(src_dir, dir_)
dst_file = os.path.join(dst_dir, dir_) dst_file = os.path.join(dst_dir, dir_)
if os.path.islink(src_file) and not os.path.exists(dst_file): if os.path.islink(src_file) and not file_exists(dst_file, follow_symlinks=True):
self.pfx_copy(src_file, dst_file) self.pfx_copy(src_file, dst_file)
for file_ in files: for file_ in files:
src_file = os.path.join(src_dir, file_) src_file = os.path.join(src_dir, file_)
dst_file = os.path.join(dst_dir, file_) dst_file = os.path.join(dst_dir, file_)
if not os.path.exists(dst_file): if not file_exists(dst_file, follow_symlinks=True):
self.pfx_copy(src_file, dst_file) self.pfx_copy(src_file, dst_file)
tracked_files.write(rel_dir + file_ + "\n") tracked_files.write(rel_dir + file_ + "\n")
@ -361,8 +371,8 @@ class CompatData:
if len(rel_dir) > 0: if len(rel_dir) > 0:
rel_dir = rel_dir + "/" rel_dir = rel_dir + "/"
dst_dir = src_dir.replace(g_proton.default_pfx_dir, self.prefix_dir, 1) dst_dir = src_dir.replace(g_proton.default_pfx_dir, self.prefix_dir, 1)
if not os.path.exists(dst_dir): if not file_exists(dst_dir, follow_symlinks=True):
os.makedirs(dst_dir) makedirs(dst_dir)
tracked_files.write(rel_dir + "\n") tracked_files.write(rel_dir + "\n")
for file_ in files: for file_ in files:
src_file = os.path.join(src_dir, file_) src_file = os.path.join(src_dir, file_)
@ -372,7 +382,7 @@ class CompatData:
continue continue
if file_is_wine_builtin_dll(dst_file): if file_is_wine_builtin_dll(dst_file):
os.unlink(dst_file) os.unlink(dst_file)
elif os.path.lexists(dst_file): elif file_exists(dst_file, follow_symlinks=False):
# builtin library was replaced # builtin library was replaced
continue continue
else: else:
@ -397,7 +407,7 @@ class CompatData:
for p in fontsmap: for p in fontsmap:
lname = os.path.join(windowsfonts, p[1]) lname = os.path.join(windowsfonts, p[1])
fname = os.path.join(g_proton.fonts_dir, p[0]) fname = os.path.join(g_proton.fonts_dir, p[0])
if os.path.lexists(lname): if file_exists(lname, follow_symlinks=False):
if os.path.islink(lname): if os.path.islink(lname):
os.remove(lname) os.remove(lname)
os.symlink(fname, lname) os.symlink(fname, lname)
@ -406,7 +416,7 @@ class CompatData:
def setup_prefix(self): def setup_prefix(self):
with self.prefix_lock: with self.prefix_lock:
if os.path.exists(self.version_file): if file_exists(self.version_file, follow_symlinks=True):
with open(self.version_file, "r") as f: with open(self.version_file, "r") as f:
old_ver = f.readline().strip() old_ver = f.readline().strip()
else: else:
@ -414,11 +424,11 @@ class CompatData:
self.upgrade_pfx(old_ver) self.upgrade_pfx(old_ver)
if not os.path.exists(self.prefix_dir): if not file_exists(self.prefix_dir, follow_symlinks=True):
makedirs(self.prefix_dir + "/drive_c") makedirs(self.prefix_dir + "/drive_c")
set_dir_casefold_bit(self.prefix_dir + "/drive_c") set_dir_casefold_bit(self.prefix_dir + "/drive_c")
if not os.path.exists(self.prefix_dir + "/user.reg"): if not file_exists(self.prefix_dir + "/user.reg", follow_symlinks=True):
self.copy_pfx() self.copy_pfx()
# collect configuration info # collect configuration info
@ -477,20 +487,19 @@ class CompatData:
builtin_dll_copy, builtin_dll_copy,
)) ))
if old_ver == CURRENT_PREFIX_VERSION: # check whether any prefix config has changed
# check whether any prefix config has changed try:
try: with open(self.config_info_file, "r") as f:
with open(self.config_info_file, "r") as f: old_prefix_info = f.read()
old_prefix_info = f.read() except IOError:
except IOError: old_prefix_info = ""
old_prefix_info = ""
if old_prefix_info != prefix_info: if old_ver != CURRENT_PREFIX_VERSION or old_prefix_info != prefix_info:
# update builtin dll symlinks or copies # update builtin dll symlinks or copies
self.update_builtin_libs(builtin_dll_copy) self.update_builtin_libs(builtin_dll_copy)
with open(self.config_info_file, "w") as f: with open(self.config_info_file, "w") as f:
f.write(prefix_info) f.write(prefix_info)
with open(self.version_file, "w") as f: with open(self.version_file, "w") as f:
f.write(CURRENT_PREFIX_VERSION + "\n") f.write(CURRENT_PREFIX_VERSION + "\n")
@ -578,17 +587,17 @@ class CompatData:
if "gamedrive" in g_session.compat_config: if "gamedrive" in g_session.compat_config:
library_dir = try_get_game_library_dir() library_dir = try_get_game_library_dir()
if not library_dir: if not library_dir:
if os.path.lexists(gamedrive_path): if file_exists(gamedrive_path, follow_symlinks=False):
os.remove(gamedrive_path) os.remove(gamedrive_path)
else: else:
if os.path.lexists(gamedrive_path): if file_exists(gamedrive_path, follow_symlinks=False):
cur_tgt = os.readlink(gamedrive_path) cur_tgt = os.readlink(gamedrive_path)
if cur_tgt != library_dir: if cur_tgt != library_dir:
os.remove(gamedrive_path) os.remove(gamedrive_path)
os.symlink(library_dir, gamedrive_path) os.symlink(library_dir, gamedrive_path)
else: else:
os.symlink(library_dir, gamedrive_path) os.symlink(library_dir, gamedrive_path)
elif os.path.lexists(gamedrive_path): elif file_exists(gamedrive_path, follow_symlinks=False):
os.remove(gamedrive_path) os.remove(gamedrive_path)
def comma_escaped(s): def comma_escaped(s):
@ -688,7 +697,7 @@ class Session:
self.env["WINEPREFIX"] = g_compatdata.prefix_dir self.env["WINEPREFIX"] = g_compatdata.prefix_dir
#load environment overrides #load environment overrides
if os.path.exists(g_proton.user_settings_file): if file_exists(g_proton.user_settings_file, follow_symlinks=True):
try: try:
import user_settings import user_settings
for key, value in user_settings.user_settings.items(): for key, value in user_settings.user_settings.items():
@ -765,7 +774,7 @@ class Session:
basedir = self.env.get("PROTON_LOG_DIR", os.environ["HOME"]) basedir = self.env.get("PROTON_LOG_DIR", os.environ["HOME"])
makedirs(basedir) makedirs(basedir)
lfile_path = basedir + "/steam-" + os.environ["SteamGameId"] + ".log" lfile_path = basedir + "/steam-" + os.environ["SteamGameId"] + ".log"
if os.path.exists(lfile_path): if file_exists(lfile_path, follow_symlinks=False):
os.remove(lfile_path) os.remove(lfile_path)
self.log_file = open(lfile_path, "w+") self.log_file = open(lfile_path, "w+")
self.log_file.write("======================\n") self.log_file.write("======================\n")