OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [fs/] [fcntl.c] - Blame information for rev 19

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 *  linux/fs/fcntl.c
3
 *
4
 *  Copyright (C) 1991, 1992  Linus Torvalds
5
 */
6
 
7
#include <linux/syscalls.h>
8
#include <linux/init.h>
9
#include <linux/mm.h>
10
#include <linux/fs.h>
11
#include <linux/file.h>
12
#include <linux/capability.h>
13
#include <linux/dnotify.h>
14
#include <linux/smp_lock.h>
15
#include <linux/slab.h>
16
#include <linux/module.h>
17
#include <linux/security.h>
18
#include <linux/ptrace.h>
19
#include <linux/signal.h>
20
#include <linux/rcupdate.h>
21
#include <linux/pid_namespace.h>
22
 
23
#include <asm/poll.h>
24
#include <asm/siginfo.h>
25
#include <asm/uaccess.h>
26
 
27
void fastcall set_close_on_exec(unsigned int fd, int flag)
28
{
29
        struct files_struct *files = current->files;
30
        struct fdtable *fdt;
31
        spin_lock(&files->file_lock);
32
        fdt = files_fdtable(files);
33
        if (flag)
34
                FD_SET(fd, fdt->close_on_exec);
35
        else
36
                FD_CLR(fd, fdt->close_on_exec);
37
        spin_unlock(&files->file_lock);
38
}
39
 
40
static int get_close_on_exec(unsigned int fd)
41
{
42
        struct files_struct *files = current->files;
43
        struct fdtable *fdt;
44
        int res;
45
        rcu_read_lock();
46
        fdt = files_fdtable(files);
47
        res = FD_ISSET(fd, fdt->close_on_exec);
48
        rcu_read_unlock();
49
        return res;
50
}
51
 
52
/*
53
 * locate_fd finds a free file descriptor in the open_fds fdset,
54
 * expanding the fd arrays if necessary.  Must be called with the
55
 * file_lock held for write.
56
 */
57
 
58
static int locate_fd(struct files_struct *files,
59
                            struct file *file, unsigned int orig_start)
60
{
61
        unsigned int newfd;
62
        unsigned int start;
63
        int error;
64
        struct fdtable *fdt;
65
 
66
        error = -EINVAL;
67
        if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
68
                goto out;
69
 
70
repeat:
71
        fdt = files_fdtable(files);
72
        /*
73
         * Someone might have closed fd's in the range
74
         * orig_start..fdt->next_fd
75
         */
76
        start = orig_start;
77
        if (start < files->next_fd)
78
                start = files->next_fd;
79
 
80
        newfd = start;
81
        if (start < fdt->max_fds)
82
                newfd = find_next_zero_bit(fdt->open_fds->fds_bits,
83
                                           fdt->max_fds, start);
84
 
85
        error = -EMFILE;
86
        if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
87
                goto out;
88
 
89
        error = expand_files(files, newfd);
90
        if (error < 0)
91
                goto out;
92
 
93
        /*
94
         * If we needed to expand the fs array we
95
         * might have blocked - try again.
96
         */
97
        if (error)
98
                goto repeat;
99
 
100
        /*
101
         * We reacquired files_lock, so we are safe as long as
102
         * we reacquire the fdtable pointer and use it while holding
103
         * the lock, no one can free it during that time.
104
         */
105
        if (start <= files->next_fd)
106
                files->next_fd = newfd + 1;
107
 
108
        error = newfd;
109
 
110
out:
111
        return error;
112
}
113
 
114
static int dupfd(struct file *file, unsigned int start, int cloexec)
115
{
116
        struct files_struct * files = current->files;
117
        struct fdtable *fdt;
118
        int fd;
119
 
120
        spin_lock(&files->file_lock);
121
        fd = locate_fd(files, file, start);
122
        if (fd >= 0) {
123
                /* locate_fd() may have expanded fdtable, load the ptr */
124
                fdt = files_fdtable(files);
125
                FD_SET(fd, fdt->open_fds);
126
                if (cloexec)
127
                        FD_SET(fd, fdt->close_on_exec);
128
                else
129
                        FD_CLR(fd, fdt->close_on_exec);
130
                spin_unlock(&files->file_lock);
131
                fd_install(fd, file);
132
        } else {
133
                spin_unlock(&files->file_lock);
134
                fput(file);
135
        }
136
 
137
        return fd;
138
}
139
 
