aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/doc/src/notes.xml28
-rw-r--r--erts/emulator/drivers/unix/unix_efile.c89
-rw-r--r--erts/vsn.mk2
3 files changed, 75 insertions, 44 deletions
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index 14fcdb7e0e..ae1d2b1d93 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -32,6 +32,34 @@
<p>This document describes the changes made to the ERTS application.</p>
+<section><title>Erts 8.2.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix bug in <c>binary_to_term</c> for binaries created by
+ <c>term_to_binary </c> with option <c>compressed</c>. The
+ bug can cause <c>badarg</c> exception for a valid binary
+ when Erlang VM is linked against a <c>zlib</c> library of
+ version 1.2.9 or newer. Bug exists since OTP 17.0.</p>
+ <p>
+ Own Id: OTP-14159 Aux Id: ERL-340 </p>
+ </item>
+ <item>
+ <p>
+ The driver efile_drv when opening a file now use fstat()
+ on the open file instead of stat() before opening, if
+ fstat() exists. This avoids a race when the file happens
+ to change between stat() and open().</p>
+ <p>
+ Own Id: OTP-14184 Aux Id: seq-13266 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 8.2.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c
index bfe0807df8..3ff68a8859 100644
--- a/erts/emulator/drivers/unix/unix_efile.c
+++ b/erts/emulator/drivers/unix/unix_efile.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 1997-2016. All Rights Reserved.
+ * Copyright Ericsson AB 1997-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -79,11 +79,10 @@
* Macros for testing file types.
*/
-#define ISDIR(st) (((st).st_mode & S_IFMT) == S_IFDIR)
-#define ISREG(st) (((st).st_mode & S_IFMT) == S_IFREG)
-#define ISDEV(st) \
- (((st).st_mode&S_IFMT) == S_IFCHR || ((st).st_mode&S_IFMT) == S_IFBLK)
-#define ISLNK(st) (((st).st_mode & S_IFLNK) == S_IFLNK)
+#define ISDIR(st) (S_ISDIR((st).st_mode))
+#define ISREG(st) (S_ISREG((st).st_mode))
+#define ISDEV(st) (S_ISCHR((st).st_mode) || S_ISBLK((st).st_mode))
+#define ISLNK(st) (S_ISLNK((st).st_mode))
#ifdef NO_UMASK
#define FILE_MODE 0644
#define DIR_MODE 0755
@@ -366,33 +365,6 @@ efile_openfile(Efile_error* errInfo, /* Where to return error codes. */
int fd;
int mode; /* Open mode. */
- if (stat(name, &statbuf) < 0) {
- /* statbuf is undefined: if the caller depends on it,
- i.e. invoke_read_file(), fail the call immediately */
- if (pSize && flags == EFILE_MODE_READ)
- return check_error(-1, errInfo);
- } else if (!ISREG(statbuf)) {
- /*
- * For UNIX only, here is some ugly code to allow
- * /dev/null to be opened as a file.
- *
- * Assumption: The i-node number for /dev/null cannot be zero.
- */
- static ino_t dev_null_ino = 0;
-
- if (dev_null_ino == 0) {
- struct stat nullstatbuf;
-
- if (stat("/dev/null", &nullstatbuf) >= 0) {
- dev_null_ino = nullstatbuf.st_ino;
- }
- }
- if (!(dev_null_ino && statbuf.st_ino == dev_null_ino)) {
- errno = EISDIR;
- return check_error(-1, errInfo);
- }
- }
-
switch (flags & (EFILE_MODE_READ|EFILE_MODE_WRITE)) {
case EFILE_MODE_READ:
mode = O_RDONLY;
@@ -411,16 +383,13 @@ efile_openfile(Efile_error* errInfo, /* Where to return error codes. */
return check_error(-1, errInfo);
}
-
if (flags & EFILE_MODE_APPEND) {
mode &= ~O_TRUNC;
mode |= O_APPEND;
}
-
if (flags & EFILE_MODE_EXCL) {
mode |= O_EXCL;
}
-
if (flags & EFILE_MODE_SYNC) {
#ifdef O_SYNC
mode |= O_SYNC;
@@ -430,15 +399,49 @@ efile_openfile(Efile_error* errInfo, /* Where to return error codes. */
#endif
}
- fd = open(name, mode, FILE_MODE);
+#ifdef HAVE_FSTAT
+ while (((fd = open(name, mode, FILE_MODE)) < 0) && (errno == EINTR));
+ if (!check_error(fd, errInfo)) return 0;
+#endif
+
+ if (
+#ifdef HAVE_FSTAT
+ fstat(fd, &statbuf) < 0
+#else
+ stat(name, &statbuf) < 0
+#endif
+ ) {
+ /* statbuf is undefined: if the caller depends on it,
+ i.e. invoke_read_file(), fail the call immediately */
+ if (pSize && flags == EFILE_MODE_READ) {
+ check_error(-1, errInfo);
+#ifdef HAVE_FSTAT
+ efile_closefile(fd);
+#endif
+ return 0;
+ }
+ }
+ else if (! ISREG(statbuf)) {
+ struct stat nullstatbuf;
+ /*
+ * For UNIX only, here is some ugly code to allow
+ * /dev/null to be opened as a file.
+ */
+ if ( (stat("/dev/null", &nullstatbuf) < 0)
+ || (statbuf.st_ino != nullstatbuf.st_ino)
+ || (statbuf.st_dev != nullstatbuf.st_dev) ) {
+ errno = EISDIR;
+ return check_error(-1, errInfo);
+ }
+ }
- if (!check_error(fd, errInfo))
- return 0;
+#ifndef HAVE_FSTAT
+ while (((fd = open(name, mode, FILE_MODE)) < 0) && (errno == EINTR));
+ if (!check_error(fd, errInfo)) return 0;
+#endif
*pfd = fd;
- if (pSize) {
- *pSize = statbuf.st_size;
- }
+ if (pSize) *pSize = statbuf.st_size;
return 1;
}
@@ -460,7 +463,7 @@ efile_may_openfile(Efile_error* errInfo, char *name) {
void
efile_closefile(int fd)
{
- close(fd);
+ while((close(fd) < 0) && (errno == EINTR));
}
int
diff --git a/erts/vsn.mk b/erts/vsn.mk
index 028b114068..a0a991f5a9 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -18,7 +18,7 @@
# %CopyrightEnd%
#
-VSN = 8.2.1
+VSN = 8.2.2
# Port number 4365 in 4.2
# Port number 4366 in 4.3