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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [proc/] [fd.c] - Diff between revs 1765 and 1782

Only display areas with differences | Details | Blame | View Log

Rev 1765 Rev 1782
/*
/*
 *  linux/fs/proc/fd.c
 *  linux/fs/proc/fd.c
 *
 *
 *  Copyright (C) 1991, 1992 Linus Torvalds
 *  Copyright (C) 1991, 1992 Linus Torvalds
 *
 *
 *  proc fd directory handling functions
 *  proc fd directory handling functions
 */
 */
 
 
#include <asm/segment.h>
#include <asm/segment.h>
 
 
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/stat.h>
 
 
static int proc_readfd(struct inode *, struct file *, void *, filldir_t);
static int proc_readfd(struct inode *, struct file *, void *, filldir_t);
static int proc_lookupfd(struct inode *,const char *,int,struct inode **);
static int proc_lookupfd(struct inode *,const char *,int,struct inode **);
 
 
static struct file_operations proc_fd_operations = {
static struct file_operations proc_fd_operations = {
        NULL,                   /* lseek - default */
        NULL,                   /* lseek - default */
        NULL,                   /* read - bad */
        NULL,                   /* read - bad */
        NULL,                   /* write - bad */
        NULL,                   /* write - bad */
        proc_readfd,            /* readdir */
        proc_readfd,            /* readdir */
        NULL,                   /* select - default */
        NULL,                   /* select - default */
        NULL,                   /* ioctl - default */
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
        NULL,                   /* no special open code */
        NULL,                   /* no special release code */
        NULL,                   /* no special release code */
        NULL                    /* can't fsync */
        NULL                    /* can't fsync */
};
};
 
 
/*
/*
 * proc directories can do almost nothing..
 * proc directories can do almost nothing..
 */
 */
