mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Possible fix for crash on some linux systems in Qt 5 with --detach
Do the fork() before loading any Qt modules.
This commit is contained in:
parent
ebc552e118
commit
b505225c90
@ -874,23 +874,6 @@ def setup_gui_option_parser(parser):
|
|||||||
parser.add_option('--detach', default=False, action='store_true',
|
parser.add_option('--detach', default=False, action='store_true',
|
||||||
help=_('Detach from the controlling terminal, if any (linux only)'))
|
help=_('Detach from the controlling terminal, if any (linux only)'))
|
||||||
|
|
||||||
def do_detach(fork=True, setsid=True, redirect=True):
|
|
||||||
if fork:
|
|
||||||
# Detach from the controlling process.
|
|
||||||
if os.fork() != 0:
|
|
||||||
raise SystemExit(0)
|
|
||||||
if setsid:
|
|
||||||
os.setsid()
|
|
||||||
if redirect:
|
|
||||||
try:
|
|
||||||
plugins['speedup'][0].detach(os.devnull)
|
|
||||||
except AttributeError:
|
|
||||||
pass # people running from source without updated binaries
|
|
||||||
|
|
||||||
def detach_gui():
|
|
||||||
if islinux and not DEBUG:
|
|
||||||
do_detach()
|
|
||||||
|
|
||||||
class Application(QApplication):
|
class Application(QApplication):
|
||||||
|
|
||||||
def __init__(self, args, force_calibre_style=False, override_program_name=None, headless=False):
|
def __init__(self, args, force_calibre_style=False, override_program_name=None, headless=False):
|
||||||
|
@ -13,7 +13,7 @@ from calibre.constants import (iswindows, __appname__, isosx, DEBUG, islinux,
|
|||||||
from calibre.utils.ipc import gui_socket_address, RC
|
from calibre.utils.ipc import gui_socket_address, RC
|
||||||
from calibre.gui2 import (
|
from calibre.gui2 import (
|
||||||
ORG_NAME, APP_UID, initialize_file_icon_provider, Application, choose_dir,
|
ORG_NAME, APP_UID, initialize_file_icon_provider, Application, choose_dir,
|
||||||
error_dialog, question_dialog, gprefs, detach_gui, setup_gui_option_parser)
|
error_dialog, question_dialog, gprefs, setup_gui_option_parser)
|
||||||
from calibre.gui2.main_window import option_parser as _option_parser
|
from calibre.gui2.main_window import option_parser as _option_parser
|
||||||
from calibre.gui2.splash import SplashScreen
|
from calibre.gui2.splash import SplashScreen
|
||||||
from calibre.utils.config import prefs, dynamic
|
from calibre.utils.config import prefs, dynamic
|
||||||
@ -86,8 +86,6 @@ def find_portable_library():
|
|||||||
def init_qt(args):
|
def init_qt(args):
|
||||||
parser = option_parser()
|
parser = option_parser()
|
||||||
opts, args = parser.parse_args(args)
|
opts, args = parser.parse_args(args)
|
||||||
if getattr(opts, 'detach', False):
|
|
||||||
detach_gui()
|
|
||||||
find_portable_library()
|
find_portable_library()
|
||||||
if opts.with_library is not None:
|
if opts.with_library is not None:
|
||||||
libpath = os.path.expanduser(opts.with_library)
|
libpath = os.path.expanduser(opts.with_library)
|
||||||
|
@ -11,7 +11,7 @@ import sys, os, importlib, time
|
|||||||
from PyQt5.Qt import QIcon
|
from PyQt5.Qt import QIcon
|
||||||
|
|
||||||
from calibre.constants import islinux, iswindows
|
from calibre.constants import islinux, iswindows
|
||||||
from calibre.gui2 import Application, ORG_NAME, APP_UID, setup_gui_option_parser, detach_gui, decouple
|
from calibre.gui2 import Application, ORG_NAME, APP_UID, setup_gui_option_parser, decouple
|
||||||
from calibre.ptempfile import reset_base_dir
|
from calibre.ptempfile import reset_base_dir
|
||||||
from calibre.utils.config import OptionParser
|
from calibre.utils.config import OptionParser
|
||||||
|
|
||||||
@ -51,8 +51,6 @@ def _run(args, notify=None):
|
|||||||
|
|
||||||
parser = option_parser()
|
parser = option_parser()
|
||||||
opts, args = parser.parse_args(args)
|
opts, args = parser.parse_args(args)
|
||||||
if getattr(opts, 'detach', False):
|
|
||||||
detach_gui()
|
|
||||||
decouple('edit-book-')
|
decouple('edit-book-')
|
||||||
override = 'calibre-edit-book' if islinux else None
|
override = 'calibre-edit-book' if islinux else None
|
||||||
app = Application(args, override_program_name=override)
|
app = Application(args, override_program_name=override)
|
||||||
|
@ -15,7 +15,7 @@ from calibre.gui2.viewer.toc import TOC
|
|||||||
from calibre.gui2.widgets import ProgressIndicator
|
from calibre.gui2.widgets import ProgressIndicator
|
||||||
from calibre.gui2 import (
|
from calibre.gui2 import (
|
||||||
Application, ORG_NAME, APP_UID, choose_files, info_dialog, error_dialog,
|
Application, ORG_NAME, APP_UID, choose_files, info_dialog, error_dialog,
|
||||||
open_url, setup_gui_option_parser, detach_gui)
|
open_url, setup_gui_option_parser)
|
||||||
from calibre.ebooks.oeb.iterator.book import EbookIterator
|
from calibre.ebooks.oeb.iterator.book import EbookIterator
|
||||||
from calibre.ebooks import DRMError
|
from calibre.ebooks import DRMError
|
||||||
from calibre.constants import islinux, filesystem_encoding
|
from calibre.constants import islinux, filesystem_encoding
|
||||||
@ -991,8 +991,6 @@ def main(args=sys.argv):
|
|||||||
|
|
||||||
parser = option_parser()
|
parser = option_parser()
|
||||||
opts, args = parser.parse_args(args)
|
opts, args = parser.parse_args(args)
|
||||||
if getattr(opts, 'detach', False):
|
|
||||||
detach_gui()
|
|
||||||
open_at = float(opts.open_at.replace(',', '.')) if opts.open_at else None
|
open_at = float(opts.open_at.replace(',', '.')) if opts.open_at else None
|
||||||
override = 'calibre-ebook-viewer' if islinux else None
|
override = 'calibre-ebook-viewer' if islinux else None
|
||||||
app = Application(args, override_program_name=override)
|
app = Application(args, override_program_name=override)
|
||||||
|
51
src/calibre/gui_launch.py
Normal file
51
src/calibre/gui_launch.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=utf-8
|
||||||
|
from __future__ import (unicode_literals, division, absolute_import,
|
||||||
|
print_function)
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
|
|
||||||
|
import os, sys
|
||||||
|
|
||||||
|
# For some reason Qt 5 crashes on some linux systems if the fork() is done
|
||||||
|
# after the Qt modules are loaded in calibre.gui2. We also cannot do a fork()
|
||||||
|
# while python is importing a module. So we use this simple launcher module to
|
||||||
|
# launch all the GUI apps, forking before Qt is loaded and not during a
|
||||||
|
# python import.
|
||||||
|
|
||||||
|
def do_detach(fork=True, setsid=True, redirect=True):
|
||||||
|
if fork:
|
||||||
|
# Detach from the controlling process.
|
||||||
|
if os.fork() != 0:
|
||||||
|
raise SystemExit(0)
|
||||||
|
if setsid:
|
||||||
|
os.setsid()
|
||||||
|
if redirect:
|
||||||
|
from calibre.constants import plugins
|
||||||
|
try:
|
||||||
|
plugins['speedup'][0].detach(os.devnull)
|
||||||
|
except AttributeError:
|
||||||
|
pass # people running from source without updated binaries
|
||||||
|
|
||||||
|
def detach_gui():
|
||||||
|
from calibre.constants import islinux, isbsd, DEBUG
|
||||||
|
if (islinux or isbsd) and not DEBUG and '--detach' in sys.argv:
|
||||||
|
do_detach()
|
||||||
|
|
||||||
|
|
||||||
|
def calibre():
|
||||||
|
detach_gui()
|
||||||
|
from calibre.gui2.main import main
|
||||||
|
main()
|
||||||
|
|
||||||
|
def ebook_viewer():
|
||||||
|
detach_gui()
|
||||||
|
from calibre.gui2.viewer.main import main
|
||||||
|
main()
|
||||||
|
|
||||||
|
def ebook_edit():
|
||||||
|
detach_gui()
|
||||||
|
from calibre.gui2.tweak_book.main import main
|
||||||
|
main()
|
||||||
|
|
@ -34,11 +34,11 @@ entry_points = {
|
|||||||
'calibre-smtp = calibre.utils.smtp:main',
|
'calibre-smtp = calibre.utils.smtp:main',
|
||||||
],
|
],
|
||||||
'gui_scripts' : [
|
'gui_scripts' : [
|
||||||
__appname__+' = calibre.gui2.main:main',
|
__appname__+' = calibre.gui_launch:calibre',
|
||||||
'lrfviewer = calibre.gui2.lrf_renderer.main:main',
|
'lrfviewer = calibre.gui2.lrf_renderer.main:main',
|
||||||
'ebook-viewer = calibre.gui2.viewer.main:main',
|
'ebook-viewer = calibre.gui_launch:ebook_viewer',
|
||||||
'ebook-edit = calibre.gui2.tweak_book.main:main',
|
'ebook-edit = calibre.gui_launch:ebook_edit',
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
class PreserveMIMEDefaults(object):
|
class PreserveMIMEDefaults(object):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user