Bug Summary

File:obj-scan-build/boot/../../boot/boot.c
Location:line 1523, column 3
Description:The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage

Annotated Source Code

1/* Load a task using the single server, and then run it
2 as if we were the kernel.
3 Copyright (C) 1993,94,95,96,97,98,99,2000,01,02,2006
4 Free Software Foundation, Inc.
5
6This file is part of the GNU Hurd.
7
8The GNU Hurd is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13The GNU Hurd is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with the GNU Hurd; see the file COPYING. If not, write to
20the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21
22/* Written by Michael I. Bushnell. */
23
24#include <mach.h>
25#include <mach/notify.h>
26#include <device/device.h>
27#include <a.out.h>
28#include <mach/message.h>
29#include <mach/mig_errors.h>
30#include <stdlib.h>
31#include <string.h>
32#include <stdio.h>
33#include <pthread.h>
34#include <fcntl.h>
35#include <elf.h>
36#include <mach/mig_support.h>
37#include <mach/default_pager.h>
38#include <mach/machine/vm_param.h> /* For VM_XXX_ADDRESS */
39#include <argp.h>
40#include <hurd/store.h>
41#include <sys/mman.h>
42#include <version.h>
43
44#include "notify_S.h"
45#include "device_S.h"
46#include "io_S.h"
47#include "device_reply_U.h"
48#include "io_reply_U.h"
49#include "term_S.h"
50#include "bootstrap_S.h"
51/* #include "tioctl_S.h" */
52
53#include "boot_script.h"
54
55#include <hurd/auth.h>
56
57#ifdef UX
58#undef STORE /* We can't use libstore when under UX. */
59#else
60#define STORE
61#endif
62
63#ifdef UX
64
65#include "ux.h"
66
67#else /* !UX */
68
69#include <unistd.h>
70#include <fcntl.h>
71#include <signal.h>
72#include <sys/ioctl.h>
73#include <sys/stat.h>
74#include <termios.h>
75#include <error.h>
76#include <hurd.h>
77#include <assert.h>
78
79static struct termios orig_tty_state;
80static int isig;
81static char *kernel_command_line;
82
83static void
84init_termstate ()
85{
86 struct termios tty_state;
87
88 if (tcgetattr (0, &tty_state) < 0)
89 error (10, errno(*__errno_location ()), "tcgetattr");
90
91 orig_tty_state = tty_state;
92 cfmakeraw (&tty_state);
93 if (isig)
94 tty_state.c_lflag |= ISIG(1 << 7);
95
96 if (tcsetattr (0, 0, &tty_state) < 0)
97 error (11, errno(*__errno_location ()), "tcsetattr");
98}
99
100static void
101restore_termstate ()
102{
103 tcsetattr (0, 0, &orig_tty_state);
104}
105
106#define host_fstatfstat fstat
107typedef struct stat host_stat_t;
108#define host_exitexit exit
109
110#endif /* UX */
111
112mach_port_t privileged_host_port, master_device_port;
113mach_port_t pseudo_master_device_port;
114mach_port_t receive_set;
115mach_port_t pseudo_console, pseudo_root, pseudo_time;
116auth_t authserver;
117
118struct store *root_store;
119
120pthread_spinlock_t queuelock = PTHREAD_SPINLOCK_INITIALIZER((__pthread_spinlock_t) 0);
121pthread_spinlock_t readlock = PTHREAD_SPINLOCK_INITIALIZER((__pthread_spinlock_t) 0);
122
123mach_port_t php_child_name, psmdp_child_name, taskname;
124
125task_t child_task;
126mach_port_t bootport;
127
128int console_mscount;
129
130vm_address_t fs_stack_base;
131vm_size_t fs_stack_size;
132
133void init_termstate ();
134void restore_termstate ();
135
136char *fsname;
137
138char bootstrap_args[100] = "-";
139char *bootdevice = 0;
140char *bootscript = 0;
141
142
143void safe_gets (char *buf, int buf_len)
144{
145 fgets (buf, buf_len, stdinstdin);
146}
147
148char *useropen_dir;
149
150int
151useropen (const char *name, int flags, int mode)
152{
153 if (useropen_dir)
154 {
155 static int dlen;
156 if (!dlen) dlen = strlen (useropen_dir);
157 {
158 int len = strlen (name);
159 char try[dlen + 1 + len + 1];
160 int fd;
161 memcpy (try, useropen_dir, dlen);
162 try[dlen] = '/';
163 memcpy (&try[dlen + 1], name, len + 1);
164 fd = open (try, flags, mode);
165 if (fd >= 0)
166 return fd;
167 }
168 }
169 return open (name, flags, mode);
170}
171
172/* XXX: glibc should provide mig_reply_setup but does not. */
173/* Fill in default response. */
174void
175mig_reply_setup (
176 const mach_msg_header_t *in,
177 mach_msg_header_t *out)
178{
179 static const mach_msg_type_t RetCodeType = {
180 /* msgt_name = */ MACH_MSG_TYPE_INTEGER_322,
181 /* msgt_size = */ 32,
182 /* msgt_number = */ 1,
183 /* msgt_inline = */ TRUE((boolean_t) 1),
184 /* msgt_longform = */ FALSE((boolean_t) 0),
185 /* msgt_deallocate = */ FALSE((boolean_t) 0),
186 /* msgt_unused = */ 0
187 };
188
189#define InP (in)
190#define OutP ((mig_reply_header_t *) out)
191 OutP->Head.msgh_bits =
192 MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(InP->msgh_bits), 0)((((InP->msgh_bits) & 0x000000ff)) | ((0) << 8));
193 OutP->Head.msgh_size = sizeof *OutP;
194 OutP->Head.msgh_remote_port = InP->msgh_remote_port;
195 OutP->Head.msgh_local_port = MACH_PORT_NULL((mach_port_t) 0);
196 OutP->Head.msgh_seqno = 0;
197 OutP->Head.msgh_id = InP->msgh_id + 100;
198 OutP->RetCodeType = RetCodeType;
199 OutP->RetCode = MIG_BAD_ID-303;
200#undef InP
201#undef OutP
202}
203
204int
205boot_demuxer (mach_msg_header_t *inp,
206 mach_msg_header_t *outp)
207{
208 mig_routine_t routine;
209 mig_reply_setup (inp, outp);
210 if ((routine = io_server_routine (inp)) ||
211 (routine = device_server_routine (inp)) ||
212 (routine = notify_server_routine (inp)) ||
213 (routine = term_server_routine (inp))
214 /* (routine = tioctl_server_routine (inp)) */)
215 {
216 (*routine) (inp, outp);
217 return TRUE((boolean_t) 1);
218 }
219 else
220 return FALSE((boolean_t) 0);
221}
222
223vm_address_t
224load_image (task_t t,
225 char *file)
226{
227 int fd;
228 union
229 {
230 struct exec a;
231 Elf32_Ehdr e;
232 } hdr;
233 char msg[] = ": cannot open bootstrap file\n";
234
235 fd = useropen (file, O_RDONLY0x0001, 0);
236
237 if (fd == -1)
238 {
239 write (2, file, strlen (file));
240 write (2, msg, sizeof msg - 1);
241 task_terminate (t);
242 host_exitexit (1);
243 }
244
245 read (fd, &hdr, sizeof hdr);
246 if (*(Elf32_Word *) hdr.e.e_ident == *(Elf32_Word *) "\177ELF")
247 {
248 Elf32_Phdr phdrs[hdr.e.e_phnum], *ph;
249 lseek (fd, hdr.e.e_phoff, SEEK_SET0);
250 read (fd, phdrs, sizeof phdrs);
251 for (ph = phdrs; ph < &phdrs[sizeof phdrs/sizeof phdrs[0]]; ++ph)
252 if (ph->p_type == PT_LOAD1)
253 {
254 vm_address_t buf;
255 vm_size_t offs = ph->p_offset & (ph->p_align - 1);
256 vm_size_t bufsz = round_page (ph->p_filesz + offs)((((vm_offset_t) (ph->p_filesz + offs) + __vm_page_size - 1
) / __vm_page_size) * __vm_page_size)
;
257
258 buf = (vm_address_t) mmap (0, bufsz,
259 PROT_READ0x04|PROT_WRITE0x02, MAP_ANON0x0002, 0, 0);
260
261 lseek (fd, ph->p_offset, SEEK_SET0);
262 read (fd, (void *)(buf + offs), ph->p_filesz);
263
264 ph->p_memsz = ((ph->p_vaddr + ph->p_memsz + ph->p_align - 1)
265 & ~(ph->p_align - 1));
266 ph->p_vaddr &= ~(ph->p_align - 1);
267 ph->p_memsz -= ph->p_vaddr;
268
269 vm_allocate (t, (vm_address_t*)&ph->p_vaddr, ph->p_memsz, 0);
270 vm_write (t, ph->p_vaddr, buf, bufsz);
271 munmap ((caddr_t) buf, bufsz);
272 vm_protect (t, ph->p_vaddr, ph->p_memsz, 0,
273 ((ph->p_flags & PF_R(1 << 2)) ? VM_PROT_READ((vm_prot_t) 0x01) : 0) |
274 ((ph->p_flags & PF_W(1 << 1)) ? VM_PROT_WRITE((vm_prot_t) 0x02) : 0) |
275 ((ph->p_flags & PF_X(1 << 0)) ? VM_PROT_EXECUTE((vm_prot_t) 0x04) : 0));
276 }
277 return hdr.e.e_entry;
278 }
279 else
280 {
281 /* a.out */
282 int magic = N_MAGIC (hdr.a)((hdr.a).a_info & 0xffff);
283 int headercruft;
284 vm_address_t base = 0x10000;
285 int rndamount, amount;
286 vm_address_t bsspagestart, bssstart;
287 char *buf;
288
289 headercruft = sizeof (struct exec) * (magic == ZMAGIC0413);
290
291 amount = headercruft + hdr.a.a_text + hdr.a.a_data;
292 rndamount = round_page (amount)((((vm_offset_t) (amount) + __vm_page_size - 1) / __vm_page_size
) * __vm_page_size)
;
293 buf = mmap (0, rndamount, PROT_READ0x04|PROT_WRITE0x02, MAP_ANON0x0002, 0, 0);
294 lseek (fd, sizeof hdr.a - headercruft, SEEK_SET0);
295 read (fd, buf, amount);
296 vm_allocate (t, &base, rndamount, 0);
297 vm_write (t, base, (vm_address_t) buf, rndamount);
298 if (magic != OMAGIC0407)
299 vm_protect (t, base, trunc_page (headercruft + hdr.a.a_text)((((vm_offset_t) (headercruft + hdr.a.a_text)) / __vm_page_size
) * __vm_page_size)
,
300 0, VM_PROT_READ((vm_prot_t) 0x01) | VM_PROT_EXECUTE((vm_prot_t) 0x04));
301 munmap ((caddr_t) buf, rndamount);
302
303 bssstart = base + hdr.a.a_text + hdr.a.a_data + headercruft;
304 bsspagestart = round_page (bssstart)((((vm_offset_t) (bssstart) + __vm_page_size - 1) / __vm_page_size
) * __vm_page_size)
;
305 vm_allocate (t, &bsspagestart,
306 hdr.a.a_bss - (bsspagestart - bssstart), 0);
307
308 return hdr.a.a_entry;
309 }
310}
311
312
313void read_reply ();
314void * msg_thread (void *);
315
316/* Callbacks for boot_script.c; see boot_script.h. */
317int
318boot_script_exec_cmd (void *hook,
319 mach_port_t task, char *path, int argc,
320 char **argv, char *strings, int stringlen)
321{
322 char *args, *p;
323 int arg_len, i;
324 size_t reg_size;
325 void *arg_pos;
326 vm_offset_t stack_start, stack_end;
327 vm_address_t startpc, str_start;
328 thread_t thread;
329
330 write (2, path, strlen (path));
331 for (i = 1; i < argc; ++i)
332 {
333 write (2, " ", 1);
334 write (2, argv[i], strlen (argv[i]));
335 }
336 write (2, "\r\n", 2);
337
338 startpc = load_image (task, path);
339 arg_len = stringlen + (argc + 2) * sizeof (char *) + sizeof (integer_t);
340 arg_len += 5 * sizeof (int);
341 stack_end = VM_MAX_ADDRESS(0x80000000UL);
342 stack_start = VM_MAX_ADDRESS(0x80000000UL) - 16 * 1024 * 1024;
343 vm_allocate (task, &stack_start, stack_end - stack_start, FALSE((boolean_t) 0));
344 arg_pos = (void *) ((stack_end - arg_len) & ~(sizeof (natural_t) - 1));
345 args = mmap (0, stack_end - trunc_page ((vm_offset_t) arg_pos)((((vm_offset_t) ((vm_offset_t) arg_pos)) / __vm_page_size) *
__vm_page_size)
,
346 PROT_READ0x04|PROT_WRITE0x02, MAP_ANON0x0002, 0, 0);
347 str_start = ((vm_address_t) arg_pos
348 + (argc + 2) * sizeof (char *) + sizeof (integer_t));
349 p = args + ((vm_address_t) arg_pos & (vm_page_size - 1));
350 *(int *) p = argc;
351 p = (void *) p + sizeof (int);
352 for (i = 0; i < argc; i++)
353 {
354 *(char **) p = argv[i] - strings + (char *) str_start;
355 p = (void *) p + sizeof (char *);
356 }
357 *(char **) p = 0;
358 p = (void *) p + sizeof (char *);
359 *(char **) p = 0;
360 p = (void *) p + sizeof (char *);
361 memcpy (p, strings, stringlen);
362 memset (args, 0, (vm_offset_t)arg_pos & (vm_page_size - 1));
363 vm_write (task, trunc_page ((vm_offset_t) arg_pos)((((vm_offset_t) ((vm_offset_t) arg_pos)) / __vm_page_size) *
__vm_page_size)
, (vm_address_t) args,
364 stack_end - trunc_page ((vm_offset_t) arg_pos)((((vm_offset_t) ((vm_offset_t) arg_pos)) / __vm_page_size) *
__vm_page_size)
);
365 munmap ((caddr_t) args,
366 stack_end - trunc_page ((vm_offset_t) arg_pos)((((vm_offset_t) ((vm_offset_t) arg_pos)) / __vm_page_size) *
__vm_page_size)
);
367
368 thread_create (task, &thread);
369#ifdef i386_THREAD_STATE_COUNT(sizeof (struct i386_thread_state)/sizeof(unsigned int))
370 {
371 struct i386_thread_state regs;
372 reg_size = i386_THREAD_STATE_COUNT(sizeof (struct i386_thread_state)/sizeof(unsigned int));
373 thread_get_state (thread, i386_THREAD_STATE1,
374 (thread_state_t) &regs, &reg_size);
375 regs.eip = (int) startpc;
376 regs.uesp = (int) arg_pos;
377 thread_set_state (thread, i386_THREAD_STATE1,
378 (thread_state_t) &regs, reg_size);
379 }
380#elif defined(ALPHA_THREAD_STATE_COUNT)
381 {
382 struct alpha_thread_state regs;
383 reg_size = ALPHA_THREAD_STATE_COUNT;
384 thread_get_state (thread, ALPHA_THREAD_STATE,
385 (thread_state_t) &regs, &reg_size);
386 regs.r30 = (natural_t) arg_pos;
387 regs.pc = (natural_t) startpc;
388 thread_set_state (thread, ALPHA_THREAD_STATE,
389 (thread_state_t) &regs, reg_size);
390 }
391#else
392# error needs to be ported
393#endif
394
395 thread_resume (thread);
396 mach_port_deallocate (mach_task_self ()((__mach_task_self_ + 0)), thread);
397 return 0;
398}
399
400const char *argp_program_version = STANDARD_HURD_VERSION (boot)"boot" " (GNU Hurd) " "0.5";
401
402static struct argp_option options[] =
403{
404 { "boot-root", 'D', "DIR", 0,
405 "Root of a directory tree in which to find files specified in BOOT-SCRIPT" },
406 { "single-user", 's', 0, 0,
407 "Boot in single user mode" },
408 { "kernel-command-line", 'c', "COMMAND LINE", 0,
409 "Simulated multiboot command line to supply" },
410 { "pause" , 'd', 0, 0,
411 "Pause for user confirmation at various times during booting" },
412 { "isig", 'I', 0, 0,
413 "Do not disable terminal signals, so you can suspend and interrupt boot."},
414 { "device", 'f', "device_name=device_file", 0,
415 "Specify a device file used by subhurd and its virtual name."},
416 { 0 }
417};
418static char args_doc[] = "BOOT-SCRIPT";
419static char doc[] = "Boot a second hurd";
420
421struct dev_map
422{
423 char *name;
424 mach_port_t port;
425 struct dev_map *next;
426};
427
428static struct dev_map *dev_map_head;
429
430static struct dev_map *add_dev_map (char *dev_name, char *dev_file)
431{
432 struct dev_map *map = malloc (sizeof (*map));
433
434 assert (map)((map) ? (void) (0) : __assert_fail ("map", "../../boot/boot.c"
, 434, __PRETTY_FUNCTION__))
;
435 map->name = dev_name;
436 map->port = file_name_lookup (dev_file, 0, 0);
437 if (map->port == MACH_PORT_NULL((mach_port_t) 0))
438 error (1, errno(*__errno_location ()), "file_name_lookup: %s", dev_file);
439 map->next = dev_map_head;
440 dev_map_head = map;
441 return map;
442}
443
444static struct dev_map *lookup_dev (char *dev_name)
445{
446 struct dev_map *map;
447
448 for (map = dev_map_head; map; map = map->next)
449 {
450 if (strcmp (map->name, dev_name) == 0)
451 return map;
452 }
453 return NULL((void*)0);
454}
455
456static error_t
457parse_opt (int key, char *arg, struct argp_state *state)
458{
459 char *dev_file;
460
461 switch (key)
462 {
463 size_t len;
464
465 case 'c': kernel_command_line = arg; break;
466
467 case 'D': useropen_dir = arg; break;
468
469 case 'I': isig = 1; break;
470
471 case 's': case 'd':
472 len = strlen (bootstrap_args);
473 if (len >= sizeof bootstrap_args - 1)
474 argp_error (state, "Too many bootstrap args");
475 bootstrap_args[len++] = key;
476 bootstrap_args[len] = '\0';
477 break;
478
479 case 'f':
480 dev_file = strchr (arg, '=');
481 if (dev_file == NULL((void*)0))
482 return ARGP_ERR_UNKNOWN((0x10 << 26) | ((7) & 0x3fff));
483 *dev_file = 0;
484 add_dev_map (arg, dev_file+1);
485 break;
486
487 case ARGP_KEY_ARG0:
488 if (state->arg_num == 0)
489 bootscript = arg;
490 else
491 return ARGP_ERR_UNKNOWN((0x10 << 26) | ((7) & 0x3fff));
492 break;
493
494 case ARGP_KEY_INIT0x1000003:
495 state->child_inputs[0] = state->input; break;
496
497 default:
498 return ARGP_ERR_UNKNOWN((0x10 << 26) | ((7) & 0x3fff));
499 }
500 return 0;
501}
502
503int
504main (int argc, char **argv, char **envp)
505{
506 error_t err;
507 mach_port_t foo;
508 char *buf = 0;
509 int i, len;
510 pthread_t pthread_id;
511 char *root_store_name;
512 const struct argp_child kids[] = { { &store_argp }, { 0 }};
513 struct argp argp = { options, parse_opt, args_doc, doc, kids };
514 struct store_argp_params store_argp_params = { 0 };
515
516 argp_parse (&argp, argc, argv, 0, 0, &store_argp_params);
517 err = store_parsed_name (store_argp_params.result, &root_store_name);
518 if (err)
519 error (2, err, "store_parsed_name");
520
521 err = store_parsed_open (store_argp_params.result, 0, &root_store);
522 if (err)
523 error (4, err, "%s", root_store_name);
524
525 get_privileged_ports (&privileged_host_port, &master_device_port);
526
527 strcat (bootstrap_args, "f");
528
529 mach_port_allocate (mach_task_self ()((__mach_task_self_ + 0)), MACH_PORT_RIGHT_PORT_SET((mach_port_right_t) 3),
530 &receive_set);
531
532 if (root_store->class == &store_device_class && root_store->name
533 && (root_store->flags & STORE_ENFORCED0x2000)
534 && root_store->num_runs == 1 && root_store->runs[0].start == 0)
535 /* Let known device nodes pass through directly. */
536 bootdevice = root_store->name;
537 else
538 /* Pass a magic value that we can use to do I/O to ROOT_STORE. */
539 {
540 bootdevice = "pseudo-root";
541 mach_port_allocate (mach_task_self ()((__mach_task_self_ + 0)), MACH_PORT_RIGHT_RECEIVE((mach_port_right_t) 1),
542 &pseudo_root);
543 mach_port_move_member (mach_task_self ()((__mach_task_self_ + 0)), pseudo_root, receive_set);
544 }
545
546 mach_port_allocate (mach_task_self ()((__mach_task_self_ + 0)), MACH_PORT_RIGHT_RECEIVE((mach_port_right_t) 1),
547 &pseudo_master_device_port);
548 mach_port_insert_right (mach_task_self ()((__mach_task_self_ + 0)),
549 pseudo_master_device_port,
550 pseudo_master_device_port,
551 MACH_MSG_TYPE_MAKE_SEND20);
552 mach_port_move_member (mach_task_self ()((__mach_task_self_ + 0)), pseudo_master_device_port,
553 receive_set);
554 mach_port_request_notification (mach_task_self ()((__mach_task_self_ + 0)), pseudo_master_device_port,
555 MACH_NOTIFY_NO_SENDERS(0100 + 006), 1,
556 pseudo_master_device_port,
557 MACH_MSG_TYPE_MAKE_SEND_ONCE21, &foo);
558 if (foo != MACH_PORT_NULL((mach_port_t) 0))
559 mach_port_deallocate (mach_task_self ()((__mach_task_self_ + 0)), foo);
560
561 mach_port_allocate (mach_task_self ()((__mach_task_self_ + 0)), MACH_PORT_RIGHT_RECEIVE((mach_port_right_t) 1),
562 &pseudo_console);
563 mach_port_move_member (mach_task_self ()((__mach_task_self_ + 0)), pseudo_console, receive_set);
564 mach_port_request_notification (mach_task_self ()((__mach_task_self_ + 0)), pseudo_console,
565 MACH_NOTIFY_NO_SENDERS(0100 + 006), 1, pseudo_console,
566 MACH_MSG_TYPE_MAKE_SEND_ONCE21, &foo);
567 if (foo != MACH_PORT_NULL((mach_port_t) 0))
568 mach_port_deallocate (mach_task_self ()((__mach_task_self_ + 0)), foo);
569
570 mach_port_allocate (mach_task_self ()((__mach_task_self_ + 0)), MACH_PORT_RIGHT_RECEIVE((mach_port_right_t) 1),
571 &pseudo_time);
572 mach_port_move_member (mach_task_self ()((__mach_task_self_ + 0)), pseudo_time, receive_set);
573 mach_port_request_notification (mach_task_self ()((__mach_task_self_ + 0)), pseudo_time,
574 MACH_NOTIFY_NO_SENDERS(0100 + 006), 1, pseudo_time,
575 MACH_MSG_TYPE_MAKE_SEND_ONCE21, &foo);
576 if (foo != MACH_PORT_NULL((mach_port_t) 0))
577 mach_port_deallocate (mach_task_self ()((__mach_task_self_ + 0)), foo);
578
579 if (kernel_command_line == 0)
580 asprintf (&kernel_command_line, "%s %s root=%s",
581 argv[0], bootstrap_args, bootdevice);
582
583 /* Initialize boot script variables. */
584 if (boot_script_set_variable ("host-port", VAL_PORT2,
585 (int) privileged_host_port)
586 || boot_script_set_variable ("device-port", VAL_PORT2,
587 (integer_t) pseudo_master_device_port)
588 || boot_script_set_variable ("kernel-command-line", VAL_STR1,
589 (integer_t) kernel_command_line)
590 || boot_script_set_variable ("root-device",
591 VAL_STR1, (integer_t) bootdevice)
592 || boot_script_set_variable ("boot-args",
593 VAL_STR1, (integer_t) bootstrap_args))
594 {
595 static const char msg[] = "error setting variable";
596
597 write (2, msg, strlen (msg));
598 host_exitexit (1);
599 }
600
601 /* Turn each `FOO=BAR' word in the command line into a boot script
602 variable ${FOO} with value BAR. */
603 {
604 int len = strlen (kernel_command_line) + 1;
605 char *s = memcpy (alloca (len)__builtin_alloca (len), kernel_command_line, len);
606 char *word;
607
608 while ((word = strsep (&s, " \t")) != 0)
609 {
610 char *eq = strchr (word, '=');
611 if (eq == 0)
612 continue;
613 *eq++ = '\0';
614 err = boot_script_set_variable (word, VAL_STR1, (integer_t) eq);
615 if (err)
616 {
617 char *msg;
618 asprintf (&msg, "cannot set boot-script variable %s: %s\n",
619 word, boot_script_error_string (err));
620 assert (msg)((msg) ? (void) (0) : __assert_fail ("msg", "../../boot/boot.c"
, 620, __PRETTY_FUNCTION__))
;
621 write (2, msg, strlen (msg));
622 free (msg);
623 host_exitexit (1);
624 }
625 }
626 }
627
628 /* Parse the boot script. */
629 {
630 char *p, *line;
631 static const char filemsg[] = "Can't open boot script\n";
632 static const char memmsg[] = "Not enough memory\n";
633 int amt, fd, err;
634
635 fd = open (bootscript, O_RDONLY0x0001, 0);
636 if (fd < 0)
637 {
638 write (2, filemsg, sizeof (filemsg));
639 host_exitexit (1);
640 }
641 p = buf = malloc (500);
642 if (!buf)
643 {
644 write (2, memmsg, sizeof (memmsg));
645 host_exitexit (1);
646 }
647 len = 500;
648 amt = 0;
649 while (1)
650 {
651 i = read (fd, p, len - (p - buf));
652 if (i <= 0)
653 break;
654 p += i;
655 amt += i;
656 if (p == buf + len)
657 {
658 char *newbuf;
659
660 len += 500;
661 newbuf = realloc (buf, len);
662 if (!newbuf)
663 {
664 write (2, memmsg, sizeof (memmsg));
665 host_exitexit (1);
666 }
667 p = newbuf + (p - buf);
668 buf = newbuf;
669 }
670 }
671 line = p = buf;
672 while (1)
673 {
674 while (p < buf + amt && *p != '\n')
675 p++;
676 *p = '\0';
677 err = boot_script_parse_line (0, line);
678 if (err)
679 {
680 char *str;
681 int i;
682
683 str = boot_script_error_string (err);
684 i = strlen (str);
685 write (2, str, i);
686 write (2, " in `", 5);
687 write (2, line, strlen (line));
688 write (2, "'\n", 2);
689 host_exitexit (1);
690 }
691 if (p == buf + amt)
692 break;
693 line = ++p;
694 }
695 }
696
697 if (index (bootstrap_args, 'd'))
698 {
699 static const char msg[] = "Pausing. . .";
700 char c;
701 write (2, msg, sizeof (msg) - 1);
702 read (0, &c, 1);
703 }
704
705 init_termstate ();
706
707 /* The boot script has now been parsed into internal data structures.
708 Now execute its directives. */
709 {
710 int err;
711
712 err = boot_script_exec ();
713 if (err)
714 {
715 char *str = boot_script_error_string (err);
716 int i = strlen (str);
717
718 write (2, str, i);
719 write (2, "\n", 1);
720 host_exitexit (1);
721 }
722 free (buf);
723 }
724
725 mach_port_deallocate (mach_task_self ()((__mach_task_self_ + 0)), pseudo_master_device_port);
726
727 err = pthread_create (&pthread_id, NULL((void*)0), msg_thread, NULL((void*)0));
728 if (!err)
729 pthread_detach (pthread_id);
730 else
731 {
732 errno(*__errno_location ()) = err;
733 perror ("pthread_create");
734 }
735
736 for (;;)
737 {
738 fd_set rmask;
739 FD_ZERO (&rmask)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosl"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&rmask)->fds_bits)[0
]) : "memory"); } while (0)
;
740 FD_SET (0, &rmask)((void) (((&rmask)->fds_bits)[((0) / (8 * (int) sizeof
(__fd_mask)))] |= ((__fd_mask) 1 << ((0) % (8 * (int) sizeof
(__fd_mask))))))
;
741 if (select (1, &rmask, 0, 0, 0) == 1)
742 read_reply ();
743 else /* We hosed */
744 error (5, errno(*__errno_location ()), "select");
745 }
746}
747
748void *
749msg_thread (void *arg)
750{
751 while (1)
752 mach_msg_server (boot_demuxer, 0, receive_set);
753}
754
755
756enum read_type
757{
758 DEV_READ,
759 DEV_READI,
760 IO_READ,
761};
762struct qr
763{
764 enum read_type type;
765 mach_port_t reply_port;
766 mach_msg_type_name_t reply_type;
767 int amount;
768 struct qr *next;
769};
770struct qr *qrhead, *qrtail;
771
772/* Queue a read for later reply. */
773kern_return_t
774queue_read (enum read_type type,
775 mach_port_t reply_port,
776 mach_msg_type_name_t reply_type,
777 int amount)
778{
779 struct qr *qr;
780
781 qr = malloc (sizeof (struct qr));
782 if (!qr)
783 return D_NO_MEMORY2508;
784
785 pthread_spin_lock (&queuelock);
786
787 qr->type = type;
788 qr->reply_port = reply_port;
789 qr->reply_type = reply_type;
790 qr->amount = amount;
791 qr->next = 0;
792 if (qrtail)
793 qrtail->next = qr;
794 else
795 qrhead = qrtail = qr;
796
797 pthread_spin_unlock (&queuelock);
798 return D_SUCCESS0;
799}
800
801/* TRUE if there's data available on stdin, which should be used to satisfy
802 console read requests. */
803static int should_read = 0;
804
805/* Reply to a queued read. */
806void
807read_reply ()
808{
809 int avail;
810 struct qr *qr;
811 char * buf;
812 int amtread;
813
814 /* By forcing SHOULD_READ to true before trying the lock, we ensure that
815 either we get the lock ourselves or that whoever currently holds the
816 lock will service this read when he unlocks it. */
817 should_read = 1;
818 if (pthread_spin_trylock (&readlock))
819 return;
820
821 /* Since we're committed to servicing the read, no one else need do so. */
822 should_read = 0;
823
824 ioctl (0, FIONREAD(((127)) | ((((('f')) - 'f') | ((((0) | (((0) | ((1) | ((0) |
((0) | ((sizeof (int) == 8 ? IOC_64 : (enum __ioctl_datum) (
sizeof (int) >> 1))) << 2) << 2) << 5
) << 5) << 3))) | (IOC_OUT) << 19) <<
4) << 7))
, &avail);
825 if (!avail)
826 {
827 pthread_spin_unlock (&readlock);
828 return;
829 }
830
831 pthread_spin_lock (&queuelock);
832
833 if (!qrhead)
834 {
835 pthread_spin_unlock (&queuelock);
836 pthread_spin_unlock (&readlock);
837 return;
838 }
839
840 qr = qrhead;
841 qrhead = qr->next;
842 if (qr == qrtail)
843 qrtail = 0;
844
845 pthread_spin_unlock (&queuelock);
846
847 if (qr->type == DEV_READ)
848 buf = mmap (0, qr->amount, PROT_READ0x04|PROT_WRITE0x02, MAP_ANON0x0002, 0, 0);
849 else
850 buf = alloca (qr->amount)__builtin_alloca (qr->amount);
851 amtread = read (0, buf, qr->amount);
852
853 pthread_spin_unlock (&readlock);
854
855 switch (qr->type)
856 {
857 case DEV_READ:
858 if (amtread >= 0)
859 ds_device_read_reply (qr->reply_port, qr->reply_type, 0,
860 (io_buf_ptr_t) buf, amtread);
861 else
862 ds_device_read_reply (qr->reply_port, qr->reply_type, errno(*__errno_location ()), 0, 0);
863 break;
864
865 case DEV_READI:
866 if (amtread >= 0)
867 ds_device_read_reply_inband (qr->reply_port, qr->reply_type, 0,
868 buf, amtread);
869 else
870 ds_device_read_reply_inband (qr->reply_port, qr->reply_type, errno(*__errno_location ()),
871 0, 0);
872 break;
873
874 case IO_READ:
875 if (amtread >= 0)
876 io_read_reply (qr->reply_port, qr->reply_type, 0,
877 buf, amtread);
878 else
879 io_read_reply (qr->reply_port, qr->reply_type, errno(*__errno_location ()), 0, 0);
880 break;
881 }
882
883 free (qr);
884}
885
886/* Unlock READLOCK, and also service any new read requests that it was
887 blocking. */
888static void
889unlock_readlock ()
890{
891 pthread_spin_unlock (&readlock);
892 while (should_read)
893 read_reply ();
894}
895
896/*
897 * Handle bootstrap requests.
898 */
899kern_return_t
900do_bootstrap_privileged_ports(bootstrap, hostp, devicep)
901 mach_port_t bootstrap;
902 mach_port_t *hostp, *devicep;
903{
904 *hostp = privileged_host_port;
905 *devicep = pseudo_master_device_port;
906 return KERN_SUCCESS0;
907}
908
909/* Implementation of device interface */
910
911kern_return_t
912ds_device_open (mach_port_t master_port,
913 mach_port_t reply_port,
914 mach_msg_type_name_t reply_type,
915 dev_mode_t mode,
916 dev_name_t name,
917 mach_port_t *device,
918 mach_msg_type_name_t *devicetype)
919{
920 struct dev_map *map;
921
922 if (master_port != pseudo_master_device_port)
923 return D_INVALID_OPERATION2505;
924
925 if (!strcmp (name, "console"))
926 {
927#if 0
928 mach_port_insert_right (mach_task_self ()((__mach_task_self_ + 0)), pseudo_console,
929 pseudo_console, MACH_MSG_TYPE_MAKE_SEND20);
930 console_send_rights++;
931#endif
932 console_mscount++;
933 *device = pseudo_console;
934 *devicetype = MACH_MSG_TYPE_MAKE_SEND20;
935 return 0;
936 }
937 else if (!strcmp (name, "time"))
938 {
939 *device = pseudo_time;
940 *devicetype = MACH_MSG_TYPE_MAKE_SEND20;
941 return 0;
942 }
943 else if (strcmp (name, "pseudo-root") == 0)
944 /* Magic root device. */
945 {
946 *device = pseudo_root;
947 *devicetype = MACH_MSG_TYPE_MAKE_SEND20;
948 return 0;
949 }
950
951 map = lookup_dev (name);
952 if (map)
953 {
954 *devicetype = MACH_MSG_TYPE_MOVE_SEND17;
955 return device_open (map->port, mode, "", device);
956 }
957
958 *devicetype = MACH_MSG_TYPE_MOVE_SEND17;
959 return device_open (master_device_port, mode, name, device);
960}
961
962kern_return_t
963ds_device_close (device_t device)
964{
965 if (device != pseudo_console && device != pseudo_root)
966 return D_NO_SUCH_DEVICE2502;
967 return 0;
968}
969
970kern_return_t
971ds_device_write (device_t device,
972 mach_port_t reply_port,
973 mach_msg_type_name_t reply_type,
974 dev_mode_t mode,
975 recnum_t recnum,
976 io_buf_ptr_t data,
977 size_t datalen,
978 int *bytes_written)
979{
980 if (device == pseudo_console)
981 {
982#if 0
983 if (console_send_rights)
984 {
985 mach_port_mod_refs (mach_task_self ()((__mach_task_self_ + 0)), pseudo_console,
986 MACH_PORT_TYPE_SEND((mach_port_type_t)(1 << ((((mach_port_right_t) 0))+16)
))
, -console_send_rights);
987 console_send_rights = 0;
988 }
989#endif
990
991 *bytes_written = write (1, data, datalen);
992
993 return (*bytes_written == -1 ? D_IO_ERROR2500 : D_SUCCESS0);
994 }
995 else if (device == pseudo_root)
996 {
997 size_t wrote;
998 if (store_write (root_store, recnum, data, datalen, &wrote) != 0)
999 return D_IO_ERROR2500;
1000 *bytes_written = wrote;
1001 return D_SUCCESS0;
1002 }
1003 else
1004 return D_NO_SUCH_DEVICE2502;
1005}
1006
1007kern_return_t
1008ds_device_write_inband (device_t device,
1009 mach_port_t reply_port,
1010 mach_msg_type_name_t reply_type,
1011 dev_mode_t mode,
1012 recnum_t recnum,
1013 io_buf_ptr_inband_t data,
1014 size_t datalen,
1015 int *bytes_written)
1016{
1017 if (device == pseudo_console)
1018 {
1019#if 0
1020 if (console_send_rights)
1021 {
1022 mach_port_mod_refs (mach_task_self ()((__mach_task_self_ + 0)), pseudo_console,
1023 MACH_PORT_TYPE_SEND((mach_port_type_t)(1 << ((((mach_port_right_t) 0))+16)
))
, -console_send_rights);
1024 console_send_rights = 0;
1025 }
1026#endif
1027
1028 *bytes_written = write (1, data, datalen);
1029
1030 return (*bytes_written == -1 ? D_IO_ERROR2500 : D_SUCCESS0);
1031 }
1032 else if (device == pseudo_root)
1033 {
1034 size_t wrote;
1035 if (store_write (root_store, recnum, data, datalen, &wrote) != 0)
1036 return D_IO_ERROR2500;
1037 *bytes_written = wrote;
1038 return D_SUCCESS0;
1039 }
1040 else
1041 return D_NO_SUCH_DEVICE2502;
1042}
1043
1044kern_return_t
1045ds_device_read (device_t device,
1046 mach_port_t reply_port,
1047 mach_msg_type_name_t reply_type,
1048 dev_mode_t mode,
1049 recnum_t recnum,
1050 int bytes_wanted,
1051 io_buf_ptr_t *data,
1052 size_t *datalen)
1053{
1054 if (device == pseudo_console)
1055 {
1056 int avail;
1057
1058#if 0
1059 if (console_send_rights)
1060 {
1061 mach_port_mod_refs (mach_task_self ()((__mach_task_self_ + 0)), pseudo_console,
1062 MACH_PORT_TYPE_SEND((mach_port_type_t)(1 << ((((mach_port_right_t) 0))+16)
))
, -console_send_rights);
1063 console_send_rights = 0;
1064 }
1065#endif
1066
1067 pthread_spin_lock (&readlock);
1068 ioctl (0, FIONREAD(((127)) | ((((('f')) - 'f') | ((((0) | (((0) | ((1) | ((0) |
((0) | ((sizeof (int) == 8 ? IOC_64 : (enum __ioctl_datum) (
sizeof (int) >> 1))) << 2) << 2) << 5
) << 5) << 3))) | (IOC_OUT) << 19) <<
4) << 7))
, &avail);
1069 if (avail)
1070 {
1071 *data = mmap (0, bytes_wanted, PROT_READ0x04|PROT_WRITE0x02, MAP_ANON0x0002, 0, 0);
1072 *datalen = read (0, *data, bytes_wanted);
1073 unlock_readlock ();
1074 return (*datalen == -1 ? D_IO_ERROR2500 : D_SUCCESS0);
1075 }
1076 else
1077 {
1078 kern_return_t err;
1079
1080 unlock_readlock ();
1081 err = queue_read (DEV_READ, reply_port, reply_type, bytes_wanted);
1082 if (err)
1083 return err;
1084 return MIG_NO_REPLY-305;
1085 }
1086 }
1087 else if (device == pseudo_root)
1088 {
1089 *datalen = 0;
1090 return
1091 (store_read (root_store, recnum, bytes_wanted, (void **)data, datalen) == 0
1092 ? D_SUCCESS0
1093 : D_IO_ERROR2500);
1094 }
1095 else
1096 return D_NO_SUCH_DEVICE2502;
1097}
1098
1099kern_return_t
1100ds_device_read_inband (device_t device,
1101 mach_port_t reply_port,
1102 mach_msg_type_name_t reply_type,
1103 dev_mode_t mode,
1104 recnum_t recnum,
1105 int bytes_wanted,
1106 io_buf_ptr_inband_t data,
1107 size_t *datalen)
1108{
1109 if (device == pseudo_console)
1110 {
1111 int avail;
1112
1113#if 0
1114 if (console_send_rights)
1115 {
1116 mach_port_mod_refs (mach_task_self ()((__mach_task_self_ + 0)), pseudo_console,
1117 MACH_PORT_TYPE_SEND((mach_port_type_t)(1 << ((((mach_port_right_t) 0))+16)
))
, -console_send_rights);
1118 console_send_rights = 0;
1119 }
1120#endif
1121
1122 pthread_spin_lock (&readlock);
1123 ioctl (0, FIONREAD(((127)) | ((((('f')) - 'f') | ((((0) | (((0) | ((1) | ((0) |
((0) | ((sizeof (int) == 8 ? IOC_64 : (enum __ioctl_datum) (
sizeof (int) >> 1))) << 2) << 2) << 5
) << 5) << 3))) | (IOC_OUT) << 19) <<
4) << 7))
, &avail);
1124 if (avail)
1125 {
1126 *datalen = read (0, data, bytes_wanted);
1127 unlock_readlock ();
1128 return (*datalen == -1 ? D_IO_ERROR2500 : D_SUCCESS0);
1129 }
1130 else
1131 {
1132 kern_return_t err;
1133
1134 unlock_readlock ();
1135 err = queue_read (DEV_READI, reply_port, reply_type, bytes_wanted);
1136 if (err)
1137 return err;
1138 return MIG_NO_REPLY-305;
1139 }
1140 }
1141 else if (device == pseudo_root)
1142 {
1143 error_t err;
1144 void *returned = data;
1145
1146 *datalen = bytes_wanted;
1147 err =
1148 store_read (root_store, recnum, bytes_wanted, (void **)&returned, datalen);
1149
1150 if (! err)
1151 {
1152 if (returned != data)
1153 {
1154 bcopy (returned, (void *)data, *datalen);
1155 munmap ((caddr_t) returned, *datalen);
1156 }
1157 return D_SUCCESS0;
1158 }
1159 else
1160 return D_IO_ERROR2500;
1161 }
1162 else
1163 return D_NO_SUCH_DEVICE2502;
1164}
1165
1166kern_return_t
1167ds_device_map (device_t device,
1168 vm_prot_t prot,
1169 vm_offset_t offset,
1170 vm_size_t size,
1171 memory_object_t *pager,
1172 int unmap)
1173{
1174 if (device == pseudo_console || device == pseudo_root)
1175 return D_INVALID_OPERATION2505;
1176 else if (device == pseudo_time)
1177 {
1178 error_t err;
1179 mach_port_t wr_memobj;
1180 file_t node = file_name_lookup ("/dev/time", O_RDONLY0x0001, 0);
1181
1182 if (node == MACH_PORT_NULL((mach_port_t) 0))
1183 return D_IO_ERROR2500;
1184
1185 err = io_map (node, pager, &wr_memobj);
1186 if (!err && MACH_PORT_VALID (wr_memobj)(((wr_memobj) != ((mach_port_t) 0)) && ((wr_memobj) !=
((mach_port_t) ~0)))
)
1187 mach_port_deallocate (mach_task_self ()((__mach_task_self_ + 0)), wr_memobj);
1188
1189 mach_port_deallocate (mach_task_self ()((__mach_task_self_ + 0)), node);
1190 return D_SUCCESS0;
1191 }
1192 else
1193 return D_NO_SUCH_DEVICE2502;
1194}
1195
1196kern_return_t
1197ds_device_set_status (device_t device,
1198 dev_flavor_t flavor,
1199 dev_status_t status,
1200 size_t statuslen)
1201{
1202 if (device != pseudo_console && device != pseudo_root)
1203 return D_NO_SUCH_DEVICE2502;
1204 return D_INVALID_OPERATION2505;
1205}
1206
1207kern_return_t
1208ds_device_get_status (device_t device,
1209 dev_flavor_t flavor,
1210 dev_status_t status,
1211 size_t *statuslen)
1212{
1213 if (device == pseudo_console)
1214 return D_INVALID_OPERATION2505;
1215 else if (device == pseudo_root)
1216 switch (flavor)
1217 {
1218 case DEV_GET_SIZE0:
1219 if (*statuslen < DEV_GET_SIZE_COUNT2)
1220 return D_INVALID_SIZE2507;
1221 status[DEV_GET_SIZE_DEVICE_SIZE0] = root_store->size;
1222 status[DEV_GET_SIZE_RECORD_SIZE1] = root_store->block_size;
1223 *statuslen = DEV_GET_SIZE_COUNT2;
1224 return D_SUCCESS0;
1225
1226 case DEV_GET_RECORDS1:
1227 if (*statuslen < DEV_GET_RECORDS_COUNT2)
1228 return D_INVALID_SIZE2507;
1229 status[DEV_GET_RECORDS_DEVICE_RECORDS0] = root_store->blocks;
1230 status[DEV_GET_RECORDS_RECORD_SIZE1] = root_store->block_size;
1231 *statuslen = DEV_GET_RECORDS_COUNT2;
1232 return D_SUCCESS0;
1233
1234 default:
1235 return D_INVALID_OPERATION2505;
1236 }
1237 else
1238 return D_NO_SUCH_DEVICE2502;
1239}
1240
1241kern_return_t
1242ds_device_set_filter (device_t device,
1243 mach_port_t receive_port,
1244 int priority,
1245 filter_array_t filter,
1246 size_t filterlen)
1247{
1248 if (device != pseudo_console && device != pseudo_root)
1249 return D_NO_SUCH_DEVICE2502;
1250 return D_INVALID_OPERATION2505;
1251}
1252
1253
1254/* Implementation of notify interface */
1255kern_return_t
1256do_mach_notify_port_deleted (mach_port_t notify,
1257 mach_port_t name)
1258{
1259 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1260}
1261
1262kern_return_t
1263do_mach_notify_msg_accepted (mach_port_t notify,
1264 mach_port_t name)
1265{
1266 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1267}
1268
1269kern_return_t
1270do_mach_notify_port_destroyed (mach_port_t notify,
1271 mach_port_t port)
1272{
1273 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1274}
1275
1276kern_return_t
1277do_mach_notify_no_senders (mach_port_t notify,
1278 mach_port_mscount_t mscount)
1279{
1280 static int no_console;
1281 mach_port_t foo;
1282 if (notify == pseudo_master_device_port)
1283 {
1284 if (no_console)
1285 goto bye;
1286 pseudo_master_device_port = MACH_PORT_NULL((mach_port_t) 0);
1287 return 0;
1288 }
1289 if (notify == pseudo_console)
1290 {
1291 if (mscount == console_mscount &&
1292 pseudo_master_device_port == MACH_PORT_NULL((mach_port_t) 0))
1293 {
1294 bye:
1295 restore_termstate ();
1296 write (2, "bye\n", 4);
1297 host_exitexit (0);
1298 }
1299 else
1300 {
1301 no_console = (mscount == console_mscount);
1302
1303 mach_port_request_notification (mach_task_self ()((__mach_task_self_ + 0)), pseudo_console,
1304 MACH_NOTIFY_NO_SENDERS(0100 + 006),
1305 console_mscount == mscount
1306 ? mscount + 1
1307 : console_mscount,
1308 pseudo_console,
1309 MACH_MSG_TYPE_MAKE_SEND_ONCE21, &foo);
1310 if (foo != MACH_PORT_NULL((mach_port_t) 0))
1311 mach_port_deallocate (mach_task_self ()((__mach_task_self_ + 0)), foo);
1312 }
1313 }
1314
1315 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1316}
1317
1318kern_return_t
1319do_mach_notify_send_once (mach_port_t notify)
1320{
1321 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1322}
1323
1324kern_return_t
1325do_mach_notify_dead_name (mach_port_t notify,
1326 mach_port_t name)
1327{
1328#if 0
1329 if (name == child_task && notify == bootport)
1330 host_exitexit (0);
1331#endif
1332 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1333}
1334
1335
1336/* Implementation of the Hurd I/O interface, which
1337 we support for the console port only. */
1338
1339kern_return_t
1340S_io_write (mach_port_t object,
1341 mach_port_t reply_port,
1342 mach_msg_type_name_t reply_type,
1343 char *data,
1344 mach_msg_type_number_t datalen,
1345 off_t offset,
1346 mach_msg_type_number_t *amtwritten)
1347{
1348 if (object != pseudo_console)
1349 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1350
1351#if 0
1352 if (console_send_rights)
1353 {
1354 mach_port_mod_refs (mach_task_self ()((__mach_task_self_ + 0)), pseudo_console,
1355 MACH_PORT_TYPE_SEND((mach_port_type_t)(1 << ((((mach_port_right_t) 0))+16)
))
, -console_send_rights);
1356 console_send_rights = 0;
1357 }
1358#endif
1359
1360 *amtwritten = write (1, data, datalen);
1361 return *amtwritten == -1 ? errno(*__errno_location ()) : 0;
1362}
1363
1364kern_return_t
1365S_io_read (mach_port_t object,
1366 mach_port_t reply_port,
1367 mach_msg_type_name_t reply_type,
1368 char **data,
1369 mach_msg_type_number_t *datalen,
1370 off_t offset,
1371 mach_msg_type_number_t amount)
1372{
1373 mach_msg_type_number_t avail;
1374
1375 if (object != pseudo_console)
1376 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1377
1378#if 0
1379 if (console_send_rights)
1380 {
1381 mach_port_mod_refs (mach_task_self ()((__mach_task_self_ + 0)), pseudo_console,
1382 MACH_PORT_TYPE_SEND((mach_port_type_t)(1 << ((((mach_port_right_t) 0))+16)
))
, -console_send_rights);
1383 console_send_rights = 0;
1384 }
1385#endif
1386
1387 pthread_spin_lock (&readlock);
1388 ioctl (0, FIONREAD(((127)) | ((((('f')) - 'f') | ((((0) | (((0) | ((1) | ((0) |
((0) | ((sizeof (int) == 8 ? IOC_64 : (enum __ioctl_datum) (
sizeof (int) >> 1))) << 2) << 2) << 5
) << 5) << 3))) | (IOC_OUT) << 19) <<
4) << 7))
, &avail);
1389 if (avail)
1390 {
1391 if (amount > *datalen)
1392 *data = mmap (0, amount, PROT_READ0x04|PROT_WRITE0x02, MAP_ANON0x0002, 0, 0);
1393 *datalen = read (0, *data, amount);
1394 unlock_readlock ();
1395 return *datalen == -1 ? errno(*__errno_location ()) : 0;
1396 }
1397 else
1398 {
1399 kern_return_t err;
1400 unlock_readlock ();
1401 err = queue_read (IO_READ, reply_port, reply_type, amount);
1402 if (err)
1403 return err;
1404 return MIG_NO_REPLY-305;
1405 }
1406}
1407
1408kern_return_t
1409S_io_seek (mach_port_t object,
1410 mach_port_t reply_port,
1411 mach_msg_type_name_t reply_type,
1412 off_t offset,
1413 int whence,
1414 off_t *newp)
1415{
1416 return object == pseudo_console ? ESPIPE((0x10 << 26) | ((29) & 0x3fff)) : EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1417}
1418
1419kern_return_t
1420S_io_readable (mach_port_t object,
1421 mach_port_t reply_port,
1422 mach_msg_type_name_t reply_type,
1423 mach_msg_type_number_t *amt)
1424{
1425 if (object != pseudo_console)
1426 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1427 ioctl (0, FIONREAD(((127)) | ((((('f')) - 'f') | ((((0) | (((0) | ((1) | ((0) |
((0) | ((sizeof (int) == 8 ? IOC_64 : (enum __ioctl_datum) (
sizeof (int) >> 1))) << 2) << 2) << 5
) << 5) << 3))) | (IOC_OUT) << 19) <<
4) << 7))
, amt);
1428 return 0;
1429}
1430
1431kern_return_t
1432S_io_set_all_openmodes (mach_port_t object,
1433 mach_port_t reply_port,
1434 mach_msg_type_name_t reply_type,
1435 int bits)
1436{
1437 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1438}
1439
1440kern_return_t
1441S_io_get_openmodes (mach_port_t object,
1442 mach_port_t reply_port,
1443 mach_msg_type_name_t reply_type,
1444 int *modes)
1445{
1446 *modes = O_READ0x0001 | O_WRITE0x0002;
1447 return object == pseudo_console ? 0 : EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1448}
1449
1450kern_return_t
1451S_io_set_some_openmodes (mach_port_t object,
1452 mach_port_t reply_port,
1453 mach_msg_type_name_t reply_type,
1454 int bits)
1455{
1456 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1457}
1458
1459kern_return_t
1460S_io_clear_some_openmodes (mach_port_t object,
1461 mach_port_t reply_port,
1462 mach_msg_type_name_t reply_type,
1463 int bits)
1464{
1465 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1466}
1467
1468kern_return_t
1469S_io_async (mach_port_t object,
1470 mach_port_t reply_port,
1471 mach_msg_type_name_t reply_type,
1472 mach_port_t notify,
1473 mach_port_t *id,
1474 mach_msg_type_name_t *idtype)
1475{
1476 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1477}
1478
1479kern_return_t
1480S_io_mod_owner (mach_port_t object,
1481 mach_port_t reply_port,
1482 mach_msg_type_name_t reply_type,
1483 pid_t owner)
1484{
1485 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1486}
1487
1488kern_return_t
1489S_io_get_owner (mach_port_t object,
1490 mach_port_t reply_port,
1491 mach_msg_type_name_t reply_type,
1492 pid_t *owner)
1493{
1494 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1495}
1496
1497kern_return_t
1498S_io_get_icky_async_id (mach_port_t object,
1499 mach_port_t reply_port,
1500 mach_msg_type_name_t reply_type,
1501 mach_port_t *id,
1502 mach_msg_type_name_t *idtype)
1503{
1504 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1505}
1506
1507static kern_return_t
1508io_select_common (mach_port_t object,
1509 mach_port_t reply_port,
1510 mach_msg_type_name_t reply_type,
1511 struct timespec *tsp, int *type)
1512{
1513 struct timeval tv, *tvp;
1514 fd_set r, w, x;
1515 int n;
1516
1517 if (object != pseudo_console)
2
Taking false branch
1518 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1519
1520 FD_ZERO (&r)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosl"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&r)->fds_bits)[0]) :
"memory"); } while (0)
;
1521 FD_ZERO (&w)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosl"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&w)->fds_bits)[0]) :
"memory"); } while (0)
;
1522 FD_ZERO (&x)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosl"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&x)->fds_bits)[0]) :
"memory"); } while (0)
;
1523 FD_SET (0, &r)((void) (((&r)->fds_bits)[((0) / (8 * (int) sizeof (__fd_mask
)))] |= ((__fd_mask) 1 << ((0) % (8 * (int) sizeof (__fd_mask
))))))
;
3
Within the expansion of the macro 'FD_SET':
a
The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage
1524 FD_SET (0, &w)((void) (((&w)->fds_bits)[((0) / (8 * (int) sizeof (__fd_mask
)))] |= ((__fd_mask) 1 << ((0) % (8 * (int) sizeof (__fd_mask
))))))
;
1525 FD_SET (0, &x)((void) (((&x)->fds_bits)[((0) / (8 * (int) sizeof (__fd_mask
)))] |= ((__fd_mask) 1 << ((0) % (8 * (int) sizeof (__fd_mask
))))))
;
1526
1527 if (tsp == NULL((void*)0))
1528 tvp = NULL((void*)0);
1529 else
1530 {
1531 tv.tv_sec = tsp->tv_sec;
1532 tv.tv_usec = tsp->tv_nsec / 1000;
1533 tvp = &tv;
1534 }
1535
1536 n = select (1,
1537 (*type & SELECT_READ0x00000001) ? &r : 0,
1538 (*type & SELECT_WRITE0x00000002) ? &w : 0,
1539 (*type & SELECT_URG0x00000004) ? &x : 0,
1540 tvp);
1541 if (n < 0)
1542 return errno(*__errno_location ());
1543
1544 if (! FD_ISSET (0, &r)((((&r)->fds_bits)[((0) / (8 * (int) sizeof (__fd_mask
)))] & ((__fd_mask) 1 << ((0) % (8 * (int) sizeof (
__fd_mask))))) != 0)
)
1545 *type &= ~SELECT_READ0x00000001;
1546 if (! FD_ISSET (0, &w)((((&w)->fds_bits)[((0) / (8 * (int) sizeof (__fd_mask
)))] & ((__fd_mask) 1 << ((0) % (8 * (int) sizeof (
__fd_mask))))) != 0)
)
1547 *type &= ~SELECT_WRITE0x00000002;
1548 if (! FD_ISSET (0, &x)((((&x)->fds_bits)[((0) / (8 * (int) sizeof (__fd_mask
)))] & ((__fd_mask) 1 << ((0) % (8 * (int) sizeof (
__fd_mask))))) != 0)
)
1549 *type &= ~SELECT_URG0x00000004;
1550
1551 return 0;
1552}
1553
1554kern_return_t
1555S_io_select (mach_port_t object,
1556 mach_port_t reply_port,
1557 mach_msg_type_name_t reply_type,
1558 int *type)
1559{
1560 return io_select_common (object, reply_port, reply_type, NULL((void*)0), type);
1561}
1562
1563kern_return_t
1564S_io_select_timeout (mach_port_t object,
1565 mach_port_t reply_port,
1566 mach_msg_type_name_t reply_type,
1567 struct timespec ts,
1568 int *type)
1569{
1570 return io_select_common (object, reply_port, reply_type, &ts, type);
1
Calling 'io_select_common'
1571}
1572
1573kern_return_t
1574S_io_stat (mach_port_t object,
1575 mach_port_t reply_port,
1576 mach_msg_type_name_t reply_type,
1577 struct stat *st)
1578{
1579 if (object != pseudo_console)
1580 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1581
1582 memset (st, 0, sizeof(struct stat));
1583 st->st_blksize = 1024;
1584 return 0;
1585}
1586
1587kern_return_t
1588S_io_reauthenticate (mach_port_t object,
1589 mach_port_t reply_port,
1590 mach_msg_type_name_t reply_type,
1591 mach_port_t rend)
1592{
1593 uid_t *gu, *au;
1594 gid_t *gg, *ag;
1595 size_t gulen = 0, aulen = 0, gglen = 0, aglen = 0;
1596 error_t err;
1597
1598 err = mach_port_insert_right (mach_task_self ()((__mach_task_self_ + 0)), object, object,
1599 MACH_MSG_TYPE_MAKE_SEND20);
1600 assert_perror (err)(!(err) ? (void) (0) : __assert_perror_fail ((err), "../../boot/boot.c"
, 1600, __PRETTY_FUNCTION__))
;
1601
1602 if (! auth_server_authenticate (authserver,
1603 rend, MACH_MSG_TYPE_COPY_SEND19,
1604 object, MACH_MSG_TYPE_COPY_SEND19,
1605 &gu, &gulen,
1606 &au, &aulen,
1607 &gg, &gglen,
1608 &ag, &aglen))
1609 {
1610 mig_deallocate ((vm_address_t) gu, gulen * sizeof *gu);
1611 mig_deallocate ((vm_address_t) au, aulen * sizeof *gu);
1612 mig_deallocate ((vm_address_t) gg, gglen * sizeof *gu);
1613 mig_deallocate ((vm_address_t) au, aulen * sizeof *gu);
1614 }
1615 mach_port_deallocate (mach_task_self ()((__mach_task_self_ + 0)), rend);
1616 mach_port_deallocate (mach_task_self ()((__mach_task_self_ + 0)), object);
1617
1618 return 0;
1619}
1620
1621kern_return_t
1622S_io_restrict_auth (mach_port_t object,
1623 mach_port_t reply_port,
1624 mach_msg_type_name_t reply_type,
1625 mach_port_t *newobject,
1626 mach_msg_type_name_t *newobjtype,
1627 uid_t *uids,
1628 size_t nuids,
1629 uid_t *gids,
1630 size_t ngids)
1631{
1632 if (object != pseudo_console)
1633 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1634 *newobject = pseudo_console;
1635 *newobjtype = MACH_MSG_TYPE_MAKE_SEND20;
1636 console_mscount++;
1637 return 0;
1638}
1639
1640kern_return_t
1641S_io_duplicate (mach_port_t object,
1642 mach_port_t reply_port,
1643 mach_msg_type_name_t reply_type,
1644 mach_port_t *newobj,
1645 mach_msg_type_name_t *newobjtype)
1646{
1647 if (object != pseudo_console)
1648 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1649 *newobj = pseudo_console;
1650 *newobjtype = MACH_MSG_TYPE_MAKE_SEND20;
1651 console_mscount++;
1652 return 0;
1653}
1654
1655kern_return_t
1656S_io_server_version (mach_port_t object,
1657 mach_port_t reply_port,
1658 mach_msg_type_name_t reply_type,
1659 char *name,
1660 int *maj,
1661 int *min,
1662 int *edit)
1663{
1664 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1665}
1666
1667kern_return_t
1668S_io_map (mach_port_t obj,
1669 mach_port_t reply_port,
1670 mach_msg_type_name_t reply_type,
1671 mach_port_t *rd,
1672 mach_msg_type_name_t *rdtype,
1673 mach_port_t *wr,
1674 mach_msg_type_name_t *wrtype)
1675{
1676 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1677}
1678
1679kern_return_t
1680S_io_map_cntl (mach_port_t obj,
1681 mach_port_t reply_port,
1682 mach_msg_type_name_t reply_type,
1683 mach_port_t *mem,
1684 mach_msg_type_name_t *memtype)
1685{
1686 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1687}
1688
1689kern_return_t
1690S_io_get_conch (mach_port_t obj,
1691 mach_port_t reply_port,
1692 mach_msg_type_name_t reply_type)
1693{
1694 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1695}
1696
1697kern_return_t
1698S_io_release_conch (mach_port_t obj,
1699 mach_port_t reply_port,
1700 mach_msg_type_name_t reply_type)
1701{
1702 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1703}
1704
1705kern_return_t
1706S_io_eofnotify (mach_port_t obj,
1707 mach_port_t reply_port,
1708 mach_msg_type_name_t reply_type)
1709
1710{
1711 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1712}
1713
1714kern_return_t
1715S_io_prenotify (mach_port_t obj,
1716 mach_port_t reply_port,
1717 mach_msg_type_name_t reply_type,
1718 vm_offset_t start,
1719 vm_offset_t end)
1720{
1721 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1722}
1723
1724kern_return_t
1725S_io_postnotify (mach_port_t obj,
1726 mach_port_t reply_port,
1727 mach_msg_type_name_t reply_type,
1728 vm_offset_t start,
1729 vm_offset_t end)
1730{
1731 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1732}
1733
1734kern_return_t
1735S_io_readsleep (mach_port_t obj,
1736 mach_port_t reply_port,
1737 mach_msg_type_name_t reply_type)
1738{
1739 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1740}
1741
1742kern_return_t
1743S_io_readnotify (mach_port_t obj,
1744 mach_port_t reply_port,
1745 mach_msg_type_name_t reply_type)
1746{
1747 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1748}
1749
1750
1751kern_return_t
1752S_io_sigio (mach_port_t obj,
1753 mach_port_t reply_port,
1754 mach_msg_type_name_t reply_type)
1755{
1756 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1757}
1758
1759
1760kern_return_t
1761S_io_pathconf (mach_port_t obj,
1762 mach_port_t reply_port,
1763 mach_msg_type_name_t reply_type,
1764 int name, int *value)
1765{
1766 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1767}
1768
1769kern_return_t
1770S_io_identity (mach_port_t obj,
1771 mach_port_t reply,
1772 mach_msg_type_name_t replytype,
1773 mach_port_t *id,
1774 mach_msg_type_name_t *idtype,
1775 mach_port_t *fsid,
1776 mach_msg_type_name_t *fsidtype,
1777 ino_t *fileno)
1778{
1779 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1780}
1781
1782kern_return_t
1783S_io_revoke (mach_port_t obj,
1784 mach_port_t reply, mach_msg_type_name_t replyPoly)
1785{
1786 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1787}
1788
1789
1790
1791/* Implementation of the Hurd terminal driver interface, which we only
1792 support on the console device. */
1793
1794kern_return_t
1795S_termctty_open_terminal (ctty_t object,
1796 int flags,
1797 mach_port_t *result,
1798 mach_msg_type_name_t *restype)
1799{
1800 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1801}
1802
1803kern_return_t
1804S_term_getctty (mach_port_t object,
1805 mach_port_t *cttyid, mach_msg_type_name_t *cttyPoly)
1806{
1807 static mach_port_t id = MACH_PORT_NULL((mach_port_t) 0);
1808
1809 if (object != pseudo_console)
1810 return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff));
1811
1812 if (id == MACH_PORT_NULL((mach_port_t) 0))
1813 mach_port_allocate (mach_task_self ()((__mach_task_self_ + 0)), MACH_PORT_RIGHT_DEAD_NAME((mach_port_right_t) 4), &id);
1814
1815 *cttyid = id;
1816 *cttyPoly = MACH_MSG_TYPE_COPY_SEND19;
1817 return 0;
1818}
1819
1820
1821kern_return_t S_term_open_ctty
1822(
1823 io_t terminal,
1824 pid_t pid,
1825 pid_t pgrp,
1826 mach_port_t *newtty,
1827 mach_msg_type_name_t *newttytype
1828)
1829{ return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff)); }
1830
1831kern_return_t S_term_set_nodename
1832(
1833 io_t terminal,
1834 string_t name
1835)
1836{ return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff)); }
1837
1838kern_return_t S_term_get_nodename
1839(
1840 io_t terminal,
1841 string_t name
1842)
1843{ return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff)); }
1844
1845kern_return_t S_term_get_peername
1846(
1847 io_t terminal,
1848 string_t name
1849)
1850{ return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff)); }
1851
1852kern_return_t S_term_set_filenode
1853(
1854 io_t terminal,
1855 file_t filenode
1856)
1857{ return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff)); }
1858
1859kern_return_t S_term_get_bottom_type
1860(
1861 io_t terminal,
1862 int *ttype
1863)
1864{ return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff)); }
1865
1866kern_return_t S_term_on_machdev
1867(
1868 io_t terminal,
1869 mach_port_t machdev
1870)
1871{ return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff)); }
1872
1873kern_return_t S_term_on_hurddev
1874(
1875 io_t terminal,
1876 io_t hurddev
1877)
1878{ return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff)); }
1879
1880kern_return_t S_term_on_pty
1881(
1882 io_t terminal,
1883 io_t *ptymaster
1884)
1885{ return EOPNOTSUPP((0x10 << 26) | ((45) & 0x3fff)); }