Skip to content

Commit d175143

Browse files
authored
Merge pull request #207 from smartobjectoriented/206-add-writev-syscall
Add 'writev' & 'readv' syscall
2 parents 5044652 + 0c97a7f commit d175143

File tree

12 files changed

+107
-27
lines changed

12 files changed

+107
-27
lines changed

.github/workflows/style.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ on:
1010
push:
1111
branches: ["main"]
1212
pull_request:
13-
branches: ["main"]
13+
branches: ["main", "144-support-musl"]
1414

1515
jobs:
1616
formatting-check:

so3/arch/arm32/include/asm/syscall_number.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,7 @@
7878
#define SYSCALL_SETSOCKOPT 110
7979
#define SYSCALL_RECVFROM 111
8080

81+
#define SYSCALL_READV 145
82+
#define SYSCALL_WRITEV 146
83+
8184
#endif /* ARCH_ARM32_SYSCALL_NUMBER_H */

so3/arch/arm64/include/asm/syscall_number.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@
7171
#define SYSCALL_MUTEX_LOCK 60
7272
#define SYSCALL_MUTEX_UNLOCK 61
7373

74+
#define SYSCALL_READV 65
75+
#define SYSCALL_WRITEV 66
76+
7477
#define SYSCALL_NANOSLEEP 70
7578

7679
#define SYSCALL_SYSINFO 99

so3/devices/serial/pl011.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ static irq_return_t pl011_int(int irq, void *dummy)
119119

120120
#ifdef CONFIG_IPC_SIGNAL
121121
if (current()->pcb != NULL)
122-
do_kill(current()->pcb->pid, SIGINT);
122+
sys_do_kill(current()->pcb->pid, SIGINT);
123123
#endif
124124
}
125125

so3/fs/elf.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ uint8_t *elf_load_buffer(const char *filename)
3535
struct stat st;
3636

3737
/* open and read file */
38-
fd = do_open(filename, O_RDONLY);
38+
fd = sys_do_open(filename, O_RDONLY);
3939

4040
if (fd < 0)
4141
return NULL;
4242

43-
if (do_stat(filename, &st))
43+
if (sys_do_stat(filename, &st))
4444
return NULL;
4545

4646
if (!st.st_size)
@@ -52,9 +52,9 @@ uint8_t *elf_load_buffer(const char *filename)
5252
return NULL;
5353
}
5454

55-
do_read(fd, buffer, st.st_size);
55+
sys_do_read(fd, buffer, st.st_size);
5656

57-
do_close(fd);
57+
sys_do_close(fd);
5858

5959
return buffer;
6060
}

so3/fs/vfs.c

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,8 @@ int vfs_clone_fd(int *fd_src, int *fd_dst)
380380

381381
/**************************** Syscall implementation ****************************/
382382

383-
SYSCALL_DEFINE3(read, int, fd, void *, buffer, int, count)
383+
/* Low Level read */
384+
static int do_read(int fd, void *buffer, int count)
384385
{
385386
int gfd;
386387
int ret;
@@ -421,10 +422,8 @@ SYSCALL_DEFINE3(read, int, fd, void *, buffer, int, count)
421422
return ret;
422423
}
423424

424-
/**
425-
* @brief This function writes a REGULAR FILE/FOLDER. It only support regular file, dirs and pipes
426-
*/
427-
SYSCALL_DEFINE3(write, int, fd, const void *, buffer, int, count)
425+
/* Low Level write */
426+
static int do_write(int fd, const void *buffer, int count)
428427
{
429428
int gfd;
430429
int ret;
@@ -464,6 +463,19 @@ SYSCALL_DEFINE3(write, int, fd, const void *, buffer, int, count)
464463
return ret;
465464
}
466465

466+
SYSCALL_DEFINE3(read, int, fd, void *, buffer, int, count)
467+
{
468+
return do_read(fd, buffer, count);
469+
}
470+
471+
/**
472+
* @brief This function writes a REGULAR FILE/FOLDER. It only support regular file, dirs and pipes
473+
*/
474+
SYSCALL_DEFINE3(write, int, fd, const void *, buffer, int, count)
475+
{
476+
return do_write(fd, buffer, count);
477+
}
478+
467479
/**
468480
* @brief This function opens a file. Not all file types are supported.
469481
*/
@@ -655,7 +667,7 @@ SYSCALL_DEFINE2(dup2, int, oldfd, int, newfd)
655667
}
656668

657669
if (vfs_get_gfd(oldfd) != vfs_get_gfd(newfd))
658-
do_close(newfd);
670+
sys_do_close(newfd);
659671

660672
vfs_link_fd(newfd, vfs_get_gfd(oldfd));
661673

@@ -824,6 +836,57 @@ SYSCALL_DEFINE3(fcntl, int, fd, unsigned long, cmd, unsigned long, args)
824836
return 0;
825837
}
826838

