#include #include #include #include "linuxsys.h" #include "linux.h" struct __old_kernel_stat { ushort st_dev; ushort st_ino; ushort st_mode; ushort st_nlink; ushort st_uid; ushort st_gid; ushort st_rdev; ulong st_size; ulong st_atime; ulong st_mtime; ulong st_ctime; }; struct stat { ushort st_dev; ushort __pad1; ulong st_ino; ushort st_mode; ushort st_nlink; ushort st_uid; ushort st_gid; ushort st_rdev; ushort __pad2; ulong st_size; ulong st_blksize; ulong st_blocks; ulong st_atime; ulong __unused1; ulong st_mtime; ulong __unused2; ulong st_ctime; ulong __unused3; ulong __unused4; ulong __unused5; }; #define S_IFMT 0170000 #define S_IFSOCK 0140000 #define S_IFLNK 0120000 #define S_IFREG 0100000 #define S_IFBLK 0060000 #define S_IFDIR 0040000 #define S_IFCHR 0020000 #define S_IFIFO 0010000 #define S_ISUID 0004000 #define S_ISGID 0002000 #define S_ISVTX 0001000 static void dir2nstat(struct stat *st, Dir *d) { st->st_dev = d->type; st->st_ino = d->qid.path; st->st_mode = d->mode & 0777; /* BUG handle more file types. */ //print("stat on #%C: %s\n", d->type, d->name); if(d->mode & DMDIR) st->st_mode |= S_IFDIR; else if(strcmp(d->name, "cons") == 0) // bug, surely. st->st_mode |= S_IFCHR; else if(d->type == '|') st->st_mode |= S_IFIFO; else if(d->type == 'H') st->st_mode |= S_IFBLK; else if(d->type == 'M') st->st_mode |= S_IFREG; st->st_nlink = 1; st->st_uid = 1; // BUG get uid st->st_gid = 1; // BUG get gid st->st_size = d->length; st->st_rdev = 0; st->st_blksize = 4096; // good as any st->st_blocks = (d->length+st->st_blksize-1) / st->st_blksize; st->st_atime = d->atime; st->st_mtime = d->mtime; st->st_ctime = d->mtime; } SYSCALL(sys_newfstat) { ulong fd = ARG1; struct stat *sbuf = (struct stat *) ARG2; Dir *d; DPRINT("newfstat(%lud, %p)...", fd, sbuf); if((d = dirfstat(fd)) == nil) RETURN(-EBADF); dir2nstat(sbuf, d); free(d); RETURN(0); } SYSCALL(sys_newstat) { char *file = (char*) ARG1; struct stat *sbuf = (struct stat *) ARG2; Dir *d; DPRINT("newstat(%s, %p)...", file, sbuf); if((d = dirstat(file)) == nil) RETURN(mkerror()); dir2nstat(sbuf, d); free(d); RETURN(0); } /* * same as stat except when called on a * link, which we don't support. */ SYSCALL(sys_newlstat) { char *file = (char*) ARG1; struct stat *sbuf = (struct stat *) ARG2; Dir *d; DPRINT("newlstat(%s, %p)...", file, sbuf); if((d = dirstat(file)) == nil) RETURN(mkerror()); dir2nstat(sbuf, d); free(d); RETURN(0); }