1/*
2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/sched.h"
7#include "linux/file.h"
8#include "linux/smp_lock.h"
9#include "linux/mm.h"
10#include "linux/utsname.h"
11#include "linux/msg.h"
12#include "linux/shm.h"
13#include "linux/sys.h"
14#include "linux/syscalls.h"
15#include "linux/unistd.h"
16#include "linux/slab.h"
17#include "linux/utime.h"
18#include "asm/mman.h"
19#include "asm/uaccess.h"
20#include "kern_util.h"
21#include "sysdep/syscalls.h"
22#include "mode_kern.h"
23#include "choose-mode.h"
24
25/*  Unlocked, I don't care if this is a bit off */
26int nsyscalls = 0;
27
28long sys_fork(void)
29{
30	long ret;
31
32	current->thread.forking = 1;
33	ret = do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
34		      &current->thread.regs, 0, NULL, NULL);
35	current->thread.forking = 0;
36	return(ret);
37}
38
39long sys_vfork(void)
40{
41	long ret;
42
43	current->thread.forking = 1;
44	ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
45		      UPT_SP(&current->thread.regs.regs),
46		      &current->thread.regs, 0, NULL, NULL);
47	current->thread.forking = 0;
48	return(ret);
49}
50
51/* common code for old and new mmaps */
52long sys_mmap2(unsigned long addr, unsigned long len,
53	       unsigned long prot, unsigned long flags,
54	       unsigned long fd, unsigned long pgoff)
55{
56	long error = -EBADF;
57	struct file * file = NULL;
58
59	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
60	if (!(flags & MAP_ANONYMOUS)) {
61		file = fget(fd);
62		if (!file)
63			goto out;
64	}
65
66	down_write(&current->mm->mmap_sem);
67	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
68	up_write(&current->mm->mmap_sem);
69
70	if (file)
71		fput(file);
72 out:
73	return error;
74}
75
76long old_mmap(unsigned long addr, unsigned long len,
77	      unsigned long prot, unsigned long flags,
78	      unsigned long fd, unsigned long offset)
79{
80	long err = -EINVAL;
81	if (offset & ~PAGE_MASK)
82		goto out;
83
84	err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
85 out:
86	return err;
87}
88/*
89 * sys_pipe() is the normal C calling standard for creating
90 * a pipe. It's not the way unix traditionally does this, though.
91 */
92long sys_pipe(unsigned long __user * fildes)
93{
94        int fd[2];
95        long error;
96
97        error = do_pipe(fd);
98        if (!error) {
99		if (copy_to_user(fildes, fd, sizeof(fd)))
100                        error = -EFAULT;
101        }
102        return error;
103}
104
105
106long sys_uname(struct old_utsname __user * name)
107{
108	long err;
109	if (!name)
110		return -EFAULT;
111	down_read(&uts_sem);
112	err = copy_to_user(name, utsname(), sizeof (*name));
113	up_read(&uts_sem);
114	return err?-EFAULT:0;
115}
116
117long sys_olduname(struct oldold_utsname __user * name)
118{
119	long error;
120
121	if (!name)
122		return -EFAULT;
123	if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
124		return -EFAULT;
125
126  	down_read(&uts_sem);
127
128	error = __copy_to_user(&name->sysname, &utsname()->sysname,
129			       __OLD_UTS_LEN);
130	error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
131	error |= __copy_to_user(&name->nodename, &utsname()->nodename,
132				__OLD_UTS_LEN);
133	error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
134	error |= __copy_to_user(&name->release, &utsname()->release,
135				__OLD_UTS_LEN);
136	error |= __put_user(0, name->release + __OLD_UTS_LEN);
137	error |= __copy_to_user(&name->version, &utsname()->version,
138				__OLD_UTS_LEN);
139	error |= __put_user(0, name->version + __OLD_UTS_LEN);
140	error |= __copy_to_user(&name->machine, &utsname()->machine,
141				__OLD_UTS_LEN);
142	error |= __put_user(0, name->machine + __OLD_UTS_LEN);
143
144	up_read(&uts_sem);
145
146	error = error ? -EFAULT : 0;
147
148	return error;
149}
150
151int kernel_execve(const char *filename, char *const argv[], char *const envp[])
152{
153	mm_segment_t fs;
154	int ret;
155
156	fs = get_fs();
157	set_fs(KERNEL_DS);
158	ret = um_execve(filename, argv, envp);
159	set_fs(fs);
160
161	return ret;
162}
163