summaryrefslogtreecommitdiff
path: root/doio.c
diff options
context:
space:
mode:
authorLarry Wall <lwall@jpl-devvax.jpl.nasa.gov>1990-08-13 09:45:26 +0000
committerLarry Wall <lwall@jpl-devvax.jpl.nasa.gov>1990-08-13 09:45:26 +0000
commit6eb13c3b624098fc688ac86672bc30e26cbf8fd4 (patch)
tree13f2a8c28c0c79a68f94d0a2c6d852b0ad86f1b9 /doio.c
parent62b28dd9eb2541847d5ce270cb7493fed626d1ef (diff)
downloadperl-6eb13c3b624098fc688ac86672bc30e26cbf8fd4.tar.gz
perl 3.0 patch #28 (combined patch)
Certain systems, notable Ultrix, set the close-on-exec flag by default on dup'ed file descriptors. This is anti-social when you're creating a new STDOUT. The flag is now forced off for STDIN, STDOUT and STDERR. Some yaccs report 29 shift/reduce conflicts and 59 reduce/reduce conflicts, while other yaccs and bison report 27 and 61. The Makefile now says to expect either thing. I'm not sure if there's a bug lurking there somewhere. The defined(@array) and defined(%array) ended up defining the arrays they were trying to determine the status of. Oops. Using the status of NSIG to determine whether <signal.h> had been included didn't work right on Xenix. A fix seems to be beyond Configure at the moment, so we've got some OS dependent #ifdefs in there. There were some syntax errors in the new code to determine whether it is safe to emulate rename() with unlink/link/unlink. Obviously heavily tested code... :-) Patch 27 introduced the possibility of using identifiers as unquoted strings, but the code to warn against the use of totally lowercase identifiers looped infinitely. I documented that you can't interpolate $) or $| in pattern. It was actually implied under s///, but it should have been more explicit. Patterns with {m} rather than {m,n} didn't work right. Tests io.fs and op.stat had difficulties under AFS. They now ignore the tests in question if they think they're running under /afs. The shift/reduce expectation message was off for a2p's Makefile.
Diffstat (limited to 'doio.c')
-rw-r--r--doio.c70
1 files changed, 63 insertions, 7 deletions
diff --git a/doio.c b/doio.c
index 88c0f4c2bd..40ac26cfb8 100644
--- a/doio.c
+++ b/doio.c
@@ -1,4 +1,4 @@
-/* $Header: doio.c,v 3.0.1.9 90/08/09 02:56:19 lwall Locked $
+/* $Header: doio.c,v 3.0.1.10 90/08/13 22:14:29 lwall Locked $
*
* Copyright (c) 1989, Larry Wall
*
@@ -6,6 +6,10 @@
* as specified in the README file that comes with the perl 3.0 kit.
*
* $Log: doio.c,v $
+ * Revision 3.0.1.10 90/08/13 22:14:29 lwall
+ * patch28: close-on-exec problems on dup'ed file descriptors
+ * patch28: F_FREESP wasn't implemented the way I thought
+ *
* Revision 3.0.1.9 90/08/09 02:56:19 lwall
* patch19: various MSDOS and OS/2 patches folded in
* patch19: prints now check error status better
@@ -67,6 +71,10 @@
#include <netdb.h>
#endif
+#if defined(SELECT) && (defined(M_UNIX) || defined(M_XENIX))
+#include <sys/select.h>
+#endif
+
#ifdef I_PWD
#include <pwd.h>
#endif
@@ -237,8 +245,7 @@ int len;
}
#if defined(FCNTL) && defined(F_SETFD)
fd = fileno(fp);
- if (fd >= 3)
- fcntl(fd,F_SETFD,1);
+ fcntl(fd,F_SETFD,fd >= 3);
#endif
stio->ifp = fp;
if (writing) {
@@ -657,6 +664,58 @@ int *arglast;
return sp;
}
+#if !defined(TRUNCATE) && !defined(CHSIZE) && defined(F_FREESP)
+ /* code courtesy of Pim Zandbergen */
+#define CHSIZE
+
+int chsize(fd, length)
+int fd; /* file descriptor */
+off_t length; /* length to set file to */
+{
+ extern long lseek();
+ struct flock fl;
+ struct stat filebuf;
+
+ if (fstat(fd, &filebuf) < 0)
+ return -1;
+
+ if (filebuf.st_size < length) {
+
+ /* extend file length */
+
+ if ((lseek(fd, (length - 1), 0)) < 0)
+ return -1;
+
+ /* write a "0" byte */
+
+ if ((write(fd, "", 1)) != 1)
+ return -1;
+ }
+ else {
+ /* truncate length */
+
+ fl.l_whence = 0;
+ fl.l_len = 0;
+ fl.l_start = length;
+ fl.l_type = F_WRLCK; /* write lock on file space */
+
+ /*
+ * This relies on the UNDOCUMENTED F_FREESP argument to
+ * fcntl(2), which truncates the file so that it ends at the
+ * position indicated by fl.l_start.
+ *
+ * Will minor miracles never cease?
+ */
+
+ if (fcntl(fd, F_FREESP, &fl) < 0)
+ return -1;
+
+ }
+
+ return 0;
+}
+#endif /* F_FREESP */
+
int
do_truncate(str,arg,gimme,arglast)
STR *str;
@@ -670,7 +729,7 @@ int *arglast;
int result = 1;
STAB *tmpstab;
-#if defined(TRUNCATE) || defined(CHSIZE) || defined(F_FREESP)
+#if defined(TRUNCATE) || defined(CHSIZE)
#ifdef TRUNCATE
if ((arg[1].arg_type & A_MASK) == A_WORD) {
tmpstab = arg[1].arg_ptr.arg_stab;
@@ -681,9 +740,6 @@ int *arglast;
else if (truncate(str_get(ary->ary_array[sp]), len) < 0)
result = 0;
#else
-#ifndef CHSIZE
-#define chsize(f,l) fcntl(f,F_FREESP,l)
-#endif
if ((arg[1].arg_type & A_MASK) == A_WORD) {
tmpstab = arg[1].arg_ptr.arg_stab;
if (!stab_io(tmpstab) ||