140
asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
141
{
142
        int err = -EBADF;
143
        struct file * file, *tofree;
144
        struct files_struct * files = current->files;
145
        struct fdtable *fdt;
146
 
147
        spin_lock(&files->file_lock);
148
        if (!(file = fcheck(oldfd)))
149
                goto out_unlock;
150
        err = newfd;
151
        if (newfd == oldfd)
152
                goto out_unlock;
153
        err = -EBADF;
154
        if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
155
                goto out_unlock;
156
        get_file(file);                 /* We are now finished with oldfd */
157
 
158
        err = expand_files(files, newfd);
159
        if (err < 0)
160
                goto out_fput;
161
 
162
        /* To avoid races with open() and dup(), we will mark the fd as
163
         * in-use in the open-file bitmap throughout the entire dup2()
164
         * process.  This is quite safe: do_close() uses the fd array
165
         * entry, not the bitmap, to decide what work needs to be
166
         * done.  --sct */
167
        /* Doesn't work. open() might be there first. --AV */
168
 
169
        /* Yes. It's a race. In user space. Nothing sane to do */
170
        err = -EBUSY;
171
        fdt = files_fdtable(files);
172
        tofree = fdt->fd[newfd];
173
        if (!tofree && FD_ISSET(newfd, fdt->open_fds))
174
                goto out_fput;
175
 
176
        rcu_assign_pointer(fdt->fd[newfd], file);
177
        FD_SET(newfd, fdt->open_fds);
178
        FD_CLR(newfd, fdt->close_on_exec);
179
        spin_unlock(&files->file_lock);
180
 
181
        if (tofree)
182
                filp_close(tofree, files);
183
        err = newfd;
184
out:
185
        return err;
186
out_unlock:
187
        spin_unlock(&files->file_lock);
188
        goto out;
189
 
190
out_fput:
191
        spin_unlock(&files->file_lock);
192
        fput(file);
193
        goto out;
194
}
195
 
196
asmlinkage long sys_dup(unsigned int fildes)
197
{
198
        int ret = -EBADF;
199
        struct file * file = fget(fildes);
200
 
201
        if (file)
202
                ret = dupfd(file, 0, 0);
203
        return ret;
204
}
205
 
206
#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC | O_DIRECT | O_NOATIME)
207
 
208
static int setfl(int fd, struct file * filp, unsigned long arg)
209
{
210
        struct inode * inode = filp->f_path.dentry->d_inode;
211
        int error = 0;
212
 
213
        /*
214
         * O_APPEND cannot be cleared if the file is marked as append-only
215
         * and the file is open for write.
216
         */
217
        if (((arg ^ filp->f_flags) & O_APPEND) && IS_APPEND(inode))
218
                return -EPERM;
219
 
220
        /* O_NOATIME can only be set by the owner or superuser */
221
        if ((arg & O_NOATIME) && !(filp->f_flags & O_NOATIME))
222
                if (!is_owner_or_cap(inode))
223
                        return -EPERM;
224
 
225
        /* required for strict SunOS emulation */
226
        if (O_NONBLOCK != O_NDELAY)
227
               if (arg & O_NDELAY)
228
                   arg |= O_NONBLOCK;
229
 
230
        if (arg & O_DIRECT) {
231
                if (!filp->f_mapping || !filp->f_mapping->a_ops ||
232
                        !filp->f_mapping->a_ops->direct_IO)
233
                                return -EINVAL;
234
        }
235
 
236
        if (filp->f_op && filp->f_op->check_flags)
237
                error = filp->f_op->check_flags(arg);
238
        if (error)
239
                return error;
240
 
241
        lock_kernel();
242
        if ((arg ^ filp->f_flags) & FASYNC) {
243
                if (filp->f_op && filp->f_op->fasync) {
244
                        error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0);
245
                        if (error < 0)
246
                                goto out;
247
                }
248
        }
249
 
250
        filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK);
251
 out:
252
        unlock_kernel();
253
        return error;
254
}
255
 
256
static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
257
                     uid_t uid, uid_t euid, int force)
258
{
259
        write_lock_irq(&filp->f_owner.lock);
260
        if (force || !filp->f_owner.pid) {
261
                put_pid(filp->f_owner.pid);
262
                filp->f_owner.pid = get_pid(pid);
263
                filp->f_owner.pid_type = type;
264
                filp->f_owner.uid = uid;
265
                filp->f_owner.euid = euid;
266
        }
267
        write_unlock_irq(&filp->f_owner.lock);
268
}
269
 
