Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 52671a78 authored by Nick Kralevich's avatar Nick Kralevich
Browse files

FileUtils.java: Don't treat open access modes as flags

O_RDONLY, O_WRONLY, and O_RDWR are not flags. Rather, they are the
integer values 0, 1, and 2, respectively.

  #define O_RDONLY 00000000
  #define O_WRONLY 00000001
  #define O_RDWR 00000002

Quoting "man 2 open"

  * File access mode *

  Unlike  the  other  values  that  can  be  specified in flags,
  the access mode values O_RDONLY, O_WRONLY, and O_RDWR do not
  specify individual bits.  Rather, they define the low order
  two bits of flags, and are defined respectively as 0, 1, and
  2. In other words, the combination O_RDONLY | O_WRONLY is a
  logical error, and certainly does not have the same meaning
  as O_RDWR.

  Linux reserves the special, nonstandard access mode 3
  (binary 11) in flags to mean: check for read and write
  permission on the file and return a file descriptor that
  can't be used for reading or writing. This nonstandard access
  mode is used by some Linux drivers to return a file
  descriptor that is to be used only for device-specific
  ioctl(2) operations.

Rather than treat these values like flags, use O_ACCMODE to extract the
values and then perform the comparisons.

Introduced in 63280e06.

Test: android compiles and boots.
Change-Id: I4d3185e835615ffba3a7854d3d58351e124599d0
parent f98c2c41
Loading
Loading
Loading
Loading
+19 −19
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
import static android.os.ParcelFileDescriptor.MODE_TRUNCATE;
import static android.os.ParcelFileDescriptor.MODE_WRITE_ONLY;
import static android.system.OsConstants.F_OK;
import static android.system.OsConstants.O_ACCMODE;
import static android.system.OsConstants.O_APPEND;
import static android.system.OsConstants.O_CREAT;
import static android.system.OsConstants.O_RDONLY;
@@ -1259,11 +1260,11 @@ public class FileUtils {

        int res = 0;
        if (mode.startsWith("rw")) {
            res |= O_RDWR | O_CREAT;
            res = O_RDWR | O_CREAT;
        } else if (mode.startsWith("w")) {
            res |= O_WRONLY | O_CREAT;
            res = O_WRONLY | O_CREAT;
        } else if (mode.startsWith("r")) {
            res |= O_RDONLY;
            res = O_RDONLY;
        } else {
            throw new IllegalArgumentException("Bad mode: " + mode);
        }
@@ -1279,12 +1280,12 @@ public class FileUtils {
    /** {@hide} */
    public static String translateModePosixToString(int mode) {
        String res = "";
        if ((mode & O_RDWR) == O_RDWR) {
            res += "rw";
        } else if ((mode & O_WRONLY) == O_WRONLY) {
            res += "w";
        } else if ((mode & O_RDONLY) == O_RDONLY) {
            res += "r";
        if ((mode & O_ACCMODE) == O_RDWR) {
            res = "rw";
        } else if ((mode & O_ACCMODE) == O_WRONLY) {
            res = "w";
        } else if ((mode & O_ACCMODE) == O_RDONLY) {
            res = "r";
        } else {
            throw new IllegalArgumentException("Bad mode: " + mode);
        }
@@ -1300,12 +1301,12 @@ public class FileUtils {
    /** {@hide} */
    public static int translateModePosixToPfd(int mode) {
        int res = 0;
        if ((mode & O_RDWR) == O_RDWR) {
            res |= MODE_READ_WRITE;
        } else if ((mode & O_WRONLY) == O_WRONLY) {
            res |= MODE_WRITE_ONLY;
        } else if ((mode & O_RDONLY) == O_RDONLY) {
            res |= MODE_READ_ONLY;
        if ((mode & O_ACCMODE) == O_RDWR) {
            res = MODE_READ_WRITE;
        } else if ((mode & O_ACCMODE) == O_WRONLY) {
            res = MODE_WRITE_ONLY;
        } else if ((mode & O_ACCMODE) == O_RDONLY) {
            res = MODE_READ_ONLY;
        } else {
            throw new IllegalArgumentException("Bad mode: " + mode);
        }
@@ -1325,11 +1326,11 @@ public class FileUtils {
    public static int translateModePfdToPosix(int mode) {
        int res = 0;
        if ((mode & MODE_READ_WRITE) == MODE_READ_WRITE) {
            res |= O_RDWR;
            res = O_RDWR;
        } else if ((mode & MODE_WRITE_ONLY) == MODE_WRITE_ONLY) {
            res |= O_WRONLY;
            res = O_WRONLY;
        } else if ((mode & MODE_READ_ONLY) == MODE_READ_ONLY) {
            res |= O_RDONLY;
            res = O_RDONLY;
        } else {
            throw new IllegalArgumentException("Bad mode: " + mode);
        }
@@ -1428,4 +1429,3 @@ public class FileUtils {
        }
    }
}
+22 −0
Original line number Diff line number Diff line
@@ -516,6 +516,28 @@ public class FileUtilsTest {
                MODE_WRITE_ONLY | MODE_CREATE | MODE_APPEND);
    }

    @Test
    public void testMalformedTransate_int() throws Exception {
        try {
            // The non-standard Linux access mode 3 should throw
            // an IllegalArgumentException.
            translateModePosixToPfd(O_RDWR | O_WRONLY);
            fail();
        } catch (IllegalArgumentException expected) {
        }
    }

    @Test
    public void testMalformedTransate_string() throws Exception {
        try {
            // The non-standard Linux access mode 3 should throw
            // an IllegalArgumentException.
            translateModePosixToString(O_RDWR | O_WRONLY);
            fail();
        } catch (IllegalArgumentException expected) {
        }
    }

    @Test
    public void testTranslateMode_Invalid() throws Exception {
        try {