struct inode_operations proc_fd_inode_operations = {
struct inode_operations proc_fd_inode_operations = {
        &proc_fd_operations,    /* default base directory file-ops */
        &proc_fd_operations,    /* default base directory file-ops */
        NULL,                   /* create */
        NULL,                   /* create */
        proc_lookupfd,          /* lookup */
        proc_lookupfd,          /* lookup */
        NULL,                   /* link */
        NULL,                   /* link */
        NULL,                   /* unlink */
        NULL,                   /* unlink */
        NULL,                   /* symlink */
        NULL,                   /* symlink */
        NULL,                   /* mkdir */
        NULL,                   /* mkdir */
        NULL,                   /* rmdir */
        NULL,                   /* rmdir */
        NULL,                   /* mknod */
        NULL,                   /* mknod */
        NULL,                   /* rename */
        NULL,                   /* rename */
        NULL,                   /* readlink */
        NULL,                   /* readlink */
        NULL,                   /* follow_link */
        NULL,                   /* follow_link */
        NULL,                   /* readpage */
        NULL,                   /* readpage */
        NULL,                   /* writepage */
        NULL,                   /* writepage */
        NULL,                   /* bmap */
        NULL,                   /* bmap */
        NULL,                   /* truncate */
        NULL,                   /* truncate */
        NULL                    /* permission */
        NULL                    /* permission */
};
};
 
 
static int proc_lookupfd(struct inode * dir, const char * name, int len,
static int proc_lookupfd(struct inode * dir, const char * name, int len,
        struct inode ** result)
        struct inode ** result)
{
{
        unsigned int ino, pid, fd, c;
        unsigned int ino, pid, fd, c;
        struct task_struct * p;
        struct task_struct * p;
        struct super_block * sb;
        struct super_block * sb;
        int i;
        int i;
 
 
        *result = NULL;
        *result = NULL;
        ino = dir->i_ino;
        ino = dir->i_ino;
        pid = ino >> 16;
        pid = ino >> 16;
        ino &= 0x0000ffff;
        ino &= 0x0000ffff;
        if (!dir)
        if (!dir)
                return -ENOENT;
                return -ENOENT;
        sb = dir->i_sb;
        sb = dir->i_sb;
        if (!pid || ino != PROC_PID_FD || !S_ISDIR(dir->i_mode)) {
        if (!pid || ino != PROC_PID_FD || !S_ISDIR(dir->i_mode)) {
                iput(dir);
                iput(dir);
                return -ENOENT;
                return -ENOENT;
        }
        }
        if (!len || (name[0] == '.' && (len == 1 ||
        if (!len || (name[0] == '.' && (len == 1 ||
            (name[1] == '.' && len == 2)))) {
            (name[1] == '.' && len == 2)))) {
                if (len < 2) {
                if (len < 2) {
                        *result = dir;
                        *result = dir;
                        return 0;
                        return 0;
                }
                }
                if (!(*result = proc_get_inode(sb, (pid << 16)+PROC_PID_INO, &proc_pid))) {
                if (!(*result = proc_get_inode(sb, (pid << 16)+PROC_PID_INO, &proc_pid))) {
                        iput(dir);
                        iput(dir);
                        return -ENOENT;
                        return -ENOENT;
                }
                }
                iput(dir);
                iput(dir);
                return 0;
                return 0;
        }
        }
        iput(dir);
        iput(dir);
        fd = 0;
        fd = 0;
        while (len-- > 0) {
        while (len-- > 0) {
                c = *name - '0';
                c = *name - '0';
                name++;
                name++;
                if (c > 9) {
                if (c > 9) {
                        fd = 0xfffff;
                        fd = 0xfffff;
                        break;
                        break;
                }
                }
                fd *= 10;
                fd *= 10;
                fd += c;
                fd += c;
                if (fd & 0xffff0000) {
                if (fd & 0xffff0000) {
                        fd = 0xfffff;
                        fd = 0xfffff;
                        break;
                        break;
                }
                }
        }
        }
        for (i = 0 ; i < NR_TASKS ; i++)
        for (i = 0 ; i < NR_TASKS ; i++)
                if ((p = task[i]) && p->pid == pid)
                if ((p = task[i]) && p->pid == pid)
                        break;
                        break;
        if (!pid || i >= NR_TASKS)
        if (!pid || i >= NR_TASKS)
                return -ENOENT;
                return -ENOENT;
 
 
        if (fd >= NR_OPEN || !p->files || !p->files->fd[fd]
        if (fd >= NR_OPEN || !p->files || !p->files->fd[fd]
                || !p->files->fd[fd]->f_inode)
                || !p->files->fd[fd]->f_inode)
                return -ENOENT;
                return -ENOENT;
 
 
        ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd;
        ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd;
 
 
        if (!(*result = proc_get_inode(sb, ino, NULL)))
        if (!(*result = proc_get_inode(sb, ino, NULL)))
                return -ENOENT;
                return -ENOENT;
        return 0;
        return 0;
}
}
 
 
#define NUMBUF 10
#define NUMBUF 10
 
 
static int proc_readfd(struct inode * inode, struct file * filp,
static int proc_readfd(struct inode * inode, struct file * filp,
        void * dirent, filldir_t filldir)
        void * dirent, filldir_t filldir)
{
{
        char buf[NUMBUF];
        char buf[NUMBUF];
        int task_nr;
        int task_nr;
        struct task_struct * p;
        struct task_struct * p;
        unsigned int fd, pid, ino;
        unsigned int fd, pid, ino;
        unsigned long i,j;
        unsigned long i,j;
 
 
        if (!inode || !S_ISDIR(inode->i_mode))
        if (!inode || !S_ISDIR(inode->i_mode))
                return -EBADF;
                return -EBADF;
        ino = inode->i_ino;
        ino = inode->i_ino;
        pid = ino >> 16;
        pid = ino >> 16;
        ino &= 0x0000ffff;
        ino &= 0x0000ffff;
        if (ino != PROC_PID_FD)
        if (ino != PROC_PID_FD)
                return 0;
                return 0;
 
 
        for (fd = filp->f_pos; fd < 2; fd++, filp->f_pos++) {
        for (fd = filp->f_pos; fd < 2; fd++, filp->f_pos++) {
                unsigned long ino = inode->i_ino;
                unsigned long ino = inode->i_ino;
                if (fd)
                if (fd)
                        ino = (ino & 0xffff0000) | PROC_PID_INO;
                        ino = (ino & 0xffff0000) | PROC_PID_INO;
                if (filldir(dirent, "..", fd+1, fd, ino) < 0)
                if (filldir(dirent, "..", fd+1, fd, ino) < 0)
                        return 0;
                        return 0;
        }
        }
 
 
        task_nr = 1;
        task_nr = 1;
        for (;;) {
        for (;;) {
                if ((p = task[task_nr]) && p->pid == pid)
                if ((p = task[task_nr]) && p->pid == pid)
                        break;
                        break;
                if (++task_nr >= NR_TASKS)
                if (++task_nr >= NR_TASKS)
                        return 0;
                        return 0;
        }
        }
 
 
        for (fd -= 2 ; fd < NR_OPEN; fd++, filp->f_pos++) {
        for (fd -= 2 ; fd < NR_OPEN; fd++, filp->f_pos++) {
                if (!p->files)
                if (!p->files)
                        break;
                        break;
                if (!p->files->fd[fd] || !p->files->fd[fd]->f_inode)
                if (!p->files->fd[fd] || !p->files->fd[fd]->f_inode)
                        continue;
                        continue;
 
 
                j = NUMBUF;
                j = NUMBUF;
                i = fd;
                i = fd;
                do {
                do {
                        j--;
                        j--;
                        buf[j] = '0' + (i % 10);
                        buf[j] = '0' + (i % 10);
                        i /= 10;
                        i /= 10;
                } while (i);
                } while (i);
 
 
                ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd;
                ino = (pid << 16) + (PROC_PID_FD_DIR << 8) + fd;
                if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino) < 0)
                if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino) < 0)
                        break;
                        break;
 
 
                /* filldir() might have slept, so we must re-validate "p" */
                /* filldir() might have slept, so we must re-validate "p" */
                if (p != task[task_nr] || p->pid != pid)
                if (p != task[task_nr] || p->pid != pid)
                        break;
                        break;
        }
        }
        return 0;
        return 0;
}
}
 
 

powered by: WebSVN 2.1.0

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