aboutsummaryrefslogtreecommitdiff
path: root/sys/fio/seek.x
blob: 73440a3cf59751aed0a217f7ef57e90f324580a3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.

include	<config.h>
include	<syserr.h>
include	<fio.h>

# SEEK -- Position the i/o pointer (file offset at which the next i/o transfer
# will occur) for a file.  Note that ITOP may have to be adjusted before
# performing the seek, to make newly written data readable (as when writing at
# EOF, seeking backward within the same buffer, and reading).  A physical seek
# is performed for text files.  For binary files, a logical seek is performed,
# adjusting the i/o pointer.  Physical seeks on binary files are initiated
# by FFAULT, when filling or flushing a file buffer.

procedure seek (fd, offset)

int	fd			# file
long	offset			# offset == BOF,EOF, or char offset

pointer	bp
long	file_offset
int	status
long	ffilsz()
errchk	filerr, syserr, ffilsz
include	<fio.com>

begin
	fp = fiodes[fd]
	if (fd <= 0 || fp == NULL)
	    call syserr (SYS_FILENOTOPEN)

	call fcanpb (fd)	# cancel any pushback
	UPDATE_IOP(fd)		# make newly written data readable

	if (FTYPE(fp) == TEXT_FILE) {
	    # General seeks only permitted on text files opened for reading.
	    if (FMODE(fp) != READ_ONLY)
		if (offset != BOF && offset != EOF)
		    call filerr (FNAME(fp), SYS_FSEEKNTXF)

	    bp = bufptr[fd]
	    if (BUF_MODIFIED(fd)) {		# flush buffer?
		call fputtx (fd, Memc[bp], otop[fd] - bp, status)
		if (status != ERR)
		    call zcall2 (ZFLSTX(fp), FCHAN(fp), status)
		if (status == ERR)
		    call filerr (FNAME(fp), SYS_FWRITE)
	    }

	    iop[fd] = bp
	    itop[fd] = bp
	    otop[fd] = bp

	    call zcall3 (ZSEKTX(fp), FCHAN(fp), offset, status)
	    if (status == ERR)
		call filerr (FNAME(fp), SYS_FSEEK)

	} else {				# logical seek (binary files)
	    switch (offset) {
	    case BOF:
		file_offset = 1
	    case EOF:
		file_offset = ffilsz (fd) + 1
	    default:
		file_offset = offset
	    }
	    iop[fd] = file_offset - boffset[fd] + bufptr[fd]
	}
end