PageRenderTime 45ms CodeModel.GetById 10ms app.highlight 30ms RepoModel.GetById 1ms app.codeStats 1ms

/arch/v850/kernel/syscalls.c

https://bitbucket.org/evzijst/gittest
C | 197 lines | 154 code | 18 blank | 25 comment | 18 complexity | 253f4283f4eeba11abe1647c5115a85f MD5 | raw file
  1/*
  2 * arch/v850/kernel/syscalls.c -- Various system-call definitions not
  3 * 	defined in machine-independent code
  4 *
  5 *  Copyright (C) 2001,02  NEC Corporation
  6 *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
  7 *
  8 * This file is subject to the terms and conditions of the GNU General
  9 * Public License.  See the file COPYING in the main directory of this
 10 * archive for more details.
 11 *
 12 * This file was derived the ppc version, arch/ppc/kernel/syscalls.c
 13 * ... which was derived from "arch/i386/kernel/sys_i386.c" by Gary Thomas;
 14 *     modified by Cort Dougan (cort@cs.nmt.edu)
 15 *     and Paul Mackerras (paulus@cs.anu.edu.au).
 16 */
 17
 18#include <linux/config.h>
 19#include <linux/errno.h>
 20#include <linux/mm.h>
 21#include <linux/smp.h>
 22#include <linux/smp_lock.h>
 23#include <linux/syscalls.h>
 24#include <linux/sem.h>
 25#include <linux/msg.h>
 26#include <linux/shm.h>
 27#include <linux/stat.h>
 28#include <linux/mman.h>
 29#include <linux/sys.h>
 30#include <linux/ipc.h>
 31#include <linux/utsname.h>
 32#include <linux/file.h>
 33
 34#include <asm/uaccess.h>
 35#include <asm/ipc.h>
 36#include <asm/semaphore.h>
 37
 38/*
 39 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
 40 *
 41 * This is really horribly ugly.
 42 */
 43int
 44sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
 45{
 46	int version, ret;
 47
 48	version = call >> 16; /* hack for backward compatibility */
 49	call &= 0xffff;
 50
 51	ret = -EINVAL;
 52	switch (call) {
 53	case SEMOP:
 54		ret = sys_semop (first, (struct sembuf *)ptr, second);
 55		break;
 56	case SEMGET:
 57		ret = sys_semget (first, second, third);
 58		break;
 59	case SEMCTL:
 60	{
 61		union semun fourth;
 62
 63		if (!ptr)
 64			break;
 65		if ((ret = access_ok(VERIFY_READ, ptr, sizeof(long)) ? 0 : -EFAULT)
 66		    || (ret = get_user(fourth.__pad, (void **)ptr)))
 67			break;
 68		ret = sys_semctl (first, second, third, fourth);
 69		break;
 70	}
 71	case MSGSND:
 72		ret = sys_msgsnd (first, (struct msgbuf *) ptr, second, third);
 73		break;
 74	case MSGRCV:
 75		switch (version) {
 76		case 0: {
 77			struct ipc_kludge tmp;
 78
 79			if (!ptr)
 80				break;
 81			if ((ret = access_ok(VERIFY_READ, ptr, sizeof(tmp)) ? 0 : -EFAULT)
 82			    || (ret = copy_from_user(&tmp,
 83						(struct ipc_kludge *) ptr,
 84						sizeof (tmp))))
 85				break;
 86			ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp,
 87					  third);
 88			break;
 89			}
 90		default:
 91			ret = sys_msgrcv (first, (struct msgbuf *) ptr,
 92					  second, fifth, third);
 93			break;
 94		}
 95		break;
 96	case MSGGET:
 97		ret = sys_msgget ((key_t) first, second);
 98		break;
 99	case MSGCTL:
100		ret = sys_msgctl (first, second, (struct msqid_ds *) ptr);
101		break;
102	case SHMAT:
103		switch (version) {
104		default: {
105			ulong raddr;
106
107			if ((ret = access_ok(VERIFY_WRITE, (ulong*) third,
108					       sizeof(ulong)) ? 0 : -EFAULT))
109				break;
110			ret = do_shmat (first, (char *) ptr, second, &raddr);
111			if (ret)
112				break;
113			ret = put_user (raddr, (ulong *) third);
114			break;
115			}
116		case 1:	/* iBCS2 emulator entry point */
117			if (!segment_eq(get_fs(), get_ds()))
118				break;
119			ret = do_shmat (first, (char *) ptr, second,
120					 (ulong *) third);
121			break;
122		}
123		break;
124	case SHMDT: 
125		ret = sys_shmdt ((char *)ptr);
126		break;
127	case SHMGET:
128		ret = sys_shmget (first, second, third);
129		break;
130	case SHMCTL:
131		ret = sys_shmctl (first, second, (struct shmid_ds *) ptr);
132		break;
133	}
134
135	return ret;
136}
137
138/*
139 * sys_pipe() is the normal C calling standard for creating
140 * a pipe. It's not the way unix traditionally does this, though.
141 */
142int sys_pipe (int *fildes)
143{
144	int fd[2];
145	int error;
146
147	error = do_pipe (fd);
148	if (!error) {
149		if (copy_to_user (fildes, fd, 2*sizeof (int)))
150			error = -EFAULT;
151	}
152	return error;
153}
154
155static inline unsigned long
156do_mmap2 (unsigned long addr, size_t len,
157	 unsigned long prot, unsigned long flags,
158	 unsigned long fd, unsigned long pgoff)
159{
160	struct file * file = NULL;
161	int ret = -EBADF;
162
163	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
164	if (! (flags & MAP_ANONYMOUS)) {
165		if (!(file = fget (fd)))
166			goto out;
167	}
168	
169	down_write (&current->mm->mmap_sem);
170	ret = do_mmap_pgoff (file, addr, len, prot, flags, pgoff);
171	up_write (&current->mm->mmap_sem);
172	if (file)
173		fput (file);
174out:
175	return ret;
176}
177
178unsigned long sys_mmap2 (unsigned long addr, size_t len,
179			unsigned long prot, unsigned long flags,
180			unsigned long fd, unsigned long pgoff)
181{
182	return do_mmap2 (addr, len, prot, flags, fd, pgoff);
183}
184
185unsigned long sys_mmap (unsigned long addr, size_t len,
186		       unsigned long prot, unsigned long flags,
187		       unsigned long fd, off_t offset)
188{
189	int err = -EINVAL;
190
191	if (offset & ~PAGE_MASK)
192		goto out;
193
194	err = do_mmap2 (addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
195out:
196	return err;
197}