aboutsummaryrefslogtreecommitdiff
path: root/libdiskfs/file-get-trans.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdiskfs/file-get-trans.c')
-rw-r--r--libdiskfs/file-get-trans.c42
1 files changed, 22 insertions, 20 deletions
diff --git a/libdiskfs/file-get-trans.c b/libdiskfs/file-get-trans.c
index abb9e9e7..e77dba82 100644
--- a/libdiskfs/file-get-trans.c
+++ b/libdiskfs/file-get-trans.c
@@ -1,5 +1,5 @@
/* libdiskfs implementation of fs.defs: file_get_translator
- Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation
+ Copyright (C) 1992,93,94,95,96,98,99,2002 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -25,14 +25,14 @@
kern_return_t
diskfs_S_file_get_translator (struct protid *cred,
char **trans,
- u_int *translen)
+ size_t *translen)
{
struct node *np;
error_t error = 0;
-
+
if (!cred)
return EOPNOTSUPP;
-
+
np = cred->po->np;
mutex_lock (&np->lock);
@@ -41,14 +41,14 @@ diskfs_S_file_get_translator (struct protid *cred,
if (S_ISLNK (np->dn_stat.st_mode))
{
unsigned int len = sizeof _HURD_SYMLINK + np->dn_stat.st_size + 1;
- int amt;
+ size_t amt;
assert (diskfs_shortcut_symlink);
- if (len > *translen)
- vm_allocate (mach_task_self (), (vm_address_t *)trans, len, 1);
+ if (len > *translen)
+ *trans = mmap (0, len, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
bcopy (_HURD_SYMLINK, *trans, sizeof _HURD_SYMLINK);
if (diskfs_read_symlink_hook)
- error = (*diskfs_read_symlink_hook) (np,
+ error = (*diskfs_read_symlink_hook) (np,
*trans + sizeof _HURD_SYMLINK);
if (!diskfs_read_symlink_hook || error == EINVAL)
{
@@ -62,6 +62,8 @@ diskfs_S_file_get_translator (struct protid *cred,
(*trans)[sizeof _HURD_SYMLINK + np->dn_stat.st_size] = '\0';
*translen = len;
}
+ else if (len > *translen)
+ munmap (trans, len);
}
else if (S_ISCHR (np->dn_stat.st_mode) || S_ISBLK (np->dn_stat.st_mode))
{
@@ -73,27 +75,28 @@ diskfs_S_file_get_translator (struct protid *cred,
else
assert (diskfs_shortcut_blkdev);
- buflen = asprintf (&buf, "%s%c%d%c%d",
- (S_ISCHR (np->dn_stat.st_mode)
+ buflen = asprintf (&buf, "%s%c%d%c%d",
+ (S_ISCHR (np->dn_stat.st_mode)
? _HURD_CHRDEV
: _HURD_BLKDEV),
'\0', (np->dn_stat.st_rdev >> 8) & 0377,
'\0', (np->dn_stat.st_rdev) & 0377);
buflen++; /* terminating nul */
-
+
if (buflen > *translen)
- vm_allocate (mach_task_self (), (vm_address_t *) trans, buflen, 1);
+ *trans = mmap (0, buflen, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
bcopy (buf, *trans, buflen);
+ free (buf);
*translen = buflen;
error = 0;
}
else if (S_ISFIFO (np->dn_stat.st_mode))
{
unsigned int len;
-
+
len = sizeof _HURD_FIFO;
if (len > *translen)
- vm_allocate (mach_task_self (), (vm_address_t *) trans, len, 1);
+ *trans = mmap (0, len, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
bcopy (_HURD_FIFO, *trans, sizeof _HURD_FIFO);
*translen = len;
error = 0;
@@ -101,17 +104,17 @@ diskfs_S_file_get_translator (struct protid *cred,
else if (S_ISSOCK (np->dn_stat.st_mode))
{
unsigned int len;
-
+
len = sizeof _HURD_IFSOCK;
if (len > *translen)
- vm_allocate (mach_task_self (), (vm_address_t *) trans, len, 1);
+ *trans = mmap (0, len, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
bcopy (_HURD_IFSOCK, *trans, sizeof _HURD_IFSOCK);
*translen = len;
error = 0;
}
else
{
- if (!np->istranslated)
+ if (! (np->dn_stat.st_mode & S_IPTRANS))
error = EINVAL;
else
{
@@ -121,15 +124,14 @@ diskfs_S_file_get_translator (struct protid *cred,
if (!error)
{
if (len > *translen)
- vm_allocate (mach_task_self (), (vm_address_t *) trans,
- len, 1);
+ *trans = mmap (0, len, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0);
bcopy (string, *trans, len);
*translen = len;
free (string);
}
}
}
-
+
mutex_unlock (&np->lock);
return error;