Example #1
0
asmlinkage int sys_dup2(unsigned int oldfd, unsigned int newfd)
{
	int err = -EBADF;

	lock_kernel();
#ifdef FDSET_DEBUG	
	printk (KERN_ERR __FUNCTION__ " 0: oldfd = %d, newfd = %d\n", 
		oldfd, newfd);
#endif
	if (!fcheck(oldfd))
		goto out;
	if (newfd >= NR_OPEN)
		goto out;	/* following POSIX.1 6.2.1 */

	err = newfd;
	if (newfd == oldfd)
		goto out;

	/* We must be able to do the fd setting inside dupfd() without
           blocking after the sys_close(). */
	if ((err = expand_files(current->files, newfd)) < 0)
		goto out;
	
	sys_close(newfd);
	err = dupfd(oldfd, newfd);
out:
#ifdef FDSET_DEBUG	
	printk (KERN_ERR __FUNCTION__ ": return %d\n", err);
#endif
	unlock_kernel();
	return err;
}
Example #2
0
//// 文件控制系统调用函数。
// 参数fd 是文件句柄,cmd 是操作命令(参见include/fcntl.h,23-30 行)。
int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
{	
	struct file * filp;

// 如果文件句柄值大于一个进程最多打开文件数NR_OPEN,或者该句柄的文件结构指针为空,则出错,
// 返回出错码并退出。
	if (fd >= NR_OPEN || !(filp = current->filp[fd]))
		return -EBADF;
// 根据不同命令cmd 进行分别处理。
	switch (cmd) {
		case F_DUPFD:	// 复制文件句柄。
			return dupfd(fd,arg);
		case F_GETFD:	// 取文件句柄的执行时关闭标志。
			return (current->close_on_exec>>fd)&1;
		case F_SETFD:	// 设置句柄执行时关闭标志。arg 位0 置位是设置,否则关闭。
			if (arg&1)
				current->close_on_exec |= (1<<fd);
			else
				current->close_on_exec &= ~(1<<fd);
			return 0;
		case F_GETFL:	// 取文件状态标志和访问模式。
			return filp->f_flags;
		case F_SETFL:	// 设置文件状态和访问模式(根据arg 设置添加、非阻塞标志)。
			filp->f_flags &= ~(O_APPEND | O_NONBLOCK);
			filp->f_flags |= arg & (O_APPEND | O_NONBLOCK);
			return 0;
		case F_GETLK:	case F_SETLK:	case F_SETLKW:	// 未实现。
			return -1;
		default:
			return -1;
	}
}
Example #3
0
int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
{	
    struct file * filp;

    if (fd >= NR_OPEN || !(filp = current->filp[fd]))
	return -EBADF;
    switch (cmd) {
    case F_DUPFD:
	return dupfd(fd,arg);
    case F_GETFD:
	return (current->close_on_exec>>fd)&1;
    case F_SETFD:
	if (arg&1)
	    current->close_on_exec |= (1<<fd);
	else
	    current->close_on_exec &= ~(1<<fd);
	return 0;
    case F_GETFL:
	return filp->f_flags;
    case F_SETFL:
	filp->f_flags &= ~(O_APPEND | O_NONBLOCK);
	filp->f_flags |= arg & (O_APPEND | O_NONBLOCK);
	return 0;
    case F_GETLK:	case F_SETLK:	case F_SETLKW:
	return -1;
    default:
	return -1;
    }
}
Example #4
0
File: fcntl.c Project: Mellvik/elks
int sys_dup2(unsigned int oldfd, unsigned int newfd)
{
    if (oldfd < NR_OPEN && current->files.fd[oldfd]) {
	if (newfd == oldfd) return (int) newfd;
	/* following POSIX.1 6.2.1, if newfd >= NR_OPEN, return -EBADF */
	if (newfd < NR_OPEN) {
	    sys_close(newfd);
	    return dupfd(oldfd, newfd);
	}
    }
    return -EBADF;
}
Example #5
0
File: dup2.c Project: aosm/gnutar
int
dup2 (int fd, int desired_fd)
{
  if (fd == desired_fd)
    return fd;
  close (desired_fd);
#ifdef F_DUPFD
  return fcntl (fd, F_DUPFD, desired_fd);
#else
  return dupfd (fd, desired_fd);
#endif
}
Example #6
0
asmlinkage int sys_dup(unsigned int fildes)
{
	int ret;

	lock_kernel();
	ret = dupfd(fildes, 0);
	unlock_kernel();
#ifdef FDSET_DEBUG	
	if (ret < 0)
		printk (KERN_ERR __FUNCTION__ ": return %d\n", ret);
#endif
	return ret;
}
Example #7
0
int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
	struct file *file;

	if (fd > NR_OPEN || !(file = (CURRENT_TASK() )->file[fd]))
		return -EBADF;

	switch (cmd) {
		case F_DUPFD:
			return dupfd(fd, arg);
		default:
			return -EIO;
	}
}
Example #8
0
static int
dupfd (int fd, int desired_fd)
{
  int duplicated_fd = dup (fd);
  if (duplicated_fd < 0 || duplicated_fd == desired_fd)
    return duplicated_fd;
  else
    {
      int r = dupfd (fd, desired_fd);
      int e = errno;
      close (duplicated_fd);
      errno = e;
      return r;
    }
}
Example #9
0
File: fcntl.c Project: Mellvik/elks
int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned int arg)
{
    register struct file *filp;
    register struct file_struct *fils = &current->files;
    int result;

    if (fd >= NR_OPEN || !(filp = fils->fd[fd])) return -EBADF;

    switch (cmd) {
    case F_DUPFD:
	result = dupfd(fd, arg);
	break;
    case F_GETFD:
	result = test_bit(fd, &fils->close_on_exec);
	break;
    case F_SETFD:
	if (arg & 1)
	    set_bit(fd, &fils->close_on_exec);
	else
	    clear_bit(fd, &fils->close_on_exec);
	result = 0;
	break;
    case F_GETFL:
	result = (int) filp->f_flags;
	break;
    case F_SETFL:
	/*
	 * In the case of an append-only file, O_APPEND
	 * cannot be cleared
	 */
	result = -EPERM;
	if (!IS_APPEND(filp->f_inode) || (arg & O_APPEND)) {
	    filp->f_flags &= ~(O_APPEND | O_NONBLOCK);
	    filp->f_flags |= arg & (O_APPEND | O_NONBLOCK);
	    result = 0;
	}
	break;
    default:
	result = -EINVAL;
	break;
    }

    return result;
}
Example #10
0
int
dup2 (int fd, int desired_fd)
{
  int result = fcntl (fd, F_GETFL) < 0 ? -1 : fd;
  if (result == -1 || fd == desired_fd)
    return result;
  close (desired_fd);
# ifdef F_DUPFD
  result = fcntl (fd, F_DUPFD, desired_fd);
#  if REPLACE_FCHDIR
  if (0 <= result)
    result = _gl_register_dup (fd, result);
#  endif
# else
  result = dupfd (fd, desired_fd);
# endif
  if (result == -1 && (errno == EMFILE || errno == EINVAL))
    errno = EBADF;
  return result;
}
Example #11
0
int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
{	
	struct file * filp;
	extern int sock_fcntl (struct file *, unsigned int cmd,
			       unsigned long arg);
	if (fd >= NR_OPEN || !(filp = current->filp[fd]))
		return -EBADF;
	switch (cmd) {
		case F_DUPFD:
			return dupfd(fd,arg);
		case F_GETFD:
			return FD_ISSET(fd, &current->close_on_exec);
		case F_SETFD:
			if (arg&1)
				FD_SET(fd, &current->close_on_exec);
			else
				FD_CLR(fd, &current->close_on_exec);
			return 0;
		case F_GETFL:
			return filp->f_flags;
		case F_SETFL:
			filp->f_flags &= ~(O_APPEND | O_NONBLOCK);
			filp->f_flags |= arg & (O_APPEND | O_NONBLOCK);
			return 0;
		case F_GETLK:
			return fcntl_getlk(fd, (struct flock *) arg);
		case F_SETLK:
			return fcntl_setlk(fd, cmd, (struct flock *) arg);
		case F_SETLKW:
			return fcntl_setlk(fd, cmd, (struct flock *) arg);
		default:
			/* sockets need a few special fcntls. */
			if (S_ISSOCK (filp->f_inode->i_mode))
			  {
			     return (sock_fcntl (filp, cmd, arg));
			  }
			return -EINVAL;
	}
}
Example #12
0
asmlinkage int sys_dup2(unsigned int oldfd, unsigned int newfd)
{
	if (oldfd >= NR_OPEN || !current->files->fd[oldfd])
		return -EBADF;
	if (newfd == oldfd)
		return newfd;
	/*
	 * errno's for dup2() are slightly different than for fcntl(F_DUPFD)
	 * for historical reasons.
	 */
	if (newfd > NR_OPEN)	/* historical botch - should have been >= */
		return -EBADF;	/* dupfd() would return -EINVAL */
#if 1
	if (newfd == NR_OPEN)
		return -EBADF;	/* dupfd() does return -EINVAL and that may
				 * even be the standard!  But that is too
				 * weird for now.
				 */
#endif
	sys_close(newfd);
	return dupfd(oldfd,newfd);
}
Example #13
0
asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
{	
	struct file * filp;
	long err = -EBADF;

	lock_kernel();
	filp = fget(fd);
	if (!filp)
		goto out;

	err = 0;
	switch (cmd) {
		case F_DUPFD:
			err = dupfd(fd, arg);
			break;
		case F_GETFD:
			err = FD_ISSET(fd, current->files->close_on_exec);
			break;
		case F_SETFD:
			if (arg&1)
				FD_SET(fd, current->files->close_on_exec);
			else
				FD_CLR(fd, current->files->close_on_exec);
			break;
		case F_GETFL:
			err = filp->f_flags;
			break;
		case F_SETFL:
			err = setfl(fd, filp, arg);
			break;
		case F_GETLK:
			err = fcntl_getlk(fd, (struct flock *) arg);
			break;
		case F_SETLK:
			err = fcntl_setlk(fd, cmd, (struct flock *) arg);
			break;
		case F_SETLKW:
			err = fcntl_setlk(fd, cmd, (struct flock *) arg);
			break;
		case F_GETOWN:
			/*
			 * XXX If f_owner is a process group, the
			 * negative return value will get converted
			 * into an error.  Oops.  If we keep the
			 * current syscall conventions, the only way
			 * to fix this will be in libc.
			 */
			err = filp->f_owner.pid;
			break;
		case F_SETOWN:
			filp->f_owner.pid = arg;
			filp->f_owner.uid = current->uid;
			filp->f_owner.euid = current->euid;
			if (S_ISSOCK (filp->f_dentry->d_inode->i_mode))
				err = sock_fcntl (filp, F_SETOWN, arg);
			break;
		case F_GETSIG:
			err = filp->f_owner.signum;
			break;
		case F_SETSIG:
			if (arg <= 0 || arg > _NSIG) {
				err = -EINVAL;
				break;
			}
			err = 0;
			filp->f_owner.signum = arg;
			break;
		default:
			/* sockets need a few special fcntls. */
			err = -EINVAL;
			if (S_ISSOCK (filp->f_dentry->d_inode->i_mode))
				err = sock_fcntl (filp, cmd, arg);
			break;
	}
	fput(filp);
out:
	unlock_kernel();
	return err;
}
Example #14
0
int sys_dup(unsigned int fildes)
{
    return dupfd(fildes,0);
}
Example #15
0
int sys_dup2(unsigned int oldfd, unsigned int newfd)
{
    sys_close(newfd);
    return dupfd(oldfd,newfd);
}
Example #16
0
//// 复制文件句柄系统调用函数。
// 复制指定文件句柄oldfd,新句柄值等于newfd。如果newfd 已经打开,则首先关闭之。
int sys_dup2(unsigned int oldfd, unsigned int newfd)
{
	sys_close(newfd);			// 若句柄newfd 已经打开,则首先关闭之。
	return dupfd(oldfd,newfd);	// 复制并返回新句柄。
}
Example #17
0
asmlinkage int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
{	
	struct file * filp;

	if (fd >= NR_OPEN || !(filp = current->files->fd[fd]))
		return -EBADF;
	switch (cmd) {
		case F_DUPFD:
			return dupfd(fd,arg);
		case F_GETFD:
			return FD_ISSET(fd, &current->files->close_on_exec);
		case F_SETFD:
			if (arg&1)
				FD_SET(fd, &current->files->close_on_exec);
			else
				FD_CLR(fd, &current->files->close_on_exec);
			return 0;
		case F_GETFL:
			return filp->f_flags;
		case F_SETFL:
			/*
			 * In the case of an append-only file, O_APPEND
			 * cannot be cleared
			 */
			if (IS_APPEND(filp->f_inode) && !(arg & O_APPEND))
				return -EPERM;
			if ((arg & FASYNC) && !(filp->f_flags & FASYNC) &&
			    filp->f_op->fasync)
				filp->f_op->fasync(filp->f_inode, filp, 1);
			if (!(arg & FASYNC) && (filp->f_flags & FASYNC) &&
			    filp->f_op->fasync)
				filp->f_op->fasync(filp->f_inode, filp, 0);
			filp->f_flags &= ~(O_APPEND | O_NONBLOCK | FASYNC);
			filp->f_flags |= arg & (O_APPEND | O_NONBLOCK |
						FASYNC);
			return 0;
		case F_GETLK:
			return fcntl_getlk(fd, (struct flock *) arg);
		case F_SETLK:
			return fcntl_setlk(fd, cmd, (struct flock *) arg);
		case F_SETLKW:
			return fcntl_setlk(fd, cmd, (struct flock *) arg);
		case F_GETOWN:
			/*
			 * XXX If f_owner is a process group, the
			 * negative return value will get converted
			 * into an error.  Oops.  If we keep the the
			 * current syscall conventions, the only way
			 * to fix this will be in libc.
			 */
			return filp->f_owner;
		case F_SETOWN:
			filp->f_owner = arg; /* XXX security implications? */
			if (S_ISSOCK (filp->f_inode->i_mode))
				sock_fcntl (filp, F_SETOWN, arg);
			return 0;
		default:
			/* sockets need a few special fcntls. */
			if (S_ISSOCK (filp->f_inode->i_mode))
			  {
			     return (sock_fcntl (filp, cmd, arg));
			  }
			return -EINVAL;
	}
}