summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcpplover0 <osdev555@yandex.com>2025-09-16 17:26:11 +0300
committercpplover0 <osdev555@yandex.com>2025-09-16 17:26:11 +0300
commitb6ee6d53de8519b095a9d8aa85f19ab901425368 (patch)
tree6bee181eac10fe36abacf1705e3435698ad04d2d
parent88cd9cd28419c8982f689b8568b7a074b1101856 (diff)
unix pipes bug fix
-rw-r--r--kernel/include/generic/vfs/vfs.hpp3
-rw-r--r--kernel/src/arch/x86_64/interrupts/panic.cpp9
-rw-r--r--kernel/src/arch/x86_64/syscalls/file.cpp41
-rw-r--r--tools/pkg/2/socket_test/info.txt1
-rw-r--r--tools/pkg/2/socket_test/pkg.sh5
-rw-r--r--tools/pkg/2/socket_test/src/client.c76
-rw-r--r--tools/pkg/2/socket_test/src/server.c92
7 files changed, 40 insertions, 187 deletions
diff --git a/kernel/include/generic/vfs/vfs.hpp b/kernel/include/generic/vfs/vfs.hpp
index 143891a..3332296 100644
--- a/kernel/include/generic/vfs/vfs.hpp
+++ b/kernel/include/generic/vfs/vfs.hpp
@@ -136,7 +136,7 @@ namespace vfs {
if(side == PIPE_SIDE_WRITE) {
this->connected_to_pipe_write--;
- if(this->connected_to_pipe_write == 0) {
+ if(this->connected_to_pipe_write <= 1) {
this->is_received.clear();
this->is_closed.test_and_set();
}
@@ -224,6 +224,7 @@ typedef struct {
typedef struct userspace_fd {
std::uint64_t offset;
+ std::uint64_t flags;
std::int32_t index;
std::uint8_t state;
std::uint8_t pipe_side;
diff --git a/kernel/src/arch/x86_64/interrupts/panic.cpp b/kernel/src/arch/x86_64/interrupts/panic.cpp
index 7ad0664..c43dc66 100644
--- a/kernel/src/arch/x86_64/interrupts/panic.cpp
+++ b/kernel/src/arch/x86_64/interrupts/panic.cpp
@@ -39,15 +39,6 @@ void panic(int_frame_t* ctx, const char* msg) {
asm volatile("mov %%cr2, %0" : "=r"(cr2) : : "memory");
Log::Display(LEVEL_MESSAGE_FAIL,"Got exception \"%s\" with rip 0x%p, vec %d, cr2 0x%p and error code 0x%p \n",msg,ctx->rip,ctx->vec,cr2,ctx->err_code);
- stackframe_t* rbp = (stackframe_t*)ctx->rbp;
-
- Log::Display(LEVEL_MESSAGE_INFO,"Back Trace\n");
- for(unsigned int frame = 0; rbp && frame < 10; ++frame)
- {
- Log::Display(LEVEL_MESSAGE_INFO,"Address #%d: 0x%p\n",frame,rbp->rip);
- rbp = rbp->rbp;
- }
-
asm volatile("hlt");
}
diff --git a/kernel/src/arch/x86_64/syscalls/file.cpp b/kernel/src/arch/x86_64/syscalls/file.cpp
index 1ae35d7..3f06dca 100644
--- a/kernel/src/arch/x86_64/syscalls/file.cpp
+++ b/kernel/src/arch/x86_64/syscalls/file.cpp
@@ -237,7 +237,14 @@ syscall_ret_t sys_stat(int fd, void* out) {
return {0,status,0};
copy_in_userspace(proc,out,&stat,sizeof(vfs::stat_t));
} else {
- return {0,ENOENT,0};
+ vfs::stat_t stat;
+ memset(&stat,0,sizeof(vfs::stat_t));
+ if(fd_s->state == USERSPACE_FD_STATE_SOCKET)
+ stat.st_mode |= S_IFSOCK;
+ else if(fd_s->state == USERSPACE_FD_STATE_PIPE)
+ stat.st_mode |= S_IFIFO;
+ copy_in_userspace(proc,out,&stat,sizeof(vfs::stat_t));
+ return {0,0,0};
}
return {0,0,0};
}
@@ -249,6 +256,7 @@ syscall_ret_t sys_pipe(int flags) {
userspace_fd_t* fd1 = vfs::fdmanager::search(proc,read_fd);
userspace_fd_t* fd2 = vfs::fdmanager::search(proc,write_fd);
+ Log::SerialDisplay(LEVEL_MESSAGE_INFO,"sys_pipe flags 0x%p\n",flags);
vfs::pipe* new_pipe = new vfs::pipe(flags);
fd1->pipe_side = PIPE_SIDE_READ;
fd2->pipe_side = PIPE_SIDE_WRITE;
@@ -290,7 +298,7 @@ syscall_ret_t sys_dup2(int fd, int flags, int newfd) {
userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd);
- Log::SerialDisplay(LEVEL_MESSAGE_INFO,"dup2 from %d to %d\n",fd,newfd);
+ Log::SerialDisplay(LEVEL_MESSAGE_INFO,"dup2 from %d to %d in proc %d with flags 0x%p\n",fd,newfd,proc->id,flags);
if(!fd_s)
return {0,EBADF,0};
@@ -502,13 +510,40 @@ syscall_ret_t sys_read_dir(int fd, void* buffer) {
}
syscall_ret_t sys_fcntl(int fd, int request, std::uint64_t arg) {
+ Log::SerialDisplay(LEVEL_MESSAGE_INFO,"fcntl %d\n",request);
switch(request) {
case F_DUPFD: {
return sys_dup(fd,arg);
}
+ case F_GETFL: {
+ arch::x86_64::process_t* proc = CURRENT_PROC;
+ userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd);
+ if(!fd_s)
+ return {0,EBADF,0};
+
+ return {1,0,(std::int64_t)(fd_s->flags | (fd_s->state == USERSPACE_FD_STATE_PIPE ? fd_s->pipe->flags : 0))};
+ }
+
+ case F_SETFL: {
+ arch::x86_64::process_t* proc = CURRENT_PROC;
+ userspace_fd_t* fd_s = vfs::fdmanager::search(proc,fd);
+ if(!fd_s)
+ return {0,EBADF,0};
+
+ fd_s->flags &= ~(O_APPEND | O_ASYNC | O_NONBLOCK);
+ fd_s->flags |= (arg & (O_APPEND | O_ASYNC | O_NONBLOCK));
+
+ if(fd_s->state == USERSPACE_FD_STATE_PIPE) {
+ fd_s->pipe->flags & ~(O_NONBLOCK);
+ fd_s->pipe->flags |= (arg & O_NONBLOCK);
+ }
+
+ return {1,0,0};
+ }
+
default: {
- return {0,ENOSYS,0};
+ return {0,0,0};
}
}
return {0,ENOSYS,0};
diff --git a/tools/pkg/2/socket_test/info.txt b/tools/pkg/2/socket_test/info.txt
deleted file mode 100644
index 50309c7..0000000
--- a/tools/pkg/2/socket_test/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-socket_test \ No newline at end of file
diff --git a/tools/pkg/2/socket_test/pkg.sh b/tools/pkg/2/socket_test/pkg.sh
deleted file mode 100644
index 34b8e60..0000000
--- a/tools/pkg/2/socket_test/pkg.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-
-mkdir -p "$1/etc/drivers/"
-
-x86_64-orange-gcc -o "$1/etc/drivers/socket_test.sys" src/server.c
-x86_64-orange-gcc -o "$1/usr/bin/socket_test" src/client.c \ No newline at end of file
diff --git a/tools/pkg/2/socket_test/src/client.c b/tools/pkg/2/socket_test/src/client.c
deleted file mode 100644
index 59920cb..0000000
--- a/tools/pkg/2/socket_test/src/client.c
+++ /dev/null
@@ -1,76 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/types.h>
-
-#include <string.h>
-
-static const char* socket_path = "/home/mysocket";
-static const unsigned int s_recv_len = 200;
-static const unsigned int s_send_len = 100;
-
-int main()
-{
- int sock = 0;
- int data_len = 0;
- struct sockaddr_un remote;
- char recv_msg[s_recv_len];
- char send_msg[s_send_len];
-
- memset(recv_msg, 0, s_recv_len*sizeof(char));
- memset(send_msg, 0, s_send_len*sizeof(char));
-
- if( (sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 )
- {
- printf("Client: Error on socket() call \n");
- return 1;
- }
-
- remote.sun_family = AF_UNIX;
- strcpy( remote.sun_path, socket_path );
- data_len = strlen(remote.sun_path) + sizeof(remote.sun_family);
-
- printf("Client: Trying to connect... \n");
- if( connect(sock, (struct sockaddr*)&remote, data_len) == -1 )
- {
- printf("Client: Error on connect call \n");
- return 1;
- }
-
- printf("Client: Connected \n");
-
- while( write(STDOUT_FILENO,">",1), fgets(send_msg, s_send_len, stdin), !feof(stdin))
- {
- if( send(sock, send_msg, strlen(send_msg)*sizeof(char), 0 ) == -1 )
- {
- printf("Client: Error on send() call \n");
- }
- memset(send_msg, 0, s_send_len*sizeof(char));
- memset(recv_msg, 0, s_recv_len*sizeof(char));
-
- if( (data_len = recv(sock, recv_msg, s_recv_len, 0)) > 0 )
- {
- printf("Client: Data received: %s\n", recv_msg);
- }
- else
- {
- if(data_len < 0)
- {
- printf("Client: Error on recv() call \n");
- }
- else
- {
- printf("Client: Server socket closed \n");
- close(sock);
- break;
- }
-
- }
- }
-
- printf("Client: bye! \n");
-
- return 0;
-} \ No newline at end of file
diff --git a/tools/pkg/2/socket_test/src/server.c b/tools/pkg/2/socket_test/src/server.c
deleted file mode 100644
index 1ef16a5..0000000
--- a/tools/pkg/2/socket_test/src/server.c
+++ /dev/null
@@ -1,92 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/types.h>
-
-#include <string.h>
-
-static const char* socket_path = "/home/mysocket";
-static const unsigned int nIncomingConnections = 5;
-
-int main()
-{
- //create server side
- int s = 0;
- int s2 = 0;
- struct sockaddr_un local, remote;
- int len = 0;
-
- s = socket(AF_UNIX, SOCK_STREAM, 0);
- if( -1 == s )
- {
- printf("Error on socket() call \n");
- return 1;
- }
-
- local.sun_family = AF_UNIX;
- strcpy( local.sun_path, socket_path );
- unlink(local.sun_path);
- len = strlen(local.sun_path) + sizeof(local.sun_family);
- if( bind(s, (struct sockaddr*)&local, len) != 0)
- {
- printf("Error on binding socket \n");
- return 1;
- }
-
- if( listen(s, nIncomingConnections) != 0 )
- {
- printf("Error on listen call \n");
- }
-
- char bWaiting = 1;
- while (bWaiting)
- {
- unsigned int sock_len = 0;
- printf("Waiting for connection.... \n");
- if( (s2 = accept(s, (struct sockaddr*)&remote, &sock_len)) == -1 )
- {
- printf("Error on accept() call \n");
- return 1;
- }
-
- printf("Server connected \n");
-
- int data_recv = 0;
- char recv_buf[100];
- char send_buf[200];
- do{
- memset(recv_buf, 0, 100*sizeof(char));
- memset(send_buf, 0, 200*sizeof(char));
- data_recv = recv(s2, recv_buf, 100, 0);
- if(data_recv > 0)
- {
- printf("Data received: %d : %s ", data_recv, recv_buf);
- strcpy(send_buf, "Got message: ");
- strcat(send_buf, recv_buf);
-
- if(strstr(recv_buf, "quit")!=0)
- {
- printf("Exit command received -> quitting \n");
- bWaiting = 0;
- break;
- }
-
- if( send(s2, send_buf, strlen(send_buf)*sizeof(char), 0) == -1 )
- {
- printf("Error on send() call \n");
- }
- }
- else
- {
- printf("Error on recv() call \n");
- }
- }while(data_recv > 0);
-
- close(s2);
- }
-
-
- return 0;
-}