Serenity Operating System
at portability 122 lines 3.6 kB view raw
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 49uintptr_t arg[SC_NARG]; 50char buf[BUFSIZ]; 51 52uintptr_t 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 107uintptr_t parse(char* s) 108{ 109 char* t; 110 uintptr_t l; 111 112 if (strcmp(s, "buf") == 0) { 113 return (uintptr_t)buf; 114 } 115 116 l = strtoul(s, &t, 0); 117 if (t > s && *t == 0) { 118 return l; 119 } 120 121 return (uintptr_t)s; 122}