void script_set_env(void* data) { char buf[256]; GSList* l; struct script_env_callback_data* d = data; server_set_env(d->s); for (l = g_slist_next(d->script->options); l; l = g_slist_next(l)) { ScriptOption* opt = l->data; debug(4, "%s %s", opt->section, opt->defval); snprintf(buf, sizeof(buf), "XQF_SCRIPT_OPTION_%s", opt->section+7); switch(opt->type) { case SCRIPT_OPTION_TYPE_STRING: case SCRIPT_OPTION_TYPE_INT: case SCRIPT_OPTION_TYPE_LIST: if (opt->defval) { setenv(buf, opt->defval, 1); } break; case SCRIPT_OPTION_TYPE_BOOL: setenv(buf, opt->enable?"true":"false", 1); break; case SCRIPT_OPTION_TYPE_INVALID: xqf_error("unreachable code"); break; } } }
int client_launch_exec (int forkit, char *dir, char* argv[], struct server *s) { int pid; int pipefds[2]; int flags; char msg[CLIENT_ERROR_BUFFER]; if (get_debug_level() || dontlaunch) { char* cmdline = g_strjoinv(" # ",argv); debug(0,"%s",cmdline); g_free(cmdline); } if (dontlaunch) return -1; script_action_gamestart(NULL, s); if (forkit) { if (pipe (pipefds) < 0) { dialog_failed ("pipe", NULL); return -1; } pid = fork (); if (pid == -1) { dialog_failed ("fork", NULL); return -1; } if (pid) { /* parent */ close (pipefds[1]); flags = fcntl (pipefds[0], F_GETFL, 0); if (flags < 0 || fcntl (pipefds[0], F_SETFL, flags | O_NONBLOCK) < 0) { dialog_failed ("fcntl", NULL); return -1; } client_attach (pid, pipefds[0], s); } else { /* child */ close_fds(pipefds[1]); if (dir && dir[0] != '\0') { if (chdir (dir) != 0) { g_snprintf (msg, CLIENT_ERROR_BUFFER, "%schdir failed: %s", CLIENT_ERROR_MSG_HEAD, g_strerror (errno)); goto error_out; } } server_set_env(s); execvp (argv[0], argv); g_snprintf (msg, CLIENT_ERROR_BUFFER, "%sexec(%s) failed: %s", CLIENT_ERROR_MSG_HEAD, argv[0], g_strerror (errno)); error_out: write (pipefds[1], msg, strlen (msg) + 1); close (pipefds[1]); on_sig (SIGHUP, _exit); on_sig (SIGINT, _exit); on_sig (SIGQUIT, _exit); on_sig (SIGBUS, _exit); on_sig (SIGSEGV, _exit); on_sig (SIGPIPE, _exit); on_sig (SIGTERM, _exit); on_sig (SIGALRM, _exit); on_sig (SIGCHLD, SIG_DFL); _exit (1); } return pid; } execvp (argv[0], argv); dialog_failed ("exec", argv[0]); return -1; }