2 * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
4 * $Id: seekFile.c,v 1.1 1998/04/10 10:54:49 simonm Exp $
6 * hSeek and hIsSeekable Runtime Support
12 #ifdef HAVE_SYS_TYPES_H
13 #include <sys/types.h>
16 #ifdef HAVE_SYS_STAT_H
21 seekFile(StgAddr fp, StgInt whence, StgInt size, StgByteArray d)
27 * We need to snatch the offset out of an MP_INT. The bits are there sans sign,
28 * which we pick up from our size parameter. If abs(size) is greater than 1,
29 * this integer is just too big.
34 offset = -*(StgInt *) d;
40 offset = *(StgInt *) d;
43 ghc_errtype = ERR_INVALIDARGUMENT;
44 ghc_errstr = "offset out of range";
48 /* Try to find out the file type & size for a physical file */
49 while (fstat(fileno((FILE *) fp), &sb) < 0) {
57 if (S_ISREG(sb.st_mode)) {
58 /* Verify that we are not seeking beyond end-of-file */
66 while ((posn = ftell((FILE *) fp)) == -1) {
67 /* the possibility seems awfully remote */
77 posn = sb.st_size + offset;
80 if (posn > sb.st_size) {
81 ghc_errtype = ERR_INVALIDARGUMENT;
82 ghc_errstr = "seek position beyond end of file";
85 } else if (S_ISFIFO(sb.st_mode)) {
86 ghc_errtype = ERR_UNSUPPORTEDOPERATION;
87 ghc_errstr = "can't seek on a pipe";
90 ghc_errtype = ERR_UNSUPPORTEDOPERATION;
91 ghc_errstr = "can't seek on a device";
94 while (fseek((FILE *) fp, offset, whence) != 0) {
105 seekFileP(StgAddr fp)
109 /* Try to find out the file type */
110 while (fstat(fileno((FILE *) fp), &sb) < 0) {
111 /* highly unlikely */
112 if (errno != EINTR) {
118 /* Regular files are okay */
119 if (S_ISREG(sb.st_mode)) {
122 /* For now, everything else is not */