home *** CD-ROM | disk | FTP | other *** search
- head 1.1;
- access;
- symbols
- version39-41:1.1;
- locks;
- comment @ * @;
-
-
- 1.1
- date 92.05.14.19.55.40; author mwild; state Exp;
- branches;
- next ;
-
-
- desc
- @try to find out information about an open file
- @
-
-
- 1.1
- log
- @Initial revision
- @
- text
- @/*
- * This file is part of ixemul.library for the Amiga.
- * Copyright (C) 1991, 1992 Markus M. Wild
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- *
- * $Log$
- */
-
- #define KERNEL
- #include "ixemul.h"
-
- #ifdef DEBUG
- #define DP(a) kprintf a
- #else
- #define DP(a)
- #endif
-
- #if __GNUC__ != 2
- #define alloca __builtin_alloca
- #endif
-
- #ifndef ACTION_EXAMINE_FH
- #define ACTION_EXAMINE_FH 1034
- #endif
-
- #ifndef ST_LINKDIR
- #define ST_ROOT 1
- #define ST_USERDIR 2
- #define ST_SOFTLINK 3 /* looks like dir, but may point to a file! */
- #define ST_LINKDIR 4 /* hard link to dir */
- #define ST_FILE -3 /* must be negative for FIB! */
- #define ST_LINKFILE -4 /* hard link to file */
- #define ST_PIPEFILE -5 /* for pipes that support ExamineFH */
- #endif
-
- extern void *alloca ();
-
- /************************************************************************/
- /* */
- /* fstat() function. */
- /* */
- /************************************************************************/
-
- int
- __fstat(struct file *f)
- {
- long len, pos;
- struct FileInfoBlock *fib;
- struct InfoData *info;
- int omask;
-
- omask = syscall (SYS_sigsetmask, ~0);
- __get_file (f);
-
- /* take special care of NIL:, /dev/null and friends ;-) */
- if (HANDLER_NIL(f))
- {
- f->f_stb.st_mode = S_IFCHR | 0777;
- f->f_stb.st_nlink = 1;
- f->f_stb.st_blksize = ix.ix_fs_buf_factor * 512;
- f->f_stb.st_blocks = 0;
- goto end;
- }
-
- info = alloca (sizeof (*info) + 2);
- info = LONG_ALIGN (info);
- fib = alloca (sizeof (*fib) + 2);
- fib = LONG_ALIGN (fib);
-
- __wait_packet (&f->f_sp);
- /* reset the error field */
- LastError (f) = 0;
-
- /* we now have two possibilities.. either the filesystem understands the
- * new ACTION_EXAMINE_FH packet, or we have to do some guesses at fields.. */
- /* SendPacket2 (f, __rwport, ACTION_EXAMINE_FH, CTOBPTR(f->f_fh), CTOBPTR(fib));*/
- SendPacket2 (f, __rwport, ACTION_EXAMINE_FH, f->f_fh->fh_Arg1, CTOBPTR(fib));
- __wait_packet (&f->f_sp);
- if (LastResult(f))
- {
- int mode;
-
- f->f_stb.st_nlink = 1; /* always one link entry per file, unless... */
- f->f_stb.st_amode = fib->fib_Protection;
-
- mode = 0;
- if (!(fib->fib_Protection & FIBF_EXECUTE))
- mode |= S_IXUSR | S_IXGRP | S_IXOTH;
- if (!(fib->fib_Protection & FIBF_WRITE))
- mode |= S_IWUSR | S_IWGRP | S_IWOTH;
- #if 0
- if (fib->fib_Protection & FIBF_DELETE)
- mode |= S_ISVTX;
- #endif
- if (!(fib->fib_Protection & FIBF_READ))
- mode |= S_IRUSR | S_IRGRP | S_IROTH;
-
- switch (fib->fib_DirEntryType)
- {
- case ST_LINKDIR:
- f->f_stb.st_nlink ++; /* we never get more than a link count of two.. */
- case ST_ROOT:
- case ST_USERDIR:
- mode |= S_IFDIR;
- break;
-
- /* at the moment, we NEVER get this entry, since we can't get a lock
- * on a symlink */
- case ST_SOFTLINK:
- mode |= S_IFLNK;
- break;
-
- case ST_PIPEFILE:
- /* don't use S_IFIFO, we don't have a mkfifo() call ! */
- mode |= S_IFCHR;
- break;
-
- case ST_LINKFILE:
- f->f_stb.st_nlink ++;
- case ST_FILE:
- default:
- mode |= S_IFREG;
- }
-
- /* ARGLLLLL !!!
- Some (newer, hi Bill Hawes ;-)) handlers support EXAMINE_FH, but
- don't know yet about ST_PIPEFILE. So console windows claim they're
- plain files... Until this problem is fixed in a majority of
- handlers, do an explicit SEEK here to find those fakers.. */
- LastError(f) = 0;
- SendPacket3(f,__rwport,ACTION_SEEK,f->f_fh->fh_Arg1,0,OFFSET_CURRENT);
- __wait_packet (&f->f_sp);
- if (LastError (f))
- mode = (mode & ~S_IFREG) | S_IFCHR;
-
- f->f_stb.st_mode = mode;
- /* some kind of a default-size for directories... */
- f->f_stb.st_size = fib->fib_DirEntryType<0 ? fib->fib_Size : 1024;
- f->f_stb.st_handler = (long)f->f_fh->fh_Type;
- f->f_stb.st_dev = (dev_t)f->f_stb.st_handler; /* trunc to 16 bit */
- f->f_stb.st_ino = fib->fib_DiskKey;
- f->f_stb.st_atime =
- f->f_stb.st_ctime =
- f->f_stb.st_mtime = (8*365+2)*24*3600 + /* offset to unix-timesystem */
- fib->fib_Date.ds_Days * 24 * 60 * 60 +
- fib->fib_Date.ds_Minute * 60 +
- fib->fib_Date.ds_Tick/TICKS_PER_SECOND;
- /* in a try to count the blocks used for filemanagement, we add one for
- * the fileheader. Note, that this is wrong for large files, where there
- * are some extension-blocks as well */
- f->f_stb.st_blocks = fib->fib_NumBlocks + 1;
- }
- else
- {
- /* ATTENTION: see lseek.c for Bugs in Seek() and ACTION_SEEK ! */
- /* seek to EOF */
- SendPacket3 (f, __rwport, ACTION_SEEK, f->f_fh->fh_Arg1, 0, OFFSET_END);
- __wait_packet (&f->f_sp);
- pos = LastResult (f);
- if (pos >= 0 && LastError (f) != ERROR_ACTION_NOT_KNOWN)
- {
- SendPacket3 (f, __rwport,ACTION_SEEK, f->f_fh->fh_Arg1,
- pos, OFFSET_BEGINNING);
- __wait_packet (&f->f_sp);
- len = LastError (f) ? -1 : LastResult (f);
- }
- else
- len = 0;
-
- bzero (&f->f_stb, sizeof(struct stat));
-
- f->f_stb.st_mode = ((len >= 0 &&
- /* !IsInteractive(CTOBPTR(f->f_fh)) */! f->f_fh->fh_Port)
- ? S_IFREG : S_IFCHR) | 0777;
- f->f_stb.st_handler = (long)f->f_fh->fh_Type;
- /* the following is a limited try to support programs, that assume that
- * st_dev is allways valid */
- f->f_stb.st_dev = (dev_t)f->f_fh->fh_Type; /* truncate to 16 bit */
- /* yet another kludge.. if we call this with different descriptors, we
- * should get different inode numbers.. grmpf.. */
- f->f_stb.st_ino = (ino_t)~(long)(f->f_fh);
- f->f_stb.st_nlink = 1; /* for now no problem.. 2.0... */
- /* len could be -1, if the device doesn't allow seeking.. */
- f->f_stb.st_size = len >= 0 ? len : 0;
- f->f_stb.st_atime =
- f->f_stb.st_mtime =
- f->f_stb.st_ctime = syscall (SYS_time, 0);
- }
-
- /* try to find out block size of device, hey postman, it's packet-time
- * again:-)) */
- /* make sure, the packet is not in use anymore */
- __wait_packet(&f->f_sp);
-
- /* clear the info-structure. Since this packet is used by the console
- * handler to transmit the window pointer, it actually answers the
- * request, but doesn't set the not used fields to 0.. this gives HUGE
- * block lengths :-)) */
- bzero (info, sizeof(*info));
- SendPacket1(f,__rwport,ACTION_DISK_INFO,CTOBPTR(info));
- __wait_packet(&f->f_sp);
-
- f->f_stb.st_blksize = 0;
- if (LastResult (f) && info->id_BytesPerBlock)
- {
- f->f_stb.st_blksize = info->id_BytesPerBlock;
- if (!IsInteractive(CTOBPTR(f->f_fh)) && S_ISREG(f->f_stb.st_mode))
- f->f_stb.st_blksize *= ix.ix_fs_buf_factor;
- if (! f->f_stb.st_blocks)
- f->f_stb.st_blocks = ((f->f_stb.st_size + info->id_BytesPerBlock - 1)
- / info->id_BytesPerBlock);
- }
-
- if (! f->f_stb.st_blksize)
- {
- f->f_stb.st_blksize = 512;
- f->f_stb.st_blocks = (f->f_stb.st_size + 511) >> 9;
- }
-
- end:
- /* reset error of packet. write() would fail if not */
- LastResult(f) = 0;
-
- __release_file (f);
- syscall (SYS_sigsetmask, omask);
- return 0;
- }
- @
-