예제 #1
0
asmlinkage int solaris_putmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3)
{
	struct file *filp;
	struct inode *ino;
	struct strbuf __user *ctlptr;
	struct strbuf __user *datptr;
	struct strbuf ctl, dat;
	int flags = (int) arg3;
	int error = -EBADF;
	struct fdtable *fdt;

	SOLD("entry");
	lock_kernel();
	if (fd >= sysctl_nr_open)
		goto out;

	fdt = files_fdtable(current->files);
	filp = fdt->fd[fd];
	if(!filp) goto out;

	ino = filp->f_dentry->d_inode;
	if (!ino) goto out;

	if (!S_ISSOCK(ino->i_mode) &&
		(imajor(ino) != 30 || iminor(ino) != 1))
		goto out;

	ctlptr = A(arg1);
	datptr = A(arg2);

	error = -EFAULT;

	if (ctlptr) {
		if (copy_from_user(&ctl,ctlptr,sizeof(ctl)))
			goto out;
		if (ctl.len < 0 && flags) {
			error = -EINVAL;
			goto out;
		}
	} else {
		ctl.len = 0;
		ctl.buf = 0;
	}

	if (datptr) {
		if (copy_from_user(&dat,datptr,sizeof(dat)))
			goto out;
	} else {
		dat.len = 0;
		dat.buf = 0;
	}

	error = timod_putmsg(fd,A(ctl.buf),ctl.len,
				A(dat.buf),dat.len,flags);
out:
	unlock_kernel();
	SOLD("done");
	return error;
}
예제 #2
0
파일: timod.c 프로젝트: dduval/kernel-rhel3
asmlinkage int solaris_putmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3)
{
	struct file *filp;
	struct inode *ino;
	struct strbuf *ctlptr, *datptr;
	struct strbuf ctl, dat;
	int flags = (int) arg3;
	int error = -EBADF;

	SOLD("entry");
	lock_kernel();
	if(fd >= NR_OPEN) goto out;

	read_lock(&current->files->file_lock);
	filp = fcheck(fd);
	read_unlock(&current->files->file_lock);
	if(!filp) goto out;

	ino = filp->f_dentry->d_inode;
	if (!ino) goto out;

	if (!ino->i_sock &&
		(MAJOR(ino->i_rdev) != 30 || MINOR(ino->i_rdev) != 1))
		goto out;

	ctlptr = (struct strbuf *)A(arg1);
	datptr = (struct strbuf *)A(arg2);

	error = -EFAULT;

	if (ctlptr) {
		if (copy_from_user(&ctl,ctlptr,sizeof(ctl)))
			goto out;
		if (ctl.len < 0 && flags) {
			error = -EINVAL;
			goto out;
		}
	} else {
		ctl.len = 0;
		ctl.buf = 0;
	}

	if (datptr) {
		if (copy_from_user(&dat,datptr,sizeof(dat)))
			goto out;
	} else {
		dat.len = 0;
		dat.buf = 0;
	}

	error = timod_putmsg(fd,(char*)A(ctl.buf),ctl.len,
				(char*)A(dat.buf),dat.len,flags);
out:
	unlock_kernel();
	SOLD("done");
	return error;
}
예제 #3
0
int
svr4_putpmsg(struct pt_regs *regs)
{
	struct file		*fp;
	struct inode		*ip;
	int			fd;
	int			error = -EBADF;

	fd = (int)get_syscall_parameter(regs, 0);
	fp = fget(fd);
	if (fp) {
		ip = fp->f_dentry->d_inode;
		if (S_ISSOCK(ip->i_mode) || IS_SPX(ip))
			error = timod_putmsg(fd, ip, 1, regs);
		fput(fp);
	}
	return error;
}
예제 #4
0
파일: ioctl.c 프로젝트: sarnobat/knoppix
static inline int solaris_timod(unsigned int fd, unsigned int cmd, u32 arg,
                                    int len, int *len_p)
{
	int ret;
		
	switch (cmd & 0xff) {
	case 141: /* TI_OPTMGMT */
	{
		int i;
		u32 prim;
		SOLD("TI_OPMGMT entry");
		ret = timod_putmsg(fd, (char *)A(arg), len, NULL, -1, 0);
		SOLD("timod_putmsg() returned");
		if (ret)
			return (-ret << 8) | TSYSERR;
		i = MSG_HIPRI;
		SOLD("calling timod_getmsg()");
		ret = timod_getmsg(fd, (char *)A(arg), len, len_p, NULL, -1, NULL, &i);
		SOLD("timod_getmsg() returned");
		if (ret)
			return (-ret << 8) | TSYSERR;
		SOLD("ret ok");
		if (get_user(prim, (u32 *)A(arg)))
			return (EFAULT << 8) | TSYSERR;
		SOLD("got prim");
		if (prim == T_ERROR_ACK) {
			u32 tmp, tmp2;
			SOLD("prim is T_ERROR_ACK");
			if (get_user(tmp, (u32 *)A(arg)+3) ||
			    get_user(tmp2, (u32 *)A(arg)+2))
				return (EFAULT << 8) | TSYSERR;
			return (tmp2 << 8) | tmp;
		}
		SOLD("TI_OPMGMT return 0");
		return 0;
	}
	case 142: /* TI_BIND */
	{
		int i;
		u32 prim;
		SOLD("TI_BIND entry");
		ret = timod_putmsg(fd, (char *)A(arg), len, NULL, -1, 0);
		SOLD("timod_putmsg() returned");
		if (ret)
			return (-ret << 8) | TSYSERR;
		len = 1024; /* Solaris allows arbitrary return size */
		i = MSG_HIPRI;
		SOLD("calling timod_getmsg()");
		ret = timod_getmsg(fd, (char *)A(arg), len, len_p, NULL, -1, NULL, &i);
		SOLD("timod_getmsg() returned");
		if (ret)
			return (-ret << 8) | TSYSERR;
		SOLD("ret ok");
		if (get_user(prim, (u32 *)A(arg)))
			return (EFAULT << 8) | TSYSERR;
		SOLD("got prim");
		if (prim == T_ERROR_ACK) {
			u32 tmp, tmp2;
			SOLD("prim is T_ERROR_ACK");
			if (get_user(tmp, (u32 *)A(arg)+3) ||
			    get_user(tmp2, (u32 *)A(arg)+2))
				return (EFAULT << 8) | TSYSERR;
			return (tmp2 << 8) | tmp;
		}
		SOLD("no ERROR_ACK requested");
		if (prim != T_OK_ACK)
			return TBADSEQ;
		SOLD("OK_ACK requested");
		i = MSG_HIPRI;
		SOLD("calling timod_getmsg()");
		ret = timod_getmsg(fd, (char *)A(arg), len, len_p, NULL, -1, NULL, &i);
		SOLD("timod_getmsg() returned");
		if (ret)
			return (-ret << 8) | TSYSERR;
		SOLD("TI_BIND return ok");
		return 0;
	}
	case 140: /* TI_GETINFO */
	case 143: /* TI_UNBIND */
	case 144: /* TI_GETMYNAME */
	case 145: /* TI_GETPEERNAME */
	case 146: /* TI_SETMYNAME */
	case 147: /* TI_SETPEERNAME */
		;
	}
	return TNOTSUPPORT;
}