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

📄 osf_sys.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
	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);	return 0;}/* * 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 __user *path;		long follow;		long nbytes;		char __user *buf;	} set;	struct fsetargs {		long fd;		long nbytes;		char __user *buf;	} fset;	struct getargs {		char __user *path;		long follow;		struct proplistname_args __user *name_args;		long nbytes;		char __user *buf;		int __user *min_buf_size;	} get;	struct fgetargs {		long fd;		struct proplistname_args __user *name_args;		long nbytes;		char __user *buf;		int __user *min_buf_size;	} fget;	struct delargs {		char __user *path;		long follow;		struct proplistname_args __user *name_args;	} del;	struct fdelargs {		long fd;		struct proplistname_args __user *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 longosf_proplist_syscall(enum pl_code code, union pl_args __user *args){	long error;	int __user *min_buf_size_ptr;	lock_kernel();	switch (code) {	case PL_SET:		if (get_user(error, &args->set.nbytes))			error = -EFAULT;		break;	case PL_FSET:		if (get_user(error, &args->fset.nbytes))			error = -EFAULT;		break;	case PL_GET:		error = get_user(min_buf_size_ptr, &args->get.min_buf_size);		if (error)			break;		error = put_user(0, min_buf_size_ptr);		break;	case PL_FGET:		error = get_user(min_buf_size_ptr, &args->fget.min_buf_size);		if (error)			break;		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 intosf_sigstack(struct sigstack __user *uss, struct sigstack __user *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 __user *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;}asmlinkage longosf_sysinfo(int command, char __user *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 longosf_getsysinfo(unsigned long op, void __user *buffer, unsigned long nbytes,	       int __user *start, void __user *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_info()->ieee_state & IEEE_SW_MASK; 		w = swcr_update_status(w, rdfpcr());		if (put_user(w, (unsigned long __user *) 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_info()->flags >> UAC_SHIFT) & UAC_BITMASK; 		if (put_user(w, (unsigned int __user *)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  __user*)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 longosf_setsysinfo(unsigned long op, void __user *buffer, unsigned long nbytes,	       int __user *start, void __user *arg){	switch (op) {	case SSI_IEEE_FP_CONTROL: {		unsigned long swcr, fpcr;		unsigned int *state;		/* 		 * 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.		 */		if (get_user(swcr, (unsigned long __user *)buffer))			return -EFAULT;		state = &current_thread_info()->ieee_state;		/* Update softare trap enable bits.  */		*state = (*state & ~IEEE_SW_MASK) | (swcr & IEEE_SW_MASK);		/* Update the real fpcr.  */		fpcr = rdfpcr() & FPCR_DYN_MASK;		fpcr |= ieee_swcr_to_fpcr(swcr);		wrfpcr(fpcr);		return 0;	}	case SSI_IEEE_RAISE_EXCEPTION: {		unsigned long exc, swcr, fpcr, fex;		unsigned int *state;		if (get_user(exc, (unsigned long __user *)buffer))			return -EFAULT;		state = &current_thread_info()->ieee_state;		exc &= IEEE_STATUS_MASK;		/* Update softare trap enable bits.  */ 		swcr = (*state & IEEE_SW_MASK) | exc;		*state |= exc;		/* Update the real fpcr.  */		fpcr = rdfpcr();		fpcr |= ieee_swcr_to_fpcr(swcr);		wrfpcr(fpcr); 		/* If any exceptions set by this call, and are unmasked,		   send a signal.  Old exceptions are not signaled.  */		fex = (exc >> IEEE_STATUS_TO_EXCSUM_SHIFT) & swcr; 		if (fex) {			siginfo_t info;			int si_code = 0;			if (fex & IEEE_TRAP_ENABLE_DNO) si_code = FPE_FLTUND;			if (fex & IEEE_TRAP_ENABLE_INE) si_code = FPE_FLTRES;			if (fex & IEEE_TRAP_ENABLE_UNF) si_code = FPE_FLTUND;			if (fex & IEEE_TRAP_ENABLE_OVF) si_code = FPE_FLTOVF;			if (fex & IEEE_TRAP_ENABLE_DZE) si_code = FPE_FLTDIV;			if (fex & IEEE_TRAP_ENABLE_INV) si_code = FPE_FLTINV;			info.si_signo = SIGFPE;			info.si_errno = 0;			info.si_code = si_code;			info.si_addr = NULL;  /* FIXME */ 			send_sig_info(SIGFPE, &info, current); 		}		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;		unsigned int old, new;		 		for (i = 0; i < nbytes; ++i) { 			if (get_user(v, 2*i + (unsigned int __user *)buffer)) 				return -EFAULT; 			if (get_user(w, 2*i + 1 + (unsigned int __user *)buffer)) 				return -EFAULT; 			switch (v) { 			case SSIN_UACPROC:			again:				old = current_thread_info()->flags;				new = old & ~(UAC_BITMASK << UAC_SHIFT);				new = new | (w & UAC_BITMASK) << UAC_SHIFT;				if (cmpxchg(&current_thread_info()->flags,					    old, new) != old)					goto again; 				break;  			default: 				return -EOPNOTSUPP; 			} 		} 		return 0;	} 	default:		break;	}	return -EOPNOTSUPP;}/* Translations due to the fact that OSF's time_t is an int.  Which   affects all sorts of things, like timeval and itimerval.  */extern struct timezone sys_tz;extern int do_adjtimex(struct timex *);struct timeval32{    int tv_sec, tv_usec;};struct itimerval32{    struct timeval32 it_interval;    struct timeval32 it_value;};static inline longget_tv32(struct timeval *o, struct timeval32 __user *i){	return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||		(__get_user(o->tv_sec, &i->tv_sec) |		 __get_user(o->tv_usec, &i->tv_usec)));}static inline longput_tv32(struct timeval32 __user *o, struct timeval *i){	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||		(__put_user(i->tv_sec, &o->tv_sec) |		 __put_user(i->tv_usec, &o->tv_usec)));}static inline longget_it32(struct itimerval *o, struct itimerval32 __user *i){	return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||		(__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |		 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |		 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |		 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));}static inline longput_it32(struct itimerval32 __user *o, struct itimerval *i){	return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||		(__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |		 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |		 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |		 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));}static inline voidjiffies_to_timeval32(unsigned long jiffies, struct timeval32 *value){	value->tv_usec = (jiffies % HZ) * (1000000L / HZ);	value->tv_sec = jiffies / HZ;}asmlinkage intosf_gettimeofday(struct timeval32 __user *tv, struct timezone __user *tz){	if (tv) {		struct timeval ktv;		do_gettimeofday(&ktv);		if (put_tv32(tv, &ktv))			return -EFAULT;	}	if (tz) {		if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))

⌨️ 快捷键说明

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