source: buchla-68k/libcio/lseek.c

Last change on this file was 8973acd, checked in by Thomas Lopatic <thomas@…>, 7 years ago

No more warnings in libcio.

  • Property mode set to 100644
File size: 2.2 KB
RevLine 
[f40a309]1/*
2 =============================================================================
3 lseek.c -- position a file to a specified byte location
4 Version 7 -- 1987-10-28 -- D.N. Lynx Crowe
5 =============================================================================
6*/
7
8#define DEBUGIT 0
9
[b28a12e]10#include "ram.h"
[f40a309]11
[7258c6a]12int32_t lseek(int16_t fd, int32_t pos, int16_t how)
[f40a309]13{
14 register struct fcb *fp;
15
16 if ((fd < 0) OR (fd > MAXCHAN)) {
17
18#if DEBUGIT
19 if (fsdebug)
20 printf("lseek(%d): bad file index\n", fd);
21#endif
22
23 errno = EBADF; /* file number bad */
24 return(-1L);
25 }
26
27 if (chantab[fd].c_seek EQ 0) {
28
29#if DEBUGIT
30 if (fsdebug)
31 printf("lseek(%d): device not seekable\n", fd);
32#endif
33
34 errno = EINVAL; /* device can't seek */
35 return(-1L);
36 }
37
38 fp = chantab[fd].c_arg; /* get fcb pointer from channel table */
39
40 switch (how) { /* dispatch off of seek type */
41
42 case 2: /* relative to end of file */
43 pos += fp->curlen;
44 break;
45
46 case 1: /* relative to current position */
[8973acd]47 pos += fp->offset + ((int32_t)fp->curlsn << FILESHFT);
[f40a309]48
49 case 0: /* relative to start of file */
50 break;
51
52 default:
53 errno = EINVAL; /* invalid seek type */
54 return(-1L);
55 }
[fa38804]56
[f40a309]57 if (pos < 0) { /* trap seeks before BOF */
58
59 fp->offset = 0;
60 fp->curlsn = 0;
61 fp->modefl |= FC_ERR;
62
63#if DEBUGIT
64 if (fsdebug)
65 printf("lseek(%d): seek (%ld) is before BOF\n", fd, pos);
66#endif
67
68 errno = EINVAL;
69 return(-1L);
70
71 } else if (pos > fp->curlen) { /* trap seeks past EOF */
72
73 fp->offset = fp->curlen & (BPSEC -1);
[8973acd]74 fp->curlsn = (int16_t)(fp->curlen >> FILESHFT);
[f40a309]75 fp->modefl |= FC_ERR;
76
77#if DEBUGIT
78 if (fsdebug)
79 printf("lseek(%d): seek (%ld) is after EOF (%ld)\n",
80 fd, pos, fp->curlen);
81#endif
82
83 errno = EINVAL;
84 return(-1L);
85 }
86
[7258c6a]87 fp->offset = pos & ((int32_t)BPSEC - 1); /* calculate sector offset */
[8973acd]88 fp->curlsn = (int16_t)(pos >> FILESHFT); /* calculate logical sector */
[f40a309]89
90 if (_seek(fp) < 0) { /* position to the physical sector */
91
92 fp->modefl |= FC_ERR; /* couldn't seek */
93 errno = EIO;
94 return(-1L);
95 }
96
97 if (pos EQ fp->curlen)
98 fp->modefl |= FC_EOF;
99
100#if DEBUGIT
101 if (fsdebug)
102 printf("lseek(): pos=%d, curlsn=%ld, curdsn=%ld, offset=%u\n",
103 pos, fp->curlsn, fp->curdsn, fp->offset);
104#endif
105
106 return(pos); /* return current position */
107}
108
[6262b5c]109
Note: See TracBrowser for help on using the repository browser.