cleanup setpriority thing to make it readable
[oweals/tinc.git] / src / tincd.c
index a8a0146dfc32a87813ab3d00f04a65c8e9b61ff5..d3594255f2877f4ce341102fc0cc158da65ddf04 100644 (file)
@@ -160,8 +160,13 @@ static bool parse_options(int argc, char **argv)
                                break;
 
                        case 'L':                               /* no detach */
+#ifndef HAVE_MLOCKALL
+                               logger(LOG_ERR, _("%s not supported on this platform"), "mlockall()");
+                               return false;
+#else
                                do_mlock = true;
                                break;
+#endif
 
                        case 'd':                               /* inc debug level */
                                if(optarg)
@@ -452,7 +457,8 @@ static bool drop_privs() {
                uid = pw->pw_uid;
                if (initgroups(switchuser, pw->pw_gid) != 0 ||
                    setgid(pw->pw_gid) != 0) {
-                       logger(LOG_ERR, _("%s failed"), "initgroups()");
+                       logger(LOG_ERR, _("System call `%s' failed: %s"),
+                              "initgroups", strerror(errno));
                        return false;
                }
                endgrent();
@@ -460,8 +466,9 @@ static bool drop_privs() {
        }
        if (do_chroot) {
                tzset();        /* for proper timestamps in logs */
-               if (chroot(confbase) != 0 || chdir(".") != 0) {
-                       logger(LOG_ERR, _("%s failed"), "chroot()");
+               if (chroot(confbase) != 0 || chdir("/") != 0) {
+                       logger(LOG_ERR, _("System call `%s' failed: %s"),
+                              "chroot", strerror(errno));
                        return false;
                }
                free(confbase);
@@ -469,13 +476,23 @@ static bool drop_privs() {
        }
        if (switchuser)
                if (setuid(uid) != 0) {
-                       logger(LOG_ERR, _("%s failed"), "setuid()");
+                       logger(LOG_ERR, _("System call `%s' failed: %s"),
+                              "setuid", strerror(errno));
                        return false;
                }
 #endif
        return true;
 }
 
+#ifdef HAVE_MINGW
+# define setpriority(level) SetPriorityClass(GetCurrentProcess(), level);
+#else
+# define NORMAL_PRIORITY_CLASS 0
+# define BELOW_NORMAL_PRIORITY_CLASS 10
+# define HIGH_PRIORITY_CLASS -10
+# define setpriority(level) nice(level)
+#endif
+
 int main(int argc, char **argv)
 {
        program_name = argv[0];
@@ -511,20 +528,6 @@ int main(int argc, char **argv)
 
        openlogger("tinc", use_logfile?LOGMODE_FILE:LOGMODE_STDERR);
 
-       /* Lock all pages into memory if requested */
-
-       if(do_mlock)
-#ifdef HAVE_MLOCKALL
-               if(mlockall(MCL_CURRENT | MCL_FUTURE)) {
-                       logger(LOG_ERR, _("System call `%s' failed: %s"), "mlockall",
-                                  strerror(errno));
-#else
-       {
-               logger(LOG_ERR, _("mlockall() not supported on this platform!"));
-#endif
-               return -1;
-       }
-
        g_argv = argv;
 
        init_configuration(&config_tree);
@@ -570,11 +573,39 @@ int main2(int argc, char **argv)
        if(!detach())
                return 1;
 
+#ifdef HAVE_MLOCKALL
+       /* Lock all pages into memory if requested.
+        * This has to be done after daemon()/fork() so it works for child.
+        * No need to do that in parent as it's very short-lived. */
+       if(do_mlock && mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {
+               logger(LOG_ERR, _("System call `%s' failed: %s"), "mlockall",
+                  strerror(errno));
+               return 1;
+       }
+#endif
+
        /* Setup sockets and open device. */
 
        if(!setup_network())
                goto end;
 
+        /* Change process priority */
+
+        char *priority = 0;
+
+        if(get_config_string(lookup_config(config_tree, "ProcessPriority"), &priority)) {
+                if(!strcasecmp(priority, "Normal"))
+                        setpriority(NORMAL_PRIORITY_CLASS);
+                else if(!strcasecmp(priority, "Low"))
+                        setpriority(BELOW_NORMAL_PRIORITY_CLASS);
+                else if(!strcasecmp(priority, "High"))
+                        setpriority(HIGH_PRIORITY_CLASS);
+                else {
+                        logger(LOG_ERR, _("Invalid priority `%s`!"), priority);
+                        goto end;
+                }
+        }
+
        /* drop privileges */
        if (!drop_privs())
                goto end;