cregit-Linux how code gets into the kernel

Release 4.11 drivers/isdn/divert/divert_procfs.c

/* $Id: divert_procfs.c,v 1.11.6.2 2001/09/23 22:24:36 kai Exp $
 *
 * Filesystem handling for the diversion supplementary services.
 *
 * Copyright 1998       by Werner Cornelius (werner@isdn4linux.de)
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 */

#include <linux/module.h>
#include <linux/poll.h>
#include <linux/slab.h>
#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
#else
#include <linux/fs.h>
#endif
#include <linux/sched.h>
#include <linux/isdnif.h>
#include <net/net_namespace.h>
#include <linux/mutex.h>
#include "isdn_divert.h"


/*********************************/
/* Variables for interface queue */
/*********************************/

ulong if_used = 0;		
/* number of interface users */
static DEFINE_MUTEX(isdn_divert_mutex);

static struct divert_info *divert_info_head = NULL;	
/* head of queue */

static struct divert_info *divert_info_tail = NULL;	
/* pointer to last entry */
static DEFINE_SPINLOCK(divert_info_lock);/* lock for queue */

static wait_queue_head_t rd_queue;

/*********************************/
/* put an info buffer into queue */
/*********************************/

void put_info_buffer(char *cp) { struct divert_info *ib; unsigned long flags; if (if_used <= 0) return; if (!cp) return; if (!*cp) return; if (!(ib = kmalloc(sizeof(struct divert_info) + strlen(cp), GFP_ATOMIC))) return; /* no memory */ strcpy(ib->info_start, cp); /* set output string */ ib->next = NULL; spin_lock_irqsave(&divert_info_lock, flags); ib->usage_cnt = if_used; if (!divert_info_head) divert_info_head = ib; /* new head */ else divert_info_tail->next = ib; /* follows existing messages */ divert_info_tail = ib; /* new tail */ /* delete old entrys */ while (divert_info_head->next) { if ((divert_info_head->usage_cnt <= 0) && (divert_info_head->next->usage_cnt <= 0)) { ib = divert_info_head; divert_info_head = divert_info_head->next; kfree(ib); } else break; } /* divert_info_head->next */ spin_unlock_irqrestore(&divert_info_lock, flags); wake_up_interruptible(&(rd_queue)); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)16792.27%120.00%
Linus Torvalds147.73%480.00%
Total181100.00%5100.00%

/* put_info_buffer */ #ifdef CONFIG_PROC_FS /**********************************/ /* deflection device read routine */ /**********************************/
static ssize_t isdn_divert_read(struct file *file, char __user *buf, size_t count, loff_t *off) { struct divert_info *inf; int len; if (!(inf = *((struct divert_info **) file->private_data))) { if (file->f_flags & O_NONBLOCK) return -EAGAIN; wait_event_interruptible(rd_queue, (inf = *((struct divert_info **) file->private_data))); } if (!inf) return (0); inf->usage_cnt--; /* new usage count */ file->private_data = &inf->next; /* next structure */ if ((len = strlen(inf->info_start)) <= count) { if (copy_to_user(buf, inf->info_start, len)) return -EFAULT; *off += len; return (len); } return (0); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)14690.12%240.00%
Arnd Bergmann138.02%120.00%
Linus Torvalds21.23%120.00%
Al Viro10.62%120.00%
Total162100.00%5100.00%

/* isdn_divert_read */ /**********************************/ /* deflection device write routine */ /**********************************/
static ssize_t isdn_divert_write(struct file *file, const char __user *buf, size_t count, loff_t *off) { return (-ENODEV); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)2996.67%266.67%
Al Viro13.33%133.33%
Total30100.00%3100.00%

/* isdn_divert_write */ /***************************************/ /* select routines for various kernels */ /***************************************/
static unsigned int isdn_divert_poll(struct file *file, poll_table *wait) { unsigned int mask = 0; poll_wait(file, &(rd_queue), wait); /* mask = POLLOUT | POLLWRNORM; */ if (*((struct divert_info **) file->private_data)) { mask |= POLLIN | POLLRDNORM; } return mask; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)61100.00%1100.00%
Total61100.00%1100.00%

