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
|
/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define import_kernel
#define import_knames
#define import_spp
#include <iraf.h>
/* ZFALOC -- Preallocate space for a large file of known size, without having
* to physically write zero blocks. In UNIX this is done by seeking to the
* desired end of file and writing some data. Standard UNIX does not provide
* any way to allocate a contiguous or near-contiguous file.
*/
int
ZFALOC (
PKCHAR *fname,
XLONG *nbytes,
XINT *status
)
{
char data = 0;
char *s;
int fd;
off_t lseek();
extern char *getenv();
extern int _u_fmode();
if ((fd = creat ((char *)fname, _u_fmode(FILE_MODEBITS))) == ERR) {
*status = XERR;
return (XERR);
}
/* Fix size of file by seeking to the end of file minus one byte,
* and writing one byte of data. UNIX will not allocate the remaining
* fileblocks until they are written into at run time; when referenced
* the blocks will be zero-fill on demand.
*/
if (*nbytes > 0) {
if (lseek (fd, (off_t)(*nbytes - 1), 0) == ERR) {
close (fd);
*status = XERR;
return (XERR);
}
if (write (fd, &data, 1) == ERR) {
close (fd);
*status = XERR;
return (XERR);
}
lseek (fd, (off_t)0, 0);
}
/* For efficiency reasons the above is all we normally do. However,
* if ZFALOC is set in the environment we touch each file block at
* least once in order to preallocate all the space at zfaloc time.
* ZFALOC may optionally have a string value. If no value is given
* all files are match (zfaloc is fully allocate all files).
* Otherwise, the string value is a comma delimited list of simple
* pattern strings. A file is matched, and space preallocated, if
* the given substring appears anywhere in the file name.
*/
if ( (s = getenv ("ZFALOC")) ) {
register char *ip, *op;
char patstr[SZ_PATHNAME];
int match = (*s == '\0');
int patlen, i;
while (!match && *s) {
for (op=patstr; *s && *s != ','; )
*op++ = *s++;
*op = '\0';
patlen = strlen (patstr);
if (*s == ',')
s++;
for (ip=(char *)fname; *ip; ip++)
if (*ip == patstr[0] && !strncmp(ip,patstr,patlen)) {
match++;
break;
}
}
if (match)
for (i=0; i < *nbytes; i += 512) {
lseek (fd, (off_t)i, 0);
if (write (fd, &data, 1) < 0) {
*status = XERR;
close (fd);
return (XERR);
}
}
}
close (fd);
*status = XOK;
return (XOK);
}
|