Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150053235
D3097.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D3097.diff
View Options
Index: head/sys/compat/cloudabi/cloudabi_file.c
===================================================================
--- head/sys/compat/cloudabi/cloudabi_file.c
+++ head/sys/compat/cloudabi/cloudabi_file.c
@@ -28,11 +28,67 @@
#include <sys/param.h>
#include <sys/fcntl.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/namei.h>
#include <sys/syscallsubr.h>
#include <compat/cloudabi/cloudabi_proto.h>
#include <compat/cloudabi/cloudabi_syscalldefs.h>
+static MALLOC_DEFINE(M_CLOUDABI_PATH, "cloudabipath", "CloudABI pathnames");
+
+/*
+ * Copying pathnames from userspace to kernelspace.
+ *
+ * Unlike most operating systems, CloudABI doesn't use null-terminated
+ * pathname strings. Processes always pass pathnames to the kernel by
+ * providing a base pointer and a length. This has a couple of reasons:
+ *
+ * - It makes it easier to use CloudABI in combination with programming
+ * languages other than C, that may use non-null terminated strings.
+ * - It allows for calling system calls on individual components of the
+ * pathname without modifying the input string.
+ *
+ * The function below copies in pathname strings and null-terminates it.
+ * It also ensure that the string itself does not contain any null
+ * bytes.
+ *
+ * TODO(ed): Add an abstraction to vfs_lookup.c that allows us to pass
+ * in unterminated pathname strings, so we can do away with
+ * the copying.
+ */
+
+static int
+copyin_path(const char *uaddr, size_t len, char **result)
+{
+ char *buf;
+ int error;
+
+ if (len >= PATH_MAX)
+ return (ENAMETOOLONG);
+ buf = malloc(len + 1, M_CLOUDABI_PATH, M_WAITOK);
+ error = copyin(uaddr, buf, len);
+ if (error != 0) {
+ free(buf, M_CLOUDABI_PATH);
+ return (error);
+ }
+ if (memchr(buf, '\0', len) != NULL) {
+ free(buf, M_CLOUDABI_PATH);
+ return (EINVAL);
+ }
+ buf[len] = '\0';
+ *result = buf;
+ return (0);
+}
+
+static void
+cloudabi_freestr(char *buf)
+{
+
+ free(buf, M_CLOUDABI_PATH);
+}
+
int
cloudabi_sys_file_advise(struct thread *td,
struct cloudabi_sys_file_advise_args *uap)
@@ -86,9 +142,24 @@
cloudabi_sys_file_link(struct thread *td,
struct cloudabi_sys_file_link_args *uap)
{
+ char *path1, *path2;
+ int error;
- /* Not implemented. */
- return (ENOSYS);
+ error = copyin_path(uap->path1, uap->path1len, &path1);
+ if (error != 0)
+ return (error);
+ error = copyin_path(uap->path2, uap->path2len, &path2);
+ if (error != 0) {
+ cloudabi_freestr(path1);
+ return (error);
+ }
+
+ error = kern_linkat(td, uap->fd1, uap->fd2, path1, path2,
+ UIO_SYSSPACE, (uap->fd1 & CLOUDABI_LOOKUP_SYMLINK_FOLLOW) != 0 ?
+ FOLLOW : NOFOLLOW);
+ cloudabi_freestr(path1);
+ cloudabi_freestr(path2);
+ return (error);
}
int
@@ -113,18 +184,40 @@
cloudabi_sys_file_readlink(struct thread *td,
struct cloudabi_sys_file_readlink_args *uap)
{
+ char *path;
+ int error;
- /* Not implemented. */
- return (ENOSYS);
+ error = copyin_path(uap->path, uap->pathlen, &path);
+ if (error != 0)
+ return (error);
+
+ error = kern_readlinkat(td, uap->fd, path, UIO_SYSSPACE,
+ uap->buf, UIO_USERSPACE, uap->bufsize);
+ cloudabi_freestr(path);
+ return (error);
}
int
cloudabi_sys_file_rename(struct thread *td,
struct cloudabi_sys_file_rename_args *uap)
{
+ char *old, *new;
+ int error;
- /* Not implemented. */
- return (ENOSYS);
+ error = copyin_path(uap->old, uap->oldlen, &old);
+ if (error != 0)
+ return (error);
+ error = copyin_path(uap->new, uap->newlen, &new);
+ if (error != 0) {
+ cloudabi_freestr(old);
+ return (error);
+ }
+
+ error = kern_renameat(td, uap->oldfd, old, uap->newfd, new,
+ UIO_SYSSPACE);
+ cloudabi_freestr(old);
+ cloudabi_freestr(new);
+ return (error);
}
int
@@ -167,16 +260,39 @@
cloudabi_sys_file_symlink(struct thread *td,
struct cloudabi_sys_file_symlink_args *uap)
{
+ char *path1, *path2;
+ int error;
- /* Not implemented. */
- return (ENOSYS);
+ error = copyin_path(uap->path1, uap->path1len, &path1);
+ if (error != 0)
+ return (error);
+ error = copyin_path(uap->path2, uap->path2len, &path2);
+ if (error != 0) {
+ cloudabi_freestr(path1);
+ return (error);
+ }
+
+ error = kern_symlinkat(td, path1, uap->fd, path2, UIO_SYSSPACE);
+ cloudabi_freestr(path1);
+ cloudabi_freestr(path2);
+ return (error);
}
int
cloudabi_sys_file_unlink(struct thread *td,
struct cloudabi_sys_file_unlink_args *uap)
{
+ char *path;
+ int error;
- /* Not implemented. */
- return (ENOSYS);
+ error = copyin_path(uap->path, uap->pathlen, &path);
+ if (error != 0)
+ return (error);
+
+ if (uap->flag & CLOUDABI_UNLINK_REMOVEDIR)
+ error = kern_rmdirat(td, uap->fd, path, UIO_SYSSPACE);
+ else
+ error = kern_unlinkat(td, uap->fd, path, UIO_SYSSPACE, 0);
+ cloudabi_freestr(path);
+ return (error);
}
Index: head/sys/compat/cloudabi/cloudabi_sock.c
===================================================================
--- head/sys/compat/cloudabi/cloudabi_sock.c
+++ head/sys/compat/cloudabi/cloudabi_sock.c
@@ -26,12 +26,38 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/param.h>
#include <sys/socket.h>
+#include <sys/syscallsubr.h>
#include <sys/sysproto.h>
+#include <sys/systm.h>
+#include <sys/un.h>
#include <compat/cloudabi/cloudabi_proto.h>
#include <compat/cloudabi/cloudabi_syscalldefs.h>
+/* Copies a pathname into a UNIX socket address structure. */
+static int
+copyin_sockaddr_un(const char *path, size_t pathlen, struct sockaddr_un *sun)
+{
+ int error;
+
+ /* Copy in pathname string if there's enough space. */
+ if (pathlen >= sizeof(sun->sun_path))
+ return (ENAMETOOLONG);
+ error = copyin(path, &sun->sun_path, pathlen);
+ if (error != 0)
+ return (error);
+ if (memchr(sun->sun_path, '\0', pathlen) != NULL)
+ return (EINVAL);
+
+ /* Initialize the rest of the socket address. */
+ sun->sun_path[pathlen] = '\0';
+ sun->sun_family = AF_UNIX;
+ sun->sun_len = sizeof(*sun);
+ return (0);
+}
+
int
cloudabi_sys_sock_accept(struct thread *td,
struct cloudabi_sys_sock_accept_args *uap)
@@ -45,18 +71,26 @@
cloudabi_sys_sock_bind(struct thread *td,
struct cloudabi_sys_sock_bind_args *uap)
{
+ struct sockaddr_un sun;
+ int error;
- /* Not implemented. */
- return (ENOSYS);
+ error = copyin_sockaddr_un(uap->path, uap->pathlen, &sun);
+ if (error != 0)
+ return (error);
+ return (kern_bindat(td, uap->fd, uap->s, (struct sockaddr *)&sun));
}
int
cloudabi_sys_sock_connect(struct thread *td,
struct cloudabi_sys_sock_connect_args *uap)
{
+ struct sockaddr_un sun;
+ int error;
- /* Not implemented. */
- return (ENOSYS);
+ error = copyin_sockaddr_un(uap->path, uap->pathlen, &sun);
+ if (error != 0)
+ return (error);
+ return (kern_connectat(td, uap->fd, uap->s, (struct sockaddr *)&sun));
}
int
Index: head/sys/compat/cloudabi/cloudabi_syscalldefs.h
===================================================================
--- head/sys/compat/cloudabi/cloudabi_syscalldefs.h
+++ head/sys/compat/cloudabi/cloudabi_syscalldefs.h
@@ -29,6 +29,7 @@
#define _CLOUDABI_SYSCALLDEFS_H_
#include <sys/types.h>
+#include <sys/stdint.h>
#define alignas _Alignas
#define alignof _Alignof
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Mar 30, 12:52 AM (19 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30564355
Default Alt Text
D3097.diff (7 KB)
Attached To
Mode
D3097: Implement the basic system calls that operate on pathnames.
Attached
Detach File
Event Timeline
Log In to Comment