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)
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();
}
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);
}
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
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);
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")) {
+#ifdef HAVE_MINGW
+ SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
+#else
+ nice(0);
+#endif
+ } else if(!strcasecmp(priority, "Low")) {
+#ifdef HAVE_MINGW
+ SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
+#else
+ nice(10);
+#endif
+ } else if(!strcasecmp(priority, "High")) {
+#ifdef HAVE_MINGW
+ SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
+#else
+ nice(-10);
+#endif
+ } else {
+ logger(LOG_ERR, _("Invalid priority `%s`!"), priority);
+ goto end;
+ }
+ }
+
/* drop privileges */
if (!drop_privs())
goto end;