aboutsummaryrefslogtreecommitdiff
path: root/unix/os/zfaloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'unix/os/zfaloc.c')
-rw-r--r--unix/os/zfaloc.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/unix/os/zfaloc.c b/unix/os/zfaloc.c
new file mode 100644
index 00000000..c0eb09cd
--- /dev/null
+++ b/unix/os/zfaloc.c
@@ -0,0 +1,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);
+}