270
int __f_setown(struct file *filp, struct pid *pid, enum pid_type type,
271
                int force)
272
{
273
        int err;
274
 
275
        err = security_file_set_fowner(filp);
276
        if (err)
277
                return err;
278
 
279
        f_modown(filp, pid, type, current->uid, current->euid, force);
280
        return 0;
281
}
282
EXPORT_SYMBOL(__f_setown);
283
 
284
int f_setown(struct file *filp, unsigned long arg, int force)
285
{
286
        enum pid_type type;
287
        struct pid *pid;
288
        int who = arg;
289
        int result;
290
        type = PIDTYPE_PID;
291
        if (who < 0) {
292
                type = PIDTYPE_PGID;
293
                who = -who;
294
        }
295
        rcu_read_lock();
296
        pid = find_vpid(who);
297
        result = __f_setown(filp, pid, type, force);
298
        rcu_read_unlock();
299
        return result;
300
}
301
EXPORT_SYMBOL(f_setown);
302
 
303
void f_delown(struct file *filp)
304
{
305
        f_modown(filp, NULL, PIDTYPE_PID, 0, 0, 1);
306
}
307
 
308
pid_t f_getown(struct file *filp)
309
{
310
        pid_t pid;
311
        read_lock(&filp->f_owner.lock);
312
        pid = pid_nr_ns(filp->f_owner.pid, current->nsproxy->pid_ns);
313
        if (filp->f_owner.pid_type == PIDTYPE_PGID)
314
                pid = -pid;
315
        read_unlock(&filp->f_owner.lock);
316
        return pid;
317
}
318
 
319
static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
320
                struct file *filp)
321
{
322
        long err = -EINVAL;
323
 
324
        switch (cmd) {
325
        case F_DUPFD:
326
        case F_DUPFD_CLOEXEC:
327
                get_file(filp);
328
                err = dupfd(filp, arg, cmd == F_DUPFD_CLOEXEC);
329
                break;
330
        case F_GETFD:
331
                err = get_close_on_exec(fd) ? FD_CLOEXEC : 0;
332
                break;
333
        case F_SETFD:
334
                err = 0;
335
                set_close_on_exec(fd, arg & FD_CLOEXEC);
336
                break;
337
        case F_GETFL:
338
                err = filp->f_flags;
339
                break;
340
        case F_SETFL:
341
                err = setfl(fd, filp, arg);
342
                break;
343
        case F_GETLK:
344
                err = fcntl_getlk(filp, (struct flock __user *) arg);
345
                break;
346
        case F_SETLK:
347
        case F_SETLKW:
348
                err = fcntl_setlk(fd, filp, cmd, (struct flock __user *) arg);
349
                break;
350
        case F_GETOWN:
351
                /*
352
                 * XXX If f_owner is a process group, the
353
                 * negative return value will get converted
354
                 * into an error.  Oops.  If we keep the
355
                 * current syscall conventions, the only way
356
                 * to fix this will be in libc.
357
                 */
358
                err = f_getown(filp);
359
                force_successful_syscall_return();
360
                break;
361
        case F_SETOWN:
362
                err = f_setown(filp, arg, 1);
363
                break;
364
        case F_GETSIG:
365
                err = filp->f_owner.signum;
366
                break;
367
        case F_SETSIG:
368
                /* arg == 0 restores default behaviour. */
369
                if (!valid_signal(arg)) {
370
                        break;
371
                }
372
                err = 0;
373
                filp->f_owner.signum = arg;
374
                break;
375
        case F_GETLEASE:
376
                err = fcntl_getlease(filp);
377
                break;
378
        case F_SETLEASE:
379
                err = fcntl_setlease(fd, filp, arg);
380
                break;
381
        case F_NOTIFY:
382
                err = fcntl_dirnotify(fd, filp, arg);
383
                break;
384
        default:
385
                break;
386
        }
387
        return err;
388
}
389
 
390
asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
391
{
392
        struct file *filp;
393
        long err = -EBADF;
394
 
395
        filp = fget(fd);
396
        if (!filp)
397
                goto out;
398
 
399
        err = security_file_fcntl(filp, cmd, arg);
400
        if (err) {
401
                fput(filp);
402
                return err;
403
        }
404
 
405
        err = do_fcntl(fd, cmd, arg, filp);
406
 
407
        fput(filp);
408
out:
409
        return err;
410
}
411
 
