CTC++ Coverage Report - Execution Profile    #879/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: fs/devpts/inode.c
Instrumentation mode: function-decision-multicondition
TER: 61 % ( 40/ 66)

Start/ End/    
True False - Line Source

  1 /* -*- linux-c -*- --------------------------------------------------------- *
  2  *
  3  * linux/fs/devpts/inode.c
  4  *
  5  *  Copyright 1998-2004 H. Peter Anvin -- All Rights Reserved
  6  *
  7  * This file is part of the Linux kernel and is made available under
  8  * the terms of the GNU General Public License, version 2, or at your
  9  * option, any later version, incorporated herein by reference.
  10  *
  11  * ------------------------------------------------------------------------- */
  12 
  13 #include <linux/module.h>
  14 #include <linux/init.h>
  15 #include <linux/fs.h>
  16 #include <linux/sched.h>
  17 #include <linux/namei.h>
  18 #include <linux/mount.h>
  19 #include <linux/tty.h>
  20 #include <linux/devpts_fs.h>
  21 
  22 #define DEVPTS_SUPER_MAGIC 0x1cd1
  23 
  24 static struct vfsmount *devpts_mnt;
  25 static struct dentry *devpts_root;
  26 
  27 static struct {
  28    int setuid;
  29    int setgid;
  30    uid_t   uid;
  31    gid_t   gid;
  32    umode_t mode;
  33 } config = {.mode = 0600};
  34 
 
12   35 static int devpts_remount(struct super_block *sb, int *flags, char *data)
  36 {
  37    int setuid = 0;
  38    int setgid = 0;
  39    uid_t uid = 0;
  40    gid_t gid = 0;
  41    umode_t mode = 0600;
  42    char *this_char;
  43 
  44    this_char = NULL;
12 12   45    while ((this_char = strsep(&data, ",")) != NULL) {
  46       int n;
  47       char dummy;
12 - 48       if (!*this_char)
 - 49          continue;
12 - 50       if (sscanf(this_char, "uid=%i%c", &n, &dummy) == 1) {
  51          setuid = 1;
  52          uid = n;
  53       } else if (sscanf(this_char, "gid=%i%c", &n, &dummy) == 1) {
  54          setgid = 1;
  55          gid = n;
- 56       } else if (sscanf(this_char, "mode=%o%c", &n, &dummy) == 1)
  57          mode = n & ~S_IFMT;
    58       else {
  59          printk("devpts: called with bogus options\n");
 - 60          return -EINVAL;
  61       }
  62    }
  63    config.setuid  = setuid;
  64    config.setgid  = setgid;
  65    config.uid     = uid;
  66    config.gid     = gid;
  67    config.mode    = mode;
  68 
12    69    return 0;
  70 }
  71 
  72 static struct super_operations devpts_sops = {
  73    .statfs      = simple_statfs,
  74    .remount_fs   = devpts_remount,
  75 };
  76 
  77 static int
 
  78 devpts_fill_super(struct super_block *s, void *data, int silent)
  79 {
  80    struct inode * inode;
  81 
  82    s->s_blocksize = 1024;
  83    s->s_blocksize_bits = 10;
  84    s->s_magic = DEVPTS_SUPER_MAGIC;
  85    s->s_op = &devpts_sops;
  86    s->s_time_gran = 1;
  87 
  88    inode = new_inode(s);
- 89    if (!inode)
 - 90       goto fail;
  91    inode->i_ino = 1;
  92    inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
  93    inode->i_blocks = 0;
  94    inode->i_blksize = 1024;
  95    inode->i_uid = inode->i_gid = 0;
  96    inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
  97    inode->i_op = &simple_dir_inode_operations;
  98    inode->i_fop = &simple_dir_operations;
  99    inode->i_nlink = 2;
  100 
  101    devpts_root = s->s_root = d_alloc_root(inode);
- 102    if (s->s_root)
   103       return 0;
  104    
  105    printk("devpts: get root dentry failed\n");
  106    iput(inode);
  107 fail:
 - 108    return -ENOMEM;
  109 }
  110 
 
