Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <Kernel/Syscall.h>
28#include <errno.h>
29#include <getopt.h>
30#include <stdint.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <unistd.h>
35
36#if !defined __ENUMERATE_SYSCALL
37# define __ENUMERATE_SYSCALL(x) SC_##x,
38#endif
39#if !defined __ENUMERATE_REMOVED_SYSCALL
40# define __ENUMERATE_REMOVED_SYSCALL(x)
41#endif
42
43#define SC_NARG 4
44
45Syscall::Function syscall_table[] = {
46 ENUMERATE_SYSCALLS
47};
48
49FlatPtr arg[SC_NARG];
50char buf[BUFSIZ];
51
52FlatPtr parse(char* s);
53
54int main(int argc, char** argv)
55{
56 int oflag;
57 int opt;
58 while ((opt = getopt(argc, argv, "olh")) != -1) {
59 switch (opt) {
60 case 'o':
61 oflag = 1;
62 break;
63 case 'l':
64 for (auto sc : syscall_table) {
65 fprintf(stdout, "%s ", Syscall::to_string(sc));
66 }
67 return EXIT_SUCCESS;
68 case 'h':
69 fprintf(stderr, "usage: \tsyscall [-o] [-l] [-h] <syscall-name> <args...> [buf==BUFSIZ buffer]\n");
70 fprintf(stderr, "\tsyscall write 1 hello 5\n");
71 fprintf(stderr, "\tsyscall -o read 0 buf 5\n");
72 fprintf(stderr, "\tsyscall sleep 3\n");
73 break;
74 default:
75 exit(EXIT_FAILURE);
76 }
77 }
78
79 if (optind >= argc) {
80 fprintf(stderr, "No entry specified\n");
81 return -1;
82 }
83
84 for (int i = 0; i < argc - optind; i++) {
85 arg[i] = parse(argv[i + optind]);
86 }
87
88 for (auto sc : syscall_table) {
89 if (strcmp(Syscall::to_string(sc), (char*)arg[0]) == 0) {
90 int rc = syscall(sc, arg[1], arg[2], arg[3]);
91 if (rc == -1) {
92 perror("syscall");
93 } else {
94 if (oflag)
95 fwrite(buf, 1, sizeof(buf), stdout);
96 }
97
98 fprintf(stderr, "Syscall return: %d\n", rc);
99 return 0;
100 }
101 }
102
103 fprintf(stderr, "Invalid syscall entry %s\n", (char*)arg[0]);
104 return -1;
105}
106
107FlatPtr parse(char* s)
108{
109 char* t;
110 FlatPtr l;
111
112 if (strcmp(s, "buf") == 0) {
113 return (FlatPtr)buf;
114 }
115
116 l = strtoul(s, &t, 0);
117 if (t > s && *t == 0) {
118 return l;
119 }
120
121 return (FlatPtr)s;
122}