diff options
Diffstat (limited to 'libdiskfs/file-get-trans.c')
-rw-r--r-- | libdiskfs/file-get-trans.c | 42 |
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; |