summaryrefslogtreecommitdiff
path: root/src/sys/os
diff options
context:
space:
mode:
Diffstat (limited to 'src/sys/os')
-rw-r--r--src/sys/os/os_filedes.c88
-rw-r--r--src/sys/os/os_iotap.c3
-rw-r--r--src/sys/os/os_kalloc.c11
-rw-r--r--src/sys/os/os_null.c2
-rw-r--r--src/sys/os/os_proc.c8
-rw-r--r--src/sys/os/os_socket.c256
-rw-r--r--src/sys/os/os_ucred.c90
-rw-r--r--src/sys/os/vfs_init.c3
-rw-r--r--src/sys/os/vfs_namei.c75
-rw-r--r--src/sys/os/vfs_subr.c43
10 files changed, 541 insertions, 38 deletions
diff --git a/src/sys/os/os_filedes.c b/src/sys/os/os_filedes.c
index 95452af..3eaee0d 100644
--- a/src/sys/os/os_filedes.c
+++ b/src/sys/os/os_filedes.c
@@ -44,16 +44,9 @@
#define STDOUT_FILENO 1
/*
- * Allocate a file descriptor from a specific process's
- * file descriptor table
- *
- * @procp: Process to allocate fd from
- * @fd_res: Result pointer is written here
- *
- * Returns zero on success, otherwise a less than
- * zero value upon failure
+ * Allocate a file descriptor
*/
-static int
+int
fd_alloc(struct proc *procp, struct filedesc **fd_res)
{
struct filedesc *fd;
@@ -91,16 +84,9 @@ fd_alloc(struct proc *procp, struct filedesc **fd_res)
}
/*
- * Look up a file descriptor that belongs to a specific
- * process by using its fd number
- *
- * @procp: Process to look up
- * @fd: File descriptor number
- *
- * Returns the file descriptor pointer on success,
- * otherwise a less than zero value on failure
+ * Get a file descriptor
*/
-static struct filedesc *
+struct filedesc *
fd_get(struct proc *procp, int fd)
{
struct filedesc *fdp;
@@ -160,8 +146,10 @@ fd_open(const char *path, mode_t mode)
{
struct filedesc *fd;
struct nameidata nd;
+ struct vop_create_args creat_args;
struct proc *self = proc_self();
struct vnode *vp;
+ uint32_t namei_flags = 0;
int error;
/* We need the current proc */
@@ -180,12 +168,21 @@ fd_open(const char *path, mode_t mode)
}
/*
+ * If we are creating a new file, we'll need to
+ * get the parent vnode so that we can use the
+ * create vop.
+ */
+ if (ISSET(mode, O_CREAT)) {
+ namei_flags |= NAMEI_CREATE;
+ }
+
+ /*
* Now we try to do the lookup, we'll need
* the vnode for file references to be
* useful
*/
nd.path = path;
- nd.flags = 0;
+ nd.flags = namei_flags;
nd.vp_res = &vp;
error = namei(&nd);
if (error < 0) {
@@ -348,6 +345,44 @@ read(int fd, void *buf, size_t count)
return retval;
}
+off_t
+lseek(int fd, off_t offset, int whence)
+{
+ struct filedesc *fdp;
+ struct proc *self = proc_self();
+ struct vattr attr;
+ int error;
+
+ if (fd < 0) {
+ return -EBADF;
+ }
+
+ fdp = fd_get(self, fd);
+ if (fdp == NULL) {
+ return -EBADF;
+ }
+
+ /* Could not get vnode attributes */
+ error = vop_getattr(fdp->vp, &attr);
+ if (error < 0) {
+ return 0;
+ }
+
+ switch (whence) {
+ case SEEK_SET:
+ fdp->off = offset;
+ break;
+ case SEEK_CUR:
+ fdp->off += offset;
+ break;
+ case SEEK_END:
+ fdp->off = attr.size;
+ break;
+ }
+
+ return fdp->off;
+}
+
/*
* ARG0: Path
* ARG1: Mode
@@ -367,3 +402,18 @@ sys_open(struct syscall_args *scargs)
return fd_open(pathbuf, mode);
}
+
+/*
+ * ARG0: Fd
+ * ARG1: Offset
+ * ARG2: Whence
+ */
+scret_t
+sys_lseek(struct syscall_args *scargs)
+{
+ int fd = SCARG(scargs, int, 0);
+ off_t off = SCARG(scargs, off_t, 1);
+ int whence = SCARG(scargs, int, 2);
+
+ return lseek(fd, off, whence);
+}
diff --git a/src/sys/os/os_iotap.c b/src/sys/os/os_iotap.c
index 238acfe..54d1157 100644
--- a/src/sys/os/os_iotap.c
+++ b/src/sys/os/os_iotap.c
@@ -130,6 +130,9 @@ iotap_mux(const char *name, struct iotap_msg *msg)
ops = desc.ops;
switch (msg->opcode) {
case IOTAP_OPC_READ:
+ if (ops->read == NULL) {
+ return -ENOTSUP;
+ }
return ops->read(&desc, msg->buf, msg->len);
}
diff --git a/src/sys/os/os_kalloc.c b/src/sys/os/os_kalloc.c
index 53e2e13..a5e48e5 100644
--- a/src/sys/os/os_kalloc.c
+++ b/src/sys/os/os_kalloc.c
@@ -64,6 +64,17 @@ kalloc(size_t sz)
return tmp;
}
+void *
+krealloc(void *old_ptr, size_t newsize)
+{
+ void *tmp;
+
+ spinlock_acquire(&lock);
+ tmp = tlsf_realloc(tlsf_ctx, old_ptr, newsize);
+ spinlock_release(&lock);
+ return tmp;
+}
+
/*
* Memory deallocation
*/
diff --git a/src/sys/os/os_null.c b/src/sys/os/os_null.c
index e142c6f..ae0fcf4 100644
--- a/src/sys/os/os_null.c
+++ b/src/sys/os/os_null.c
@@ -41,7 +41,7 @@ static ssize_t
null_read(struct devfs_node *dnp, struct dev_iobuf *io, int flags)
{
/* We give you a whole lot of nothing! */
- return io->count;
+ return 0;
}
/*
diff --git a/src/sys/os/os_proc.c b/src/sys/os/os_proc.c
index a8f49d7..ef6c04c 100644
--- a/src/sys/os/os_proc.c
+++ b/src/sys/os/os_proc.c
@@ -40,6 +40,7 @@
#include <os/systm.h>
#include <vm/vm.h>
#include <vm/physseg.h>
+#include <os/ucred.h>
#include <os/elfload.h>
#include <os/signal.h>
#include <os/kalloc.h>
@@ -386,9 +387,14 @@ proc_spawn(const char *path, struct penv_blk *envbp)
proc->envblk = envbp;
proc->parent = proc_self();
+ error = ucred_init(proc->parent, &proc->cred);
+ if (error < 0) {
+ kfree(proc);
+ return error;
+ }
+
md_set_ip(proc, elf.entrypoint);
sched_enq(&core->scq, proc);
-
TAILQ_INSERT_TAIL(&procq, proc, lup_link);
return proc->pid;
}
diff --git a/src/sys/os/os_socket.c b/src/sys/os/os_socket.c
new file mode 100644
index 0000000..a37d15f
--- /dev/null
+++ b/src/sys/os/os_socket.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2025 Ian Marco Moffett and L5 engineers
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/socket.h>
+#include <sys/mount.h>
+#include <sys/syslog.h>
+#include <sys/errno.h>
+#include <sys/proc.h>
+#include <os/vnode.h>
+#include <os/kalloc.h>
+#include <os/filedesc.h>
+#include <string.h>
+
+static size_t next_sockid = 1;
+
+/*
+ * Allocate a socket file descriptor
+ *
+ * @fdp_res: Result is written here
+ *
+ * XXX: Socket vnodes are never deallocated until explicitly
+ * closed
+ *
+ * Returns file descriptor on success, otherwise a
+ * less than zero value on faulure
+ */
+static int
+get_sock_fd(struct filedesc **fdp_res)
+{
+ char namebuf[256];
+ struct ksocket *sock;
+ struct mount *mp;
+ struct nameidata nd;
+ struct filedesc *fdp;
+ struct proc *self = proc_self();
+ struct vnode *vp;
+ int error;
+
+ if (fdp_res == NULL) {
+ return -EINVAL;
+ }
+
+ if (self == NULL) {
+ return -EIO;
+ }
+
+ error = mount_lookup("/tmp", &mp);
+ if (error < 0) {
+ printf("socket: could not get /tmp mountpoint\n");
+ return error;
+ }
+
+ error = fd_alloc(self, &fdp);
+ if (error < 0) {
+ printf("socket: could not allocate fd\n");
+ return error;
+ }
+
+ sock = kalloc(sizeof(*sock));
+ if (sock == NULL) {
+ fd_close(fdp->fdno);
+ return -EINVAL;
+ }
+
+ /* Format the name */
+ snprintf(
+ namebuf,
+ sizeof(namebuf),
+ "sock.%d",
+ next_sockid++
+ );
+
+ /* Allocate a persistent vnode */
+ error = vfs_valloc(&vp, VTYPE_SOCK, 0);
+ if (error < 0) {
+ printf("socket: could not allocate vnode\n");
+ fd_close(fdp->fdno);
+ kfree(sock);
+ return error;
+ }
+
+ /* Create the backing file */
+ nd.path = namebuf;
+ error = vop_create(mp->vp, &nd, VTYPE_SOCK);
+ if (error < 0) {
+ printf("socket: failed to create /tmp entry\n");
+ fd_close(fdp->fdno);
+ kfree(sock);
+ return error;
+ }
+
+ /* Mark the socket as inactive */
+ memset(sock, 0, sizeof(*sock));
+ sock->backlog = -1;
+
+ fdp->vp = vp;
+ vp->data = sock;
+ printf("socket: socket created @ /tmp/%s\n", namebuf);
+ return fdp->fdno;
+}
+
+/*
+ * Get a socket descriptor from a fd
+ *
+ * @fd: File descriptor to look up
+ * @sock_res: Result pointer is written here
+ *
+ * Returns zero on success, otherwise a less
+ * than zero value on failure
+ */
+static int
+get_sock(int fd, struct ksocket **sock_res)
+{
+ struct filedesc *fdp;
+ struct proc *self = proc_self();
+ struct vnode *vp;
+
+ if (fd < 0) {
+ return -EBADF;
+ }
+
+ if (sock_res == NULL) {
+ return -1;
+ }
+
+ if (self == NULL) {
+ return -EINVAL;
+ }
+
+ /* Get the file descriptor */
+ fdp = fd_get(
+ self,
+ fd
+ );
+
+ if (fdp == NULL) {
+ return -EBADF;
+ }
+
+ /* We need the vnode */
+ if ((vp = fdp->vp) == NULL) {
+ return -EIO;
+ }
+
+ *sock_res = vp->data;
+ return 0;
+}
+
+/*
+ * Any backlog value > 0 marks the socket
+ * as accepting connections
+ */
+int
+listen(int socket, int backlog)
+{
+ struct ksocket *ksock = NULL;
+ int error;
+
+ if (socket < 0) {
+ return -EBADF;
+ }
+
+ if (backlog < 0) {
+ backlog = 0;
+ }
+
+ error = get_sock(socket, &ksock);
+ if (error < 0) {
+ printf("listen: failed to get socket descriptor\n");
+ return error;
+ }
+
+ /* Set the backlog */
+ ksock->backlog = backlog;
+ return 0;
+}
+
+/*
+ * Handles the AF_UNIX domain
+ */
+static int
+af_unix(int type, int protocol)
+{
+ struct filedesc *desc;
+
+ return get_sock_fd(&desc);
+}
+
+int
+socket(int domain, int type, int protocol)
+{
+ if (domain < 0 || type < 0) {
+ return -EINVAL;
+ }
+
+ switch (domain) {
+ case AF_UNIX:
+ return af_unix(type, protocol);
+ }
+
+ return -1;
+}
+
+/*
+ * ARG0: Domain
+ * ARG1: Type
+ * ARG2: Protocol
+ */
+scret_t
+sys_socket(struct syscall_args *scargs)
+{
+ int domain = SCARG(scargs, int, 0);
+ int type = SCARG(scargs, int, 1);
+ int protocol = SCARG(scargs, int, 2);
+
+ return socket(domain, type, protocol);
+}
+
+/*
+ * ARG0: Socket fd
+ * @backlog: Maximum connections
+ */
+scret_t
+sys_listen(struct syscall_args *scargs)
+{
+ int sockfd = SCARG(scargs, int, 0);
+ int backlog = SCARG(scargs, int, 1);
+
+ return listen(sockfd, backlog);
+}
diff --git a/src/sys/os/os_ucred.c b/src/sys/os/os_ucred.c
new file mode 100644
index 0000000..bf46308
--- /dev/null
+++ b/src/sys/os/os_ucred.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2025 Ian Marco Moffett and L5 engineers
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <sys/errno.h>
+#include <os/ucred.h>
+#include <os/ucred.h>
+
+int
+ucred_init(struct proc *proc, struct ucred *cred)
+{
+ struct ucred *curcred;
+
+ if (cred == NULL) {
+ return -EINVAL;
+ }
+
+ if (proc != NULL) {
+ curcred = &proc->cred;
+ cred->ruid = curcred->ruid;
+ } else {
+ cred->ruid = 0;
+ }
+
+ cred->euid = cred->ruid;
+ cred->suid = cred->ruid;
+ return 0;
+}
+
+int
+seteuid(uid_t euid)
+{
+ struct proc *self = proc_self();
+ struct ucred *cred;
+ int retval = -EPERM;
+
+ if (__unlikely(self == NULL)) {
+ return -ESRCH;
+ }
+
+ /* Verify against current creds */
+ cred = &self->cred;
+ if (euid == cred->euid || euid == cred->ruid) {
+ cred->euid = euid;
+ retval = 0;
+ } else if (euid == cred->suid || cred->euid == 0) {
+ cred->euid = euid;
+ retval = 0;
+ }
+
+ return retval;
+}
+
+/*
+ * ARG0: EUID
+ */
+scret_t
+sys_seteuid(struct syscall_args *scargs)
+{
+ uid_t euid = SCARG(scargs, int, 0);
+
+ return seteuid(euid);
+}
diff --git a/src/sys/os/vfs_init.c b/src/sys/os/vfs_init.c
index 80d8559..1b6f815 100644
--- a/src/sys/os/vfs_init.c
+++ b/src/sys/os/vfs_init.c
@@ -39,7 +39,8 @@
*/
static struct fs_info fstab[] = {
{ MOUNT_INITRD, &g_omar_vfsops, 0 },
- { MOUNT_DEVFS, &g_devfs_vfops, 0 }
+ { MOUNT_DEVFS, &g_devfs_vfsops, 0 },
+ { MOUNT_TMPFS, &g_tmpfs_vfsops, 0 }
};
/*
diff --git a/src/sys/os/vfs_namei.c b/src/sys/os/vfs_namei.c
index 1425c30..013c0ea 100644
--- a/src/sys/os/vfs_namei.c
+++ b/src/sys/os/vfs_namei.c
@@ -46,10 +46,13 @@ namei(struct nameidata *ndp)
struct vnode *vp;
struct vop *vops;
struct vop_lookup_args lookup;
+ struct vop_create_args create;
+ struct nameidata nd_create;
struct fs_info *fip;
char namebuf[NAME_MAX];
+ size_t root_len;
const char *p, *pcur;
- size_t len, i = 0;
+ size_t i = 0;
int error;
if (ndp == NULL) {
@@ -61,23 +64,35 @@ namei(struct nameidata *ndp)
return -EINVAL;
}
- error = mount_lookup("/", &mp);
+ /* Get rid of leading slashes */
+ pcur = p;
+ while (*pcur == '/') {
+ ++pcur;
+ }
+
+ /* Wait until we get the '/' */
+ while (*pcur != '/' && *pcur != '\0') {
+ ++pcur;
+ }
+
+ /* Copy the root path e.g., /tmp */
+ root_len = (size_t)(pcur - p);
+ memcpy(namebuf, p, root_len);
+ error = mount_lookup(namebuf, &mp);
+
if (error < 0) {
- printf("namei: failed to get rootfs\n");
+ error = mount_lookup("/", &mp);
+ }
+ if (error < 0) {
+ printf("namei: could not get mount %s\n", namebuf);
return error;
}
- vp = mp->vp;
fip = mp->fs;
-
- if ((vops = vp->vops) == NULL) {
- printf("namei: failed to get vops\n");
+ if ((vp = mp->vp) == NULL) {
return -EIO;
}
-
- /* We need vops->lookup() */
- if (vops->lookup == NULL) {
- printf("namei: vops does not have lookup op\n");
+ if ((vops = vp->vops) == NULL) {
return -EIO;
}
@@ -99,12 +114,11 @@ namei(struct nameidata *ndp)
if (error == 0) {
return 0;
}
+
+ return -ENOENT;
}
- printf("namei: f: %s\n", ndp->path);
- printf("namei: d: /\n", ndp->path);
- pcur = p;
while (*pcur != '\0') {
/* Get out of the slashes */
while (*pcur == '/')
@@ -123,7 +137,36 @@ namei(struct nameidata *ndp)
}
i = 0;
- printf("namei: n %s\n", namebuf);
+
+ /* Get the vops */
+ vp = mp->vp;
+ if ((vops = vp->vops) == NULL) {
+ return -EIO;
+ }
+
+ /* Create as we go? */
+ if (ISSET(ndp->flags, NAMEI_CREATE)) {
+ if (vops->create == NULL)
+ return -EIO;
+
+ nd_create.path = namebuf;
+ create.ndp = &nd_create;
+ create.vtype = VTYPE_FILE;
+ error = vops->create(&create);
+ if (error < 0)
+ return error;
+ }
+
+ /* Do the lookup */
+ lookup.dirvp = vp;
+ lookup.vpp = &vp;
+ lookup.name = namebuf;
+ error = vops->lookup(&lookup);
+ if (error < 0) {
+ return -ENOENT;
+ }
}
- return -ENOENT;
+
+ *ndp->vp_res = vp;
+ return 0;
}
diff --git a/src/sys/os/vfs_subr.c b/src/sys/os/vfs_subr.c
index 6cb7767..0e8c605 100644
--- a/src/sys/os/vfs_subr.c
+++ b/src/sys/os/vfs_subr.c
@@ -224,3 +224,46 @@ vop_reclaim(struct vnode *vp, int flags)
return vops->reclaim(vp, flags);
}
+
+int
+vop_create(struct vnode *vp, struct nameidata *ndp, vtype_t type)
+{
+ struct vop *vops;
+ struct vop_create_args args;
+
+ if (vp == NULL || ndp == NULL) {
+ return -EINVAL;
+ }
+
+ if ((vops = vp->vops) == NULL) {
+ return -EIO;
+ }
+
+ if (vops->create == NULL) {
+ return -EIO;
+ }
+
+ args.ndp = ndp;
+ args.vtype = type;
+ return vops->create(&args);
+}
+
+int
+vop_getattr(struct vnode *vp, struct vattr *res)
+{
+ struct vop *vops;
+
+ if (vp == NULL || res == NULL) {
+ return -EINVAL;
+ }
+
+ if ((vops = vp->vops) == NULL) {
+ return -EIO;
+ }
+
+ if (vops->getattr == NULL) {
+ return -EIO;
+ }
+
+ return vops->getattr(vp, res);
+}