412
#if BITS_PER_LONG == 32
413
asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
414
{
415
        struct file * filp;
416
        long err;
417
 
418
        err = -EBADF;
419
        filp = fget(fd);
420
        if (!filp)
421
                goto out;
422
 
423
        err = security_file_fcntl(filp, cmd, arg);
424
        if (err) {
425
                fput(filp);
426
                return err;
427
        }
428
        err = -EBADF;
429
 
430
        switch (cmd) {
431
                case F_GETLK64:
432
                        err = fcntl_getlk64(filp, (struct flock64 __user *) arg);
433
                        break;
434
                case F_SETLK64:
435
                case F_SETLKW64:
436
                        err = fcntl_setlk64(fd, filp, cmd,
437
                                        (struct flock64 __user *) arg);
438
                        break;
439
                default:
440
                        err = do_fcntl(fd, cmd, arg, filp);
441
                        break;
442
        }
443
        fput(filp);
444
out:
445
        return err;
446
}
447
#endif
448
 
449
/* Table to convert sigio signal codes into poll band bitmaps */
450
 
451
static const long band_table[NSIGPOLL] = {
452
        POLLIN | POLLRDNORM,                    /* POLL_IN */
453
        POLLOUT | POLLWRNORM | POLLWRBAND,      /* POLL_OUT */
454
        POLLIN | POLLRDNORM | POLLMSG,          /* POLL_MSG */
455
        POLLERR,                                /* POLL_ERR */
456
        POLLPRI | POLLRDBAND,                   /* POLL_PRI */
457
        POLLHUP | POLLERR                       /* POLL_HUP */
458
};
459
 
460
static inline int sigio_perm(struct task_struct *p,
461
                             struct fown_struct *fown, int sig)
462
{
463
        return (((fown->euid == 0) ||
464
                 (fown->euid == p->suid) || (fown->euid == p->uid) ||
465
                 (fown->uid == p->suid) || (fown->uid == p->uid)) &&
466
                !security_file_send_sigiotask(p, fown, sig));
467
}
468
 
469
static void send_sigio_to_task(struct task_struct *p,
470
                               struct fown_struct *fown,
471
                               int fd,
472
                               int reason)
473
{
474
        if (!sigio_perm(p, fown, fown->signum))
475
                return;
476
 
477
        switch (fown->signum) {
478
                siginfo_t si;
479
                default:
480
                        /* Queue a rt signal with the appropriate fd as its
481
                           value.  We use SI_SIGIO as the source, not
482
                           SI_KERNEL, since kernel signals always get
483
                           delivered even if we can't queue.  Failure to
484
                           queue in this case _should_ be reported; we fall
485
                           back to SIGIO in that case. --sct */
486
                        si.si_signo = fown->signum;
487
                        si.si_errno = 0;
488
                        si.si_code  = reason;
489
                        /* Make sure we are called with one of the POLL_*
490
                           reasons, otherwise we could leak kernel stack into
491
                           userspace.  */
492
                        BUG_ON((reason & __SI_MASK) != __SI_POLL);
493
                        if (reason - POLL_IN >= NSIGPOLL)
494
                                si.si_band  = ~0L;
495
                        else
496
                                si.si_band = band_table[reason - POLL_IN];
497
                        si.si_fd    = fd;
498
                        if (!group_send_sig_info(fown->signum, &si, p))
499
                                break;
500
                /* fall-through: fall back on the old plain SIGIO signal */
501
                case 0:
502
                        group_send_sig_info(SIGIO, SEND_SIG_PRIV, p);
503
        }
504
}
505
 
506
void send_sigio(struct fown_struct *fown, int fd, int band)
507
{
508
        struct task_struct *p;
509
        enum pid_type type;
510
        struct pid *pid;
511
 
512
        read_lock(&fown->lock);
513
        type = fown->pid_type;
514
        pid = fown->pid;
515
        if (!pid)
516
                goto out_unlock_fown;
517
 
518
        read_lock(&tasklist_lock);
519
        do_each_pid_task(pid, type, p) {
520
                send_sigio_to_task(p, fown, fd, band);
521
        } while_each_pid_task(pid, type, p);
522
        read_unlock(&tasklist_lock);
523
 out_unlock_fown:
524
        read_unlock(&fown->lock);
525
}
526
 
