diff --git a/kernel/Makefile b/kernel/Makefile index 9d09816e..4b50d3ff 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -125,6 +125,7 @@ memorymanagement.o \ mouse/ps2.o \ mtable.o \ net/fs.o \ +net/socket.o \ op-new.o \ panic.o \ partition.o \ diff --git a/kernel/include/sortix/kernel/syscall.h b/kernel/include/sortix/kernel/syscall.h index af04ebda..30ffd92a 100644 --- a/kernel/include/sortix/kernel/syscall.h +++ b/kernel/include/sortix/kernel/syscall.h @@ -158,6 +158,7 @@ int sys_sigaltstack(const stack_t*, stack_t*); int sys_sigpending(sigset_t*); int sys_sigprocmask(int, const sigset_t*, sigset_t*); int sys_sigsuspend(const sigset_t*); +int sys_socket(int, int, int); int sys_symlinkat(const char*, int, const char*); int sys_tcdrain(int); int sys_tcflow(int, int); diff --git a/kernel/include/sortix/syscall.h b/kernel/include/sortix/syscall.h index 02a06b18..2cd0b303 100644 --- a/kernel/include/sortix/syscall.h +++ b/kernel/include/sortix/syscall.h @@ -185,6 +185,7 @@ #define SYSCALL_SCRAM 162 #define SYSCALL_GETSID 163 #define SYSCALL_SETSID 164 -#define SYSCALL_MAX_NUM 165 /* index of highest constant + 1 */ +#define SYSCALL_SOCKET 165 +#define SYSCALL_MAX_NUM 166 /* index of highest constant + 1 */ #endif diff --git a/kernel/kernel.cpp b/kernel/kernel.cpp index 04bfab4b..ce44312a 100644 --- a/kernel/kernel.cpp +++ b/kernel/kernel.cpp @@ -581,8 +581,8 @@ static void BootThread(void* /*user*/) // Initialize the BGA driver. BGA::Init(); - // Initialize the filesystem network- - NetFS::Init("/dev", slashdev); + // Initialize the filesystem network. + NetFS::Init(); // // Stage 6. Executing Hosted Environment ("User-Space") diff --git a/kernel/net/fs.cpp b/kernel/net/fs.cpp index 661ef436..6e160186 100644 --- a/kernel/net/fs.cpp +++ b/kernel/net/fs.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014 Jonas 'Sortie' Termansen. + * Copyright (c) 2013, 2014, 2016 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -17,8 +17,6 @@ * Filesystem based socket interface. */ -// TODO: Should this be moved into user-space? - #include #include @@ -550,26 +548,22 @@ Ref Manager::open(ioctx_t* /*ctx*/, const char* filename, return errno = ENOENT, Ref(NULL); } -void Init(const char* devpath, Ref slashdev) +static Ref manager; + +void Init() { - ioctx_t ctx; SetupKernelIOCtx(&ctx); - Ref node(new Manager(0, 0, 0666)); - if ( !node ) - PanicF("Unable to allocate %s/net/fs inode.", devpath); - // TODO: Race condition! Create a mkdir function that returns what it - // created, possibly with a O_MKDIR flag to open. - if ( slashdev->mkdir(&ctx, "net", 0755) < 0 && errno != EEXIST ) - PanicF("Could not create a %s/net directory", devpath); - if ( slashdev->mkdir(&ctx, "net/fs", 0755) < 0 && errno != EEXIST ) - PanicF("Could not create a %s/net/fs directory", devpath); - Ref mpoint = slashdev->open(&ctx, "net/fs", O_READ | O_WRITE, 0); - if ( !mpoint ) - PanicF("Could not open the %s/net/fs directory", devpath); - Ref mtable = CurrentProcess()->GetMTable(); - // TODO: Make sure that the mount point is *empty*! Add a proper function - // for this on the file descriptor class! - if ( !mtable->AddMount(mpoint->ino, mpoint->dev, node, false) ) - PanicF("Unable to mount filesystem on %s/net/fs", devpath); + manager = Ref(new Manager(0, 0, 0600)); +} + +Ref Socket(int type, int protocol) +{ + if ( protocol != 0 ) + return errno = EPROTONOSUPPORT, Ref(NULL); + switch ( type ) + { + case SOCK_STREAM: return Ref(new StreamSocket(0, 0, 0600, manager)); + default: return errno = EPROTOTYPE, Ref(NULL); + } } } // namespace NetFS diff --git a/kernel/net/fs.h b/kernel/net/fs.h index b6df9e20..76bd5ae1 100644 --- a/kernel/net/fs.h +++ b/kernel/net/fs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Jonas 'Sortie' Termansen. + * Copyright (c) 2013, 2016 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -20,10 +20,13 @@ #ifndef SORTIX_NET_FS_H #define SORTIX_NET_FS_H +#include + namespace Sortix { namespace NetFS { -void Init(const char* devpath, Ref slashdev); +void Init(); +Ref Socket(int type, int protocol); } // namespace NetFS } // namespace Sortix diff --git a/kernel/net/socket.cpp b/kernel/net/socket.cpp new file mode 100644 index 00000000..6e971f74 --- /dev/null +++ b/kernel/net/socket.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016 Jonas 'Sortie' Termansen. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * net/socket.cpp + * Socket system calls. + */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "fs.h" + +namespace Sortix { + +static Ref CreateSocket(int domain, int type, int protocol) +{ + switch ( domain ) + { + case AF_UNIX: return NetFS::Socket(type, protocol); + default: return errno = EAFNOSUPPORT, Ref(NULL); + } +} + +int sys_socket(int domain, int type, int protocol) +{ + int dflags = O_READ | O_WRITE; + int fdflags = 0; + if ( type & SOCK_NONBLOCK ) dflags |= O_NONBLOCK; + if ( type & SOCK_CLOEXEC ) fdflags |= FD_CLOEXEC; + if ( type & SOCK_CLOFORK ) fdflags |= FD_CLOFORK; + type &= ~(SOCK_NONBLOCK | SOCK_CLOEXEC | SOCK_CLOFORK); + + Ref inode = CreateSocket(domain, type, protocol); + if ( !inode ) + return -1; + Ref vnode(new Vnode(inode, Ref(NULL), 0, 0)); + if ( !vnode ) + return -1; + inode.Reset(); + Ref desc(new Descriptor(vnode, dflags)); + if ( !desc ) + return -1; + vnode.Reset(); + + Process* process = CurrentProcess(); + Ref dtable = process->GetDTable(); + return dtable->Allocate(desc, fdflags); +} + +} // namespace Sortix diff --git a/kernel/syscall.cpp b/kernel/syscall.cpp index 1990b5d5..6b3cd800 100644 --- a/kernel/syscall.cpp +++ b/kernel/syscall.cpp @@ -199,6 +199,7 @@ void* syscall_list[SYSCALL_MAX_NUM + 1] = [SYSCALL_SCRAM] = (void*) sys_scram, [SYSCALL_GETSID] = (void*) sys_getsid, [SYSCALL_SETSID] = (void*) sys_setsid, + [SYSCALL_SOCKET] = (void*) sys_socket, [SYSCALL_MAX_NUM] = (void*) sys_bad_syscall, }; } /* extern "C" */ diff --git a/libc/sys/socket/socket.c b/libc/sys/socket/socket.c index f5ba722e..2bf8082d 100644 --- a/libc/sys/socket/socket.c +++ b/libc/sys/socket/socket.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Jonas 'Sortie' Termansen. + * Copyright (c) 2013, 2016 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,59 +14,15 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * sys/socket/socket.c - * Creates a new unconnected socket. + * Create a socket. */ #include +#include -#include -#include -#include - -static const char* get_socket_factory(int domain, int type, int protocol) -{ - if ( domain == AF_INET ) - { - if ( type == SOCK_DGRAM && !protocol ) - return "/dev/net/ipv4/udp"; - if ( type == SOCK_STREAM && !protocol ) - return "/dev/net/ipv4/tcp"; - return errno = EPROTONOSUPPORT, (const char*) NULL; - } - - if ( domain == AF_INET6 ) - { - if ( type == SOCK_DGRAM && !protocol ) - return "/dev/net/ipv6/udp"; - if ( type == SOCK_STREAM && !protocol ) - return "/dev/net/ipv6/tcp"; - return errno = EPROTONOSUPPORT, (const char*) NULL; - } - - if ( domain == AF_UNIX ) - { - if ( type == SOCK_DGRAM && !protocol ) - return "/dev/net/fs/datagram"; - if ( type == SOCK_STREAM && !protocol ) - return "/dev/net/fs/stream"; - return errno = EPROTONOSUPPORT, (const char*) NULL; - } - - return errno = EAFNOSUPPORT, (const char*) NULL; -} +DEFN_SYSCALL3(int, sys_socket, SYSCALL_SOCKET, int, int, int); int socket(int domain, int type, int protocol) { - int open_flags = O_RDWR; - if ( type & SOCK_NONBLOCK ) open_flags |= O_NONBLOCK; - if ( type & SOCK_CLOEXEC ) open_flags |= O_CLOEXEC; - if ( type & SOCK_CLOFORK ) open_flags |= O_CLOFORK; - type &= SOCK_TYPE_MASK; - const char* factory = get_socket_factory(domain, type, protocol); - if ( !factory ) - return -1; - int ret = open(factory, open_flags); - if ( ret < 0 && errno == ENOENT ) - errno = EPROTONOSUPPORT; - return ret; + return sys_socket(domain, type, protocol); } diff --git a/share/man/man7/following-development.7 b/share/man/man7/following-development.7 index 1e5aa7c2..575e26f6 100644 --- a/share/man/man7/following-development.7 +++ b/share/man/man7/following-development.7 @@ -59,6 +59,21 @@ releasing Sortix x.y, foo." to allow the maintainer to easily .Xr grep 1 for it after a release. .Sh CHANGES +.Ss Add socket(2) +The +.Pa /dev/net +virtual filesystem for socket creation has been removed in favor of adding an +actual +.Xr socket 2 +system call. +This is a major incompatible ABI change. +Only Unix sockets were exposed this way. +In the base system, +.Xr sf 1 +is the only program with Unix socket capabilities. +Ports using Unix sockets must be updated. +Otherwise the system is compatible except accessing Unix sockets fails with +.Er ENOENT . .Ss Add split packages and cross-bootstrapping support to tix-build(8) .Xr tix-build 8 has gained a number of features that will soon be required in order to build