void uwsgi_as_root() {


	if (getuid() > 0)
		goto nonroot;

#ifndef __RUMP__
	if (!uwsgi.master_as_root && !uwsgi.uidname) {
		uwsgi_log_initial("uWSGI running as root, you can use --uid/--gid/--chroot options\n");
	}
#endif

	int in_jail = 0;

#if defined(__linux__) && !defined(OBSOLETE_LINUX_KERNEL)
	if (uwsgi.unshare && !uwsgi.reloads) {

		if (unshare(uwsgi.unshare)) {
			uwsgi_error("unshare()");
			exit(1);
		}
		else {
			uwsgi_log("[linux-namespace] applied unshare() mask: %d\n", uwsgi.unshare);
		}

#ifdef CLONE_NEWUSER
		if (uwsgi.unshare & CLONE_NEWUSER) {
			if (setuid(0)) {
				uwsgi_error("uwsgi_as_root()/setuid(0)");
				exit(1);
			}
		}
#endif
		in_jail = 1;
	}
#endif

#ifdef UWSGI_CAP
	if (uwsgi.cap && uwsgi.cap_count > 0 && !uwsgi.reloads) {
		uwsgi_apply_cap(uwsgi.cap, uwsgi.cap_count);
	}
#endif


#if defined(__FreeBSD__) || defined(__GNU_kFreeBSD__)
	if (uwsgi.jail && !uwsgi.reloads) {

		struct jail ujail;
		char *jarg = uwsgi_str(uwsgi.jail);
		char *j_hostname = NULL;
		char *j_name = NULL;

		char *space = strchr(jarg, ' ');
		if (space) {
			*space = 0;
			j_hostname = space + 1;
			space = strchr(j_hostname, ' ');
			if (space) {
				*space = 0;
				j_name = space + 1;
			}
		}
		ujail.version = JAIL_API_VERSION;
		ujail.path = jarg;
		ujail.hostname = j_hostname ? j_hostname : "";
		ujail.jailname = j_name;
		ujail.ip4s = 0;
		ujail.ip6s = 0;

		struct uwsgi_string_list *usl = NULL;

		uwsgi_foreach(usl, uwsgi.jail_ip4) {
			ujail.ip4s++;
		}
		struct in_addr *saddr = uwsgi_calloc(sizeof(struct in_addr) * ujail.ip4s);
		int i = 0;
		uwsgi_foreach(usl, uwsgi.jail_ip4) {
			if (!inet_pton(AF_INET, usl->value, &saddr[i].s_addr)) {
				uwsgi_error("jail()/inet_pton()");
				exit(1);
			}
			i++;
		}
		ujail.ip4 = saddr;
#ifdef AF_INET6
		uwsgi_foreach(usl, uwsgi.jail_ip6) {
			ujail.ip6s++;
		}

		struct in6_addr *saddr6 = uwsgi_calloc(sizeof(struct in6_addr) * ujail.ip6s);
		i = 0;
		uwsgi_foreach(usl, uwsgi.jail_ip6) {
			if (!inet_pton(AF_INET6, usl->value, &saddr6[i].s6_addr)) {
				uwsgi_error("jail()/inet_pton()");
				exit(1);
			}
			i++;
		}
		ujail.ip6 = saddr6;
#endif

		int jail_id = jail(&ujail);
		if (jail_id < 0) {
			uwsgi_error("jail()");
			exit(1);
		}

		if (uwsgi.jidfile) {
			if (uwsgi_write_intfile(uwsgi.jidfile, jail_id)) {
				uwsgi_log("unable to write jidfile\n");
				exit(1);
			}
		}

		uwsgi_log("--- running in FreeBSD jail %d ---\n", jail_id);
		in_jail = 1;
	}

#ifdef UWSGI_HAS_FREEBSD_LIBJAIL
	if (uwsgi.jail_attach && !uwsgi.reloads) {
		struct jailparam jparam;
		uwsgi_log("attaching to FreeBSD jail %s ...\n", uwsgi.jail_attach);
		if (!is_a_number(uwsgi.jail_attach)) {
			if (jailparam_init(&jparam, "name")) {
				uwsgi_error("jailparam_init()");
				exit(1);
			}
		}
		else {
			if (jailparam_init(&jparam, "jid")) {
				uwsgi_error("jailparam_init()");
				exit(1);
			}
		}
		jailparam_import(&jparam, uwsgi.jail_attach);
		int jail_id = jailparam_set(&jparam, 1, JAIL_UPDATE | JAIL_ATTACH);
		if (jail_id < 0) {
			uwsgi_error("jailparam_set()");
			exit(1);
		}

		jailparam_free(&jparam, 1);
		uwsgi_log("--- running in FreeBSD jail %d ---\n", jail_id);
		in_jail = 1;
	}

	if (uwsgi.jail2 && !uwsgi.reloads) {
		struct uwsgi_string_list *usl = NULL;
		unsigned nparams = 0;
		uwsgi_foreach(usl, uwsgi.jail2) {
			nparams++;
		}
		struct jailparam *params = uwsgi_malloc(sizeof(struct jailparam) * nparams);
		int i = 0;
		uwsgi_foreach(usl, uwsgi.jail2) {
			uwsgi_log("FreeBSD libjail applying %s\n", usl->value);
			char *equal = strchr(usl->value, '=');
			if (equal) {
				*equal = 0;
			}
			if (jailparam_init(&params[i], usl->value)) {
				uwsgi_error("jailparam_init()");
				exit(1);
			}
			if (equal) {
				jailparam_import(&params[i], equal + 1);
				*equal = '=';
			}
			else {
				jailparam_import(&params[i], "1");
			}
			i++;
		}
		int jail_id = jailparam_set(params, nparams, JAIL_CREATE | JAIL_ATTACH);
		if (jail_id < 0) {
			uwsgi_error("jailparam_set()");
			exit(1);
		}

		jailparam_free(params, nparams);

		if (uwsgi.jidfile) {
			if (uwsgi_write_intfile(uwsgi.jidfile, jail_id)) {
				uwsgi_log("unable to write jidfile\n");
				exit(1);
			}
		}

		uwsgi_log("--- running in FreeBSD jail %d ---\n", jail_id);
		in_jail = 1;
	}
#endif
#endif

	if (in_jail || uwsgi.jailed) {
		uwsgi_hooks_run(uwsgi.hook_post_jail, "post-jail", 1);
		struct uwsgi_string_list *usl = NULL;
		uwsgi_foreach(usl, uwsgi.mount_post_jail) {
			uwsgi_log("mounting \"%s\" (post-jail)...\n", usl->value);
			if (uwsgi_mount_hook(usl->value)) {
				exit(1);
			}
		}

		uwsgi_foreach(usl, uwsgi.umount_post_jail) {
			uwsgi_log("un-mounting \"%s\" (post-jail)...\n", usl->value);
			if (uwsgi_umount_hook(usl->value)) {
				exit(1);
			}
		}

		uwsgi_foreach(usl, uwsgi.exec_post_jail) {
			uwsgi_log("running \"%s\" (post-jail)...\n", usl->value);
			int ret = uwsgi_run_command_and_wait(NULL, usl->value);
			if (ret != 0) {
				uwsgi_log("command \"%s\" exited with non-zero code: %d\n", usl->value, ret);
				exit(1);
			}
		}

		uwsgi_foreach(usl, uwsgi.call_post_jail) {
			if (uwsgi_call_symbol(usl->value)) {
				uwsgi_log("unable to call function \"%s\"\n", usl->value);
				exit(1);
			}
		}

		if (uwsgi.refork_post_jail) {
			uwsgi_log("re-fork()ing...\n");
			pid_t pid = fork();
			if (pid < 0) {
				uwsgi_error("fork()");
				exit(1);
			}
			if (pid > 0) {
				// block all signals
				sigset_t smask;
				sigfillset(&smask);
				sigprocmask(SIG_BLOCK, &smask, NULL);
				int status;
				if (waitpid(pid, &status, 0) < 0) {
					uwsgi_error("waitpid()");
				}
				_exit(0);
			}
		}


		int i;
		for (i = 0; i < uwsgi.gp_cnt; i++) {
			if (uwsgi.gp[i]->post_jail) {
				uwsgi.gp[i]->post_jail();
			}
		}
	}

	if (uwsgi.chroot && !uwsgi.reloads) {
		if (!uwsgi.master_as_root)
			uwsgi_log("chroot() to %s\n", uwsgi.chroot);
		if (chroot(uwsgi.chroot)) {
			uwsgi_error("chroot()");
			exit(1);
		}
#ifdef __linux__
		if (uwsgi.logging_options.memory_report) {
			uwsgi_log("*** Warning, on linux system you have to bind-mount the /proc fs in your chroot to get memory debug/report.\n");
		}
#endif
	}

#ifdef __linux__
	if (uwsgi.pivot_root && !uwsgi.reloads) {
		char *arg = uwsgi_str(uwsgi.pivot_root);
		char *space = strchr(arg, ' ');
		if (!space) {
			uwsgi_log("invalid pivot_root syntax, new_root and put_old must be separated by a space\n");
			exit(1);
		}
		*space = 0;
#if defined(MS_REC) && defined(MS_PRIVATE)
		if (mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL)) {
			uwsgi_error("mount()");
			exit(1);
		}
#endif
		if (chdir(arg)) {
			uwsgi_error("pivot_root()/chdir()");
			exit(1);
		}
		space += 1 + strlen(arg);
		if (space[0] == '/')
			space++;
		if (pivot_root(".", space)) {
			uwsgi_error("pivot_root()");
			exit(1);
		}
		if (uwsgi.logging_options.memory_report) {
			uwsgi_log("*** Warning, on linux system you have to bind-mount the /proc fs in your chroot to get memory debug/report.\n");
		}
		free(arg);
		if (chdir("/")) {
			uwsgi_error("chdir()");
			exit(1);
		}

	}
