summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjdike <jdike>2003-12-16 16:22:26 +0000
committerjdike <jdike>2003-12-16 16:22:26 +0000
commitc9d8c123fdca02c3d20587050e27fc3fd70741bd (patch)
tree05b1393b5cf352dd046247bea10c99b6d8555549
parent347ab1686e44a845d7472d3c53494b5f3d1a4a60 (diff)
downloaduml-history-c9d8c123fdca02c3d20587050e27fc3fd70741bd.tar.gz
os_{read,write}_file now make sure their buffers are present before calling
{read,write} on the host.
-rw-r--r--arch/um/os-Linux/file.c64
1 files changed, 36 insertions, 28 deletions
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index eabdf9a..1b9924e 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -312,20 +312,37 @@ int os_seek_file(int fd, __u64 offset)
return(0);
}
-int os_read_file(int fd, void *buf, int len)
+static int fault_buffer(void *start, int len,
+ int (*copy_proc)(void *addr, void *buf, int len))
{
- int n;
+ int page = getpagesize(), i;
+ char c;
- /* Force buf into memory if it's not already. */
+ for(i = 0; i < len; i += page){
+ if((*copy_proc)(start + i, &c, sizeof(c)))
+ return(-EFAULT);
+ }
+ if((len % page) != 0){
+ if((*copy_proc)(start + len - 1, &c, sizeof(c)))
+ return(-EFAULT);
+ }
+ return(0);
+}
- /* XXX This fails if buf is kernel memory */
-#ifdef notdef
- if(copy_to_user_proc(buf, &c, sizeof(c)))
- return(-EFAULT);
-#endif
+static int file_io(int fd, void *buf, int len,
+ int (*io_proc)(int fd, void *buf, int len),
+ int (*copy_user_proc)(void *addr, void *buf, int len))
+{
+ int n, err;
do {
- n = read(fd, buf, len);
+ n = (*io_proc)(fd, buf, len);
+ if((n < 0) && (errno == EFAULT)){
+ err = fault_buffer(buf, len, copy_user_proc);
+ if(err)
+ return(err);
+ n = (*io_proc)(fd, buf, len);
+ }
} while((n < 0) && (errno == EINTR));
if(n < 0)
@@ -333,25 +350,16 @@ int os_read_file(int fd, void *buf, int len)
return(n);
}
-int os_write_file(int fd, const void *buf, int count)
+int os_read_file(int fd, void *buf, int len)
{
- int n;
-
- /* Force buf into memory if it's not already. */
-
- /* XXX This fails if buf is kernel memory */
-#ifdef notdef
- if(copy_to_user_proc(buf, buf, buf[0]))
- return(-EFAULT);
-#endif
-
- do {
- n = write(fd, buf, count);
- } while((n < 0) && (errno == EINTR));
+ return(file_io(fd, buf, len, (int (*)(int, void *, int)) read,
+ copy_from_user_proc));
+}
- if(n < 0)
- return(-errno);
- return(n);
+int os_write_file(int fd, const void *buf, int len)
+{
+ return(file_io(fd, (void *) buf, len,
+ (int (*)(int, void *, int)) write, copy_to_user_proc));
}
int os_file_size(char *file, long long *size_out)
@@ -610,8 +618,8 @@ int os_create_unix_socket(char *file, int len, int close_on_exec)
err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
if (err < 0){
- printk("create_listening_socket - bind failed, errno = %d\n",
- errno);
+ printk("create_listening_socket at '%s' - bind failed, "
+ "errno = %d\n", file, errno);
return(-errno);
}