Changeset 5fb32c5 in mainline
- Timestamp:
- 2011-08-20T09:05:14Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c916dfc
- Parents:
- 921b84f (diff), a0fc4be (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 24 edited
Legend:
- Unmodified
- Added
- Removed
-
HelenOS.config
r921b84f r5fb32c5 70 70 @ "pentium4" Pentium 4 71 71 @ "pentium3" Pentium 3 72 @ "i486" i48673 72 @ "core" Core Solo/Duo 74 73 @ "athlon_xp" Athlon XP 75 74 @ "athlon_mp" Athlon MP 75 @ "i486" i486 76 76 ! [PLATFORM=ia32] PROCESSOR (choice) 77 77 -
abi/include/ipc/methods.h
r921b84f r5fb32c5 96 96 * error is sent back to caller. Otherwise 97 97 * the call is accepted and the response is sent back. 98 * - the hash of the client task is passed to userspace99 * (on the receiving side) as ARG4 of the call.100 98 * - the hash of the allocated phone is passed to userspace 101 99 * (on the receiving side) as ARG5 of the call. -
kernel/arch/ia32/Makefile.inc
r921b84f r5fb32c5 44 44 # 45 45 46 ifeq ($(PROCESSOR),i486) 47 CMN2 = -march=i486 48 endif 49 46 50 ifeq ($(PROCESSOR),athlon_xp) 47 51 CMN2 = -march=athlon-xp … … 62 66 CMN2 = -march=pentium4 63 67 SUNCC_CFLAGS += -xarch=sse2 64 endif65 66 ifeq ($(PROCESSOR),i486)67 CMN2 = -march=i48668 68 endif 69 69 -
kernel/arch/ia32/include/asm.h
r921b84f r5fb32c5 312 312 313 313 #ifndef PROCESSOR_i486 314 314 315 /** Write to MSR */ 315 316 NO_TRACE static inline void write_msr(uint32_t msr, uint64_t value) … … 336 337 return ((uint64_t) dx << 32) | ax; 337 338 } 338 #endif 339 340 #endif /* PROCESSOR_i486 */ 339 341 340 342 -
kernel/arch/ia32/include/boot/boot.h
r921b84f r5fb32c5 43 43 #define MULTIBOOT_HEADER_FLAGS 0x00010003 44 44 45 #define MULTIBOOT_LOADER_MAGIC 0x2BADB002 46 45 47 #ifndef __ASM__ 46 48 -
kernel/arch/ia32/src/asm.S
r921b84f r5fb32c5 407 407 #ifdef PROCESSOR_i486 408 408 jz 0f 409 movl %eax, %ebp410 0:409 movl %eax, %ebp 410 0: 411 411 #else 412 412 cmovnzl %eax, %ebp -
kernel/arch/ia32/src/boot/boot.S
r921b84f r5fb32c5 99 99 #include "vesa_prot.inc" 100 100 101 /* Map kernel and turn paging on */ 102 call map_kernel 101 #ifndef PROCESSOR_i486 102 103 pm_status $status_prot2 104 105 movl $(INTEL_CPUID_LEVEL), %eax 106 cpuid 107 cmp $0x0, %eax /* any function > 0? */ 108 jbe pse_unsupported 109 110 movl $(INTEL_CPUID_STANDARD), %eax 111 cpuid 112 bt $(INTEL_PSE), %edx 113 jnc pse_unsupported 114 115 /* Map kernel and turn paging on */ 116 pm_status $status_pse 117 call map_kernel_pse 118 jmp stack_init 119 120 #endif /* PROCESSOR_i486 */ 121 122 pse_unsupported: 123 124 /* Map kernel and turn paging on */ 125 pm_status $status_non_pse 126 call map_kernel 127 128 stack_init: 103 129 104 130 /* Create the first stack frame */ … … 106 132 movl %esp, %ebp 107 133 108 pm2_status $status_prot 2134 pm2_status $status_prot3 109 135 110 136 /* Call arch_pre_main(grub_eax, grub_ebx) */ … … 124 150 jmp hlt0 125 151 126 /** Calculate unmapped address of the end of the kernel. */ 127 calc_end_of_kernel: 128 movl $hardcoded_load_address, %edi 129 andl $0x7fffffff, %edi 130 movl (%edi), %esi 131 andl $0x7fffffff, %esi 132 133 movl $hardcoded_ktext_size, %edi 134 andl $0x7fffffff, %edi 135 addl (%edi), %esi 136 andl $0x7fffffff, %esi 137 138 movl $hardcoded_kdata_size, %edi 139 andl $0x7fffffff, %edi 140 addl (%edi), %esi 141 andl $0x7fffffff, %esi 142 movl %esi, end_of_kernel 152 /** Setup mapping for the kernel (PSE variant) 153 * 154 * Setup mapping for both the unmapped and mapped sections 155 * of the kernel. For simplicity, we map the entire 4G space. 156 * 157 */ 158 .global map_kernel_pse 159 map_kernel_pse: 160 /* Paging features */ 161 movl %cr4, %ecx 162 orl $(1 << 4), %ecx /* PSE on */ 163 andl $(~(1 << 5)), %ecx /* PAE off */ 164 movl %ecx, %cr4 165 166 movl $(page_directory + 0), %esi 167 movl $(page_directory + 2048), %edi 168 xorl %ecx, %ecx 169 xorl %ebx, %ebx 170 171 floop_pse: 172 movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax 173 orl %ebx, %eax 174 /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */ 175 movl %eax, (%esi, %ecx, 4) 176 /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */ 177 movl %eax, (%edi, %ecx, 4) 178 addl $(4 * 1024 * 1024), %ebx 179 180 incl %ecx 181 cmpl $512, %ecx 182 jl floop_pse 183 184 movl %esi, %cr3 185 186 movl %cr0, %ebx 187 orl $(1 << 31), %ebx /* paging on */ 188 movl %ebx, %cr0 143 189 ret 144 190 145 /** Find free 2M (+4k for alignment) region where to store page tables */ 146 find_mem_for_pt: 147 /* Check if multiboot info is present */ 148 cmpl $0x2BADB002, grub_eax 149 je check_multiboot_map 150 ret 151 check_multiboot_map: 152 /* Copy address of the multiboot info to ebx */ 153 movl grub_ebx, %ebx 154 /* Check if memory map flag is present */ 155 movl (%ebx), %edx 156 andl $(1 << 6), %edx 157 jnz use_multiboot_map 158 ret 159 use_multiboot_map: 160 /* Copy address of the memory map to edx */ 161 movl 48(%ebx), %edx 162 movl %edx, %ecx 163 addl 44(%ebx), %ecx 164 /* Find a free region at least 2M in size */ 165 check_memmap_loop: 166 /* Is this a free region? */ 167 cmp $1, 20(%edx) 168 jnz next_region 169 /* Check size */ 170 cmp $0, 16(%edx) 171 jnz next_region 172 cmpl $(2 * 1024 * 1024 + 4 * 1024), 12(%edx) 173 jbe next_region 174 cmp $0, 8(%edx) 175 jz found_region 176 next_region: 177 cmp %ecx, %edx 178 jbe next_region_do 179 ret 180 next_region_do: 181 addl (%edx), %edx 182 addl $4, %edx 183 jmp check_memmap_loop 184 found_region: 185 /* Use end of the found region */ 186 mov 4(%edx), %ecx 187 add 12(%edx), %ecx 188 sub $(2 * 1024 * 1024), %ecx 189 mov %ecx, free_area 190 ret 191 192 193 /** Setup mapping for the kernel. 191 /** Setup mapping for the kernel (non-PSE variant). 194 192 * 195 193 * Setup mapping for both the unmapped and mapped sections … … 204 202 movl %ecx, %cr4 205 203 206 call calc_ end_of_kernel204 call calc_kernel_end 207 205 call find_mem_for_pt 208 mov end_of_kernel, %esi 206 207 mov kernel_end, %esi 209 208 mov free_area, %ecx 209 210 210 cmpl %esi, %ecx 211 jbe use_end_of_kernel 212 mov %ecx, %esi 213 /* Align address down to 4k */ 214 andl $(~4095), %esi 215 use_end_of_kernel: 216 217 /* Align address to 4k */ 218 addl $4095, %esi 219 andl $(~4095), %esi 220 221 /* Allocate space for page tables*/ 222 movl %esi, pt_loc 223 movl $ballocs, %edi 211 jbe use_kernel_end 212 213 mov %ecx, %esi 214 215 /* Align address down to 4k */ 216 andl $(~4095), %esi 217 218 use_kernel_end: 219 220 /* Align address to 4k */ 221 addl $4095, %esi 222 andl $(~4095), %esi 223 224 /* Allocate space for page tables */ 225 movl %esi, pt_loc 226 movl $ballocs, %edi 227 andl $0x7fffffff, %edi 228 229 movl %esi, (%edi) 230 addl $4, %edi 231 movl $(2 * 1024 * 1024), (%edi) 232 233 /* Fill page tables */ 234 xorl %ecx, %ecx 235 xorl %ebx, %ebx 236 237 floop_pt: 238 movl $((1 << 1) | (1 << 0)), %eax 239 orl %ebx, %eax 240 movl %eax, (%esi, %ecx, 4) 241 addl $(4 * 1024), %ebx 242 243 incl %ecx 244 cmpl $(512 * 1024), %ecx 245 246 jl floop_pt 247 248 /* Fill page directory */ 249 movl $(page_directory + 0), %esi 250 movl $(page_directory + 2048), %edi 251 xorl %ecx, %ecx 252 movl pt_loc, %ebx 253 254 floop: 255 movl $((1 << 1) | (1 << 0)), %eax 256 orl %ebx, %eax 257 258 /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */ 259 movl %eax, (%esi, %ecx, 4) 260 261 /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */ 262 movl %eax, (%edi, %ecx, 4) 263 addl $(4 * 1024), %ebx 264 265 incl %ecx 266 cmpl $512, %ecx 267 268 jl floop 269 270 movl %esi, %cr3 271 272 movl %cr0, %ebx 273 orl $(1 << 31), %ebx /* paging on */ 274 movl %ebx, %cr0 275 276 ret 277 278 /** Calculate unmapped address of the end of the kernel. */ 279 calc_kernel_end: 280 movl $hardcoded_load_address, %edi 224 281 andl $0x7fffffff, %edi 225 movl %esi, (%edi) 226 addl $4, %edi 227 movl $(2*1024*1024), (%edi) 228 229 /* Fill page tables */ 230 xorl %ecx, %ecx 231 xorl %ebx, %ebx 232 233 floop_pt: 234 movl $((1 << 1) | (1 << 0)), %eax 235 orl %ebx, %eax 236 movl %eax, (%esi, %ecx, 4) 237 addl $(4 * 1024), %ebx 238 239 incl %ecx 240 cmpl $(512 * 1024), %ecx 241 jl floop_pt 242 243 /* Fill page directory */ 244 movl $(page_directory + 0), %esi 245 movl $(page_directory + 2048), %edi 246 xorl %ecx, %ecx 247 movl pt_loc, %ebx 248 249 floop: 250 movl $((1 << 1) | (1 << 0)), %eax 251 orl %ebx, %eax 252 /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */ 253 movl %eax, (%esi, %ecx, 4) 254 /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */ 255 movl %eax, (%edi, %ecx, 4) 256 addl $(4 * 1024), %ebx 257 258 incl %ecx 259 cmpl $512, %ecx 260 jl floop 261 262 movl %esi, %cr3 263 264 movl %cr0, %ebx 265 orl $(1 << 31), %ebx /* paging on */ 266 movl %ebx, %cr0 282 movl (%edi), %esi 283 andl $0x7fffffff, %esi 284 285 movl $hardcoded_ktext_size, %edi 286 andl $0x7fffffff, %edi 287 addl (%edi), %esi 288 andl $0x7fffffff, %esi 289 290 movl $hardcoded_kdata_size, %edi 291 andl $0x7fffffff, %edi 292 addl (%edi), %esi 293 andl $0x7fffffff, %esi 294 movl %esi, kernel_end 295 267 296 ret 297 298 /** Find free 2M (+4k for alignment) region where to store page tables */ 299 find_mem_for_pt: 300 /* Check if multiboot info is present */ 301 cmpl $MULTIBOOT_LOADER_MAGIC, grub_eax 302 je check_multiboot_map 303 304 ret 305 306 check_multiboot_map: 307 308 /* Copy address of the multiboot info to ebx */ 309 movl grub_ebx, %ebx 310 311 /* Check if memory map flag is present */ 312 movl (%ebx), %edx 313 andl $(1 << 6), %edx 314 jnz use_multiboot_map 315 316 ret 317 318 use_multiboot_map: 319 320 /* Copy address of the memory map to edx */ 321 movl 48(%ebx), %edx 322 movl %edx, %ecx 323 324 addl 44(%ebx), %ecx 325 326 /* Find a free region at least 2M in size */ 327 check_memmap_loop: 328 329 /* Is this a free region? */ 330 cmp $1, 20(%edx) 331 jnz next_region 332 333 /* Check size */ 334 cmp $0, 16(%edx) 335 jnz next_region 336 337 cmpl $(2 * 1024 * 1024 + 4 * 1024), 12(%edx) 338 jbe next_region 339 340 cmp $0, 8(%edx) 341 jz found_region 342 343 next_region: 344 345 cmp %ecx, %edx 346 jbe next_region_do 347 348 ret 349 350 next_region_do: 351 352 addl (%edx), %edx 353 addl $4, %edx 354 jmp check_memmap_loop 355 356 found_region: 357 358 /* Use end of the found region */ 359 mov 4(%edx), %ecx 360 add 12(%edx), %ecx 361 sub $(2 * 1024 * 1024), %ecx 362 mov %ecx, free_area 363 364 ret 268 365 269 366 /** Print string to EGA display (in light red) and halt. … … 610 707 grub_eax: 611 708 .long 0 612 613 709 grub_ebx: 614 710 .long 0 … … 616 712 pt_loc: 617 713 .long 0 618 end_of_kernel:714 kernel_end: 619 715 .long 0 620 716 free_area: 621 717 .long 0 622 718 623 err_pse:624 .asciz "Page Size Extension not supported. System halted."625 626 719 status_prot: 627 720 .asciz "[prot] " 721 status_pse: 722 .asciz "[pse] " 723 status_non_pse: 724 .asciz "[non_pse] " 628 725 status_vesa_copy: 629 726 .asciz "[vesa_copy] " … … 634 731 status_prot2: 635 732 .asciz "[prot2] " 733 status_prot3: 734 .asciz "[prot3] " 636 735 status_main: 637 736 .asciz "[main] " -
kernel/arch/ia32/src/syscall.c
r921b84f r5fb32c5 40 40 41 41 #ifndef PROCESSOR_i486 42 42 43 /** Enable & setup support for SYSENTER/SYSEXIT */ 43 44 void syscall_setup_cpu(void) … … 50 51 write_msr(IA32_MSR_SYSENTER_EIP, (uint32_t) sysenter_handler); 51 52 } 52 #endif 53 54 #endif /* PROCESSOR_i486 */ 53 55 54 56 /** @} -
kernel/generic/include/ipc/ipc.h
r921b84f r5fb32c5 98 98 typedef struct { 99 99 sysarg_t args[IPC_CALL_LEN]; 100 /** Task which made or forwarded the call with IPC_FF_ROUTE_FROM_ME. */ 100 /** 101 * Task which made or forwarded the call with IPC_FF_ROUTE_FROM_ME, 102 * or the task which answered the call. 103 */ 101 104 task_id_t task_id; 102 105 /** Phone which made or last masqueraded this call. */ -
kernel/generic/src/ipc/ipc.c
r921b84f r5fb32c5 230 230 } 231 231 } 232 233 call->data.task_id = TASK->taskid; 232 234 233 235 if (do_lock) -
kernel/generic/src/ipc/sysipc.c
r921b84f r5fb32c5 253 253 /* The connection was accepted */ 254 254 phone_connect(phoneid, &answer->sender->answerbox); 255 /* Set 'task ID' as arg3 and arg4 of response */256 IPC_SET_ARG3(answer->data, LOWER32(TASK->taskid));257 IPC_SET_ARG4(answer->data, UPPER32(TASK->taskid));258 255 /* Set 'phone hash' as arg5 of response */ 259 256 IPC_SET_ARG5(answer->data, -
uspace/app/bdsh/compl.c
r921b84f r5fb32c5 1 1 /* 2 2 * Copyright (c) 2011 Jiri Svoboda 3 * Copyright (c) 2011 Martin Sucha 3 4 * All rights reserved. 4 5 * … … 37 38 #include "compl.h" 38 39 #include "exec.h" 40 #include "tok.h" 39 41 40 42 static int compl_init(wchar_t *text, size_t pos, size_t *cstart, void **state); … … 88 90 { 89 91 compl_t *cs = NULL; 90 size_t p;91 92 size_t pref_size; 92 93 char *stext = NULL; … … 96 97 static const char *dirlist_arg[] = { ".", NULL }; 97 98 int retval; 99 tokenizer_t tok; 100 token_t tokens[WORD_MAX]; 101 unsigned int current_token; 102 size_t tokens_length; 98 103 99 104 cs = calloc(1, sizeof(compl_t)); … … 103 108 } 104 109 105 /*106 * Copy token pointed to by caret from start up to the caret.107 * XXX Ideally we would use the standard tokenizer.108 */109 p = pos;110 while (p > 0 && text[p - 1] != (wchar_t) ' ')111 --p;112 *cstart = p;113 114 110 /* Convert text buffer to string */ 115 stext = wstr_to_astr(text + *cstart);111 stext = wstr_to_astr(text); 116 112 if (stext == NULL) { 117 113 retval = ENOMEM; 118 114 goto error; 119 115 } 120 121 /* Extract the prefix being completed */ 116 117 /* Tokenize the input string */ 118 retval = tok_init(&tok, stext, tokens, WORD_MAX); 119 if (retval != EOK) { 120 goto error; 121 } 122 123 retval = tok_tokenize(&tok, &tokens_length); 124 if (retval != EOK) { 125 goto error; 126 } 127 128 /* Find the current token */ 129 for (current_token = 0; current_token < tokens_length; current_token++) { 130 token_t *t = &tokens[current_token]; 131 size_t end = t->char_start + t->char_length; 132 /* Check if the caret lies inside the token or immediately 133 * after it 134 */ 135 if (t->char_start <= pos && pos <= end) { 136 break; 137 } 138 } 139 140 if (tokens[current_token].type != TOKTYPE_SPACE) { 141 *cstart = tokens[current_token].char_start; 142 } 143 else { 144 *cstart = pos; 145 } 146 147 /* Extract the prefix being completed 148 * XXX: handle strings, etc. 149 */ 122 150 pref_size = str_lsize(stext, pos - *cstart); 123 151 prefix = malloc(pref_size + 1); … … 127 155 } 128 156 129 str_ncpy(prefix, pref_size + 1, stext, pref_size); 157 str_ncpy(prefix, pref_size + 1, stext + 158 tokens[current_token].byte_start, pref_size); 130 159 131 160 /* … … 133 162 * We look at the previous token. If there is none or it is a pipe 134 163 * ('|'), it is a command, otherwise it is an argument. 135 * XXX Again we should use the standard tokenizer/parser.136 164 */ 137 165 138 166 /* Skip any whitespace before current token */ 139 while (p > 0 && text[p - 1] == (wchar_t) ' ') 140 --p; 167 int prev_token = current_token - 1; 168 if (prev_token != -1 && tokens[prev_token].type == TOKTYPE_SPACE) { 169 prev_token--; 170 } 141 171 142 172 /* … … 144 174 * follows a pipe token. 145 175 */ 146 if (p == 0 || text[p - 1] == '|')176 if (prev_token == -1 || tokens[prev_token].type == TOKTYPE_SPACE) 147 177 cs->is_command = true; 148 178 else … … 189 219 190 220 cs->prefix_len = str_length(cs->prefix); 221 222 tok_fini(&tok); 191 223 192 224 *state = cs; … … 195 227 error: 196 228 /* Error cleanup */ 229 230 tok_fini(&tok); 197 231 198 232 if (cs != NULL && cs->path_list != NULL) { -
uspace/app/bdsh/input.c
r921b84f r5fb32c5 2 2 * Copyright (c) 2008 Tim Post 3 3 * Copyright (c) 2011 Jiri Svoboda 4 * Copyright (c) 2011 Martin Sucha 4 5 * All rights reserved. 5 6 * … … 67 68 { 68 69 char *cmd[WORD_MAX]; 70 token_t tokens_space[WORD_MAX]; 71 token_t *tokens = tokens_space; 69 72 int rc = 0; 70 73 tokenizer_t tok; 71 int i, pipe_count, processed_pipes; 72 int pipe_pos[2]; 73 char **actual_cmd; 74 unsigned int i, pipe_count, processed_pipes; 75 unsigned int pipe_pos[2]; 74 76 char *redir_from = NULL; 75 77 char *redir_to = NULL; … … 78 80 return CL_EFAIL; 79 81 80 rc = tok_init(&tok, usr->line, cmd, WORD_MAX);82 rc = tok_init(&tok, usr->line, tokens, WORD_MAX); 81 83 if (rc != EOK) { 82 84 goto finit; 83 85 } 84 86 85 rc = tok_tokenize(&tok); 87 size_t tokens_length; 88 rc = tok_tokenize(&tok, &tokens_length); 86 89 if (rc != EOK) { 87 90 goto finit; 91 } 92 93 if (tokens_length > 0 && tokens[0].type == TOKTYPE_SPACE) { 94 tokens++; 95 tokens_length--; 96 } 97 98 if (tokens_length > 0 && tokens[tokens_length-1].type == TOKTYPE_SPACE) { 99 tokens_length--; 88 100 } 89 101 … … 93 105 * First find the pipes and check that there are no more 94 106 */ 95 int cmd_length = 0; 96 for (i = 0, pipe_count = 0; cmd[i] != NULL; i++, cmd_length++) { 97 if (cmd[i][0] == '|') { 107 for (i = 0, pipe_count = 0; i < tokens_length; i++) { 108 if (tokens[i].type == TOKTYPE_PIPE) { 98 109 if (pipe_count >= 2) { 99 110 print_pipe_usage(); … … 106 117 } 107 118 108 actual_cmd = cmd; 119 unsigned int cmd_token_start = 0; 120 unsigned int cmd_token_end = tokens_length; 121 109 122 processed_pipes = 0; 110 123 111 124 /* Check if the first part (from <file> |) is present */ 112 if (pipe_count > 0 && pipe_pos[0] == 2 && str_cmp(cmd[0], "from") == 0) {125 if (pipe_count > 0 && (pipe_pos[0] == 3 || pipe_pos[0] == 4) && str_cmp(tokens[0].text, "from") == 0) { 113 126 /* Ignore the first three tokens (from, file, pipe) and set from */ 114 redir_from = cmd[1];115 actual_cmd = cmd + 3;127 redir_from = tokens[2].text; 128 cmd_token_start = pipe_pos[0]+1; 116 129 processed_pipes++; 117 130 } … … 119 132 /* Check if the second part (| to <file>) is present */ 120 133 if ((pipe_count - processed_pipes) > 0 && 121 pipe_pos[processed_pipes] == cmd_length - 3 && 122 str_cmp(cmd[cmd_length-2], "to") == 0) { 134 (pipe_pos[processed_pipes] == tokens_length - 4 || 135 (pipe_pos[processed_pipes] == tokens_length - 5 && 136 tokens[tokens_length-4].type == TOKTYPE_SPACE )) && 137 str_cmp(tokens[tokens_length-3].text, "to") == 0) { 123 138 /* Ignore the last three tokens (pipe, to, file) and set to */ 124 redir_to = cmd[cmd_length-1]; 125 cmd[cmd_length-3] = NULL; 126 cmd_length -= 3; 139 redir_to = tokens[tokens_length-1].text; 140 cmd_token_end = pipe_pos[processed_pipes]; 127 141 processed_pipes++; 128 142 } … … 134 148 } 135 149 136 if (actual_cmd[0] == NULL) { 150 /* Convert tokens of the command to string array */ 151 unsigned int cmd_pos = 0; 152 for (i = cmd_token_start; i < cmd_token_end; i++) { 153 if (tokens[i].type != TOKTYPE_SPACE) { 154 cmd[cmd_pos++] = tokens[i].text; 155 } 156 } 157 cmd[cmd_pos++] = NULL; 158 159 if (cmd[0] == NULL) { 137 160 print_pipe_usage(); 138 161 rc = ENOTSUP; … … 170 193 } 171 194 172 if (str_cmp( actual_cmd[0], "batch") == 0 && actual_cmd[1] != NULL) {173 FILE *batch = fopen( actual_cmd[1], "r");195 if (str_cmp(cmd[0], "batch") == 0 && cmd[1] != NULL) { 196 FILE *batch = fopen(cmd[1], "r"); 174 197 if (batch == NULL) { 175 printf("Cannot open file %s\n", actual_cmd[1]);198 printf("Cannot open file %s\n", cmd[1]); 176 199 rc = errno; 177 200 } else { … … 211 234 } 212 235 } else { 213 rc = run_command( actual_cmd, usr, &new_iostate);214 } 236 rc = run_command(cmd, usr, &new_iostate); 237 } 215 238 216 239 finit_with_files: -
uspace/app/bdsh/tok.c
r921b84f r5fb32c5 42 42 static bool tok_pending_chars(tokenizer_t *); 43 43 static int tok_finish_string(tokenizer_t *); 44 static void tok_start_token(tokenizer_t *, token_type_t); 44 45 45 46 /** Initialize the token parser … … 50 51 * @param max_tokens number of elements of the out_tokens array 51 52 */ 52 int tok_init(tokenizer_t *tok, char *input, char **out_tokens,53 int tok_init(tokenizer_t *tok, char *input, token_t *out_tokens, 53 54 size_t max_tokens) 54 55 { 55 56 tok->in = input; 56 57 tok->in_offset = 0; 58 tok->last_in_offset = 0; 59 tok->in_char_offset = 0; 60 tok->last_in_char_offset = 0; 57 61 58 62 tok->outtok = out_tokens; 59 63 tok->outtok_offset = 0; 60 /* Leave one slot for a null terminator */ 61 assert(max_tokens > 0); 62 tok->outtok_size = max_tokens - 1; 64 tok->outtok_size = max_tokens; 63 65 64 66 /* Prepare a buffer where all the token strings will be stored */ … … 87 89 88 90 /** Tokenize the input string into the tokens */ 89 int tok_tokenize(tokenizer_t *tok )91 int tok_tokenize(tokenizer_t *tok, size_t *tokens_length) 90 92 { 91 93 int rc; 92 wchar_t cur_char;94 wchar_t next_char; 93 95 94 96 /* Read the input line char by char and append tokens */ 95 while ((cur_char = tok_get_char(tok)) != 0) { 96 if (cur_char == ' ') { 97 /* Spaces delimit tokens, but are not processed in any way 98 * Push the token if there is any. 97 while ((next_char = tok_look_char(tok)) != 0) { 98 if (next_char == ' ') { 99 /* Push the token if there is any. 99 100 * There may not be any pending char for a token in case 100 101 * there are several spaces in the input. … … 106 107 } 107 108 } 108 } 109 else if (cur_char == '|') { 110 /* Pipes are tokens that are delimiters and should be output 111 * as a separate token 109 tok_start_token(tok, TOKTYPE_SPACE); 110 /* Eat all the spaces */ 111 while (tok_look_char(tok) == ' ') { 112 tok_push_char(tok, tok_get_char(tok)); 113 } 114 tok_push_token(tok); 115 116 } 117 else if (next_char == '|') { 118 /* Pipes are tokens that are delimiters and should be 119 * output as a separate token 112 120 */ 113 121 if (tok_pending_chars(tok)) { … … 118 126 } 119 127 120 rc = tok_push_char(tok, '|'); 128 tok_start_token(tok, TOKTYPE_PIPE); 129 130 rc = tok_push_char(tok, tok_get_char(tok)); 121 131 if (rc != EOK) { 122 132 return rc; … … 128 138 } 129 139 } 130 else if ( cur_char == '\'') {140 else if (next_char == '\'') { 131 141 /* A string starts with a quote (') and ends again with a quote. 132 142 * A literal quote is written as '' 133 143 */ 144 tok_start_token(tok, TOKTYPE_TEXT); 145 /* Eat the quote */ 146 tok_get_char(tok); 134 147 rc = tok_finish_string(tok); 135 148 if (rc != EOK) { … … 138 151 } 139 152 else { 153 if (!tok_pending_chars(tok)) { 154 tok_start_token(tok, TOKTYPE_TEXT); 155 } 140 156 /* If we are handling any other character, just append it to 141 157 * the current token. 142 158 */ 143 rc = tok_push_char(tok, cur_char);159 rc = tok_push_char(tok, tok_get_char(tok)); 144 160 if (rc != EOK) { 145 161 return rc; … … 156 172 } 157 173 158 /* We always have a space for the terminator, as we 159 * reserved it in tok_init */ 160 tok->outtok[tok->outtok_offset] = 0; 174 *tokens_length = tok->outtok_offset; 161 175 162 176 return EOK; … … 167 181 { 168 182 int rc; 169 wchar_t cur_char; 170 171 while ((cur_char = tok_get_char(tok)) != 0) { 172 if (cur_char == '\'') { 183 wchar_t next_char; 184 185 while ((next_char = tok_look_char(tok)) != 0) { 186 if (next_char == '\'') { 187 /* Eat the quote */ 188 tok_get_char(tok); 173 189 if (tok_look_char(tok) == '\'') { 174 190 /* Encode a single literal quote */ … … 187 203 } 188 204 else { 189 rc = tok_push_char(tok, cur_char);205 rc = tok_push_char(tok, tok_get_char(tok)); 190 206 if (rc != EOK) { 191 207 return rc; … … 201 217 wchar_t tok_get_char(tokenizer_t *tok) 202 218 { 219 tok->in_char_offset++; 203 220 return str_decode(tok->in, &tok->in_offset, STR_NO_LIMIT); 204 221 } … … 207 224 wchar_t tok_look_char(tokenizer_t *tok) 208 225 { 209 size_t old_offset = tok->in_offset; 226 unsigned int old_offset = tok->in_offset; 227 unsigned int old_char_offset = tok->in_char_offset; 210 228 wchar_t ret = tok_get_char(tok); 211 229 tok->in_offset = old_offset; 230 tok->in_char_offset = old_char_offset; 212 231 return ret; 213 232 } … … 219 238 } 220 239 240 void tok_start_token(tokenizer_t *tok, token_type_t type) 241 { 242 tok->current_type = type; 243 } 244 221 245 /** Push the current token to the output array */ 222 246 int tok_push_token(tokenizer_t *tok) … … 231 255 232 256 tok->outbuf[tok->outbuf_offset++] = 0; 233 tok->outtok[tok->outtok_offset++] = tok->outbuf + tok->outbuf_last_start; 257 token_t *tokinfo = &tok->outtok[tok->outtok_offset++]; 258 tokinfo->type = tok->current_type; 259 tokinfo->text = tok->outbuf + tok->outbuf_last_start; 260 tokinfo->byte_start = tok->last_in_offset; 261 tokinfo->byte_length = tok->in_offset - tok->last_in_offset; 262 tokinfo->char_start = tok->last_in_char_offset; 263 tokinfo->char_length = tok->in_char_offset - tok->last_in_char_offset; 234 264 tok->outbuf_last_start = tok->outbuf_offset; 265 266 /* We have consumed the first char of the next token already */ 267 tok->last_in_offset = tok->in_offset; 268 tok->last_in_char_offset = tok->in_char_offset; 235 269 236 270 return EOK; -
uspace/app/bdsh/tok.h
r921b84f r5fb32c5 30 30 #define TOK_H 31 31 32 typedef enum { 33 TOKTYPE_TEXT, 34 TOKTYPE_PIPE, 35 TOKTYPE_SPACE 36 } token_type_t; 37 38 typedef struct { 39 char *text; 40 unsigned int byte_start; 41 unsigned int char_start; 42 size_t byte_length; 43 size_t char_length; 44 token_type_t type; 45 } token_t; 46 32 47 typedef struct { 33 48 char *in; 34 size_t in_offset; 49 unsigned int in_offset; 50 unsigned int last_in_offset; 51 unsigned int in_char_offset; 52 unsigned int last_in_char_offset; 35 53 36 54 char *outbuf; … … 39 57 size_t outbuf_last_start; 40 58 41 char **outtok; 59 token_t *outtok; 60 token_type_t current_type; 42 61 size_t outtok_offset; 43 62 size_t outtok_size; 44 63 } tokenizer_t; 45 64 46 extern int tok_init(tokenizer_t *, char *, char **, size_t);65 extern int tok_init(tokenizer_t *, char *, token_t *, size_t); 47 66 extern void tok_fini(tokenizer_t *); 48 extern int tok_tokenize(tokenizer_t * );67 extern int tok_tokenize(tokenizer_t *, size_t *); 49 68 50 69 #endif -
uspace/lib/c/arch/ia32/Makefile.common
r921b84f r5fb32c5 28 28 29 29 CLANG_ARCH = i386 30 30 31 ifeq ($(PROCESSOR),i486) 31 GCC_CFLAGS += -march=i486 -fno-omit-frame-pointer32 GCC_CFLAGS += -march=i486 -fno-omit-frame-pointer 32 33 else 33 GCC_CFLAGS += -march=pentium -fno-omit-frame-pointer34 GCC_CFLAGS += -march=pentium -fno-omit-frame-pointer 34 35 endif 35 36 -
uspace/lib/c/arch/ia32/src/entry.S
r921b84f r5fb32c5 46 46 mov %ax, %fs 47 47 # Do not set %gs, it contains descriptor that can see TLS 48 48 49 49 #ifndef PROCESSOR_i486 50 50 # Detect the mechanism used for making syscalls … … 53 53 bt $(INTEL_SEP), %edx 54 54 jnc 0f 55 leal __syscall_fast_func, %eax56 movl $__syscall_fast, (%eax)57 0:55 leal __syscall_fast_func, %eax 56 movl $__syscall_fast, (%eax) 57 0: 58 58 #endif 59 59 60 # 60 61 # Create the first stack frame. -
uspace/lib/c/generic/async.c
r921b84f r5fb32c5 98 98 #include <ipc/ipc.h> 99 99 #include <async.h> 100 #include "private/async.h" 100 101 #undef LIBC_ASYNC_C_ 101 102 … … 113 114 #include <stdlib.h> 114 115 #include <macros.h> 115 #include "private/async.h"116 116 117 117 #define CLIENT_HASH_TABLE_BUCKETS 32 … … 996 996 session_ns->arg3 = 0; 997 997 998 fibril_mutex_initialize(&session_ns->remote_state_mtx); 999 session_ns->remote_state_data = NULL; 1000 998 1001 list_initialize(&session_ns->exch_list); 999 1002 fibril_mutex_initialize(&session_ns->mutex); … … 1472 1475 return ENOENT; 1473 1476 1474 task_id_t task_id;1475 sysarg_t task_id_lo;1476 sysarg_t task_id_hi;1477 1477 sysarg_t phone_hash; 1478 int rc = async_req_3_5(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, 1479 NULL, NULL, &task_id_lo, &task_id_hi, &phone_hash); 1478 sysarg_t rc; 1479 1480 aid_t req; 1481 ipc_call_t answer; 1482 req = async_send_3(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, 1483 &answer); 1484 async_wait_for(req, &rc); 1480 1485 if (rc != EOK) 1481 return rc;1482 1483 task_id = (task_id_t) MERGE_LOUP32(task_id_lo, task_id_hi);1484 1486 return (int) rc; 1487 1488 phone_hash = IPC_GET_ARG5(answer); 1489 1485 1490 if (client_receiver != NULL) 1486 async_new_connection( task_id, phone_hash, 0, NULL,1491 async_new_connection(answer.in_task_id, phone_hash, 0, NULL, 1487 1492 client_receiver, carg); 1488 1493 … … 1559 1564 sess->arg3 = 0; 1560 1565 1566 fibril_mutex_initialize(&sess->remote_state_mtx); 1567 sess->remote_state_data = NULL; 1568 1561 1569 list_initialize(&sess->exch_list); 1562 1570 fibril_mutex_initialize(&sess->mutex); … … 1640 1648 sess->arg3 = arg3; 1641 1649 1650 fibril_mutex_initialize(&sess->remote_state_mtx); 1651 sess->remote_state_data = NULL; 1652 1642 1653 list_initialize(&sess->exch_list); 1643 1654 fibril_mutex_initialize(&sess->mutex); … … 1690 1701 sess->arg3 = arg3; 1691 1702 1703 fibril_mutex_initialize(&sess->remote_state_mtx); 1704 sess->remote_state_data = NULL; 1705 1692 1706 list_initialize(&sess->exch_list); 1693 1707 fibril_mutex_initialize(&sess->mutex); … … 1720 1734 sess->arg2 = 0; 1721 1735 sess->arg3 = 0; 1736 1737 fibril_mutex_initialize(&sess->remote_state_mtx); 1738 sess->remote_state_data = NULL; 1722 1739 1723 1740 list_initialize(&sess->exch_list); … … 2384 2401 sess->arg3 = 0; 2385 2402 2403 fibril_mutex_initialize(&sess->remote_state_mtx); 2404 sess->remote_state_data = NULL; 2405 2386 2406 list_initialize(&sess->exch_list); 2387 2407 fibril_mutex_initialize(&sess->mutex); … … 2430 2450 sess->arg3 = 0; 2431 2451 2452 fibril_mutex_initialize(&sess->remote_state_mtx); 2453 sess->remote_state_data = NULL; 2454 2432 2455 list_initialize(&sess->exch_list); 2433 2456 fibril_mutex_initialize(&sess->mutex); … … 2471 2494 sess->arg2 = 0; 2472 2495 sess->arg3 = 0; 2496 2497 fibril_mutex_initialize(&sess->remote_state_mtx); 2498 sess->remote_state_data = NULL; 2473 2499 2474 2500 list_initialize(&sess->exch_list); … … 2512 2538 } 2513 2539 2540 /** Lock and get session remote state 2541 * 2542 * Lock and get the local replica of the remote state 2543 * in stateful sessions. The call should be paired 2544 * with async_remote_state_release*(). 2545 * 2546 * @param[in] sess Stateful session. 2547 * 2548 * @return Local replica of the remote state. 2549 * 2550 */ 2551 void *async_remote_state_acquire(async_sess_t *sess) 2552 { 2553 fibril_mutex_lock(&sess->remote_state_mtx); 2554 return sess->remote_state_data; 2555 } 2556 2557 /** Update the session remote state 2558 * 2559 * Update the local replica of the remote state 2560 * in stateful sessions. The remote state must 2561 * be already locked. 2562 * 2563 * @param[in] sess Stateful session. 2564 * @param[in] state New local replica of the remote state. 2565 * 2566 */ 2567 void async_remote_state_update(async_sess_t *sess, void *state) 2568 { 2569 assert(fibril_mutex_is_locked(&sess->remote_state_mtx)); 2570 sess->remote_state_data = state; 2571 } 2572 2573 /** Release the session remote state 2574 * 2575 * Unlock the local replica of the remote state 2576 * in stateful sessions. 2577 * 2578 * @param[in] sess Stateful session. 2579 * 2580 */ 2581 void async_remote_state_release(async_sess_t *sess) 2582 { 2583 assert(fibril_mutex_is_locked(&sess->remote_state_mtx)); 2584 2585 fibril_mutex_unlock(&sess->remote_state_mtx); 2586 } 2587 2588 /** Release the session remote state and end an exchange 2589 * 2590 * Unlock the local replica of the remote state 2591 * in stateful sessions. This is convenience function 2592 * which gets the session pointer from the exchange 2593 * and also ends the exchange. 2594 * 2595 * @param[in] exch Stateful session's exchange. 2596 * 2597 */ 2598 void async_remote_state_release_exchange(async_exch_t *exch) 2599 { 2600 if (exch == NULL) 2601 return; 2602 2603 async_sess_t *sess = exch->sess; 2604 assert(fibril_mutex_is_locked(&sess->remote_state_mtx)); 2605 2606 async_exchange_end(exch); 2607 fibril_mutex_unlock(&sess->remote_state_mtx); 2608 } 2609 2514 2610 /** @} 2515 2611 */ -
uspace/lib/c/generic/async_obsolete.c
r921b84f r5fb32c5 38 38 #include <async.h> 39 39 #include <async_obsolete.h> 40 #include "private/async.h" 40 41 #undef LIBC_ASYNC_C_ 41 42 #undef LIBC_ASYNC_OBSOLETE_C_ … … 44 45 #include <malloc.h> 45 46 #include <errno.h> 46 #include "private/async.h"47 47 48 48 /** Send message and return id of the sent message. -
uspace/lib/c/generic/ipc.c
r921b84f r5fb32c5 47 47 #include <futex.h> 48 48 #include <fibril.h> 49 #include <macros.h> 49 50 50 51 /** … … 611 612 /** Request callback connection. 612 613 * 613 * The @a task hashand @a phonehash identifiers returned614 * The @a task_id and @a phonehash identifiers returned 614 615 * by the kernel can be used for connection tracking. 615 616 * … … 618 619 * @param arg2 User defined argument. 619 620 * @param arg3 User defined argument. 620 * @param task hash Opaque identifier of the client task.621 * @param task_id Identifier of the client task. 621 622 * @param phonehash Opaque identifier of the phone that will 622 623 * be used for incoming calls. … … 626 627 */ 627 628 int ipc_connect_to_me(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, 628 sysarg_t *taskhash, sysarg_t *phonehash) 629 { 630 return ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_TO_ME, arg1, arg2, 631 arg3, NULL, NULL, NULL, taskhash, phonehash); 629 task_id_t *task_id, sysarg_t *phonehash) 630 { 631 ipc_call_t data; 632 int rc = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, 633 IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, (sysarg_t) &data); 634 if (rc == EOK) { 635 *task_id = data.in_task_id; 636 *phonehash = IPC_GET_ARG5(data); 637 } 638 return rc; 632 639 } 633 640 -
uspace/lib/c/generic/private/async.h
r921b84f r5fb32c5 36 36 #define LIBC_PRIVATE_ASYNC_H_ 37 37 38 #include < ipc/common.h>38 #include <async.h> 39 39 #include <adt/list.h> 40 40 #include <fibril.h> 41 #include <fibril_synch.h> 41 42 #include <sys/time.h> 42 43 #include <bool.h> 44 45 /** Session data */ 46 struct _async_sess { 47 /** List of inactive exchanges */ 48 list_t exch_list; 49 50 /** Exchange management style */ 51 exch_mgmt_t mgmt; 52 53 /** Session identification */ 54 int phone; 55 56 /** First clone connection argument */ 57 sysarg_t arg1; 58 59 /** Second clone connection argument */ 60 sysarg_t arg2; 61 62 /** Third clone connection argument */ 63 sysarg_t arg3; 64 65 /** Exchange mutex */ 66 fibril_mutex_t mutex; 67 68 /** Number of opened exchanges */ 69 atomic_t refcnt; 70 71 /** Mutex for stateful connections */ 72 fibril_mutex_t remote_state_mtx; 73 74 /** Data for stateful connections */ 75 void *remote_state_data; 76 }; 77 78 /** Exchange data */ 79 struct _async_exch { 80 /** Link into list of inactive exchanges */ 81 link_t sess_link; 82 83 /** Link into global list of inactive exchanges */ 84 link_t global_link; 85 86 /** Session pointer */ 87 async_sess_t *sess; 88 89 /** Exchange identification */ 90 int phone; 91 }; 43 92 44 93 /** Structures of this type are used to track the timeout events. */ -
uspace/lib/c/include/async.h
r921b84f r5fb32c5 42 42 #include <ipc/common.h> 43 43 #include <fibril.h> 44 #include <fibril_synch.h>45 44 #include <sys/time.h> 46 45 #include <atomic.h> … … 96 95 } exch_mgmt_t; 97 96 98 /** Session data */ 99 typedef struct { 100 /** List of inactive exchanges */ 101 list_t exch_list; 102 103 /** Exchange management style */ 104 exch_mgmt_t mgmt; 105 106 /** Session identification */ 107 int phone; 108 109 /** First clone connection argument */ 110 sysarg_t arg1; 111 112 /** Second clone connection argument */ 113 sysarg_t arg2; 114 115 /** Third clone connection argument */ 116 sysarg_t arg3; 117 118 /** Exchange mutex */ 119 fibril_mutex_t mutex; 120 121 /** Number of opened exchanges */ 122 atomic_t refcnt; 123 } async_sess_t; 124 125 /** Exchange data */ 126 typedef struct { 127 /** Link into list of inactive exchanges */ 128 link_t sess_link; 129 130 /** Link into global list of inactive exchanges */ 131 link_t global_link; 132 133 /** Session pointer */ 134 async_sess_t *sess; 135 136 /** Exchange identification */ 137 int phone; 138 } async_exch_t; 97 /** Forward declarations */ 98 struct _async_exch; 99 struct _async_sess; 100 101 typedef struct _async_sess async_sess_t; 102 typedef struct _async_exch async_exch_t; 139 103 140 104 extern atomic_t threads_in_ipc_wait; … … 485 449 extern int async_state_change_finalize(ipc_callid_t, async_exch_t *); 486 450 451 extern void *async_remote_state_acquire(async_sess_t *); 452 extern void async_remote_state_update(async_sess_t *, void *); 453 extern void async_remote_state_release(async_sess_t *); 454 extern void async_remote_state_release_exchange(async_exch_t *); 455 487 456 #endif 488 457 -
uspace/lib/c/include/ipc/ipc.h
r921b84f r5fb32c5 254 254 sysarg_t, sysarg_t, void *, ipc_async_callback_t, bool); 255 255 256 extern int ipc_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t *,256 extern int ipc_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t, task_id_t *, 257 257 sysarg_t *); 258 258 extern int ipc_connect_me(int); -
uspace/lib/clui/tinput.c
r921b84f r5fb32c5 591 591 } 592 592 593 /* Print a list of completions */ 594 static void tinput_show_completions(tinput_t *ti, char **compl, size_t cnum) 595 { 596 unsigned int i; 597 /* Determine the maximum length of the completion in chars */ 598 size_t max_length = 0; 599 for (i = 0; i < cnum; i++) 600 max_length = max(max_length, str_length(compl[i])); 601 602 unsigned int cols = max(1, (ti->con_cols + 1) / (max_length + 1)); 603 unsigned int col_width = ti->con_cols / cols; 604 unsigned int rows = cnum / cols + ((cnum % cols) != 0); 605 606 unsigned int row, col; 607 608 for (row = 0; row < rows; row++) { 609 bool wlc = false; 610 for (col = 0; col < cols; col++) { 611 size_t compl_idx = col * rows + row; 612 if (compl_idx >= cnum) 613 break; 614 if (col) 615 printf(" "); 616 printf("%s", compl[compl_idx]); 617 size_t compl_len = str_length(compl[compl_idx]); 618 if (col == cols -1) { 619 wlc = (compl_len == max_length); 620 } 621 else { 622 for (i = compl_len; i < col_width; i++) { 623 printf(" "); 624 } 625 } 626 } 627 if (!wlc) printf("\n"); 628 } 629 } 630 631 593 632 static void tinput_text_complete(tinput_t *ti) 594 633 { … … 676 715 677 716 tinput_jump_after(ti); 678 for (i = 0; i < cnum; i++) 679 printf("%s\n", compl[i]); 717 tinput_show_completions(ti, compl, cnum); 680 718 tinput_display(ti); 681 719 }
Note:
See TracChangeset
for help on using the changeset viewer.