#endif

#if defined(__linux__) && !defined(OBSOLETE_LINUX_KERNEL)
	if (uwsgi.unshare2 && !uwsgi.reloads) {

		if (unshare(uwsgi.unshare2)) {
			uwsgi_error("unshare()");
			exit(1);
		}
		else {
			uwsgi_log("[linux-namespace] applied unshare() mask: %d\n", uwsgi.unshare2);
		}
#ifdef CLONE_NEWUSER
		if (uwsgi.unshare2 & CLONE_NEWUSER) {
			if (setuid(0)) {
				uwsgi_error("uwsgi_as_root()/setuid(0)");
				exit(1);
			}
		}
#endif
		in_jail = 1;
	}
#endif

	if (uwsgi.refork_as_root) {
		uwsgi_log("re-fork()ing...\n");
		pid_t pid = fork();
		if (pid < 0) {
			uwsgi_error("fork()");
			exit(1);
		}
		if (pid > 0) {
			// block all signals
			sigset_t smask;
			sigfillset(&smask);
			sigprocmask(SIG_BLOCK, &smask, NULL);
			int status;
			if (waitpid(pid, &status, 0) < 0) {
				uwsgi_error("waitpid()");
			}
			_exit(0);
		}
	}


	struct uwsgi_string_list *usl;
	uwsgi_foreach(usl, uwsgi.wait_for_interface) {
		if (!uwsgi.wait_for_interface_timeout) {
			uwsgi.wait_for_interface_timeout = 60;
		}
		uwsgi_log("waiting for interface %s (max %d seconds) ...\n", usl->value, uwsgi.wait_for_interface_timeout);
		int counter = 0;
		for (;;) {
			if (counter > uwsgi.wait_for_interface_timeout) {
				uwsgi_log("interface %s unavailable after %d seconds\n", usl->value, counter);
				exit(1);
			}
			unsigned int index = if_nametoindex(usl->value);
			if (index > 0) {
				uwsgi_log("interface %s found with index %u\n", usl->value, index);
				break;
			}
			else {
				sleep(1);
				counter++;
			}
		}
	}

	uwsgi_foreach(usl, uwsgi.wait_for_fs) {
		if (uwsgi_wait_for_fs(usl->value, 0)) exit(1);
	}

	uwsgi_foreach(usl, uwsgi.wait_for_file) {
		if (uwsgi_wait_for_fs(usl->value, 1)) exit(1);
	}

	uwsgi_foreach(usl, uwsgi.wait_for_dir) {
		if (uwsgi_wait_for_fs(usl->value, 2)) exit(1);
	}

	uwsgi_foreach(usl, uwsgi.wait_for_mountpoint) {
		if (uwsgi_wait_for_mountpoint(usl->value)) exit(1);
	}

	uwsgi_hooks_run(uwsgi.hook_as_root, "as root", 1);

	uwsgi_foreach(usl, uwsgi.mount_as_root) {
		uwsgi_log("mounting \"%s\" (as root)...\n", usl->value);
		if (uwsgi_mount_hook(usl->value)) {
			exit(1);
		}
	}

	uwsgi_foreach(usl, uwsgi.umount_as_root) {
		uwsgi_log("un-mounting \"%s\" (as root)...\n", usl->value);
		if (uwsgi_umount_hook(usl->value)) {
			exit(1);
		}
	}

	// now run the scripts needed by root
	uwsgi_foreach(usl, uwsgi.exec_as_root) {
		uwsgi_log("running \"%s\" (as root)...\n", usl->value);
		int ret = uwsgi_run_command_and_wait(NULL, usl->value);
		if (ret != 0) {
			uwsgi_log("command \"%s\" exited with non-zero code: %d\n", usl->value, ret);
			exit(1);
		}
	}

	uwsgi_foreach(usl, uwsgi.call_as_root) {
		if (uwsgi_call_symbol(usl->value)) {
			uwsgi_log("unable to call function \"%s\"\n", usl->value);
		}
	}


	if (uwsgi.gidname) {
		struct group *ugroup = getgrnam(uwsgi.gidname);
		if (ugroup) {
			uwsgi.gid = ugroup->gr_gid;
		}
		else {
			uwsgi_log("group %s not found.\n", uwsgi.gidname);
			exit(1);
		}
	}
	if (uwsgi.uidname) {
		struct passwd *upasswd = getpwnam(uwsgi.uidname);
		if (upasswd) {
			uwsgi.uid = upasswd->pw_uid;
		}
		else {
			uwsgi_log("user %s not found.\n", uwsgi.uidname);
			exit(1);
		}
	}

	if (uwsgi.logfile_chown) {
		int log_fd = 2;
		if (uwsgi.log_master && uwsgi.original_log_fd > -1) {
			log_fd = uwsgi.original_log_fd;
		}
		if (fchown(log_fd, uwsgi.uid, uwsgi.gid)) {
			uwsgi_error("fchown()");
			exit(1);
		}
	}

	// fix ipcsem owner
	if (uwsgi.lock_ops.lock_init == uwsgi_lock_ipcsem_init) {
		struct uwsgi_lock_item *uli = uwsgi.registered_locks;

		while (uli) {
			union semun {
				int val;
				struct semid_ds *buf;
				ushort *array;
			} semu;

			struct semid_ds sds;
			memset(&sds, 0, sizeof(sds));
			semu.buf = &sds;
			int semid = 0;
			memcpy(&semid, uli->lock_ptr, sizeof(int));

			if (semctl(semid, 0, IPC_STAT, semu)) {
				uwsgi_error("semctl()");
				exit(1);
			}

			semu.buf->sem_perm.uid = uwsgi.uid;
			semu.buf->sem_perm.gid = uwsgi.gid;

			if (semctl(semid, 0, IPC_SET, semu)) {
				uwsgi_error("semctl()");
				exit(1);
			}
			uli = uli->next;
		}

	}

	// ok try to call some special hook before finally dropping privileges
	int i;
	for (i = 0; i < uwsgi.gp_cnt; i++) {
		if (uwsgi.gp[i]->before_privileges_drop) {
			uwsgi.gp[i]->before_privileges_drop();
		}
	}

	if (uwsgi.gid) {
		if (!uwsgi.master_as_root)
			uwsgi_log("setgid() to %d\n", uwsgi.gid);
		if (setgid(uwsgi.gid)) {
			uwsgi_error("setgid()");
			exit(1);
		}
		if (uwsgi.no_initgroups || !uwsgi.uid) {
			if (setgroups(0, NULL)) {
				uwsgi_error("setgroups()");
				exit(1);
			}
		}
		else {
			char *uidname = uwsgi.uidname;
			if (!uidname) {
				struct passwd *pw = getpwuid(uwsgi.uid);
				if (pw)
					uidname = pw->pw_name;

			}
			if (!uidname)
				uidname = uwsgi_num2str(uwsgi.uid);
			if (initgroups(uidname, uwsgi.gid)) {
				uwsgi_error("setgroups()");
				exit(1);
			}
		}
		struct uwsgi_string_list *usl;
		size_t ags = 0;
		uwsgi_foreach(usl, uwsgi.additional_gids) ags++;
		if (ags > 0) {
			gid_t *ags_list = uwsgi_calloc(sizeof(gid_t) * ags);
			size_t g_pos = 0;
			uwsgi_foreach(usl, uwsgi.additional_gids) {
				ags_list[g_pos] = atoi(usl->value);
				if (!ags_list[g_pos]) {
					struct group *g = getgrnam(usl->value);
					if (g) {
						ags_list[g_pos] = g->gr_gid;
					}
					else {
						uwsgi_log("unable to find group %s\n", usl->value);
						exit(1);
					}
				}
				g_pos++;
			}
			if (setgroups(ags, ags_list)) {
				uwsgi_error("setgroups()");
				exit(1);
			}
		}
		int additional_groups = getgroups(0, NULL);
		if (additional_groups > 0) {
			gid_t *gids = uwsgi_calloc(sizeof(gid_t) * additional_groups);
			if (getgroups(additional_groups, gids) > 0) {
				int i;
				for (i = 0; i < additional_groups; i++) {
					if (gids[i] == uwsgi.gid)
						continue;
					struct group *gr = getgrgid(gids[i]);
					if (gr) {
						uwsgi_log("set additional group %d (%s)\n", gids[i], gr->gr_name);
					}
					else {
						uwsgi_log("set additional group %d\n", gids[i]);
					}
				}
			}
			free(gids);
		}
	}
	if (uwsgi.uid) {
		if (!uwsgi.master_as_root)
			uwsgi_log("setuid() to %d\n", uwsgi.uid);
		if (setuid(uwsgi.uid)) {
			uwsgi_error("setuid()");
			exit(1);
		}
	}

