diff options
author | Miles Bader <miles@gnu.org> | 1997-02-21 21:55:32 +0000 |
---|---|---|
committer | Miles Bader <miles@gnu.org> | 1997-02-21 21:55:32 +0000 |
commit | 37e138a0b010037798144653c56c7e151bd40554 (patch) | |
tree | 1c2f0ac64f18eeb55b779debb355c3ea7cfe82a9 /libdiskfs | |
parent | 7c9b2ac22c2dd7e8f499da50aed7640b3af5defd (diff) |
(diskfs_S_io_read):
Support reading from sylinks.
Diffstat (limited to 'libdiskfs')
-rw-r--r-- | libdiskfs/io-read.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/libdiskfs/io-read.c b/libdiskfs/io-read.c index 78ccf064..80c103d8 100644 --- a/libdiskfs/io-read.c +++ b/libdiskfs/io-read.c @@ -67,15 +67,38 @@ diskfs_S_io_read (struct protid *cred, buf = *data; *datalen = maxread; - if (maxread) + + if (maxread == 0) + err = 0; + else if (S_ISLNK (np->dn_stat.st_mode)) + /* Read from a symlink. */ + if (! diskfs_read_symlink_hook) + err = EINVAL; + else + { + if (off == 0 && maxread == np->dn_stat.st_size) + err = (*diskfs_read_symlink_hook)(np, buf); + else + { + char *whole_link = alloca (np->dn_stat.st_size); + err = (*diskfs_read_symlink_hook)(np, whole_link); + if (! err) + memcpy (buf, whole_link + off, maxread); + } + } + else + err = EINVAL; /* Use read below. */ + + if (err == EINVAL) err = _diskfs_rdwr_internal (np, buf, off, datalen, 0, cred->po->openstat & O_NOATIME); - else - err = 0; + if (diskfs_synchronous) diskfs_node_update (np, 1); /* atime! */ + if (offset == -1 && !err) cred->po->filepointer += *datalen; + if (err && ourbuf) vm_deallocate (mach_task_self (), (u_int) buf, maxread); |