839+
/*
840+
* Implementation of the writev syscall
841+
*/
842+
SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec *, vec, unsigned long, vlen)
843+
{
844+
int i;
845+
int ret = 0;
846+
int total = 0;
847+
848+
for (i = 0; i < vlen; i++) {
849+
ret = do_write(fd, (const void *) vec[i].iov_base, vec[i].iov_len);
850+
if (ret < 0) {
851+
break;
852+
} else if ((ret >= 0) && (ret < vec[i].iov_len)) {
853+
total += ret;
854+
break;
855+
}
856+
857+
total += ret;
858+
}
859+
860+
if (total == 0)
861+
return ret;
862+
else
863+
return total;
864+
}
865+
866+
SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec *, vec, unsigned long, vlen)
867+
{
868+
int i;
869+
int ret = 0;
870+
int total = 0;
871+
872+
for (i = 0; i < vlen; i++) {
873+
ret = do_read(fd, vec[i].iov_base, vec[i].iov_len);
874+
if (ret < 0) {
875+
break;
876+
} else if ((ret >= 0) && (ret < vec[i].iov_len)) {
877+
total += ret;
878+
break;
879+
}
880+
881+
total += ret;
882+
}
883+
884+
if (total == 0)
885+
return ret;
886+
else
887+
return total;
888+
}
889+
827890
static void vfs_gfd_init(void)
828891
{
829892
memset(open_fds, 0, MAX_FDS * sizeof(struct fd *));

so3/include/syscall.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -84,33 +84,33 @@
8484
* __sys_SYSCALL_NAME taking syscall_args_t as arguments allowing for
8585
* a common interface between all syscall to put them in an array.
8686
*
87-
* do_SYSCALL_NAME actual function with the syscall implementation with
87+
* sys_do_SYSCALL_NAME actual function with the syscall implementation with
8888
* arguments define like a normal function. That function is automatically
8989
* called by __sys_SYCALL_NAME with the correct argument number and cast.
9090
*/
9191
#define SYSCALL_DECLARE(name, ...) \
9292
long __sys_##name(syscall_args_t *args); \
93-
inline long do_##name(__VA_ARGS__);
93+
inline long sys_do_##name(__VA_ARGS__);
9494

9595
#define SYSCALL_DEFINE0(name) \
9696
long __sys_##name(syscall_args_t *unused) \
9797
{ \
98-
return do_##name(); \
98+
return sys_do_##name(); \
9999
} \
100-
inline long do_##name(void)
100+
inline long sys_do_##name(void)
101101
#define SYSCALL_DEFINE1(...) __SYSCALL_DEFINEx(1, __VA_ARGS__)
102102
#define SYSCALL_DEFINE2(...) __SYSCALL_DEFINEx(2, __VA_ARGS__)
103103
#define SYSCALL_DEFINE3(...) __SYSCALL_DEFINEx(3, __VA_ARGS__)
104104
#define SYSCALL_DEFINE4(...) __SYSCALL_DEFINEx(4, __VA_ARGS__)
105105
#define SYSCALL_DEFINE5(...) __SYSCALL_DEFINEx(5, __VA_ARGS__)
106106
#define SYSCALL_DEFINE6(...) __SYSCALL_DEFINEx(6, __VA_ARGS__)
107107

108-
#define __SYSCALL_DEFINEx(x, name, ...) \
109-
long __sys_##name(syscall_args_t *args) \
110-
{ \
111-
return do_##name(__MAP_ARGS(x, args->args, __VA_ARGS__)); \
112-
} \
113-
inline long do_##name(__MAP(x, __M_DECL, __VA_ARGS__))
108+
#define __SYSCALL_DEFINEx(x, name, ...) \
109+
long __sys_##name(syscall_args_t *args) \
110+
{ \
111+
return sys_do_##name(__MAP_ARGS(x, args->args, __VA_ARGS__)); \
112+
} \
113+
inline long sys_do_##name(__MAP(x, __M_DECL, __VA_ARGS__))
114114

115115
typedef struct {
116116
unsigned long args[6];

so3/include/vfs.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@
103103

104104
#include <device/device.h>
105105

106+
struct iovec {
107+
void *iov_base;
108+
size_t iov_len;
109+
};
110+
111+
#define iovec iovec
112+
106113
struct file_operations {
107114
int (*open)(int fd, const char *path);
108115
int (*close)(int fd);
@@ -162,6 +169,8 @@ SYSCALL_DECLARE(mmap, addr_t start, size_t length, int prot, int fd, off_t offse
162169
SYSCALL_DECLARE(ioctl, int fd, unsigned long cmd, unsigned long args);
163170
SYSCALL_DECLARE(fcntl, int fd, unsigned long cmd, unsigned long args);
164171
SYSCALL_DECLARE(lseek, int fd, off_t off, int whence);
172+
SYSCALL_DECLARE(writev, unsigned long fd, const struct iovec *vec, unsigned long vlen);
173+
SYSCALL_DECLARE(readv, unsigned long fd, const struct iovec *vec, unsigned long vlen);
165174

166175
/* VFS common interface */
167176

so3/kernel/process.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,7 @@ SYSCALL_DEFINE1(exit, int, exit_status)
925925
* locking in the low layers. */
926926

927927
for (i = 0; i < FD_MAX; i++)
928-
do_close(i);
928+
sys_do_close(i);
929929

930930
local_irq_disable();
931931

@@ -944,7 +944,7 @@ SYSCALL_DEFINE1(exit, int, exit_status)
944944
#ifdef CONFIG_IPC_SIGNAL
945945

946946
/* Send the SIGCHLD signal to the parent */
947-
do_kill(pcb->parent->pid, SIGCHLD);
947+
sys_do_kill(pcb->parent->pid, SIGCHLD);
948948

949949
#endif /* CONFIG_IPC_SIGNAL */
950950

so3/kernel/syscalls.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ static const syscall_fn_t syscall_table[NR_SYSCALLS] = {
6060
[SYSCALL_IOCTL] = __sys_ioctl,
6161
[SYSCALL_FCNTL] = __sys_fcntl,
6262
[SYSCALL_LSEEK] = __sys_lseek,
63+
[SYSCALL_READV] = __sys_readv,
64+
[SYSCALL_WRITEV] = __sys_writev,
6365
#ifdef CONFIG_IPC_PIPE
6466
[SYSCALL_PIPE] = __sys_pipe,
6567
#endif

0 commit comments

Comments
 (0)