Use C code to redirect standard I/O streams for --detach and --daemonize

This commit is contained in:
Kovid Goyal 2014-08-24 01:17:28 +05:30
parent 177998f6a3
commit df49debcf8
3 changed files with 30 additions and 12 deletions

View File

@ -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):

View File

@ -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):

View File

@ -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}
};