This source file includes following definitions.
- osf_filldir
- osf_getdirentries
- sys_madvise
- sys_getxuid
- sys_getxgid
- sys_getxpid
- osf_mmap
- osf_statfs
- osf_fstatfs
- getdev
- putdev
- osf_ufs_mount
- osf_cdfs_mount
- osf_procfs_mount
- osf_mount
- osf_umount
- osf_usleep_thread
- osf_utsname
- osf_swapon
- sys_getpagesize
- sys_getdtablesize
- sys_pipe
- osf_getdomainname
- osf_shmat
- osf_proplist_syscall
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/kernel.h>
16 #include <linux/mm.h>
17 #include <linux/stddef.h>
18 #include <linux/unistd.h>
19 #include <linux/ptrace.h>
20 #include <linux/malloc.h>
21 #include <linux/ldt.h>
22 #include <linux/user.h>
23 #include <linux/a.out.h>
24 #include <linux/utsname.h>
25 #include <linux/time.h>
26 #include <linux/major.h>
27 #include <linux/stat.h>
28 #include <linux/mman.h>
29 #include <linux/shm.h>
30
31 #include <asm/segment.h>
32 #include <asm/system.h>
33 #include <asm/io.h>
34
35 extern int do_mount(kdev_t, const char *, char *, int, void *);
36 extern int do_pipe(int *);
37
38 extern struct file_operations * get_blkfops(unsigned int);
39 extern struct file_operations * get_chrfops(unsigned int);
40
41 extern kdev_t get_unnamed_dev(void);
42 extern void put_unnamed_dev(kdev_t);
43
44 extern asmlinkage int sys_umount(char *);
45 extern asmlinkage int sys_swapon(const char *specialfile, int swap_flags);
46
47
48
49
50
51
52
53
54 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
55 #define ROUND_UP(x) (((x)+3) & ~3)
56
57 struct osf_dirent {
58 unsigned int d_ino;
59 unsigned short d_reclen;
60 unsigned short d_namlen;
61 char d_name[1];
62 };
63
64 struct osf_dirent_callback {
65 struct osf_dirent * dirent;
66 long *basep;
67 int count;
68 int error;
69 };
70
71 static int osf_filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino)
72 {
73 struct osf_dirent * dirent;
74 struct osf_dirent_callback * buf = (struct osf_dirent_callback *) __buf;
75 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
76
77 buf->error = -EINVAL;
78 if (reclen > buf->count)
79 return -EINVAL;
80 if (buf->basep) {
81 put_user(offset, buf->basep);
82 buf->basep = NULL;
83 }
84 dirent = buf->dirent;
85 put_user(ino, &dirent->d_ino);
86 put_user(namlen, &dirent->d_namlen);
87 put_user(reclen, &dirent->d_reclen);
88 memcpy_tofs(dirent->d_name, name, namlen);
89 put_fs_byte(0, dirent->d_name + namlen);
90 ((char *) dirent) += reclen;
91 buf->dirent = dirent;
92 buf->count -= reclen;
93 return 0;
94 }
95
96 asmlinkage int osf_getdirentries(unsigned int fd, struct osf_dirent * dirent,
97 unsigned int count, long *basep)
98 {
99 int error;
100 struct file * file;
101 struct osf_dirent_callback buf;
102
103 if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
104 return -EBADF;
105 if (!file->f_op || !file->f_op->readdir)
106 return -ENOTDIR;
107 error = verify_area(VERIFY_WRITE, dirent, count);
108 if (error)
109 return error;
110 if (basep) {
111 error = verify_area(VERIFY_WRITE, basep, sizeof(long));
112 if (error)
113 return error;
114 }
115 buf.dirent = dirent;
116 buf.basep = basep;
117 buf.count = count;
118 buf.error = 0;
119 error = file->f_op->readdir(file->f_inode, file, &buf, osf_filldir);
120 if (error < 0)
121 return error;
122 if (count == buf.count)
123 return buf.error;
124 return count - buf.count;
125 }
126
127
128
129
130 asmlinkage unsigned long sys_madvise(void)
131 {
132 return 0;
133 }
134
135 asmlinkage unsigned long sys_getxuid(int a0, int a1, int a2, int a3, int a4, int a5,
136 struct pt_regs regs)
137 {
138 (®s)->r20 = current->euid;
139 return current->uid;
140 }
141
142 asmlinkage unsigned long sys_getxgid(int a0, int a1, int a2, int a3, int a4, int a5,
143 struct pt_regs regs)
144 {
145 (®s)->r20 = current->egid;
146 return current->gid;
147 }
148
149 asmlinkage unsigned long sys_getxpid(int a0, int a1, int a2, int a3, int a4, int a5,
150 struct pt_regs regs)
151 {
152 (®s)->r20 = current->p_opptr->pid;
153 return current->pid;
154 }
155
156 asmlinkage unsigned long osf_mmap(unsigned long addr, unsigned long len,
157 unsigned long prot, unsigned long flags, unsigned long fd,
158 unsigned long off)
159 {
160 struct file * file = NULL;
161
162 if (flags & (MAP_HASSEMAPHORE | MAP_INHERIT | MAP_UNALIGNED))
163 printk("%s: unimplemented OSF mmap flags %04lx\n", current->comm, flags);
164 if (!(flags & MAP_ANONYMOUS)) {
165 if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
166 return -EBADF;
167 }
168 return do_mmap(file, addr, len, prot, flags, off);
169 }
170
171 asmlinkage int osf_statfs(char * path, struct statfs * buffer, unsigned long bufsiz)
172 {
173 struct inode * inode;
174 int retval;
175
176 if (bufsiz > sizeof(struct statfs))
177 bufsiz = sizeof(struct statfs);
178 retval = verify_area(VERIFY_WRITE, buffer, bufsiz);
179 if (retval)
180 return retval;
181 retval = namei(path, &inode);
182 if (retval)
183 return retval;
184 if (!inode->i_sb->s_op->statfs) {
185 iput(inode);
186 return -ENOSYS;
187 }
188 inode->i_sb->s_op->statfs(inode->i_sb, buffer, bufsiz);
189 iput(inode);
190 return 0;
191 }
192
193 asmlinkage int osf_fstatfs(unsigned long fd, struct statfs * buffer, unsigned long bufsiz)
194 {
195 struct file * file;
196 struct inode * inode;
197 int retval;
198
199 retval = verify_area(VERIFY_WRITE, buffer, bufsiz);
200 if (retval)
201 return retval;
202 if (bufsiz > sizeof(struct statfs))
203 bufsiz = sizeof(struct statfs);
204 if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
205 return -EBADF;
206 if (!(inode = file->f_inode))
207 return -ENOENT;
208 if (!inode->i_sb->s_op->statfs)
209 return -ENOSYS;
210 inode->i_sb->s_op->statfs(inode->i_sb, buffer, bufsiz);
211 return 0;
212 }
213
214
215
216
217
218
219 struct ufs_args {
220 char * devname;
221 int flags;
222 uid_t exroot;
223 };
224
225 struct cdfs_args {
226 char * devname;
227 int flags;
228 uid_t exroot;
229
230
231
232
233 };
234
235 struct procfs_args {
236 char * devname;
237 int flags;
238 uid_t exroot;
239 };
240
241 static int getdev(const char * name, int rdonly, struct inode ** ino)
242 {
243 kdev_t dev;
244 struct inode * inode;
245 struct file_operations * fops;
246 int retval;
247
248 retval = namei(name, &inode);
249 if (retval)
250 return retval;
251 if (!S_ISBLK(inode->i_mode)) {
252 iput(inode);
253 return -ENOTBLK;
254 }
255 if (IS_NODEV(inode)) {
256 iput(inode);
257 return -EACCES;
258 }
259 dev = inode->i_rdev;
260 if (MAJOR(dev) >= MAX_BLKDEV) {
261 iput(inode);
262 return -ENXIO;
263 }
264 fops = get_blkfops(MAJOR(dev));
265 if (!fops) {
266 iput(inode);
267 return -ENODEV;
268 }
269 if (fops->open) {
270 struct file dummy;
271 memset(&dummy, 0, sizeof(dummy));
272 dummy.f_inode = inode;
273 dummy.f_mode = rdonly ? 1 : 3;
274 retval = fops->open(inode, &dummy);
275 if (retval) {
276 iput(inode);
277 return retval;
278 }
279 }
280 *ino = inode;
281 return 0;
282 }
283
284 static void putdev(struct inode * inode)
285 {
286 struct file_operations * fops;
287
288 fops = get_blkfops(MAJOR(inode->i_rdev));
289 if (fops->release)
290 fops->release(inode, NULL);
291 }
292
293
294
295
296
297
298 static int osf_ufs_mount(char * dirname, struct ufs_args * args, int flags)
299 {
300 int retval;
301 struct inode * inode;
302 struct cdfs_args tmp;
303
304 retval = verify_area(VERIFY_READ, args, sizeof(*args));
305 if (retval)
306 return retval;
307 memcpy_fromfs(&tmp, args, sizeof(tmp));
308 retval = getdev(tmp.devname, 0, &inode);
309 if (retval)
310 return retval;
311 retval = do_mount(inode->i_rdev, dirname, "ext2", flags, NULL);
312 if (retval)
313 putdev(inode);
314 iput(inode);
315 return retval;
316 }
317
318 static int osf_cdfs_mount(char * dirname, struct cdfs_args * args, int flags)
319 {
320 int retval;
321 struct inode * inode;
322 struct cdfs_args tmp;
323
324 retval = verify_area(VERIFY_READ, args, sizeof(*args));
325 if (retval)
326 return retval;
327 memcpy_fromfs(&tmp, args, sizeof(tmp));
328 retval = getdev(tmp.devname, 1, &inode);
329 if (retval)
330 return retval;
331 retval = do_mount(inode->i_rdev, dirname, "iso9660", flags, NULL);
332 if (retval)
333 putdev(inode);
334 iput(inode);
335 return retval;
336 }
337
338 static int osf_procfs_mount(char * dirname, struct procfs_args * args, int flags)
339 {
340 kdev_t dev;
341 int retval;
342 struct procfs_args tmp;
343
344 retval = verify_area(VERIFY_READ, args, sizeof(*args));
345 if (retval)
346 return retval;
347 memcpy_fromfs(&tmp, args, sizeof(tmp));
348 dev = get_unnamed_dev();
349 if (!dev)
350 return -ENODEV;
351 retval = do_mount(dev, dirname, "proc", flags, NULL);
352 if (retval)
353 put_unnamed_dev(dev);
354 return retval;
355 }
356
357 asmlinkage int osf_mount(unsigned long typenr, char * path, int flag, void * data)
358 {
359 int retval;
360
361 retval = -EINVAL;
362 switch (typenr) {
363 case 1:
364 retval = osf_ufs_mount(path, (struct ufs_args *) data, flag);
365 break;
366 case 6:
367 retval = osf_cdfs_mount(path, (struct cdfs_args *) data, flag);
368 break;
369 case 9:
370 retval = osf_procfs_mount(path, (struct procfs_args *) data, flag);
371 break;
372 default:
373 printk("osf_mount(%ld, %x)\n", typenr, flag);
374 }
375 return retval;
376 }
377
378 asmlinkage int osf_umount(char * path, int flag)
379 {
380 return sys_umount(path);
381 }
382
383
384
385
386
387
388 asmlinkage int osf_usleep_thread(struct timeval * sleep, struct timeval * remain)
389 {
390 struct timeval tmp;
391 unsigned long ticks;
392 int retval;
393
394 retval = verify_area(VERIFY_READ, sleep, sizeof(*sleep));
395 if (retval)
396 return retval;
397 if (remain && (retval = verify_area(VERIFY_WRITE, remain, sizeof(*remain))))
398 return retval;
399 memcpy_fromfs(&tmp, sleep, sizeof(*sleep));
400 ticks = tmp.tv_usec;
401 ticks = (ticks + (1000000 / HZ) - 1) / (1000000 / HZ);
402 ticks += tmp.tv_sec * HZ;
403 current->timeout = ticks + jiffies;
404 current->state = TASK_INTERRUPTIBLE;
405 schedule();
406 if (!remain)
407 return 0;
408 ticks = jiffies;
409 if (ticks < current->timeout)
410 ticks = current->timeout - ticks;
411 else
412 ticks = 0;
413 current->timeout = 0;
414 tmp.tv_sec = ticks / HZ;
415 tmp.tv_usec = ticks % HZ;
416 memcpy_tofs(remain, &tmp, sizeof(*remain));
417 return 0;
418 }
419
420 asmlinkage int osf_utsname(char * name)
421 {
422 int error = verify_area(VERIFY_WRITE, name, 5*32);
423 if (error)
424 return error;
425 memcpy_tofs(name + 0, system_utsname.sysname, 32);
426 memcpy_tofs(name + 32, system_utsname.nodename, 32);
427 memcpy_tofs(name + 64, system_utsname.release, 32);
428 memcpy_tofs(name + 96, system_utsname.version, 32);
429 memcpy_tofs(name + 128, system_utsname.machine, 32);
430 return 0;
431 }
432
433 asmlinkage int osf_swapon(const char * path, int flags, int lowat, int hiwat)
434 {
435
436 return sys_swapon(path, flags);
437 }
438
439 asmlinkage unsigned long sys_getpagesize(void)
440 {
441 return PAGE_SIZE;
442 }
443
444 asmlinkage unsigned long sys_getdtablesize(void)
445 {
446 return NR_OPEN;
447 }
448
449 asmlinkage int sys_pipe(int a0, int a1, int a2, int a3, int a4, int a5,
450 struct pt_regs regs)
451 {
452 int fd[2];
453 int error;
454
455 error = do_pipe(fd);
456 if (error)
457 return error;
458 (®s)->r20 = fd[1];
459 return fd[0];
460 }
461
462
463
464
465 asmlinkage int osf_getdomainname(char *name, int namelen)
466 {
467 unsigned len;
468 int i, error;
469
470 error = verify_area(VERIFY_WRITE, name, namelen);
471 if (error)
472 return error;
473
474 len = namelen;
475 if (namelen > 32)
476 len = 32;
477
478 for (i = 0; i < len; ++i) {
479 put_user(system_utsname.domainname[i], name + i);
480 if (system_utsname.domainname[i] == '\0')
481 break;
482 }
483 return 0;
484 }
485
486
487 asmlinkage long osf_shmat(int shmid, void *shmaddr, int shmflg)
488 {
489 unsigned long raddr;
490 int err;
491
492 err = sys_shmat(shmid, shmaddr, shmflg, &raddr);
493 if (err)
494 return err;
495
496
497
498
499 return raddr;
500 }
501
502
503
504
505
506
507
508
509
510
511
512
513 #define PLE_PROPAGATE_ON_COPY 0x1
514
515 #define PLE_FLAG_MASK 0x1
516 #define PLE_FLAG_ALL -1
517
518 struct proplistname_args {
519 unsigned int pl_mask;
520 unsigned int pl_numnames;
521 char **pl_names;
522 };
523
524 union pl_args {
525 struct setargs {
526 char *path;
527 long follow;
528 long nbytes;
529 char *buf;
530 } set;
531 struct fsetargs {
532 long fd;
533 long nbytes;
534 char *buf;
535 } fset;
536 struct getargs {
537 char *path;
538 long follow;
539 struct proplistname_args *name_args;
540 long nbytes;
541 char *buf;
542 int *min_buf_size;
543 } get;
544 struct fgetargs {
545 long fd;
546 struct proplistname_args *name_args;
547 long nbytes;
548 char *buf;
549 int *min_buf_size;
550 } fget;
551 struct delargs {
552 char *path;
553 long follow;
554 struct proplistname_args *name_args;
555 } del;
556 struct fdelargs {
557 long fd;
558 struct proplistname_args *name_args;
559 } fdel;
560 };
561
562 enum pl_code {
563 PL_SET = 1, PL_FSET = 2,
564 PL_GET = 3, PL_FGET = 4,
565 PL_DEL = 5, PL_FDEL = 6
566 };
567
568 asmlinkage long osf_proplist_syscall (enum pl_code code, union pl_args *args)
569 {
570 long error;
571 int *min_buf_size_ptr;
572
573 switch (code) {
574 case PL_SET:
575 error = verify_area(VERIFY_READ, &args->set.nbytes,
576 sizeof(args->set.nbytes));
577 if (error)
578 return error;
579 return args->set.nbytes;
580
581 case PL_FSET:
582 error = verify_area(VERIFY_READ, &args->fset.nbytes,
583 sizeof(args->fset.nbytes));
584 if (error)
585 return error;
586 return args->fset.nbytes;
587
588 case PL_GET:
589 error = verify_area(VERIFY_READ, &args->get.min_buf_size,
590 sizeof(args->get.min_buf_size));
591 if (error)
592 return error;
593 min_buf_size_ptr = get_user(&args->get.min_buf_size);
594 error = verify_area(VERIFY_WRITE, min_buf_size_ptr,
595 sizeof(*min_buf_size_ptr));
596 if (error)
597 return error;
598 put_user(0, min_buf_size_ptr);
599 return 0;
600
601 case PL_FGET:
602 error = verify_area(VERIFY_READ, &args->fget.min_buf_size,
603 sizeof(args->fget.min_buf_size));
604 if (error)
605 return error;
606 min_buf_size_ptr = get_user(&args->fget.min_buf_size);
607 error = verify_area(VERIFY_WRITE, min_buf_size_ptr,
608 sizeof(*min_buf_size_ptr));
609 if (error)
610 return error;
611 put_user(0, min_buf_size_ptr);
612 return 0;
613
614 case PL_DEL:
615 case PL_FDEL:
616 return 0;
617
618 default:
619 return -EOPNOTSUPP;
620 }
621 }