⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sys.c

📁 在linux下使用c语言编写的一个文件拷贝的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  linux/kernel/sys.c * *  Copyright (C) 1991, 1992  Linus Torvalds */#include <linux/module.h>#include <linux/mm.h>#include <linux/utsname.h>#include <linux/mman.h>#include <linux/smp_lock.h>#include <linux/notifier.h>#include <linux/reboot.h>#include <linux/prctl.h>#include <linux/init.h>#include <linux/highuid.h>#include <asm/uaccess.h>#include <asm/io.h>#include <linux/unistd.h>#include <asm/fcntl.h>#include <asm/types.h>#include <asm/stat.h>#include <asm/errno.h>/* * this is where the system-wide overflow UID and GID are defined, for * architectures that now have 32-bit UID/GID but didn't in the past */int overflowuid = DEFAULT_OVERFLOWUID;int overflowgid = DEFAULT_OVERFLOWGID;/* * the same as above, but for filesystems which can only store a 16-bit * UID and GID. as such, this is needed on all architectures */int fs_overflowuid = DEFAULT_FS_OVERFLOWUID;int fs_overflowgid = DEFAULT_FS_OVERFLOWUID;/* * this indicates whether you can reboot with ctrl-alt-del: the default is yes */int C_A_D = 1;int cad_pid = 1;/* *	Notifier list for kernel code which wants to be called *	at shutdown. This is used to stop any idling DMA operations *	and the like.  */static struct notifier_block *reboot_notifier_list;rwlock_t notifier_lock = RW_LOCK_UNLOCKED;/** *	notifier_chain_register	- Add notifier to a notifier chain *	@list: Pointer to root list pointer *	@n: New entry in notifier chain * *	Adds a notifier to a notifier chain. * *	Currently always returns zero. */int notifier_chain_register(struct notifier_block **list,			    struct notifier_block *n){    write_lock(&notifier_lock);    while (*list) {	if (n->priority > (*list)->priority)	    break;	list = &((*list)->next);    }    n->next = *list;    *list = n;    write_unlock(&notifier_lock);    return 0;}/** *	notifier_chain_unregister - Remove notifier from a notifier chain *	@nl: Pointer to root list pointer *	@n: New entry in notifier chain * *	Removes a notifier from a notifier chain. * *	Returns zero on success, or %-ENOENT on failure. */int notifier_chain_unregister(struct notifier_block **nl,			      struct notifier_block *n){    write_lock(&notifier_lock);    while ((*nl) != NULL) {	if ((*nl) == n) {	    *nl = n->next;	    write_unlock(&notifier_lock);	    return 0;	}	nl = &((*nl)->next);    }    write_unlock(&notifier_lock);    return -ENOENT;}/** *	notifier_call_chain - Call functions in a notifier chain *	@n: Pointer to root pointer of notifier chain *	@val: Value passed unmodified to notifier function *	@v: Pointer passed unmodified to notifier function * *	Calls each function in a notifier chain in turn. * *	If the return value of the notifier can be and'd *	with %NOTIFY_STOP_MASK, then notifier_call_chain *	will return immediately, with the return value of *	the notifier function which halted execution. *	Otherwise, the return value is the return value *	of the last notifier function called. */int notifier_call_chain(struct notifier_block **n, unsigned long val,			void *v){    int ret = NOTIFY_DONE;    struct notifier_block *nb = *n;    while (nb) {	ret = nb->notifier_call(nb, val, v);	if (ret & NOTIFY_STOP_MASK) {	    return ret;	}	nb = nb->next;    }    return ret;}/** *	register_reboot_notifier - Register function to be called at reboot time *	@nb: Info about notifier function to be called * *	Registers a function with the list of functions *	to be called at reboot time. * *	Currently always returns zero, as notifier_chain_register *	always returns zero. */int register_reboot_notifier(struct notifier_block *nb){    return notifier_chain_register(&reboot_notifier_list, nb);}/** *	unregister_reboot_notifier - Unregister previously registered reboot notifier *	@nb: Hook to be unregistered * *	Unregisters a previously registered reboot *	notifier function. * *	Returns zero on success, or %-ENOENT on failure. */int unregister_reboot_notifier(struct notifier_block *nb){    return notifier_chain_unregister(&reboot_notifier_list, nb);}asmlinkage int sys_mycopy(int SourceFile,int DestFile,char *Buffer,int BUFFER_SIZE){    int BytesReaded, BytesWrited;    char *ptr;    /*  Read content from the Fromfile  */    while (BytesReaded = sys_read(SourceFile, Buffer, BUFFER_SIZE)) {	/*  An error occurt when reading    */	if ((BytesReaded == -1) && (errno != EINTR))	    return 1;	else if (BytesReaded > 0) {	    ptr = Buffer;	    while (BytesWrited = sys_write(DestFile, ptr, BytesReaded)) {		/*  An errot occurt when writing  */		if ((BytesWrited == -1) && (errno != EINTR))		    return 2;		/*  Finish  */		else if (BytesWrited == BytesReaded)		    break;		else if (BytesWrited > 0){		    ptr += BytesWrited;	    	    BytesReaded -= BytesWrited;			    		}	    }	    /*  An errot occurt when writing  */	    if (BytesWrited == -1)		return 2;	}    }    return 0;}asmlinkage long sys_ni_syscall(void){    return -ENOSYS;}static int proc_sel(struct task_struct *p, int which, int who){    if (p->pid) {	switch (which) {	case PRIO_PROCESS:	    if (!who && p == current)		return 1;	    return (p->pid == who);	case PRIO_PGRP:	    if (!who)		who = current->pgrp;	    return (p->pgrp == who);	case PRIO_USER:	    if (!who)		who = current->uid;	    return (p->uid == who);	}    }    return 0;}asmlinkage long sys_setpriority(int which, int who, int niceval){    struct task_struct *p;    int error;    if (which > 2 || which < 0)	return -EINVAL;    /* normalize: avoid signed division (rounding problems) */    error = -ESRCH;    if (niceval < -20)	niceval = -20;    if (niceval > 19)	niceval = 19;    read_lock(&tasklist_lock);    for_each_task(p) {	if (!proc_sel(p, which, who))	    continue;	if (p->uid != current->euid &&	    p->uid != current->uid && !capable(CAP_SYS_NICE)) {	    error = -EPERM;	    continue;	}	if (error == -ESRCH)	    error = 0;	if (niceval < p->nice && !capable(CAP_SYS_NICE))	    error = -EACCES;	else	    p->nice = niceval;    }    read_unlock(&tasklist_lock);    return error;}/* * Ugh. To avoid negative return values, "getpriority()" will * not return the normal nice-value, but a negated value that * has been offset by 20 (ie it returns 40..1 instead of -20..19) * to stay compatible. */asmlinkage long sys_getpriority(int which, int who){    struct task_struct *p;    long retval = -ESRCH;    if (which > 2 || which < 0)	return -EINVAL;    read_lock(&tasklist_lock);    for_each_task(p) {	long niceval;	if (!proc_sel(p, which, who))	    continue;	niceval = 20 - p->nice;	if (niceval > retval)	    retval = niceval;    }    read_unlock(&tasklist_lock);    return retval;}/* * Reboot system call: for obvious reasons only root may call it, * and even root needs to set up some magic numbers in the registers * so that some mistake won't make this reboot the whole machine. * You can also set the meaning of the ctrl-alt-del-key here. * * reboot doesn't sync: do that yourself before calling this. */asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd,			   void *arg){    char buffer[256];    /* We only trust the superuser with rebooting the system. */    if (!capable(CAP_SYS_BOOT))	return -EPERM;    /* For safety, we require "magic" arguments. */    if (magic1 != LINUX_REBOOT_MAGIC1 ||	(magic2 != LINUX_REBOOT_MAGIC2 && magic2 != LINUX_REBOOT_MAGIC2A &&	 magic2 != LINUX_REBOOT_MAGIC2B))	return -EINVAL;    lock_kernel();    switch (cmd) {    case LINUX_REBOOT_CMD_RESTART:	notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);	printk(KERN_EMERG "Restarting system.\n");	machine_restart(NULL);	break;    case LINUX_REBOOT_CMD_CAD_ON:	C_A_D = 1;	break;    case LINUX_REBOOT_CMD_CAD_OFF:	C_A_D = 0;	break;    case LINUX_REBOOT_CMD_HALT:	notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);	printk(KERN_EMERG "System halted.\n");	machine_halt();	do_exit(0);	break;    case LINUX_REBOOT_CMD_POWER_OFF:	notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);	printk(KERN_EMERG "Power down.\n");	machine_power_off();	do_exit(0);	break;    case LINUX_REBOOT_CMD_RESTART2:	if (strncpy_from_user(&buffer[0], (char *) arg, sizeof(buffer) - 1)	    < 0) {	    unlock_kernel();	    return -EFAULT;	}	buffer[sizeof(buffer) - 1] = '\0';	notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer);	printk(KERN_EMERG "Restarting system with command '%s'.\n",	       buffer);	machine_restart(buffer);	break;    default:	unlock_kernel();	return -EINVAL;    }    unlock_kernel();    return 0;}static void deferred_cad(void *dummy){    notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);    machine_restart(NULL);}/* * This function gets called by ctrl-alt-del - ie the keyboard interrupt. * As it's called within an interrupt, it may NOT sync: the only choice * is whether to reboot at once, or just ignore the ctrl-alt-del. */void ctrl_alt_del(void){    static struct tq_struct cad_tq = {	routine:deferred_cad,    };    if (C_A_D)	schedule_task(&cad_tq);    else	kill_proc(cad_pid, SIGINT, 1);}/*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -