1 /* 2 * A test of executing code in a new task. 3 * 4 * Copyright (C) 2022, 2023 Paul Boddie <paul@boddie.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA 20 */ 21 22 #include <l4/re/env.h> 23 #include <l4/sys/err.h> 24 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 29 #include <fsclient/client.h> 30 #include <systypes/env.h> 31 #include <systypes/fcntl.h> 32 33 34 35 /* Read a line from the file. */ 36 37 static int readline(file_t *file, int *lineno, char **start, char **end) 38 { 39 static char buf[256]; 40 static offset_t current = 0, limit = 0; 41 char *newline = NULL; 42 43 do 44 { 45 /* Obtain file content. */ 46 47 if (!limit) 48 { 49 limit = client_read(file, buf, 256); 50 51 if (!limit) 52 { 53 *start = NULL; 54 *end = NULL; 55 return 0; 56 } 57 58 current = 0; 59 60 /* Start of line at start of buffer. */ 61 62 if (newline != NULL) 63 { 64 current += 1; 65 *start = buf; 66 *end = (char *) memchr(buf + current, (int) '\n', limit - current); 67 68 if (*end == NULL) 69 *end = buf + limit; 70 71 return 1; 72 } 73 } 74 75 /* Find newline. */ 76 77 newline = (char *) memchr(buf + current, (int) '\n', limit - current); 78 79 if (newline != NULL) 80 { 81 (*lineno)++; 82 current = newline - (char *) buf + 1; 83 84 /* Start of line before end of buffer. */ 85 86 if (current < limit) 87 { 88 *start = newline + 1; 89 *end = (char *) memchr(buf + current, (int) '\n', limit - current); 90 91 if (*end == NULL) 92 *end = buf + limit; 93 94 return 1; 95 } 96 97 /* Otherwise, reset the buffer to read the start of line. */ 98 99 else 100 limit = 0; 101 } 102 103 /* No newline: read more data. */ 104 105 else 106 limit = 0; 107 } 108 while (1); 109 } 110 111 112 113 int main(int argc, char *argv[]) 114 { 115 file_t *file; 116 int i, lineno; 117 char *start, *end; 118 119 printf("Hello from %s (%d)!\n", argc > 0 ? argv[0] : "exec_payload.c", argc); 120 121 for (i = 0; i < argc; i++) 122 printf("Arg #%d: %s\n", i, argv[i]); 123 124 if (argc < 2) 125 return 1; 126 127 printf("Filesystem is %lx\n", l4re_env_get_cap(ENV_FILESYSTEM_SERVER_NAME)); 128 printf("Opening file %s...\n", argv[1]); 129 130 file = client_open(argv[1], O_RDONLY); 131 132 if (!client_opened(file)) 133 { 134 if (file != NULL) 135 printf("Error: %s\n", l4sys_errtostr(file->error)); 136 else 137 printf("Could not open file.\n"); 138 139 while (1); 140 } 141 142 lineno = atoi(argv[2]); 143 144 printf("Finding line %d...\n", lineno); 145 146 i = 1; 147 while (i < lineno) 148 if (!readline(file, &i, &start, &end)) 149 break; 150 151 printf("Showing line %d...\n", lineno); 152 153 while (i == lineno) 154 { 155 fwrite(start, sizeof(char), end - start, stdout); 156 if (!readline(file, &i, &start, &end)) 157 break; 158 } 159 160 fputs("\n\n", stdout); 161 162 printf("Closing file...\n"); 163 164 client_close(file); 165 client_notifier_close(client_notifier_task()); 166 167 printf("Terminating.\n"); 168 return 0; 169 } 170 171 /* vim: tabstop=2 expandtab shiftwidth=2 172 */