2 % (c) The GRASP/AQUA Project, Glasgow University, 1994
4 \subsection[seekFile.lc]{hSeek and hIsSeekable Runtime Support}
11 #ifdef HAVE_SYS_TYPES_H
12 #include <sys/types.h>
15 #ifdef HAVE_SYS_STAT_H
20 seekFile(fp, whence, size, d)
30 * We need to snatch the offset out of an MP_INT. The bits are there sans sign,
31 * which we pick up from our size parameter. If abs(size) is greater than 1,
32 * this integer is just too big.
37 offset = -*(StgInt *) d;
43 offset = *(StgInt *) d;
46 ghc_errtype = ERR_INVALIDARGUMENT;
47 ghc_errstr = "offset out of range";
51 /* Try to find out the file type & size for a physical file */
52 while (fstat(fileno((FILE *) fp), &sb) < 0) {
60 if (S_ISREG(sb.st_mode)) {
61 /* Verify that we are not seeking beyond end-of-file */
69 while ((posn = ftell((FILE *) fp)) == -1) {
70 /* the possibility seems awfully remote */
80 posn = sb.st_size + offset;
83 if (posn > sb.st_size) {
84 ghc_errtype = ERR_INVALIDARGUMENT;
85 ghc_errstr = "seek position beyond end of file";
88 } else if (S_ISFIFO(sb.st_mode)) {
89 ghc_errtype = ERR_UNSUPPORTEDOPERATION;
90 ghc_errstr = "can't seek on a pipe";
93 ghc_errtype = ERR_UNSUPPORTEDOPERATION;
94 ghc_errstr = "can't seek on a device";
97 while (fseek((FILE *) fp, offset, whence) != 0) {
113 /* Try to find out the file type */
114 while (fstat(fileno((FILE *) fp), &sb) < 0) {
115 /* highly unlikely */
116 if (errno != EINTR) {
122 /* Regular files are okay */
123 if (S_ISREG(sb.st_mode)) {
126 /* For now, everything else is not */