2 * TUX - Integrated Application Protocols Layer and Object Cache
4 * Copyright (C) 2000, 2001, Ingo Molnar <mingo@redhat.com>
6 * cgi.c: user-space CGI (and other) code execution.
9 #define __KERNEL_SYSCALLS__
10 #define __KERNEL_SYSCALLS_NO_ERRNO__
14 /****************************************************************
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 ****************************************************************/
31 static int exec_usermode(char *program_path, char *argv[], char *envp[])
35 err = tux_chroot(tux_cgiroot);
37 printk(KERN_ERR "TUX: CGI chroot returned %d, /proc/sys/net/tux/cgiroot is probably set up incorrectly! Aborting CGI execution.\n", err);
41 /* Allow execve args to be in kernel space. */
44 flush_signals(current);
45 spin_lock_irq(¤t->sighand->siglock);
46 flush_signal_handlers(current, 1);
47 spin_unlock_irq(¤t->sighand->siglock);
49 for (i = 3; i < current->files->max_fds; i++ )
50 if (current->files->fd[i])
53 err = execve(program_path, argv, envp);
59 static inline long tux_dup(unsigned int fildes)
62 struct file * file = fget(fildes);
69 static int exec_helper (void * data)
71 exec_param_t *param = data;
75 sprintf(current->comm,"doexec - %d", current->pid);
77 if (!tux_cgi_inherit_cpu) {
79 cpumask_t cgi_mask, map;
81 mask_to_cpumask(tux_cgi_cpu_mask, &cgi_mask);
82 cpus_and(map, cpu_online_map, cgi_mask);
84 if (!(cpus_empty(map)))
85 set_cpus_allowed(current, cgi_mask);
87 set_cpus_allowed(current, cpu_online_map);
93 Dprintk("doing exec(%s).\n", param->command);
98 Dprintk("{%s} ", *tmp);
105 Dprintk("{%s} ", *tmp);
110 * Set up stdin, stdout and stderr of the external
113 if (param->pipe_fds) {
123 // do not close on exec.
125 sys_fcntl(0, F_SETFD, 0);
126 sys_fcntl(1, F_SETFD, 0);
127 sys_fcntl(2, F_SETFD, 0);
129 spin_lock(¤t->files->file_lock);
130 FD_CLR(0, current->files->close_on_exec);
131 FD_CLR(1, current->files->close_on_exec);
132 FD_CLR(2, current->files->close_on_exec);
133 spin_unlock(¤t->files->file_lock);
136 ret = exec_usermode(param->command, param->argv, param->envp);
138 Dprintk("bug: exec() returned %d.\n", ret);
140 Dprintk("exec()-ed successfully!\n");
144 pid_t tux_exec_process (char *command, char **argv,
145 char **envp, int pipe_fds,
146 exec_param_t *param, int wait)
148 exec_param_t param_local;
150 struct k_sigaction *ka;
152 ka = current->sighand->action + SIGCHLD-1;
153 ka->sa.sa_handler = SIG_IGN;
156 param = ¶m_local;
158 param->command = command;
161 param->pipe_fds = pipe_fds;
164 pid = kernel_thread(exec_helper, (void*) param, CLONE_SIGHAND|SIGCHLD);
165 Dprintk("kernel thread created PID %d.\n", pid);
167 printk(KERN_ERR "TUX: could not create new CGI kernel thread due to %d... retrying.\n", pid);
168 current->state = TASK_UNINTERRUPTIBLE;
169 schedule_timeout(HZ);