Changeset View
Changeset View
Standalone View
Standalone View
src/kcrash.cpp
Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Line(s) | |||||
42 | #ifdef Q_OS_LINUX | 42 | #ifdef Q_OS_LINUX | ||
43 | #include <sys/poll.h> | 43 | #include <sys/poll.h> | ||
44 | #include <sys/prctl.h> | 44 | #include <sys/prctl.h> | ||
45 | #endif | 45 | #endif | ||
46 | 46 | | |||
47 | #include <kaboutdata.h> | 47 | #include <kaboutdata.h> | ||
48 | #include <kstartupinfo.h> | 48 | #include <kstartupinfo.h> | ||
49 | 49 | | |||
50 | #include <array> | ||||
51 | #include <algorithm> | ||||
52 | | ||||
50 | #include <QDebug> | 53 | #include <QDebug> | ||
51 | #include <QGuiApplication> | 54 | #include <QGuiApplication> | ||
52 | #include <QStandardPaths> | 55 | #include <QStandardPaths> | ||
53 | #include <QThread> | 56 | #include <QThread> | ||
54 | #include <QLibraryInfo> | 57 | #include <QLibraryInfo> | ||
55 | #include <QFile> | 58 | #include <QFile> | ||
56 | 59 | | |||
57 | #include <QLoggingCategory> | 60 | #include <QLoggingCategory> | ||
▲ Show 20 Lines • Show All 620 Lines • ▼ Show 20 Line(s) | 680 | if (!s_coreConfig->isProcess()) { | |||
678 | // Only exit if we don't forward to core dumps | 681 | // Only exit if we don't forward to core dumps | ||
679 | _exit(253); | 682 | _exit(253); | ||
680 | } | 683 | } | ||
681 | } | 684 | } | ||
682 | } | 685 | } | ||
683 | 686 | | |||
684 | static pid_t startDirectly(const char *argv[]) | 687 | static pid_t startDirectly(const char *argv[]) | ||
685 | { | 688 | { | ||
689 | static char autorestarted_envvar[] = "KCRASH_AUTO_RESTARTED"; | ||||
bruns: move this to the lambda scope, you can also make the var name shorter then. | |||||
690 | char** environ_end; | ||||
691 | for(environ_end = environ; *environ_end; ++environ_end) {} | ||||
apol: Use {} instead of ; for readability. | |||||
jpalecek: Done that. | |||||
692 | | ||||
693 | std::array<const char*, 1024> environ_data; //hope it's big enough | ||||
anthonyfieroni: Just use vector, get the size by `environ_end - environ` | |||||
No, that would be dynamic allocation, which is not safe in signal handlers. The whole purpose was to avoid it. jpalecek: No, that would be dynamic allocation, which is not safe in signal handlers. The whole purpose… | |||||
694 | if((unsigned)(environ_end - environ) +2 >= environ_data.size()) { | ||||
695 | fprintf(stderr, "environ_data in KCrash not big enough!\n"); | ||||
696 | return 0; | ||||
697 | } | ||||
698 | auto end = std::copy(environ, environ_end, environ_data.begin()); | ||||
bruns: `std::copy_if`, instead of a separate `remove_if` pass. | |||||
Thanks for that suggestion, updated accordingly. I admit I'm still more accustomed to the old ways of remove_if. jpalecek: Thanks for that suggestion, updated accordingly. I admit I'm still more accustomed to the old… | |||||
699 | | ||||
700 | end = std::remove_if(environ_data.begin(), end, | ||||
701 | [](const char* s) { | ||||
702 | return strncmp(autorestarted_envvar, s, sizeof(autorestarted_envvar)-1) == 0 && | ||||
703 | s[sizeof(autorestarted_envvar)-1] == '='; | ||||
the part after the && can be removed when you include the '=' in the static string bruns: the part after the `&&` can be removed when you include the '=' in the static string | |||||
704 | }); | ||||
705 | *end++ = "KCRASH_AUTO_RESTARTED=1"; | ||||
706 | *end++ = nullptr; | ||||
686 | pid_t pid = fork(); | 707 | pid_t pid = fork(); | ||
687 | switch (pid) { | 708 | switch (pid) { | ||
688 | case -1: | 709 | case -1: | ||
689 | fprintf(stderr, "KCrash failed to fork(), errno = %d\n", errno); | 710 | fprintf(stderr, "KCrash failed to fork(), errno = %d\n", errno); | ||
690 | return 0; | 711 | return 0; | ||
691 | case 0: | 712 | case 0: | ||
692 | setgroups(0, nullptr); // Remove any extraneous groups | 713 | setgroups(0, nullptr); // Remove any extraneous groups | ||
693 | if (setgid(getgid()) < 0 || setuid(getuid()) < 0) { | 714 | if (setgid(getgid()) < 0 || setuid(getuid()) < 0) { | ||
694 | _exit(253); // This cannot happen. Theoretically. | 715 | _exit(253); // This cannot happen. Theoretically. | ||
695 | } | 716 | } | ||
696 | #ifndef Q_OS_OSX | 717 | #ifndef Q_OS_OSX | ||
697 | closeAllFDs(); // We are in the child now. Close FDs unconditionally. | 718 | closeAllFDs(); // We are in the child now. Close FDs unconditionally. | ||
698 | #endif | 719 | #endif | ||
699 | setenv("KCRASH_AUTO_RESTARTED", "1", 1); | 720 | execvpe(argv[0], const_cast< char ** >(argv), const_cast<char**> (environ_data.data())); | ||
700 | execvp(argv[0], const_cast< char ** >(argv)); | | |||
701 | fprintf(stderr, "KCrash failed to exec(), errno = %d\n", errno); | 721 | fprintf(stderr, "KCrash failed to exec(), errno = %d\n", errno); | ||
702 | _exit(253); | 722 | _exit(253); | ||
703 | default: | 723 | default: | ||
704 | return pid; | 724 | return pid; | ||
705 | } | 725 | } | ||
706 | } | 726 | } | ||
707 | 727 | | |||
708 | /* | 728 | /* | ||
▲ Show 20 Lines • Show All 136 Lines • Show Last 20 Lines |
move this to the lambda scope, you can also make the var name shorter then.