int main(int argc, char *argv[]) { if (argc != 2) { err_sys("fcntl usarge:<descripter>\n"); } int fd=atoi(argv[1]); getfl(fd); setfl(fd,O_NONBLOCK); getfl(fd); exit(0); }
int pipe2(int fildes[2], int flags) { int rc = pipe(fildes); if (rc == 0) { if (flags & O_NONBLOCK) { rc |= setfl(fildes[0], O_NONBLOCK); rc |= setfl(fildes[1], O_NONBLOCK); } if (flags & O_CLOEXEC) { rc |= setfd(fildes[0], FD_CLOEXEC); rc |= setfd(fildes[1], FD_CLOEXEC); } if (rc != 0) { int e = errno; close(fildes[0]); close(fildes[1]); errno = e; } } return rc; }
int main(void){ setfl(STDOUT_FILENO,O_SYNC);//同步写,每次write都要等待数据写入磁盘再返回,而通常write只是将数据 //排入队列,实际io则等到以后某个时刻进行 int n; char buf[BUFFSIZE]; while( (n=read(STDIN_FILENO,buf,BUFFSIZE)) >0){ if( write(STDOUT_FILENO,buf,n) != n) err_sys("write error"); } if( n<0) err_sys("read_error"); exit(0); }
int bsd_socketpair(int domain, int type, int protocol, int socket_vector[2]) { int flags = type & ~0xf; type &= 0xf; int rc = socketpair(domain, type, protocol, socket_vector); if (rc == 0) { if (flags & SOCK_NONBLOCK) { rc |= setfl(socket_vector[0], O_NONBLOCK); rc |= setfl(socket_vector[1], O_NONBLOCK); } if (flags & SOCK_CLOEXEC) { rc |= setfd(socket_vector[0], FD_CLOEXEC); rc |= setfd(socket_vector[1], FD_CLOEXEC); } if (rc != 0) { int e = errno; close(socket_vector[0]); close(socket_vector[1]); errno = e; } } return rc; }
int main (int argc, char const* argv[]) { char buf[BUFF_SIZE]; int ssize; setfl(STDOUT_FILENO,O_SYNC); while((ssize = read(STDIN_FILENO,buf,BUFF_SIZE)) >0) { if(write(STDOUT_FILENO,buf,ssize) != ssize) { printf("write error!\n"); return -1; } } if(ssize < 0) { printf ("read error!\n"); return -1; } return 0; }
static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, struct file *filp) { long err = -EINVAL; switch (cmd) { case F_DUPFD: err = f_dupfd(arg, filp, 0); break; case F_DUPFD_CLOEXEC: err = f_dupfd(arg, filp, O_CLOEXEC); break; case F_GETFD: err = get_close_on_exec(fd) ? FD_CLOEXEC : 0; break; case F_SETFD: err = 0; set_close_on_exec(fd, arg & FD_CLOEXEC); break; case F_GETFL: err = filp->f_flags; break; case F_SETFL: err = setfl(fd, filp, arg); break; #if BITS_PER_LONG != 32 /* 32-bit arches must use fcntl64() */ case F_OFD_GETLK: #endif case F_GETLK: err = fcntl_getlk(filp, cmd, (struct flock __user *) arg); break; #if BITS_PER_LONG != 32 /* 32-bit arches must use fcntl64() */ case F_OFD_SETLK: case F_OFD_SETLKW: #endif /* Fallthrough */ case F_SETLK: case F_SETLKW: err = fcntl_setlk(fd, filp, cmd, (struct flock __user *) 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 = f_getown(filp); force_successful_syscall_return(); break; case F_SETOWN: err = f_setown(filp, arg, 1); break; case F_GETOWN_EX: err = f_getown_ex(filp, arg); break; case F_SETOWN_EX: err = f_setown_ex(filp, arg); break; case F_GETOWNER_UIDS: err = f_getowner_uids(filp, arg); break; case F_GETSIG: err = filp->f_owner.signum; break; case F_SETSIG: /* arg == 0 restores default behaviour. */ if (!valid_signal(arg)) { break; } err = 0; filp->f_owner.signum = arg; break; case F_GETLEASE: err = fcntl_getlease(filp); break; case F_SETLEASE: err = fcntl_setlease(fd, filp, arg); break; case F_NOTIFY: err = fcntl_dirnotify(fd, filp, arg); break; case F_SETPIPE_SZ: case F_GETPIPE_SZ: err = pipe_fcntl(filp, cmd, arg); break; case F_ADD_SEALS: case F_GET_SEALS: err = shmem_fcntl(filp, cmd, arg); break; default: break; } return err; }
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; }