aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/mach/hurd/dl-sysdep.c86
1 files changed, 68 insertions, 18 deletions
diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c
index b8ca7332e7..bc90e33a7e 100644
--- a/sysdeps/mach/hurd/dl-sysdep.c
+++ b/sysdeps/mach/hurd/dl-sysdep.c
@@ -34,6 +34,7 @@ Cambridge, MA 02139, USA. */
#include <hurd/term.h>
#include <stdarg.h>
#include <ctype.h>
+#include <sys/stat.h>
#include "dl-machine.h"
@@ -264,8 +265,11 @@ _dl_sysdep_message (const char *msg, ...)
dynamic linker re-relocates itself to be user-visible (for -ldl),
it will get the user's definition (i.e. usually libc's). */
-int weak_function
-__open (const char *file_name, int mode, ...)
+/* Open FILE_NAME and return a read-mmapable port in MEMOBJ_RD for it, or
+ return an error. If STAT is non-zero, stat the file into that stat buffer. */
+static error_t
+open_file (const char *file_name, int mode,
+ mach_port_t *memobj_rd, struct stat *stat)
{
enum retry_type doretry;
char retryname[1024]; /* XXX string_t LOSES! */
@@ -282,9 +286,9 @@ __open (const char *file_name, int mode, ...)
while (file_name[0] == '/')
file_name++;
- if (err = __dir_lookup (startdir, file_name, mode, 0,
+ if (err = __dir_lookup (startdir, (char *)file_name, mode, 0,
&doretry, retryname, &fileport))
- return __hurd_fail (err);
+ return err;
dealloc_dir = 0;
nloops = 0;
@@ -294,7 +298,7 @@ __open (const char *file_name, int mode, ...)
if (dealloc_dir)
__mach_port_deallocate (__mach_task_self (), startdir);
if (err)
- return __hurd_fail (err);
+ return err;
switch (doretry)
{
@@ -311,34 +315,40 @@ __open (const char *file_name, int mode, ...)
}
__mach_port_deallocate (__mach_task_self (), fileport);
if (err)
- return __hurd_fail (err);
+ return err;
fileport = newpt;
/* Fall through. */
case FS_RETRY_NORMAL:
#ifdef SYMLOOP_MAX
if (nloops++ >= SYMLOOP_MAX)
- return __hurd_fail (ELOOP);
+ return ELOOP;
#endif
/* An empty RETRYNAME indicates we have the final port. */
if (retryname[0] == '\0')
{
- mach_port_t memobj_rd, memobj_wr;
+ mach_port_t memobj_wr;
dealloc_dir = 1;
opened:
/* We have the file open. Now map it. */
- err = __io_map (fileport, &memobj_rd, &memobj_wr);
+
+ if (stat)
+ err = __io_stat (fileport, stat);
+ if (! err)
+ err = __io_map (fileport, memobj_rd, &memobj_wr);
+
if (dealloc_dir)
__mach_port_deallocate (__mach_task_self (), fileport);
if (err)
- return __hurd_fail (err);
+ return err;
+
if (memobj_wr != MACH_PORT_NULL)
__mach_port_deallocate (__mach_task_self (), memobj_wr);
- return (int) memobj_rd;
+ return 0;
}
startdir = fileport;
@@ -371,13 +381,13 @@ __open (const char *file_name, int mode, ...)
valid; it ends the component. Anything else does not
name a numeric file descriptor. */
if (*p != '/' && *p != '\0')
- return __hurd_fail (ENOENT);
+ return ENOENT;
if (fd < 0 || fd >= _dl_hurd_data->dtablesize ||
_dl_hurd_data->dtable[fd] == MACH_PORT_NULL)
/* If the name was a proper number, but the file
descriptor does not exist, we return EBADF instead
of ENOENT. */
- return __hurd_fail (EBADF);
+ return EBADF;
fileport = _dl_hurd_data->dtable[fd];
if (*p == '\0')
{
@@ -458,12 +468,12 @@ __open (const char *file_name, int mode, ...)
case '\0':
if (err = opentty (&fileport))
- return __hurd_fail (err);
+ return err;
dealloc_dir = 1;
goto opened;
case '/':
if (err = opentty (&startdir))
- return __hurd_fail (err);
+ return err;
dealloc_dir = 1;
strcpy (retryname, &retryname[4]);
break;
@@ -476,20 +486,31 @@ __open (const char *file_name, int mode, ...)
default:
bad_magic:
- return __hurd_fail (EGRATUITOUS);
+ return EGRATUITOUS;
}
break;
default:
- return __hurd_fail (EGRATUITOUS);
+ return EGRATUITOUS;
}
- err = __dir_lookup (startdir, file_name, mode, 0,
+ err = __dir_lookup (startdir, (char *)file_name, mode, 0,
&doretry, retryname, &fileport);
}
}
int weak_function
+__open (const char *file_name, int mode, ...)
+{
+ mach_port_t memobj_rd;
+ error_t err = open_file (file_name, mode, &memobj_rd, 0);
+ if (err)
+ return __hurd_fail (err);
+ else
+ return (int)memobj_rd;
+}
+
+int weak_function
__close (int fd)
{
if (fd != (int) MACH_PORT_NULL)
@@ -549,7 +570,36 @@ _exit (int status)
__mach_task_self_ = (__mach_task_self) ();
}
+/* Read the whole contents of FILE into new mmap'd space with given
+ protections. The size of the file is returned in SIZE. */
+void *
+_dl_sysdep_read_whole_file (const char *file, size_t *size, int prot)
+{
+ struct stat stat;
+ mach_port_t memobj_rd;
+ void *contents;
+ error_t err = open_file (file, O_RDONLY, &memobj_rd, &stat);
+
+ if (! err)
+ {
+ /* Map a copy of the file contents. */
+ contents = __mmap (0, stat.st_size, prot, MAP_COPY, memobj_rd, 0);
+ if (contents == (void *)-1)
+ contents = 0;
+ else
+ *size = stat.st_size;
+ __mach_port_deallocate (__mach_task_self (), memobj_rd);
+ }
+ else
+ {
+ __hurd_fail (err);
+ contents = 0;
+ }
+
+ return contents;
+}
+
/* This function is called by interruptible RPC stubs. For initial
dynamic linking, just use the normal mach_msg. Since this defn is
weak, the real defn in libc.so will override it if we are linked into