/* isdn_divert_poll */ /****************/ /* Open routine */ /****************/
static int isdn_divert_open(struct inode *ino, struct file *filep) { unsigned long flags; spin_lock_irqsave(&divert_info_lock, flags); if_used++; if (divert_info_head) filep->private_data = &(divert_info_tail->next); else filep->private_data = &divert_info_head; spin_unlock_irqrestore(&divert_info_lock, flags); /* start_divert(); */ return nonseekable_open(ino, filep); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)5577.46%120.00%
Linus Torvalds1622.54%480.00%
Total71100.00%5100.00%

/* isdn_divert_open */ /*******************/ /* close routine */ /*******************/
static int isdn_divert_close(struct inode *ino, struct file *filep) { struct divert_info *inf; unsigned long flags; spin_lock_irqsave(&divert_info_lock, flags); if_used--; inf = *((struct divert_info **) filep->private_data); while (inf) { inf->usage_cnt--; inf = inf->next; } if (if_used <= 0) while (divert_info_head) { inf = divert_info_head; divert_info_head = divert_info_head->next; kfree(inf); } spin_unlock_irqrestore(&divert_info_lock, flags); return (0); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)9587.96%342.86%
Linus Torvalds1312.04%457.14%
Total108100.00%7100.00%

/* isdn_divert_close */ /*********/ /* IOCTL */ /*********/
static int isdn_divert_ioctl_unlocked(struct file *file, uint cmd, ulong arg) { divert_ioctl dioctl; int i; unsigned long flags; divert_rule *rulep; char *cp; if (copy_from_user(&dioctl, (void __user *) arg, sizeof(dioctl))) return -EFAULT; switch (cmd) { case IIOCGETVER: dioctl.drv_version = DIVERT_IIOC_VERSION; /* set version */ break; case IIOCGETDRV: if ((dioctl.getid.drvid = divert_if.name_to_drv(dioctl.getid.drvnam)) < 0) return (-EINVAL); break; case IIOCGETNAM: cp = divert_if.drv_to_name(dioctl.getid.drvid); if (!cp) return (-EINVAL); if (!*cp) return (-EINVAL); strcpy(dioctl.getid.drvnam, cp); break; case IIOCGETRULE: if (!(rulep = getruleptr(dioctl.getsetrule.ruleidx))) return (-EINVAL); dioctl.getsetrule.rule = *rulep; /* copy data */ break; case IIOCMODRULE: if (!(rulep = getruleptr(dioctl.getsetrule.ruleidx))) return (-EINVAL); spin_lock_irqsave(&divert_lock, flags); *rulep = dioctl.getsetrule.rule; /* copy data */ spin_unlock_irqrestore(&divert_lock, flags); return (0); /* no copy required */ break; case IIOCINSRULE: return (insertrule(dioctl.getsetrule.ruleidx, &dioctl.getsetrule.rule)); break; case IIOCDELRULE: return (deleterule(dioctl.getsetrule.ruleidx)); break; case IIOCDODFACT: return (deflect_extern_action(dioctl.fwd_ctrl.subcmd, dioctl.fwd_ctrl.callid, dioctl.fwd_ctrl.to_nr)); case IIOCDOCFACT: case IIOCDOCFDIS: case IIOCDOCFINT: if (!divert_if.drv_to_name(dioctl.cf_ctrl.drvid)) return (-EINVAL); /* invalid driver */ if (strnlen(dioctl.cf_ctrl.msn, sizeof(dioctl.cf_ctrl.msn)) == sizeof(dioctl.cf_ctrl.msn)) return -EINVAL; if (strnlen(dioctl.cf_ctrl.fwd_nr, sizeof(dioctl.cf_ctrl.fwd_nr)) == sizeof(dioctl.cf_ctrl.fwd_nr)) return -EINVAL; if ((i = cf_command(dioctl.cf_ctrl.drvid, (cmd == IIOCDOCFACT) ? 1 : (cmd == IIOCDOCFDIS) ? 0 : 2, dioctl.cf_ctrl.cfproc, dioctl.cf_ctrl.msn, dioctl.cf_ctrl.service, dioctl.cf_ctrl.fwd_nr, &dioctl.cf_ctrl.procid))) return (i); break; default: return (-EINVAL); } /* switch cmd */ return copy_to_user((void __user *)arg, &dioctl, sizeof(dioctl)) ? -EFAULT : 0; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)42982.82%112.50%
Dan Carpenter6612.74%112.50%
Steffen A. Mork81.54%112.50%
Arnaldo Carvalho de Melo71.35%112.50%
Al Viro40.77%112.50%
Linus Torvalds30.58%225.00%
Frédéric Weisbecker10.19%112.50%
Total518100.00%8100.00%

