/* Duplicate FD to FD2, closing the old FD2 and making FD2 be open the same file as FD is. Return FD2 or -1. */ int __dup2 (int fd, int fd2) { if (fd < 0 || fd2 < 0) { __set_errno (EBADF); return-1; } if (fd == fd2) /* No way to check that they are valid. */ return fd2; __set_errno (ENOSYS); return-1; }
/* Create a named pipe (FIFO) named PATH with protections MODE. */ int mkfifo(constchar *path, mode_t mode) { dev_t dev = 0; return __xmknod (_MKNOD_VER, path, mode | S_IFIFO, &dev); }
/* Create a device file named PATH, with permission and special bits MODE and device number DEV (which can be constructed from major and minor device numbers with the `makedev' macro above). */ int __xmknod (int vers, constchar *path, mode_t mode, dev_t *dev) { unsignedlonglongint k_dev; if (vers != _MKNOD_VER) return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL); /* We must convert the value to dev_t type used by the kernel. */ k_dev = (*dev) & ((1ULL << 32) - 1); if (k_dev != *dev) return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL); return INLINE_SYSCALL (mknod, 3, path, mode, (unsignedint) k_dev); }
staticintfifo_open(struct inode *inode, struct file *filp) { structpipe_inode_info *pipe; bool is_pipe = inode->i_sb->s_magic == PIPEFS_MAGIC; int ret; filp->f_version = 0; spin_lock(&inode->i_lock); if (inode->i_pipe) { pipe = inode->i_pipe; pipe->files++; spin_unlock(&inode->i_lock); } else { spin_unlock(&inode->i_lock); pipe = alloc_pipe_info(); if (!pipe) return -ENOMEM; pipe->files = 1; spin_lock(&inode->i_lock); if (unlikely(inode->i_pipe)) { inode->i_pipe->files++; spin_unlock(&inode->i_lock); free_pipe_info(pipe); pipe = inode->i_pipe; } else { inode->i_pipe = pipe; spin_unlock(&inode->i_lock); } } filp->private_data = pipe; /* OK, we have a pipe and it's pinned down */ __pipe_lock(pipe); /* We can only do regular read/write on fifos */ filp->f_mode &= (FMODE_READ | FMODE_WRITE); switch (filp->f_mode) { case FMODE_READ: /* * O_RDONLY * POSIX.1 says that O_NONBLOCK means return with the FIFO * opened, even when there is no process writing the FIFO. */ pipe->r_counter++; if (pipe->readers++ == 0) wake_up_partner(pipe); if (!is_pipe && !pipe->writers) { if ((filp->f_flags & O_NONBLOCK)) { /* suppress EPOLLHUP until we have * seen a writer */ filp->f_version = pipe->w_counter; } else { if (wait_for_partner(pipe, &pipe->w_counter)) goto err_rd; } } break; case FMODE_WRITE: /* * O_WRONLY * POSIX.1 says that O_NONBLOCK means return -1 with * errno=ENXIO when there is no process reading the FIFO. */ ret = -ENXIO; if (!is_pipe && (filp->f_flags & O_NONBLOCK) && !pipe->readers) goto err; pipe->w_counter++; if (!pipe->writers++) wake_up_partner(pipe); if (!is_pipe && !pipe->readers) { if (wait_for_partner(pipe, &pipe->r_counter)) goto err_wr; } break; case FMODE_READ | FMODE_WRITE: /* * O_RDWR * POSIX.1 leaves this case "undefined" when O_NONBLOCK is set. * This implementation will NEVER block on a O_RDWR open, since * the process can at least talk to itself. */ pipe->readers++; pipe->writers++; pipe->r_counter++; pipe->w_counter++; if (pipe->readers == 1 || pipe->writers == 1) wake_up_partner(pipe); break; default: ret = -EINVAL; goto err; } /* Ok! */ __pipe_unlock(pipe); return0; ...... }