Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 2 May 1995 16:43:35 -0700 (PDT)
From:      Julian Elischer <julian@ref.tfs.com>
To:        dufault@hda.com (Peter Dufault)
Cc:        hackers@FreeBSD.org
Subject:   Re: what's in ioctl flag arg?
Message-ID:  <199505022343.QAA09824@ref.tfs.com>
In-Reply-To: <199505022207.SAA00880@hda.com> from "Peter Dufault" at May 2, 95 06:07:12 pm

next in thread | previous in thread | raw e-mail | index | archive | help
> 
> 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


:)






Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199505022343.QAA09824>