/* isdn_divert_ioctl */
static long isdn_divert_ioctl(struct file *file, uint cmd, ulong arg) { long ret; mutex_lock(&isdn_divert_mutex); ret = isdn_divert_ioctl_unlocked(file, cmd, arg); mutex_unlock(&isdn_divert_mutex); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Frédéric Weisbecker3678.26%150.00%
Arnd Bergmann1021.74%150.00%
Total46100.00%2100.00%

static const struct file_operations isdn_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = isdn_divert_read, .write = isdn_divert_write, .poll = isdn_divert_poll, .unlocked_ioctl = isdn_divert_ioctl, .open = isdn_divert_open, .release = isdn_divert_close, }; /****************************/ /* isdn subdir in /proc/net */ /****************************/ static struct proc_dir_entry *isdn_proc_entry = NULL; static struct proc_dir_entry *isdn_divert_entry = NULL; #endif /* CONFIG_PROC_FS */ /***************************************************************************/ /* divert_dev_init must be called before the proc filesystem may be used */ /***************************************************************************/
int divert_dev_init(void) { init_waitqueue_head(&rd_queue); #ifdef CONFIG_PROC_FS isdn_proc_entry = proc_mkdir("isdn", init_net.proc_net); if (!isdn_proc_entry) return (-1); isdn_divert_entry = proc_create("divert", S_IFREG | S_IRUGO, isdn_proc_entry, &isdn_fops); if (!isdn_divert_entry) { remove_proc_entry("isdn", init_net.proc_net); return (-1); } #endif /* CONFIG_PROC_FS */ return (0); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)7184.52%350.00%
Eric W. Biedermann89.52%116.67%
Denis V. Lunev44.76%116.67%
Al Viro11.19%116.67%
Total84100.00%6100.00%

/* divert_dev_init */ /***************************************************************************/ /* divert_dev_deinit must be called before leaving isdn when included as */ /* a module. */ /***************************************************************************/
int divert_dev_deinit(void) { #ifdef CONFIG_PROC_FS remove_proc_entry("divert", isdn_proc_entry); remove_proc_entry("isdn", init_net.proc_net); #endif /* CONFIG_PROC_FS */ return (0); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)3088.24%375.00%
Eric W. Biedermann411.76%125.00%
Total34100.00%4100.00%

/* divert_dev_deinit */

Overall Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)122382.25%517.24%
Dan Carpenter664.44%13.45%
Linus Torvalds563.77%724.14%
Frédéric Weisbecker402.69%13.45%
Arnd Bergmann302.02%26.90%
Kai Germaschewski161.08%13.45%
Eric W. Biedermann151.01%13.45%
Steffen A. Mork80.54%13.45%
Al Viro70.47%26.90%
Arnaldo Carvalho de Melo70.47%13.45%
Denis V. Lunev40.27%13.45%
Thomas Gleixner40.27%13.45%
Charlie Shepherd30.20%13.45%
Alexey Dobriyan30.20%13.45%
Tejun Heo30.20%13.45%
Joe Perches10.07%13.45%
Arjan van de Ven10.07%13.45%
Total1487100.00%29100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.