From owner-freebsd-hackers Tue May 2 16:43:50 1995 Return-Path: hackers-owner Received: (from majordom@localhost) by freefall.cdrom.com (8.6.10/8.6.6) id QAA20553 for hackers-outgoing; Tue, 2 May 1995 16:43:50 -0700 Received: from ref.tfs.com (ref.tfs.com [140.145.254.251]) by freefall.cdrom.com (8.6.10/8.6.6) with ESMTP id QAA20547 for ; Tue, 2 May 1995 16:43:49 -0700 Received: (from julian@localhost) by ref.tfs.com (8.6.8/8.6.6) id QAA09824; Tue, 2 May 1995 16:43:36 -0700 From: Julian Elischer Message-Id: <199505022343.QAA09824@ref.tfs.com> Subject: Re: what's in ioctl flag arg? To: dufault@hda.com (Peter Dufault) Date: Tue, 2 May 1995 16:43:35 -0700 (PDT) Cc: hackers@FreeBSD.org In-Reply-To: <199505022207.SAA00880@hda.com> from "Peter Dufault" at May 2, 95 06:07:12 pm Content-Type: text Content-Length: 5347 Sender: hackers-owner@FreeBSD.org Precedence: bulk > > What's in the ioctl flag arg? I hope it is a copy of the > flag passed in to the open(), but I can't find where it gets > set up and I'm not sure if it gets translated into an "F_" > thing instead. > > Is this how I verify that you can't write to a file in the ioctl call: > > (flag & O_ACCMODE) == O_RDONLY > > Peter > > -- > Peter Dufault Real Time Machine Control and Simulation > HD Associates, Inc. Voice: 508 433 6936 > dufault@hda.com Fax: 508 433 5267 > hmmmmmmmm /* * Ioctl system call */ struct ioctl_args { int fd; int com; caddr_t data; }; calls error = (*fp->f_ops->fo_ioctl)(fp, com, data, p); which is in fact.... /* * File table vnode ioctl routine. */ int vn_ioctl(fp, com, data, p) struct file *fp; int com; caddr_t data; struct proc *p; which in turn calls case VCHR: case VBLK: error = VOP_IOCTL(vp, com, data, fp->f_flag, p->p_ucred, p); which is in fact: /* * Device ioctl operation. */ /* ARGSUSED */ int spec_ioctl(ap) struct vop_ioctl_args /* { struct vnode *a_vp; int a_command; caddr_t a_data; int a_fflag; struct ucred *a_cred; struct proc *a_p; } */ *ap; { which calls: case VCHR: return ((*cdevsw[major(dev)].d_ioctl)(dev, ap->a_command, ap->a_data, ap->a_fflag, ap->a_p)); thus the flag comes from: fp->f_flag, which is the flags in the file table.. /* * Kernel descriptor table. * One entry for each open kernel vnode and socket. */ struct file { struct file *f_filef; /* list of active files */ struct file **f_fileb; /* list of active files */ short f_flag; /* see fcntl.h */ #define DTYPE_VNODE 1 /* file */ #define DTYPE_SOCKET 2 /* communications endpoint */ short f_type; /* descriptor type */ short f_count; /* reference count */ short f_msgcount; /* references from message queue */ struct ucred *f_cred; /* credentials associated with descriptor */ struct fileops { int (*fo_read) __P((struct file *fp, struct uio *uio, struct ucred *cred)); int (*fo_write) __P((struct file *fp, struct uio *uio, struct ucred *cred)); int (*fo_ioctl) __P((struct file *fp, int com, caddr_t data, struct proc *p)); int (*fo_select) __P((struct file *fp, int which, struct proc *p)); int (*fo_close) __P((struct file *fp, struct proc *p)); } *f_ops; off_t f_offset; caddr_t f_data; /* vnode or socket */ }; .. following to fcntl.h /* * Kernel encoding of open mode; separate read and write bits that are * independently testable: 1 greater than the above. * * XXX * FREAD and FWRITE are excluded from the #ifdef KERNEL so that TIOCFLUSH, * which was documented to use FREAD/FWRITE, continues to work. */ #ifndef _POSIX_SOURCE #define FREAD 0x0001 #define FWRITE 0x0002 #endif #define O_NONBLOCK 0x0004 /* no delay */ #define O_APPEND 0x0008 /* set append mode */ #ifndef _POSIX_SOURCE #define O_SHLOCK 0x0010 /* open with shared file lock */ #define O_EXLOCK 0x0020 /* open with exclusive file lock */ #define O_ASYNC 0x0040 /* signal pgrp when data ready */ #define O_FSYNC 0x0080 /* synchronous writes */ #endif #define O_CREAT 0x0200 /* create if nonexistant */ #define O_TRUNC 0x0400 /* truncate to zero length */ #define O_EXCL 0x0800 /* error if already exists */ #ifdef KERNEL #define FMARK 0x1000 /* mark during gc() */ #define FDEFER 0x2000 /* defer for next gc pass */ #define FHASLOCK 0x4000 /* descriptor holds advisory lock */ #endif /* defined by POSIX 1003.1; BSD default, so no bit required */ #define O_NOCTTY 0 /* don't assign controlling terminal */ #ifdef KERNEL /* convert from open() flags to/from fflags; convert O_RD/WR to FREAD/FWRITE */ #define FFLAGS(oflags) ((oflags) + 1) #define OFLAGS(fflags) ((fflags) - 1) /* bits to save after open */ #define FMASK (FREAD|FWRITE|FAPPEND|FASYNC|FFSYNC|FNONBLOCK) /* bits settable by fcntl(F_SETFL, ...) */ #define FCNTLFLAGS (FAPPEND|FASYNC|FFSYNC|FNONBLOCK) #endif /* * The O_* flags used to have only F* names, which were used in the kernel * and by fcntl. We retain the F* names for the kernel f_flags field * and for backward compatibility for fcntl. */ #ifndef _POSIX_SOURCE #define FAPPEND O_APPEND /* kernel/compat */ #define FASYNC O_ASYNC /* kernel/compat */ #define FFSYNC O_FSYNC /* kernel */ #define FNONBLOCK O_NONBLOCK /* kernel */ #define FNDELAY O_NONBLOCK /* compat */ #define O_NDELAY O_NONBLOCK /* compat */ #endif :)