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

📄 osf_sys.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 3 页
字号:
	down_read(&uts_sem);	error = -EFAULT;	if (copy_to_user(name + 0, system_utsname.sysname, 32))		goto out;	if (copy_to_user(name + 32, system_utsname.nodename, 32))		goto out;	if (copy_to_user(name + 64, system_utsname.release, 32))		goto out;	if (copy_to_user(name + 96, system_utsname.version, 32))		goto out;	if (copy_to_user(name + 128, system_utsname.machine, 32))		goto out;	error = 0;out:	up_read(&uts_sem);		return error;}asmlinkage int osf_swapon(const char *path, int flags, int lowat, int hiwat){	int ret;	/* for now, simply ignore lowat and hiwat... */	lock_kernel();	ret = sys_swapon(path, flags);	unlock_kernel();	return ret;}asmlinkage unsigned long sys_getpagesize(void){	return PAGE_SIZE;}asmlinkage unsigned long sys_getdtablesize(void){	return NR_OPEN;}asmlinkage int sys_pipe(int a0, int a1, int a2, int a3, int a4, int a5,			struct pt_regs regs){	int fd[2];	int error;	error = do_pipe(fd);	if (error)		goto out;	(&regs)->r20 = fd[1];	error = fd[0];out:	return error;}/* * For compatibility with OSF/1 only.  Use utsname(2) instead. */asmlinkage int osf_getdomainname(char *name, int namelen){	unsigned len;	int i, error;	error = verify_area(VERIFY_WRITE, name, namelen);	if (error)		goto out;	len = namelen;	if (namelen > 32)		len = 32;	down_read(&uts_sem);	for (i = 0; i < len; ++i) {		__put_user(system_utsname.domainname[i], name + i);		if (system_utsname.domainname[i] == '\0')			break;	}	up_read(&uts_sem);out:	return error;}asmlinkage long osf_shmat(int shmid, void *shmaddr, int shmflg){	unsigned long raddr;	long err;	lock_kernel();	err = sys_shmat(shmid, shmaddr, shmflg, &raddr);	if (err)		goto out;	/*	 * This works because all user-level addresses are	 * non-negative longs!	 */	err = raddr;out:	unlock_kernel();	return err;}/* * The following stuff should move into a header file should it ever * be labeled "officially supported."  Right now, there is just enough * support to avoid applications (such as tar) printing error * messages.  The attributes are not really implemented. *//* * Values for Property list entry flag */#define PLE_PROPAGATE_ON_COPY		0x1	/* cp(1) will copy entry						   by default */#define PLE_FLAG_MASK			0x1	/* Valid flag values */#define PLE_FLAG_ALL			-1	/* All flag value */struct proplistname_args {	unsigned int pl_mask;	unsigned int pl_numnames;	char **pl_names;};union pl_args {	struct setargs {		char *path;		long follow;		long nbytes;		char *buf;	} set;	struct fsetargs {		long fd;		long nbytes;		char *buf;	} fset;	struct getargs {		char *path;		long follow;		struct proplistname_args *name_args;		long nbytes;		char *buf;		int *min_buf_size;	} get;	struct fgetargs {		long fd;		struct proplistname_args *name_args;		long nbytes;		char *buf;		int *min_buf_size;	} fget;	struct delargs {		char *path;		long follow;		struct proplistname_args *name_args;	} del;	struct fdelargs {		long fd;		struct proplistname_args *name_args;	} fdel;};enum pl_code {	PL_SET = 1, PL_FSET = 2,	PL_GET = 3, PL_FGET = 4,	PL_DEL = 5, PL_FDEL = 6};asmlinkage long osf_proplist_syscall(enum pl_code code, union pl_args *args){	long error;	int *min_buf_size_ptr;	lock_kernel();	switch (code) {	case PL_SET:		error = verify_area(VERIFY_READ, &args->set.nbytes,				    sizeof(args->set.nbytes));		if (!error)			error = args->set.nbytes;		break;	case PL_FSET:		error = verify_area(VERIFY_READ, &args->fset.nbytes,				    sizeof(args->fset.nbytes));		if (!error)			error = args->fset.nbytes;		break;	case PL_GET:		get_user(min_buf_size_ptr, &args->get.min_buf_size);		error = verify_area(VERIFY_WRITE, min_buf_size_ptr,				    sizeof(*min_buf_size_ptr));		if (!error)			put_user(0, min_buf_size_ptr);		break;	case PL_FGET:		get_user(min_buf_size_ptr, &args->fget.min_buf_size);		error = verify_area(VERIFY_WRITE, min_buf_size_ptr,				    sizeof(*min_buf_size_ptr));		if (!error)			put_user(0, min_buf_size_ptr);		break;	case PL_DEL:	case PL_FDEL:		error = 0;		break;	default:		error = -EOPNOTSUPP;		break;	};	unlock_kernel();	return error;}asmlinkage int osf_sigstack(struct sigstack *uss, struct sigstack *uoss){	unsigned long usp = rdusp();	unsigned long oss_sp = current->sas_ss_sp + current->sas_ss_size;	unsigned long oss_os = on_sig_stack(usp);	int error;	if (uss) {		void *ss_sp;		error = -EFAULT;		if (get_user(ss_sp, &uss->ss_sp))			goto out;		/* If the current stack was set with sigaltstack, don't		   swap stacks while we are on it.  */		error = -EPERM;		if (current->sas_ss_sp && on_sig_stack(usp))			goto out;		/* Since we don't know the extent of the stack, and we don't		   track onstack-ness, but rather calculate it, we must 		   presume a size.  Ho hum this interface is lossy.  */		current->sas_ss_sp = (unsigned long)ss_sp - SIGSTKSZ;		current->sas_ss_size = SIGSTKSZ;	}	if (uoss) {		error = -EFAULT;		if (! access_ok(VERIFY_WRITE, uoss, sizeof(*uoss))		    || __put_user(oss_sp, &uoss->ss_sp)		    || __put_user(oss_os, &uoss->ss_onstack))			goto out;	}	error = 0;out:	return error;}/* * The Linux kernel isn't good at returning values that look * like negative longs (they are mistaken as error values). * Until that is fixed, we need this little workaround for * create_module() because it's one of the few system calls * that return kernel addresses (which are negative). */asmlinkage unsigned long alpha_create_module(char *module_name, unsigned long size,					  int a3, int a4, int a5, int a6,					     struct pt_regs regs){	asmlinkage unsigned long sys_create_module(char *, unsigned long);	long retval;	lock_kernel();	retval = sys_create_module(module_name, size);	/*	 * we get either a module address or an error number,	 * and we know the error number is a small negative	 * number, while the address is always negative but	 * much larger.	 */	if (retval + 1000 > 0)		goto out;	/* tell entry.S:syscall_error that this is NOT an error: */	regs.r0 = 0;out:	unlock_kernel();	return retval;}asmlinkage long osf_sysinfo(int command, char *buf, long count){	static char * sysinfo_table[] = {		system_utsname.sysname,		system_utsname.nodename,		system_utsname.release,		system_utsname.version,		system_utsname.machine,		"alpha",	/* instruction set architecture */		"dummy",	/* hardware serial number */		"dummy",	/* hardware manufacturer */		"dummy",	/* secure RPC domain */	};	unsigned long offset;	char *res;	long len, err = -EINVAL;	offset = command-1;	if (offset >= sizeof(sysinfo_table)/sizeof(char *)) {		/* Digital UNIX has a few unpublished interfaces here */		printk("sysinfo(%d)", command);		goto out;	}		down_read(&uts_sem);	res = sysinfo_table[offset];	len = strlen(res)+1;	if (len > count)		len = count;	if (copy_to_user(buf, res, len))		err = -EFAULT;	else		err = 0;	up_read(&uts_sem);out:	return err;}asmlinkage unsigned long osf_getsysinfo(unsigned long op, void *buffer,					unsigned long nbytes,					int *start, void *arg){	unsigned long w;	struct percpu_struct *cpu;	switch (op) {	case GSI_IEEE_FP_CONTROL:		/* Return current software fp control & status bits.  */		/* Note that DU doesn't verify available space here.  */ 		w = current->thread.flags & IEEE_SW_MASK; 		w = swcr_update_status(w, rdfpcr());		if (put_user(w, (unsigned long *) buffer))			return -EFAULT;		return 0;	case GSI_IEEE_STATE_AT_SIGNAL:		/*		 * Not sure anybody will ever use this weird stuff.  These		 * ops can be used (under OSF/1) to set the fpcr that should		 * be used when a signal handler starts executing.		 */		break; 	case GSI_UACPROC:		if (nbytes < sizeof(unsigned int))			return -EINVAL; 		w = (current->thread.flags >> UAC_SHIFT) & UAC_BITMASK; 		if (put_user(w, (unsigned int *)buffer)) 			return -EFAULT; 		return 1;	case GSI_PROC_TYPE:		if (nbytes < sizeof(unsigned long))			return -EINVAL;		cpu = (struct percpu_struct*)		  ((char*)hwrpb + hwrpb->processor_offset);		w = cpu->type;		if (put_user(w, (unsigned long *)buffer))			return -EFAULT;		return 1;	case GSI_GET_HWRPB:		if (nbytes < sizeof(*hwrpb))			return -EINVAL;		if (copy_to_user(buffer, hwrpb, nbytes) != 0)			return -EFAULT;		return 1;	default:		break;	}	return -EOPNOTSUPP;}asmlinkage unsigned long osf_setsysinfo(unsigned long op, void *buffer,					unsigned long nbytes,					int *start, void *arg){	switch (op) {	case SSI_IEEE_FP_CONTROL: {		unsigned long swcr, fpcr;		/* 		 * Alpha Architecture Handbook 4.7.7.3:		 * To be fully IEEE compiant, we must track the current IEEE		 * exception state in software, because spurrious bits can be		 * set in the trap shadow of a software-complete insn.		 */		/* Update softare trap enable bits.  */		if (get_user(swcr, (unsigned long *)buffer))			return -EFAULT;		current->thread.flags &= ~IEEE_SW_MASK;		current->thread.flags |= swcr & IEEE_SW_MASK;		/* Update the real fpcr.  */		fpcr = rdfpcr();		fpcr &= FPCR_DYN_MASK;		fpcr |= ieee_swcr_to_fpcr(swcr);		wrfpcr(fpcr); 		/* If any exceptions are now unmasked, send a signal.  */ 		if (((swcr & IEEE_STATUS_MASK) 		     >> IEEE_STATUS_TO_EXCSUM_SHIFT) & swcr) { 			send_sig(SIGFPE, current, 1); 		}		return 0;	}	case SSI_IEEE_STATE_AT_SIGNAL:	case SSI_IEEE_IGNORE_STATE_AT_SIGNAL:		/*		 * Not sure anybody will ever use this weird stuff.  These		 * ops can be used (under OSF/1) to set the fpcr that should		 * be used when a signal handler starts executing.		 */		break; 	case SSI_NVPAIRS: {		unsigned long v, w, i;		 		for (i = 0; i < nbytes; ++i) { 			if (get_user(v, 2*i + (unsigned int *)buffer)) 				return -EFAULT; 			if (get_user(w, 2*i + 1 + (unsigned int *)buffer)) 				return -EFAULT; 			switch (v) { 			case SSIN_UACPROC: 				current->thread.flags &= 					~(UAC_BITMASK << UAC_SHIFT); 				current->thread.flags |= 					(w & UAC_BITMASK) << UAC_SHIFT;

⌨️ 快捷键说明

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