/* * linux/kernel/sys.c * * (C) 1991 Linus Torvalds */ #include #include #include #include #include #include #include #include #include #include #include //ADD FOR getcwd struct linux_dirent { long d_ino; off_t d_off; unsigned short d_reclen; char d_name[]; }; long sys_getcwd(char *buf,size_t size) { int block=current->pwd->i_zone[0]; int idev=current->pwd->i_dev; int flag=0; struct buffer_head * bh; struct dir_entry * de; struct m_inode *dir=current->pwd,*rdir=current->root; if(dir==rdir) { flag=1; goto mytag; } unsigned short curinode,finode,tempfi; char name[128],base[128]; int entries,i; if (!(block = current->pwd->i_zone[0])) return NULL; if (!(bh = bread(current->pwd->i_dev,block))) return NULL; de = (struct dir_entry *) bh->b_data; curinode=de->inode; de++; finode=de->inode; while (rdir!=dir) { //update father dir=iget(idev,finode); if (!(block = dir->i_zone[0])) return NULL; if (!(bh = bread(dir->i_dev,block))) return NULL; i = 0; entries = dir->i_size / (sizeof (struct dir_entry)); de = (struct dir_entry *) bh->b_data; tempfi=(de+1)->inode; while (i < entries) { if ((char *)de >= BLOCK_SIZE+bh->b_data) { brelse(bh); bh = NULL; if (!(block = bmap(dir,i/DIR_ENTRIES_PER_BLOCK)) || !(bh = bread(dir->i_dev,block))) { i += DIR_ENTRIES_PER_BLOCK; continue; } de = (struct dir_entry *) bh->b_data; } if(de->inode==curinode) { memset(base,'\0',sizeof(base)); strcat(base,"/"); strcat(base,de->name); strcat(base,name); strcpy(name,base); break; } de++; i++; } curinode=finode; finode=tempfi; } mytag: if(flag) strcpy(name,"/"); size_t len=strlen(name); if(sizefilp[fd]->f_inode; int block,i,entries,sizdir=sizeof(struct dir_entry); struct buffer_head * bh; struct dir_entry * de; struct linux_dirent *initmp,*temp; if(!(temp=(struct linux_dirent *)malloc(count+64))) return -1; initmp=temp; int size=sizeof(long)+sizeof(off_t)+sizeof(unsigned short); if (!(block = filenode->i_zone[0])) return -1; if (!(bh = bread(filenode->i_dev,block))) return -1; de = (struct dir_entry *) bh->b_data; entries=filenode->i_size/(sizeof(struct dir_entry)); i=0; int nread=0,pos=0; while(i= BLOCK_SIZE+bh->b_data) { brelse(bh); bh = NULL; if (!(block = bmap(filenode,i/DIR_ENTRIES_PER_BLOCK)) || !(bh = bread(filenode->i_dev,block))) { i += DIR_ENTRIES_PER_BLOCK; continue; } pos+=((char*) bh->b_data-(char*)(de)); de = (struct dir_entry *) bh->b_data; } temp->d_ino=de->inode; temp->d_off=pos; strcpy(temp->d_name,de->name); temp->d_reclen=size+strlen(de->name)+1; nread+=temp->d_reclen; temp=(struct linux_dirent*)((char*)temp+temp->d_reclen); de++; pos+=sizdir; i++; } if(countsigaction[SIGALRM-1] = tmp; current->alarm=(seconds>0)?(jiffies+HZ*seconds):0; current->state=TASK_INTERRUPTIBLE; current->counter=(current->counter>>1)+current->priority; schedule(); return 0; } int sys_mmap() { return -1; } int sys_munmap() { return -1; } int sys_clone() { return -1; } int sys_ftime() { return -ENOSYS; } int sys_break() { return -ENOSYS; } int sys_ptrace() { return -ENOSYS; } int sys_stty() { return -ENOSYS; } int sys_gtty() { return -ENOSYS; } int sys_rename() { return -ENOSYS; } int sys_prof() { return -ENOSYS; } int sys_setregid(int rgid, int egid) { if (rgid>0) { if ((current->gid == rgid) || suser()) current->gid = rgid; else return(-EPERM); } if (egid>0) { if ((current->gid == egid) || (current->egid == egid) || suser()) { current->egid = egid; current->sgid = egid; } else return(-EPERM); } return 0; } int sys_setgid(int gid) { /* return(sys_setregid(gid, gid)); */ if (suser()) current->gid = current->egid = current->sgid = gid; else if ((gid == current->gid) || (gid == current->sgid)) current->egid = gid; else return -EPERM; return 0; } int sys_acct() { return -ENOSYS; } int sys_phys() { return -ENOSYS; } int sys_lock() { return -ENOSYS; } int sys_mpx() { return -ENOSYS; } int sys_ulimit() { return -ENOSYS; } int sys_time(long * tloc) { int i; i = CURRENT_TIME; if (tloc) { verify_area(tloc,4); put_fs_long(i,(unsigned long *)tloc); } return i; } /* * Unprivileged users may change the real user id to the effective uid * or vice versa. */ int sys_setreuid(int ruid, int euid) { int old_ruid = current->uid; if (ruid>0) { if ((current->euid==ruid) || (old_ruid == ruid) || suser()) current->uid = ruid; else return(-EPERM); } if (euid>0) { if ((old_ruid == euid) || (current->euid == euid) || suser()) { current->euid = euid; current->suid = euid; } else { current->uid = old_ruid; return(-EPERM); } } return 0; } int sys_setuid(int uid) { /* return(sys_setreuid(uid, uid)); */ if (suser()) current->uid = current->euid = current->suid = uid; else if ((uid == current->uid) || (uid == current->suid)) current->euid = uid; else return -EPERM; return(0); } int sys_stime(long * tptr) { if (!suser()) return -EPERM; startup_time = get_fs_long((unsigned long *)tptr) - jiffies/HZ; return 0; } int sys_times(struct tms * tbuf) { if (tbuf) { verify_area(tbuf,sizeof *tbuf); put_fs_long(current->utime,(unsigned long *)&tbuf->tms_utime); put_fs_long(current->stime,(unsigned long *)&tbuf->tms_stime); put_fs_long(current->cutime,(unsigned long *)&tbuf->tms_cutime); put_fs_long(current->cstime,(unsigned long *)&tbuf->tms_cstime); } return jiffies; } int sys_brk(unsigned long end_data_seg) { if (end_data_seg >= current->end_code && end_data_seg < current->start_stack - 16384) current->brk = end_data_seg; return current->brk; } /* * This needs some heave checking ... * I just haven't get the stomach for it. I also don't fully * understand sessions/pgrp etc. Let somebody who does explain it. */ int sys_setpgid(int pid, int pgid) { int i; if (!pid) pid = current->pid; if (!pgid) pgid = current->pid; for (i=0 ; ipid==pid) { if (task[i]->leader) return -EPERM; if (task[i]->session != current->session) return -EPERM; task[i]->pgrp = pgid; return 0; } return -ESRCH; } int sys_getpgrp(void) { return current->pgrp; } int sys_setsid(void) { if (current->leader && !suser()) return -EPERM; current->leader = 1; current->session = current->pgrp = current->pid; current->tty = -1; return current->pgrp; } int sys_getgroups() { return -ENOSYS; } int sys_setgroups() { return -ENOSYS; } int sys_uname(struct utsname * name) { static struct utsname thisname = { "linux .0","nodename","release ","version ","machine " }; int i; if (!name) return -ERROR; verify_area(name,sizeof *name); for(i=0;iumask; current->umask = mask & 0777; return (old); }