527
static void send_sigurg_to_task(struct task_struct *p,
528
                                struct fown_struct *fown)
529
{
530
        if (sigio_perm(p, fown, SIGURG))
531
                group_send_sig_info(SIGURG, SEND_SIG_PRIV, p);
532
}
533
 
534
int send_sigurg(struct fown_struct *fown)
535
{
536
        struct task_struct *p;
537
        enum pid_type type;
538
        struct pid *pid;
539
        int ret = 0;
540
 
541
        read_lock(&fown->lock);
542
        type = fown->pid_type;
543
        pid = fown->pid;
544
        if (!pid)
545
                goto out_unlock_fown;
546
 
547
        ret = 1;
548
 
549
        read_lock(&tasklist_lock);
550
        do_each_pid_task(pid, type, p) {
551
                send_sigurg_to_task(p, fown);
552
        } while_each_pid_task(pid, type, p);
553
        read_unlock(&tasklist_lock);
554
 out_unlock_fown:
555
        read_unlock(&fown->lock);
556
        return ret;
557
}
558
 
559
static DEFINE_RWLOCK(fasync_lock);
560
static struct kmem_cache *fasync_cache __read_mostly;
561
 
562
/*
563
 * fasync_helper() is used by some character device drivers (mainly mice)
564
 * to set up the fasync queue. It returns negative on error, 0 if it did
565
 * no changes and positive if it added/deleted the entry.
566
 */
567
int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp)
568
{
569
        struct fasync_struct *fa, **fp;
570
        struct fasync_struct *new = NULL;
571
        int result = 0;
572
 
573
        if (on) {
574
                new = kmem_cache_alloc(fasync_cache, GFP_KERNEL);
575
                if (!new)
576
                        return -ENOMEM;
577
        }
578
        write_lock_irq(&fasync_lock);
579
        for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) {
580
                if (fa->fa_file == filp) {
581
                        if(on) {
582
                                fa->fa_fd = fd;
583
                                kmem_cache_free(fasync_cache, new);
584
                        } else {
585
                                *fp = fa->fa_next;
586
                                kmem_cache_free(fasync_cache, fa);
587
                                result = 1;
588
                        }
589
                        goto out;
590
                }
591
        }
592
 
593
        if (on) {
594
                new->magic = FASYNC_MAGIC;
595
                new->fa_file = filp;
596
                new->fa_fd = fd;
597
                new->fa_next = *fapp;
598
                *fapp = new;
599
                result = 1;
600
        }
601
out:
602
        write_unlock_irq(&fasync_lock);
603
        return result;
604
}
605
 
606
EXPORT_SYMBOL(fasync_helper);
607
 
608
void __kill_fasync(struct fasync_struct *fa, int sig, int band)
609
{
610
        while (fa) {
611
                struct fown_struct * fown;
612
                if (fa->magic != FASYNC_MAGIC) {
613
                        printk(KERN_ERR "kill_fasync: bad magic number in "
614
                               "fasync_struct!\n");
615
                        return;
616
                }
617
                fown = &fa->fa_file->f_owner;
618
                /* Don't send SIGURG to processes which have not set a
619
                   queued signum: SIGURG has its own default signalling
620
                   mechanism. */
621
                if (!(sig == SIGURG && fown->signum == 0))
622
                        send_sigio(fown, fa->fa_fd, band);
623
                fa = fa->fa_next;
624
        }
625
}
626
 
627
EXPORT_SYMBOL(__kill_fasync);
628
 
629
void kill_fasync(struct fasync_struct **fp, int sig, int band)
630
{
631
        /* First a quick test without locking: usually
632
         * the list is empty.
633
         */
634
        if (*fp) {
635
                read_lock(&fasync_lock);
636
                /* reread *fp after obtaining the lock */
637
                __kill_fasync(*fp, sig, band);
638
                read_unlock(&fasync_lock);
639
        }
640
}
641
EXPORT_SYMBOL(kill_fasync);
642
 
643
static int __init fasync_init(void)
644
{
645
        fasync_cache = kmem_cache_create("fasync_cache",
646
                sizeof(struct fasync_struct), 0, SLAB_PANIC, NULL);
647
        return 0;
648
}
649
 
650
module_init(fasync_init)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.