mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Use C code to redirect standard I/O streams for --detach and --daemonize
This commit is contained in:
parent
177998f6a3
commit
df49debcf8
@ -880,10 +880,10 @@ def detach_gui():
|
||||
if os.fork() != 0:
|
||||
raise SystemExit(0)
|
||||
os.setsid()
|
||||
si, so, se = os.open(os.devnull, os.O_RDONLY), os.open(os.devnull, os.O_WRONLY), os.open(os.devnull, os.O_WRONLY)
|
||||
os.dup2(si, sys.__stdin__.fileno())
|
||||
os.dup2(so, sys.__stdout__.fileno())
|
||||
os.dup2(se, sys.__stderr__.fileno())
|
||||
try:
|
||||
plugins['speedup'][0].detach(os.devnull)
|
||||
except AttributeError:
|
||||
pass # people running from source without updated binaries
|
||||
|
||||
class Application(QApplication):
|
||||
|
||||
|
@ -10,7 +10,7 @@ from threading import Thread
|
||||
|
||||
from calibre.library.server import server_config as config
|
||||
from calibre.library.server.base import LibraryServer
|
||||
from calibre.constants import iswindows
|
||||
from calibre.constants import iswindows, plugins
|
||||
import cherrypy
|
||||
|
||||
def start_threaded_server(db, opts):
|
||||
@ -67,7 +67,7 @@ The OPDS interface is advertised via BonJour automatically.
|
||||
' work in all environments.'))
|
||||
return parser
|
||||
|
||||
def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
|
||||
def daemonize():
|
||||
try:
|
||||
pid = os.fork()
|
||||
if pid > 0:
|
||||
@ -93,12 +93,15 @@ def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
|
||||
sys.exit(1)
|
||||
|
||||
# Redirect standard file descriptors.
|
||||
si = file(stdin, 'r')
|
||||
so = file(stdout, 'a+')
|
||||
se = file(stderr, 'a+', 0)
|
||||
os.dup2(si.fileno(), sys.stdin.fileno())
|
||||
os.dup2(so.fileno(), sys.stdout.fileno())
|
||||
os.dup2(se.fileno(), sys.stderr.fileno())
|
||||
try:
|
||||
plugins['speedup'][0].detach(os.devnull)
|
||||
except AttributeError: # people running from source without updated binaries
|
||||
si = os.open(os.devnull, os.O_RDONLY)
|
||||
so = os.open(os.devnull, os.O_WRONLY)
|
||||
se = os.open(os.devnull, os.O_WRONLY)
|
||||
os.dup2(si, sys.stdin.fileno())
|
||||
os.dup2(so, sys.stdout.fileno())
|
||||
os.dup2(se, sys.stderr.fileno())
|
||||
|
||||
|
||||
def main(args=sys.argv):
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define min(x, y) ((x < y) ? x : y)
|
||||
#define max(x, y) ((x > y) ? x : y)
|
||||
@ -97,6 +98,16 @@ speedup_pdf_float(PyObject *self, PyObject *args) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
speedup_detach(PyObject *self, PyObject *args) {
|
||||
char *devnull = NULL;
|
||||
if (!PyArg_ParseTuple(args, "s", &devnull)) return NULL;
|
||||
if (freopen(devnull, "r", stdin) == NULL) return PyErr_SetFromErrno(PyExc_EnvironmentError);
|
||||
if (freopen(devnull, "w", stdout) == NULL) return PyErr_SetFromErrno(PyExc_EnvironmentError);
|
||||
if (freopen(devnull, "w", stderr) == NULL) return PyErr_SetFromErrno(PyExc_EnvironmentError);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyMethodDef speedup_methods[] = {
|
||||
{"parse_date", speedup_parse_date, METH_VARARGS,
|
||||
"parse_date()\n\nParse ISO dates faster."
|
||||
@ -106,6 +117,10 @@ static PyMethodDef speedup_methods[] = {
|
||||
"pdf_float()\n\nConvert float to a string representation suitable for PDF"
|
||||
},
|
||||
|
||||
{"detach", speedup_detach, METH_VARARGS,
|
||||
"detach()\n\nRedirect the standard I/O stream to the specified file (usually os.devnull)"
|
||||
},
|
||||
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user