sys_hpux.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:8k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * linux/arch/parisc/kernel/sys_hpux.c
  3.  *
  4.  * implements HPUX syscalls.
  5.  */
  6. #include <linux/sched.h>
  7. #include <linux/smp_lock.h>
  8. #include <linux/utsname.h>
  9. #include <asm/errno.h>
  10. #include <asm/uaccess.h>
  11. unsigned long sys_brk(unsigned long addr);
  12.  
  13. unsigned long hpux_brk(unsigned long addr)
  14. {
  15. /* Sigh.  Looks like HP/UX libc relies on kernel bugs. */
  16. return sys_brk(addr + PAGE_SIZE);
  17. }
  18. int hpux_sbrk(void)
  19. {
  20. return -ENOSYS;
  21. }
  22. /* Random other syscalls */
  23. int hpux_nice(int priority_change)
  24. {
  25. return -ENOSYS;
  26. }
  27. int hpux_ptrace(void)
  28. {
  29. return -ENOSYS;
  30. }
  31. int hpux_wait(int *stat_loc)
  32. {
  33. extern int sys_waitpid(int, int *, int);
  34. return sys_waitpid(-1, stat_loc, 0);
  35. }
  36. #define _SC_CPU_VERSION 10001
  37. #define _SC_OPEN_MAX 4
  38. #define CPU_PA_RISC1_1 0x210
  39. int hpux_sysconf(int which)
  40. {
  41. switch (which) {
  42. case _SC_CPU_VERSION:
  43. return CPU_PA_RISC1_1;
  44. case _SC_OPEN_MAX:
  45. return INT_MAX;
  46. default:
  47. return -EINVAL;
  48. }
  49. }
  50. /*****************************************************************************/
  51. #define HPUX_UTSLEN 9
  52. #define HPUX_SNLEN 15
  53. struct hpux_utsname {
  54. char sysname[HPUX_UTSLEN];
  55. char nodename[HPUX_UTSLEN];
  56. char release[HPUX_UTSLEN];
  57. char version[HPUX_UTSLEN];
  58. char machine[HPUX_UTSLEN];
  59. char idnumber[HPUX_SNLEN];
  60. } ;
  61. struct hpux_ustat {
  62. int32_t f_tfree; /* total free (daddr_t)  */
  63. u_int32_t f_tinode; /* total inodes free (ino_t)  */
  64. char f_fname[6]; /* filsys name */
  65. char f_fpack[6]; /* filsys pack name */
  66. u_int32_t f_blksize; /* filsys block size (int) */
  67. };
  68. /*
  69.  * HPUX's utssys() call.  It's a collection of miscellaneous functions,
  70.  * alas, so there's no nice way of splitting them up.
  71.  */
  72. /*  This function is called from hpux_utssys(); HP-UX implements
  73.  *  ustat() as an option to utssys().
  74.  *
  75.  *  Now, struct ustat on HP-UX is exactly the same as on Linux, except
  76.  *  that it contains one addition field on the end, int32_t f_blksize.
  77.  *  So, we could have written this function to just call the Linux
  78.  *  sys_ustat(), (defined in linux/fs/super.c), and then just
  79.  *  added this additional field to the user's structure.  But I figure
  80.  *  if we're gonna be digging through filesystem structures to get
  81.  *  this, we might as well just do the whole enchilada all in one go.
  82.  *
  83.  *  So, most of this function is almost identical to sys_ustat().
  84.  *  I have placed comments at the few lines changed or added, to
  85.  *  aid in porting forward if and when sys_ustat() is changed from
  86.  *  its form in kernel 2.2.5.
  87.  */
  88. static int hpux_ustat(dev_t dev, struct hpux_ustat *ubuf)
  89. {
  90. struct super_block *s;
  91. struct hpux_ustat tmp;  /* Changed to hpux_ustat */
  92. struct statfs sbuf;
  93. int err = -EINVAL;
  94. lock_kernel();
  95. s = get_super(to_kdev_t(dev));
  96. unlock_kernel();
  97. if (s == NULL)
  98. goto out;
  99. err = vfs_statfs(s, &sbuf);
  100. drop_super(s);
  101. if (err)
  102. goto out;
  103. memset(&tmp,0,sizeof(struct hpux_ustat));  /* Changed to hpux_ustat */
  104. tmp.f_tfree = (int32_t)sbuf.f_bfree;
  105. tmp.f_tinode = (u_int32_t)sbuf.f_ffree;
  106. tmp.f_blksize = (u_int32_t)sbuf.f_bsize;  /*  Added this line  */
  107. /* Changed to hpux_ustat:  */
  108. err = copy_to_user(ubuf,&tmp,sizeof(struct hpux_ustat)) ? -EFAULT : 0;
  109. out:
  110. return err;
  111. }
  112. /*  This function is called from hpux_utssys(); HP-UX implements
  113.  *  uname() as an option to utssys().
  114.  *
  115.  *  The form of this function is pretty much copied from sys_olduname(),
  116.  *  defined in linux/arch/i386/kernel/sys_i386.c.
  117.  */
  118. /*  TODO: Are these put_user calls OK?  Should they pass an int?
  119.  *        (I copied it from sys_i386.c like this.)
  120.  */
  121. static int hpux_uname(struct hpux_utsname *name)
  122. {
  123. int error;
  124. if (!name)
  125. return -EFAULT;
  126. if (!access_ok(VERIFY_WRITE,name,sizeof(struct hpux_utsname)))
  127. return -EFAULT;
  128. down_read(&uts_sem);
  129. error = __copy_to_user(&name->sysname,&system_utsname.sysname,HPUX_UTSLEN-1);
  130. error |= __put_user(0,name->sysname+HPUX_UTSLEN-1);
  131. error |= __copy_to_user(&name->nodename,&system_utsname.nodename,HPUX_UTSLEN-1);
  132. error |= __put_user(0,name->nodename+HPUX_UTSLEN-1);
  133. error |= __copy_to_user(&name->release,&system_utsname.release,HPUX_UTSLEN-1);
  134. error |= __put_user(0,name->release+HPUX_UTSLEN-1);
  135. error |= __copy_to_user(&name->version,&system_utsname.version,HPUX_UTSLEN-1);
  136. error |= __put_user(0,name->version+HPUX_UTSLEN-1);
  137. error |= __copy_to_user(&name->machine,&system_utsname.machine,HPUX_UTSLEN-1);
  138. error |= __put_user(0,name->machine+HPUX_UTSLEN-1);
  139. up_read(&uts_sem);
  140. /*  HP-UX  utsname has no domainname field.  */
  141. /*  TODO:  Implement idnumber!!!  */
  142. #if 0
  143. error |= __put_user(0,name->idnumber);
  144. error |= __put_user(0,name->idnumber+HPUX_SNLEN-1);
  145. #endif
  146. error = error ? -EFAULT : 0;
  147. return error;
  148. }
  149. int sys_sethostname(char *, int);
  150. int sys_gethostname(char *, int);
  151. /*  Note: HP-UX just uses the old suser() function to check perms
  152.  *  in this system call.  We'll use capable(CAP_SYS_ADMIN).
  153.  */
  154. int hpux_utssys(char *ubuf, int n, int type)
  155. {
  156. int len;
  157. int error;
  158. switch( type ) {
  159. case 0:
  160. /*  uname():  */
  161. return( hpux_uname( (struct hpux_utsname *)ubuf ) );
  162. break ;
  163. case 1:
  164. /*  Obsolete (used to be umask().)  */
  165. return -EFAULT ;
  166. break ;
  167. case 2:
  168. /*  ustat():  */
  169. return( hpux_ustat((dev_t)n, (struct hpux_ustat *)ubuf) );
  170. break ;
  171. case 3:
  172. /*  setuname():
  173.  *
  174.  *  On linux (unlike HP-UX), utsname.nodename
  175.  *  is the same as the hostname.
  176.  *
  177.  *  sys_sethostname() is defined in linux/kernel/sys.c.
  178.  */
  179. if (!capable(CAP_SYS_ADMIN))
  180. return -EPERM;
  181. /*  Unlike Linux, HP-UX returns an error if n==0:  */
  182. if ( n <= 0 )
  183. return -EINVAL ;
  184. /*  Unlike Linux, HP-UX truncates it if n is too big:  */
  185. len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
  186. return( sys_sethostname(ubuf, len) );
  187. break ;
  188. case 4:
  189. /*  sethostname():
  190.  *
  191.  *  sys_sethostname() is defined in linux/kernel/sys.c.
  192.  */
  193. if (!capable(CAP_SYS_ADMIN))
  194. return -EPERM;
  195. /*  Unlike Linux, HP-UX returns an error if n==0:  */
  196. if ( n <= 0 )
  197. return -EINVAL ;
  198. /*  Unlike Linux, HP-UX truncates it if n is too big:  */
  199. len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
  200. return( sys_sethostname(ubuf, len) );
  201. break ;
  202. case 5:
  203. /*  gethostname():
  204.  *
  205.  *  sys_gethostname() is defined in linux/kernel/sys.c.
  206.  */
  207. /*  Unlike Linux, HP-UX returns an error if n==0:  */
  208. if ( n <= 0 )
  209. return -EINVAL ;
  210. return( sys_gethostname(ubuf, n) );
  211. break ;
  212. case 6:
  213. /*  Supposedly called from setuname() in libc.
  214.  *  TODO: When and why is this called?
  215.  *        Is it ever even called?
  216.  *
  217.  *  This code should look a lot like sys_sethostname(),
  218.  *  defined in linux/kernel/sys.c.  If that gets updated,
  219.  *  update this code similarly.
  220.  */
  221. if (!capable(CAP_SYS_ADMIN))
  222. return -EPERM;
  223. /*  Unlike Linux, HP-UX returns an error if n==0:  */
  224. if ( n <= 0 )
  225. return -EINVAL ;
  226. /*  Unlike Linux, HP-UX truncates it if n is too big:  */
  227. len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
  228. /**/
  229. /*  TODO:  print a warning about using this?  */
  230. down_write(&uts_sem);
  231. error = -EFAULT;
  232. if (!copy_from_user(system_utsname.sysname, ubuf, len)) {
  233. system_utsname.sysname[len] = 0;
  234. error = 0;
  235. }
  236. up_write(&uts_sem);
  237. return error;
  238. break ;
  239. case 7:
  240. /*  Sets utsname.release, if you're allowed.
  241.  *  Undocumented.  Used by swinstall to change the
  242.  *  OS version, during OS updates.  Yuck!!!
  243.  *
  244.  *  This code should look a lot like sys_sethostname()
  245.  *  in linux/kernel/sys.c.  If that gets updated, update
  246.  *  this code similarly.
  247.  */
  248. if (!capable(CAP_SYS_ADMIN))
  249. return -EPERM;
  250. /*  Unlike Linux, HP-UX returns an error if n==0:  */
  251. if ( n <= 0 )
  252. return -EINVAL ;
  253. /*  Unlike Linux, HP-UX truncates it if n is too big:  */
  254. len = (n <= __NEW_UTS_LEN) ? n : __NEW_UTS_LEN ;
  255. /**/
  256. /*  TODO:  print a warning about this?  */
  257. down_write(&uts_sem);
  258. error = -EFAULT;
  259. if (!copy_from_user(system_utsname.release, ubuf, len)) {
  260. system_utsname.release[len] = 0;
  261. error = 0;
  262. }
  263. up_write(&uts_sem);
  264. return error;
  265. break ;
  266. default:
  267. /*  This system call returns -EFAULT if given an unknown type.
  268.    *  Why not -EINVAL?  I don't know, it's just not what they did.
  269.    */
  270. return -EFAULT ;
  271. }
  272. }
  273. int hpux_getdomainname(char *name, int len)
  274. {
  275.   int nlen;
  276.   int err = -EFAULT;
  277.  
  278.   down_read(&uts_sem);
  279.  
  280. nlen = strlen(system_utsname.domainname) + 1;
  281. if (nlen < len)
  282. len = nlen;
  283. if(len > __NEW_UTS_LEN)
  284. goto done;
  285. if(copy_to_user(name, system_utsname.domainname, len))
  286. goto done;
  287. err = 0;
  288. done:
  289. up_read(&uts_sem);
  290. return err;
  291. }
  292. int hpux_pipe(int *kstack_fildes)
  293. {
  294. int error;
  295. lock_kernel();
  296. error = do_pipe(kstack_fildes);
  297. unlock_kernel();
  298. return error;
  299. }