summaryrefslogtreecommitdiff
path: root/emu
diff options
context:
space:
mode:
Diffstat (limited to 'emu')
-rw-r--r--emu/DragonFly/devfs.c6
-rw-r--r--emu/FreeBSD/devfs.c6
-rw-r--r--emu/Hp/devfs.c6
-rw-r--r--emu/Irix/devfs.c6
-rw-r--r--emu/Linux/devfs.c25
-rw-r--r--emu/MacOSX/devfs.c6
-rw-r--r--emu/NetBSD/devfs.c6
-rw-r--r--emu/OpenBSD/devfs.c6
-rw-r--r--emu/Solaris/devfs.c6
-rw-r--r--emu/Unixware/devfs.c6
-rw-r--r--emu/port/devfs-posix.c33
11 files changed, 105 insertions, 7 deletions
diff --git a/emu/DragonFly/devfs.c b/emu/DragonFly/devfs.c
index 9017c3fc..194c1090 100644
--- a/emu/DragonFly/devfs.c
+++ b/emu/DragonFly/devfs.c
@@ -1 +1,7 @@
#include "devfs-posix.c"
+
+static vlong
+osdisksize(int fd)
+{
+ return 0;
+}
diff --git a/emu/FreeBSD/devfs.c b/emu/FreeBSD/devfs.c
index 9017c3fc..194c1090 100644
--- a/emu/FreeBSD/devfs.c
+++ b/emu/FreeBSD/devfs.c
@@ -1 +1,7 @@
#include "devfs-posix.c"
+
+static vlong
+osdisksize(int fd)
+{
+ return 0;
+}
diff --git a/emu/Hp/devfs.c b/emu/Hp/devfs.c
index 9017c3fc..194c1090 100644
--- a/emu/Hp/devfs.c
+++ b/emu/Hp/devfs.c
@@ -1 +1,7 @@
#include "devfs-posix.c"
+
+static vlong
+osdisksize(int fd)
+{
+ return 0;
+}
diff --git a/emu/Irix/devfs.c b/emu/Irix/devfs.c
index 9017c3fc..194c1090 100644
--- a/emu/Irix/devfs.c
+++ b/emu/Irix/devfs.c
@@ -1 +1,7 @@
#include "devfs-posix.c"
+
+static vlong
+osdisksize(int fd)
+{
+ return 0;
+}
diff --git a/emu/Linux/devfs.c b/emu/Linux/devfs.c
index 9017c3fc..d697d7b4 100644
--- a/emu/Linux/devfs.c
+++ b/emu/Linux/devfs.c
@@ -1 +1,26 @@
#include "devfs-posix.c"
+
+#include <linux/hdreg.h>
+#include <linux/fs.h>
+#include <sys/ioctl.h>
+
+static vlong
+osdisksize(int fd)
+{
+ uvlong u64;
+ long l;
+ struct hd_geometry geo;
+
+ memset(&geo, 0, sizeof geo);
+ l = 0;
+ u64 = 0;
+#ifdef BLKGETSIZE64
+ if(ioctl(fd, BLKGETSIZE64, &u64) >= 0)
+ return u64;
+#endif
+ if(ioctl(fd, BLKGETSIZE, &l) >= 0)
+ return l*512;
+ if(ioctl(fd, HDIO_GETGEO, &geo) >= 0)
+ return (vlong)geo.heads*geo.sectors*geo.cylinders*512;
+ return 0;
+}
diff --git a/emu/MacOSX/devfs.c b/emu/MacOSX/devfs.c
index 9017c3fc..194c1090 100644
--- a/emu/MacOSX/devfs.c
+++ b/emu/MacOSX/devfs.c
@@ -1 +1,7 @@
#include "devfs-posix.c"
+
+static vlong
+osdisksize(int fd)
+{
+ return 0;
+}
diff --git a/emu/NetBSD/devfs.c b/emu/NetBSD/devfs.c
index 9017c3fc..194c1090 100644
--- a/emu/NetBSD/devfs.c
+++ b/emu/NetBSD/devfs.c
@@ -1 +1,7 @@
#include "devfs-posix.c"
+
+static vlong
+osdisksize(int fd)
+{
+ return 0;
+}
diff --git a/emu/OpenBSD/devfs.c b/emu/OpenBSD/devfs.c
index 9017c3fc..194c1090 100644
--- a/emu/OpenBSD/devfs.c
+++ b/emu/OpenBSD/devfs.c
@@ -1 +1,7 @@
#include "devfs-posix.c"
+
+static vlong
+osdisksize(int fd)
+{
+ return 0;
+}
diff --git a/emu/Solaris/devfs.c b/emu/Solaris/devfs.c
index 9017c3fc..194c1090 100644
--- a/emu/Solaris/devfs.c
+++ b/emu/Solaris/devfs.c
@@ -1 +1,7 @@
#include "devfs-posix.c"
+
+static vlong
+osdisksize(int fd)
+{
+ return 0;
+}
diff --git a/emu/Unixware/devfs.c b/emu/Unixware/devfs.c
index 9017c3fc..194c1090 100644
--- a/emu/Unixware/devfs.c
+++ b/emu/Unixware/devfs.c
@@ -1 +1,7 @@
#include "devfs-posix.c"
+
+static vlong
+osdisksize(int fd)
+{
+ return 0;
+}
diff --git a/emu/port/devfs-posix.c b/emu/port/devfs-posix.c
index 763694d1..67e06169 100644
--- a/emu/port/devfs-posix.c
+++ b/emu/port/devfs-posix.c
@@ -74,7 +74,7 @@ static User* newgname(char*);
static Qid fsqid(struct stat *);
static void fspath(Cname*, char*, char*);
-static int fsdirconv(Chan*, char*, struct stat*, uchar*, int, int);
+static int fsdirconv(Chan*, char*, char*, struct stat*, uchar*, int, int);
static Cname* fswalkpath(Cname*, char*, int);
static char* fslastelem(Cname*);
static int ingroup(int id, int gid);
@@ -82,6 +82,7 @@ static void fsperm(Chan*, int);
static long fsdirread(Chan*, uchar*, int, vlong);
static int fsomode(int);
static void fsremove(Chan*);
+static vlong osdisksize(int); /* defined by including file */
/*
* make invalid symbolic links visible; less confusing, and at least you can then delete them.
@@ -236,13 +237,18 @@ fsstat(Chan *c, uchar *dp, int n)
struct stat st;
char *p;
- if(xstat(FS(c)->name->s, &st) < 0)
- oserror();
+ if(FS(c)->fd >= 0){
+ if(fstat(FS(c)->fd, &st) < 0)
+ oserror();
+ }else{
+ if(xstat(FS(c)->name->s, &st) < 0)
+ oserror();
+ }
p = fslastelem(FS(c)->name);
if(*p == 0)
p = "/";
qlock(&idl);
- n = fsdirconv(c, p, &st, dp, n, 0);
+ n = fsdirconv(c, FS(c)->name->s, p, &st, dp, n, 0);
qunlock(&idl);
return n;
}
@@ -263,6 +269,11 @@ opensocket(char *path)
if(connect(fd, (struct sockaddr*)&su, sizeof su) >= 0)
return fd;
close(fd);
+ if((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
+ return -1;
+ if(connect(fd, (struct sockaddr*)&su, sizeof su) >= 0)
+ return fd;
+ close(fd);
return -1;
}
@@ -725,11 +736,12 @@ isdots(char *name)
}
static int
-fsdirconv(Chan *c, char *name, struct stat *s, uchar *va, int nb, int indir)
+fsdirconv(Chan *c, char *path, char *name, struct stat *s, uchar *va, int nb, int indir)
{
Dir d;
char uidbuf[NUMSIZE], gidbuf[NUMSIZE];
User *u;
+ int fd;
memset(&d, 0, sizeof(d));
d.name = name;
@@ -753,6 +765,13 @@ fsdirconv(Chan *c, char *name, struct stat *s, uchar *va, int nb, int indir)
d.length = s->st_size;
if(d.mode&DMDIR)
d.length = 0;
+ else if(S_ISBLK(s->st_mode) && s->st_size == 0){
+ fd = open(path, O_RDONLY);
+ if(fd >= 0){
+ d.length = osdisksize(fd);
+ close(fd);
+ }
+ }
d.type = 'U';
d.dev = c->dev;
if(indir && sizeD2M(&d) > nb)
@@ -797,7 +816,7 @@ fsdirread(Chan *c, uchar *va, int count, vlong offset)
qunlock(&idl);
nexterror();
}
- r = fsdirconv(c, de->d_name, &st, slop, sizeof(slop), 1);
+ r = fsdirconv(c, path, de->d_name, &st, slop, sizeof(slop), 1);
poperror();
qunlock(&idl);
if(r <= 0) {
@@ -836,7 +855,7 @@ fsdirread(Chan *c, uchar *va, int count, vlong offset)
fprint(2, "dir: bad path %s\n", path);
continue;
}
- r = fsdirconv(c, de->d_name, &st, va+i, count-i, 1);
+ r = fsdirconv(c, path, de->d_name, &st, va+i, count-i, 1);
if(r <= 0){
FS(c)->de = de;
break;