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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
include <error.h>
include <ctype.h>
include <syserr.h>
include <config.h>
include <fio.h>
include <fset.h>
# FILOPN -- Open a file on an installed device. A file descriptor is
# allocated and initialized. If a new file is being opened, file clobber
# (overwrite) checking is performed. If the file exists but cannot be
# accessed because it is open by another process, and file waiting is
# enabled (usually in batch mode), the process is blocked until the file
# becomes available. If one attempts to "open" one of the files "STDIN",
# "STDOUT", "STDERR", etc. the fd of the appropriate standard file is returned.
# Interrupts are disabled while the VFN database is open to protect the
# database, ensure that that the lock on the mapping file is cleared, and to
# ensure that the mapping file is closed.
int procedure filopn (fname, mode, type, zopen_proc, device)
char fname[ARB] # virtual file name
int mode # access mode (ro,rw,apnd,newf,temp)
int type # text or binary file
extern zopen_proc(), device()
pointer vp
bool standard_device
int ip, fd, dev_epa, junk, status, vfnmode
pointer vfnopen()
int fgetfd(), fstdfile(), vfnadd(), vfnmap(), locpr()
errchk fwtacc, seek, fclobber, fgetfd
include <fio.com>
define cleanup_ 91
define close_ 92
define abort_ 93
begin
for (ip=1; IS_WHITE (fname[ip]); ip=ip+1)
;
# Do not bother to check access mode if reopening a standard
# stream. If one attempts to write to STDIN or read from STDOUT,
# a suitable error message will be generated at that time. If
# a standard file such as STDIN is reopened read-write but never
# written to, however, that is acceptable.
if (fstdfile (fname[ip], fd) == YES) # standard stream?
return (fd)
# Determine if "device" is a standard disk device, i.e., the driver
# TX or BF or the static file driver SF. Clobber and filewait are
# only performed for disk files.
dev_epa = locpr (device)
standard_device = (dev_epa == zdev[TX_DRIVER] ||
dev_epa == zdev[BF_DRIVER] ||
dev_epa == zdev[SF_DRIVER])
# Perform clobber checking and waiting only for standard devices.
# If clobber is enabled and we are opening a new file, any existing
# file will be deleted.
if (standard_device && (mode == NEW_FILE || mode == TEMP_FILE))
call fclobber (fname[ip])
# Allocate and initialize the file descriptor.
fd = fgetfd (fname[ip], mode, type)
call fseti (fd, F_DEVICE, dev_epa)
fp = fiodes[fd]
# Get OS pathname of file.
if (standard_device) {
# Don't open VFN with write perm if file is readonly, else
# lockout may occur on the mapping file.
if (FMODE(fp) == READ_ONLY)
vfnmode = VFN_READ
else
vfnmode = VFN_WRITE
call intr_disable()
iferr (vp = vfnopen (fname[ip], vfnmode))
goto abort_
if (FMODE(fp) == NEW_FILE) {
iferr (junk = vfnadd (vp, FPKOSFN(fp), SZ_FFNAME))
goto close_
} else {
iferr (status = vfnmap (vp, FPKOSFN(fp), SZ_FFNAME))
goto close_
if (status == ERR)
iferr (call syserrs (SYS_FOPEN, fname[ip]))
goto close_
}
iferr (call vfnclose (vp, VFN_UPDATE))
goto abort_
call intr_enable()
} else
call strpak (fname[ip], FPKOSFN(fp), SZ_FFNAME)
# Open file. If file exists on a standard device but cannot be
# accessed and "filewait" is enabled, wait for file to become
# accessible.
repeat {
call zopen_proc (FPKOSFN(fp), FMODE(fp), FCHAN(fp))
FDEVOPEN(fp) = locpr (zopen_proc)
fp = fiodes[fd]
if (FCHAN(fp) == ERR) {
iferr {
if (standard_device) {
iferr (call fwtacc (fd, fname[ip]))
call syserrs (SYS_FOPEN, fname[ip])
} else {
call syserrs (SYS_FOPENDEV, fname[ip])
}
} then
goto cleanup_
} else
break
}
# Get the device parameters (block size, file size, streamer, etc.)
iferr (call fgdev_param (fd))
goto cleanup_
iferr {
if (mode == APPEND)
call seek (fd, EOFL)
else
call seek (fd, BOFL)
# Save name of temporary file for automatic deletion at program
# termination.
if (mode == TEMP_FILE)
call fsvtfn (fname)
} then
goto cleanup_
return (fd)
cleanup_
call frtnfd (fd)
call erract (EA_ERROR)
return (ERR)
# Error recovery nasties for when the VFN is open.
close_
iferr (call vfnclose (vp, VFN_NOUPDATE))
;
abort_
call frtnfd (fd)
call intr_enable()
call erract (EA_ERROR)
return (ERR)
end
|