home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / fs / minix / symlink.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-01  |  1.9 KB  |  103 lines

  1. /*
  2.  *  linux/fs/minix/symlink.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  *
  6.  *  minix symlink handling code
  7.  */
  8.  
  9. #include <asm/segment.h>
  10.  
  11. #include <linux/errno.h>
  12. #include <linux/sched.h>
  13. #include <linux/fs.h>
  14. #include <linux/minix_fs.h>
  15. #include <linux/stat.h>
  16.  
  17. static int minix_readlink(struct inode *, char *, int);
  18. static int minix_follow_link(struct inode *, struct inode *, int, int, struct inode **);
  19.  
  20. /*
  21.  * symlinks can't do much...
  22.  */
  23. struct inode_operations minix_symlink_inode_operations = {
  24.     NULL,            /* no file-operations */
  25.     NULL,            /* create */
  26.     NULL,            /* lookup */
  27.     NULL,            /* link */
  28.     NULL,            /* unlink */
  29.     NULL,            /* symlink */
  30.     NULL,            /* mkdir */
  31.     NULL,            /* rmdir */
  32.     NULL,            /* mknod */
  33.     NULL,            /* rename */
  34.     minix_readlink,        /* readlink */
  35.     minix_follow_link,    /* follow_link */
  36.     NULL,            /* bmap */
  37.     NULL,            /* truncate */
  38.     NULL            /* permission */
  39. };
  40.  
  41. static int minix_follow_link(struct inode * dir, struct inode * inode,
  42.     int flag, int mode, struct inode ** res_inode)
  43. {
  44.     int error;
  45.     struct buffer_head * bh;
  46.  
  47.     *res_inode = NULL;
  48.     if (!dir) {
  49.         dir = current->root;
  50.         dir->i_count++;
  51.     }
  52.     if (!inode) {
  53.         iput(dir);
  54.         return -ENOENT;
  55.     }
  56.     if (!S_ISLNK(inode->i_mode)) {
  57.         iput(dir);
  58.         *res_inode = inode;
  59.         return 0;
  60.     }
  61.     if (current->link_count > 5) {
  62.         iput(inode);
  63.         iput(dir);
  64.         return -ELOOP;
  65.     }
  66.     if (!(bh = minix_bread(inode, 0, 0))) {
  67.         iput(inode);
  68.         iput(dir);
  69.         return -EIO;
  70.     }
  71.     iput(inode);
  72.     current->link_count++;
  73.     error = open_namei(bh->b_data,flag,mode,res_inode,dir);
  74.     current->link_count--;
  75.     brelse(bh);
  76.     return error;
  77. }
  78.  
  79. static int minix_readlink(struct inode * inode, char * buffer, int buflen)
  80. {
  81.     struct buffer_head * bh;
  82.     int i;
  83.     char c;
  84.  
  85.     if (!S_ISLNK(inode->i_mode)) {
  86.         iput(inode);
  87.         return -EINVAL;
  88.     }
  89.     if (buflen > 1023)
  90.         buflen = 1023;
  91.     bh = minix_bread(inode, 0, 0);
  92.     iput(inode);
  93.     if (!bh)
  94.         return 0;
  95.     i = 0;
  96.     while (i<buflen && (c = bh->b_data[i])) {
  97.         i++;
  98.         put_fs_byte(c,buffer++);
  99.     }
  100.     brelse(bh);
  101.     return i;
  102. }
  103.