12   111 static struct super_block *devpts_get_sb(struct file_system_type *fs_type,
  112    int flags, const char *dev_name, void *data)
  113 {
12    114    return get_sb_single(fs_type, flags, data, devpts_fill_super);
  115 }
  116 
  117 static struct file_system_type devpts_fs_type = {
  118    .owner      = THIS_MODULE,
  119    .name      = "devpts",
  120    .get_sb      = devpts_get_sb,
  121    .kill_sb   = kill_anon_super,
  122 };
  123 
  124 /*
  125  * The normal naming convention is simply /dev/pts/<number>; this conforms
  126  * to the System V naming convention
  127  */
  128 
 
2757   129 static struct dentry *get_node(int num)
  130 {
  131    char s[12];
  132    struct dentry *root = devpts_root;
  133    mutex_lock(&root->d_inode->i_mutex);
2757    134    return lookup_one_len(s, root, sprintf(s, "%d", num));
  135 }
  136 
 
113   137 int devpts_pty_new(struct tty_struct *tty)
  138 {
  139    int number = tty->index;
  140    struct tty_driver *driver = tty->driver;
  141    dev_t device = MKDEV(driver->major, driver->minor_start+number);
  142    struct dentry *dentry;
  143    struct inode *inode = new_inode(devpts_mnt->mnt_sb);
  144 
  145    /* We're supposed to be given the slave end of a pty */
    146    BUG_ON(driver->type != TTY_DRIVER_TYPE_PTY);
113 - 146   if (__builtin_expect ( ! ! ( ( driver -> typ..
113 - 146 do-while (0)
    147    BUG_ON(driver->subtype != PTY_TYPE_SLAVE);
113 - 147   if (__builtin_expect ( ! ! ( ( driver -> sub..
113 - 147 do-while (0)
  148 
113 - 149    if (!inode)
 - 150       return -ENOMEM;
  151 
  152    inode->i_ino = number+2;
  153    inode->i_blksize = 1024;
    154    inode->i_uid = config.setuid ? config.uid : current->fsuid;
113 - 154 ternary-?: config . setuid
    155    inode->i_gid = config.setgid ? config.gid : current->fsgid;
113 - 155 ternary-?: config . setgid
  156    inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
  157    init_special_inode(inode, S_IFCHR|config.mode, device);
  158    inode->u.generic_ip = tty;
  159 
  160    dentry = get_node(number);
113 - 161    if (!IS_ERR(dentry) && !dentry->d_inode)
113    161   T && T
 - 161   T && F
 - 161   F && _
  162       d_instantiate(dentry, inode);
  163 
  164    mutex_unlock(&devpts_root->d_inode->i_mutex);
  165 
113    166    return 0;
  167 }
  168 
 
2557   169 struct tty_struct *devpts_get_tty(int number)
  170 {
  171    struct dentry *dentry = get_node(number);
  172    struct tty_struct *tty;
  173 
  174    tty = NULL;
2557 - 175    if (!IS_ERR(dentry)) {
2444 113   176       if (dentry->d_inode)
  177          tty = dentry->d_inode->u.generic_ip;
  178       dput(dentry);
  179    }
  180 
  181    mutex_unlock(&devpts_root->d_inode->i_mutex);
  182 
2557    183    return tty;
  184 }
  185 
 
87 87   186 void devpts_pty_kill(int number)
  187 {
  188    struct dentry *dentry = get_node(number);
  189 
87 - 190    if (!IS_ERR(dentry)) {
  191       struct inode *inode = dentry->d_inode;
87 - 192       if (inode) {
  193          inode->i_nlink--;
  194          d_delete(dentry);
  195          dput(dentry);
  196       }
  197       dput(dentry);
  198    }
  199    mutex_unlock(&devpts_root->d_inode->i_mutex);
  200 }
  201 
 
  202 static int __init init_devpts_fs(void)
  203 {
  204    int err = register_filesystem(&devpts_fs_type);
- 205    if (!err) {
  206       devpts_mnt = kern_mount(&devpts_fs_type);
- 207       if (IS_ERR(devpts_mnt))
  208          err = PTR_ERR(devpts_mnt);
  209    }
   210    return err;
  211 }
  212 
 
- 213 static void __exit exit_devpts_fs(void)
  214 {
  215    unregister_filesystem(&devpts_fs_type);
  216    mntput(devpts_mnt);
  217 }
  218 
  219 module_init(init_devpts_fs)
  220 module_exit(exit_devpts_fs)
  221 MODULE_LICENSE("GPL");
***TER 61% (40/66) of SOURCE FILE inode.c

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last | Top