#ifndef __RUMP__
	if (!getuid()) {
		uwsgi_log_initial("*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** \n");
	}
#endif

#ifdef UWSGI_CAP

	if (uwsgi.cap && uwsgi.cap_count > 0 && !uwsgi.reloads) {

		cap_t caps = cap_init();

		if (!caps) {
			uwsgi_error("cap_init()");
			exit(1);
		}
		cap_clear(caps);

		cap_set_flag(caps, CAP_EFFECTIVE, uwsgi.cap_count, uwsgi.cap, CAP_SET);
		cap_set_flag(caps, CAP_PERMITTED, uwsgi.cap_count, uwsgi.cap, CAP_SET);
		cap_set_flag(caps, CAP_INHERITABLE, uwsgi.cap_count, uwsgi.cap, CAP_SET);

		if (cap_set_proc(caps) < 0) {
			uwsgi_error("cap_set_proc()");
			exit(1);
		}
		cap_free(caps);
	}
#endif

	if (uwsgi.refork) {
		uwsgi_log("re-fork()ing...\n");
		pid_t pid = fork();
		if (pid < 0) {
			uwsgi_error("fork()");
			exit(1);
		}
		if (pid > 0) {
			// block all signals
			sigset_t smask;
			sigfillset(&smask);
			sigprocmask(SIG_BLOCK, &smask, NULL);
			int status;
			if (waitpid(pid, &status, 0) < 0) {
				uwsgi_error("waitpid()");
			}
			_exit(0);
		}
	}

	uwsgi_hooks_run(uwsgi.hook_as_user, "as user", 1);

	// now run the scripts needed by the user
	uwsgi_foreach(usl, uwsgi.exec_as_user) {
		uwsgi_log("running \"%s\" (as uid: %d gid: %d) ...\n", usl->value, (int) getuid(), (int) getgid());
		int ret = uwsgi_run_command_and_wait(NULL, usl->value);
		if (ret != 0) {
			uwsgi_log("command \"%s\" exited with non-zero code: %d\n", usl->value, ret);
			exit(1);
		}
	}

	uwsgi_foreach(usl, uwsgi.call_as_user) {
		if (uwsgi_call_symbol(usl->value)) {
			uwsgi_log("unable to call function \"%s\"\n", usl->value);
			exit(1);
		}
	}

	// we could now patch the binary
	if (uwsgi.unprivileged_binary_patch) {
		uwsgi.argv[0] = uwsgi.unprivileged_binary_patch;
		execvp(uwsgi.unprivileged_binary_patch, uwsgi.argv);
		uwsgi_error("execvp()");
		exit(1);
	}

	if (uwsgi.unprivileged_binary_patch_arg) {
		uwsgi_exec_command_with_args(uwsgi.unprivileged_binary_patch_arg);
	}
	return;

nonroot:
	if (uwsgi.chroot && !uwsgi.is_a_reload) {
		uwsgi_log("cannot chroot() as non-root user\n");
		exit(1);
	}
	if (uwsgi.gid && getgid() != uwsgi.gid) {
		uwsgi_log("cannot setgid() as non-root user\n");
		exit(1);
	}
	if (uwsgi.uid && getuid() != uwsgi.uid) {
		uwsgi_log("cannot setuid() as non-root user\n");
		exit(1);
	}
}