summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2020-07-16 11:38:08 -0400
committerFrans Kaashoek <[email protected]>2020-08-10 11:19:10 -0400
commitaf9eb9114c2f8700d4315eaa1e2d637c2aaaf210 (patch)
tree9e2e5cc663d2a3d56358121761755a4d3e878d6b /kernel
parent672217ae2a3d68b73b2229ab368979ef7790e28a (diff)
downloadxv6-labs-af9eb9114c2f8700d4315eaa1e2d637c2aaaf210.tar.gz
xv6-labs-af9eb9114c2f8700d4315eaa1e2d637c2aaaf210.tar.bz2
xv6-labs-af9eb9114c2f8700d4315eaa1e2d637c2aaaf210.zip
make "echo hello > x" truncate file x.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/defs.h1
-rw-r--r--kernel/fcntl.h1
-rw-r--r--kernel/fs.c10
-rw-r--r--kernel/sysfile.c4
4 files changed, 9 insertions, 7 deletions
diff --git a/kernel/defs.h b/kernel/defs.h
index 9c5f643..f33f1f6 100644
--- a/kernel/defs.h
+++ b/kernel/defs.h
@@ -52,6 +52,7 @@ struct inode* nameiparent(char*, char*);
int readi(struct inode*, int, uint64, uint, uint);
void stati(struct inode*, struct stat*);
int writei(struct inode*, int, uint64, uint, uint);
+void itrunc(struct inode*);
// ramdisk.c
void ramdiskinit(void);
diff --git a/kernel/fcntl.h b/kernel/fcntl.h
index d565483..44861b9 100644
--- a/kernel/fcntl.h
+++ b/kernel/fcntl.h
@@ -2,3 +2,4 @@
#define O_WRONLY 0x001
#define O_RDWR 0x002
#define O_CREATE 0x200
+#define O_TRUNC 0x400
diff --git a/kernel/fs.c b/kernel/fs.c
index 53586d5..e33ec30 100644
--- a/kernel/fs.c
+++ b/kernel/fs.c
@@ -22,7 +22,6 @@
#include "file.h"
#define min(a, b) ((a) < (b) ? (a) : (b))
-static void itrunc(struct inode*);
// there should be one superblock per disk device, but we run with
// only one device
struct superblock sb;
@@ -406,11 +405,8 @@ bmap(struct inode *ip, uint bn)
}
// Truncate inode (discard contents).
-// Only called when the inode has no links
-// to it (no directory entries referring to it)
-// and has no in-memory reference to it (is
-// not an open file or current directory).
-static void
+// Caller must hold ip->lock.
+void
itrunc(struct inode *ip)
{
int i, j;
@@ -463,7 +459,7 @@ readi(struct inode *ip, int user_dst, uint64 dst, uint off, uint n)
struct buf *bp;
if(off > ip->size || off + n < off)
- return -1;
+ return 0;
if(off + n > ip->size)
n = ip->size - off;
diff --git a/kernel/sysfile.c b/kernel/sysfile.c
index 7768d20..015c942 100644
--- a/kernel/sysfile.c
+++ b/kernel/sysfile.c
@@ -341,6 +341,10 @@ sys_open(void)
f->readable = !(omode & O_WRONLY);
f->writable = (omode & O_WRONLY) || (omode & O_RDWR);
+ if((omode & O_TRUNC) && ip->type == T_FILE){
+ itrunc(ip);
+ }
+
iunlock(ip);
end_op();