mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
macOS: Fix PDF Output not working when running ebook-convert via symlink on the command line. Fixes #1857377 [ebook-convert hangs on rendering (possible packaging issue)](https://bugs.launchpad.net/calibre/+bug/1857377)
It really grinds my gears that this is necessary, but with macOS...
This commit is contained in:
parent
fb7154b67c
commit
e24e4b0a58
@ -1,5 +1,14 @@
|
||||
#include "util.h"
|
||||
#include <stdlib.h>
|
||||
#include <libproc.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define fatal(...) { fprintf(stderr, __VA_ARGS__); exit(EXIT_FAILURE); }
|
||||
#define arraysz(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
||||
|
||||
// These variables must be filled in before compiling
|
||||
static const char *ENV_VARS[] = { /*ENV_VARS*/ NULL };
|
||||
@ -10,8 +19,23 @@ static const char FUNCTION[] = "**FUNCTION**";
|
||||
static const char PYVER[] = "**PYVER**";
|
||||
|
||||
|
||||
int
|
||||
main(int argc, const char **argv, const char **envp) {
|
||||
return run(ENV_VARS, ENV_VAR_VALS, PROGRAM, MODULE, FUNCTION, PYVER, **IS_GUI**, argc, argv, envp);
|
||||
}
|
||||
int
|
||||
main(int argc, char* const *argv, const char **envp) {
|
||||
char pathbuf[PROC_PIDPATHINFO_MAXSIZE], realpath_buf[PROC_PIDPATHINFO_MAXSIZE * 5];
|
||||
pid_t pid = getpid();
|
||||
int ret = proc_pidpath(pid, pathbuf, arraysz(pathbuf));
|
||||
if (ret <= 0) fatal("failed to get executable path for current pid with error: %s", strerror(errno));
|
||||
char *path = realpath(pathbuf, realpath_buf);
|
||||
if (path == NULL) fatal("failed to get realpath for executable path with error: %s", strerror(errno));
|
||||
// We re-exec using an absolute path because the Qt WebEngine sandbox does not work
|
||||
// when running via symlink
|
||||
const int is_gui = **IS_GUI**;
|
||||
if (!is_gui && strcmp(PROGRAM, "calibre-parallel") != 0 && strcmp(argv[0], path) != 0) {
|
||||
char* new_argv[1024] = {0};
|
||||
new_argv[0] = path;
|
||||
for (int i = 1; i < argc && i < arraysz(new_argv) - 1; i++) new_argv[i] = argv[i];
|
||||
execv(path, new_argv);
|
||||
}
|
||||
|
||||
return run(ENV_VARS, ENV_VAR_VALS, PROGRAM, MODULE, FUNCTION, PYVER, is_gui, argc, argv, envp, path);
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ set_env_vars(const char **ENV_VARS, const char **ENV_VAR_VALS, const char* exe_p
|
||||
|
||||
void initialize_interpreter(const char **ENV_VARS, const char **ENV_VAR_VALS,
|
||||
char *PROGRAM, const char *MODULE, const char *FUNCTION, const char *PYVER, int IS_GUI,
|
||||
const char* exe_path, const char *rpath, int argc, const char **argv) {
|
||||
const char* exe_path, const char *rpath, int argc, char* const *argv) {
|
||||
PyObject *pargv, *v;
|
||||
int i;
|
||||
Py_OptimizeFlag = 2;
|
||||
@ -59,7 +59,7 @@ void initialize_interpreter(const char **ENV_VARS, const char **ENV_VAR_VALS,
|
||||
|
||||
//Py_VerboseFlag = 1;
|
||||
//Py_DebugFlag = 1;
|
||||
|
||||
|
||||
Py_SetProgramName(PROGRAM);
|
||||
|
||||
char pyhome[1000];
|
||||
@ -124,7 +124,7 @@ int handle_sysexit(PyObject *e) {
|
||||
|
||||
int calibre_show_python_error(const char *preamble, int code) {
|
||||
PyObject *exc, *val, *tb, *str;
|
||||
int ret, issysexit = 0; char *i;
|
||||
int ret, issysexit = 0; char *i;
|
||||
|
||||
if (!PyErr_Occurred()) return code;
|
||||
issysexit = PyErr_ExceptionMatches(PyExc_SystemExit);
|
||||
@ -159,41 +159,28 @@ EXPORT
|
||||
int
|
||||
run(const char **ENV_VARS, const char **ENV_VAR_VALS, char *PROGRAM,
|
||||
const char *MODULE, const char *FUNCTION, const char *PYVER,
|
||||
int IS_GUI, int argc, const char **argv, const char **envp) {
|
||||
char *pathPtr = NULL, *t = NULL;
|
||||
char buf[3*PATH_MAX];
|
||||
int IS_GUI, int argc, char * const *argv, const char **envp, char *full_exe_path) {
|
||||
char *t = NULL;
|
||||
int ret = 0, i;
|
||||
PyObject *site, *mainf, *res;
|
||||
uint32_t buf_size = PATH_MAX+1;
|
||||
char *ebuf = calloc(buf_size, sizeof(char));
|
||||
|
||||
ret = _NSGetExecutablePath(ebuf, &buf_size);
|
||||
if (ret == -1) {
|
||||
free(ebuf);
|
||||
ebuf = calloc(buf_size, sizeof(char));
|
||||
if (_NSGetExecutablePath(ebuf, &buf_size) != 0)
|
||||
return report_error("Failed to find real path of executable.");
|
||||
}
|
||||
pathPtr = realpath(ebuf, buf);
|
||||
if (pathPtr == NULL) {
|
||||
return report_error(strerror(errno));
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
t = rindex(pathPtr, '/');
|
||||
t = rindex(full_exe_path, '/');
|
||||
if (t == NULL) return report_error("Failed to determine bundle path.");
|
||||
*t = '\0';
|
||||
}
|
||||
if (strstr(pathPtr, "/calibre.app/Contents/") != NULL) {
|
||||
if (strstr(full_exe_path, "/calibre.app/Contents/") != NULL) {
|
||||
// We are one of the duplicate executables created to workaround codesign's limitations
|
||||
for (i = 0; i < 2; i++) {
|
||||
t = rindex(pathPtr, '/');
|
||||
t = rindex(full_exe_path, '/');
|
||||
if (t == NULL) return report_error("Failed to resolve bundle path in dummy executable");
|
||||
*t = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
char rpath[PATH_MAX+1], exe_path[PATH_MAX+1];
|
||||
snprintf(exe_path, PATH_MAX+1, "%s/Contents", pathPtr);
|
||||
snprintf(exe_path, PATH_MAX+1, "%s/Contents", full_exe_path);
|
||||
snprintf(rpath, PATH_MAX+1, "%s/Resources", exe_path);
|
||||
initialize_interpreter(ENV_VARS, ENV_VAR_VALS, PROGRAM, MODULE, FUNCTION, PYVER, IS_GUI,
|
||||
exe_path, rpath, argc, argv);
|
||||
@ -206,13 +193,13 @@ run(const char **ENV_VARS, const char **ENV_VAR_VALS, char *PROGRAM,
|
||||
Py_XINCREF(site);
|
||||
|
||||
mainf = PyObject_GetAttrString(site, "main");
|
||||
if (mainf == NULL || !PyCallable_Check(mainf))
|
||||
if (mainf == NULL || !PyCallable_Check(mainf))
|
||||
ret = calibre_show_python_error("site module has no main function", -1);
|
||||
else {
|
||||
Py_XINCREF(mainf);
|
||||
res = PyObject_CallObject(mainf, NULL);
|
||||
|
||||
if (res == NULL)
|
||||
if (res == NULL)
|
||||
ret = calibre_show_python_error("Python function terminated unexpectedly", -1);
|
||||
else {
|
||||
}
|
||||
@ -224,6 +211,3 @@ run(const char **ENV_VARS, const char **ENV_VAR_VALS, char *PROGRAM,
|
||||
//printf("11111 Returning: %d\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
int run(const char **ENV_VARS, const char **ENV_VAR_VALS, char *PROGRAM,
|
||||
const char *MODULE, const char *FUNCTION, const char *PYVER, int IS_GUI,
|
||||
int argc, const char **argv, const char **envp);
|
||||
int argc, char *const *argv, const char **envp, char *full_exe_path);
|
||||
|
Loading…
x
Reference in New Issue
Block a user