summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdoardo La Greca2025-08-09 18:44:09 +0200
committerEdoardo La Greca2025-08-09 18:44:09 +0200
commit8e5b09c28644fba6078728aacf515d1af8c218ba (patch)
tree4dbd51bcd3b777b391dca3315ff11175663bf62e
parentbedbcf252d63bcbfc3a4de24a5573667d86ca17d (diff)
implement open and add FileMode
-rw-r--r--src/main/kotlin/Connection.kt23
-rw-r--r--src/main/kotlin/FileMode.kt32
-rw-r--r--src/main/kotlin/ProtocolTranslator.kt10
3 files changed, 62 insertions, 3 deletions
diff --git a/src/main/kotlin/Connection.kt b/src/main/kotlin/Connection.kt
index 6630567..1aeb4b1 100644
--- a/src/main/kotlin/Connection.kt
+++ b/src/main/kotlin/Connection.kt
@@ -2,8 +2,10 @@ import except.MsizeValueTooBigException
import except.RErrorException
import except.UnaccessibleFileException
import except.UnknownVersionException
+import java.io.File
import java.io.IOException
import java.math.BigInteger
+import kotlin.io.path.Path
/**
* This class represents a 9P connection. It provides a practical implementation with networking to the 9P methods
@@ -182,8 +184,25 @@ class Connection(transLay: TransportLayer) : ProtocolTranslator {
this.pathInfo.addPath(PathInfo.Path(wname, newfid, qids.last()))
}
- override fun open(path: String) {
- TODO("Not yet implemented")
+ override fun open(fid: UInt, mode: FileMode): Pair<QID, UInt> {
+ val omsg = OutMessage(NinePMessageType.TOPEN, this.tagGen.generate(), listOf("fid", "mode"),
+ mapOf(
+ "fid" to BigInteger(fid.toString()),
+ "mode" to BigInteger(mode.toModeByte().toString())
+ ),
+ emptyMap(),
+ emptyMap(),
+ this.maxSize
+ )
+ omsg.write(this.tl)
+ val imsg = checkedInMessage(omsg.tag)
+ imsg.applySchema(listOf(
+ InMessage.Field("qid", InMessage.Field.Type.RAW, 13u),
+ InMessage.Field("iounit", InMessage.Field.Type.INTEGER, 4u)
+ ))
+ val qid = QID(imsg.fieldsRaw["qid"]!!.toList())
+ val iounit = imsg.fieldsInt["iounit"]!!.toInt().toUInt()
+ return Pair(qid, iounit)
}
override fun create(path: String) {
diff --git a/src/main/kotlin/FileMode.kt b/src/main/kotlin/FileMode.kt
new file mode 100644
index 0000000..81712e6
--- /dev/null
+++ b/src/main/kotlin/FileMode.kt
@@ -0,0 +1,32 @@
+/**
+ * The mode in which to open or create a file. For directories, it's illegal for directories to be written, truncated,
+ * or removed on close.
+ *
+ * @param mode The actual mode, as described by the [Mode] enum class.
+ * @param truncate Set or unset the truncation bit. It requires the write permission.
+ * @param removeClose Set or unset the "remove on close" bit. It requires the remove permission in the parent directory.
+ */
+data class FileMode(val mode: Mode, val truncate: Boolean, val removeClose: Boolean) {
+ enum class Mode(val value: UByte) {
+ READ(0u),
+ WRITE(1u),
+ READ_WRITE(2u),
+ EXECUTE(3u)
+ }
+
+ /**
+ * Turn the mode described by the [FileMode] fields into a mode byte.
+ */
+ fun toModeByte(): UByte {
+ var byte: UByte = 0u
+ byte = byte.or(this.mode.value)
+ if (truncate) {
+ byte = byte.or(0x10u)
+ }
+ if (removeClose) {
+ byte = byte.or(0x40u)
+ }
+
+ return byte
+ }
+} \ No newline at end of file
diff --git a/src/main/kotlin/ProtocolTranslator.kt b/src/main/kotlin/ProtocolTranslator.kt
index b74eef0..b3674f1 100644
--- a/src/main/kotlin/ProtocolTranslator.kt
+++ b/src/main/kotlin/ProtocolTranslator.kt
@@ -75,8 +75,16 @@ interface ProtocolTranslator {
/**
* Prepare an FID for I/O on an existing file.
+ *
+ * @param fid The FID of the file to open.
+ * @param mode The mode in which the file is opened.
+ * @return A pair of: (1) the returned QID, and (2) a value called `iounit` that indicates, if non-zero, the maximum
+ * number of bytes that are guaranteed to be read from or written to the file without breaking the I/O transfer into
+ * multiple 9P messages.
+ * @throws except.InvalidMessageException if the received message is invalid.
+ * @throws except.RErrorException if the received message is an R-error message.
*/
- fun open(path: String)
+ fun open(fid: UInt, mode: FileMode): Pair<QID, UInt>
/**
* Prepare an FID for I/O on a new file.