Statistics
| Branch: | Revision:

root / vl.c @ cbeb0857

History | View | Annotate | Download (195.9 kB)

1 0824d6fc bellard
/*
2 80cabfad bellard
 * QEMU System Emulator
3 0824d6fc bellard
 * 
4 84f2e8ef bellard
 * Copyright (c) 2003-2007 Fabrice Bellard
5 0824d6fc bellard
 * 
6 1df912cf bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 1df912cf bellard
 * of this software and associated documentation files (the "Software"), to deal
8 1df912cf bellard
 * in the Software without restriction, including without limitation the rights
9 1df912cf bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 1df912cf bellard
 * copies of the Software, and to permit persons to whom the Software is
11 1df912cf bellard
 * furnished to do so, subject to the following conditions:
12 1df912cf bellard
 *
13 1df912cf bellard
 * The above copyright notice and this permission notice shall be included in
14 1df912cf bellard
 * all copies or substantial portions of the Software.
15 1df912cf bellard
 *
16 1df912cf bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 1df912cf bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 1df912cf bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 1df912cf bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 1df912cf bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 1df912cf bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 1df912cf bellard
 * THE SOFTWARE.
23 0824d6fc bellard
 */
24 67b915a5 bellard
#include "vl.h"
25 67b915a5 bellard
26 0824d6fc bellard
#include <unistd.h>
27 0824d6fc bellard
#include <fcntl.h>
28 0824d6fc bellard
#include <signal.h>
29 0824d6fc bellard
#include <time.h>
30 0824d6fc bellard
#include <errno.h>
31 67b915a5 bellard
#include <sys/time.h>
32 c88676f8 bellard
#include <zlib.h>
33 67b915a5 bellard
34 67b915a5 bellard
#ifndef _WIN32
35 67b915a5 bellard
#include <sys/times.h>
36 f1510b2c bellard
#include <sys/wait.h>
37 67b915a5 bellard
#include <termios.h>
38 67b915a5 bellard
#include <sys/poll.h>
39 67b915a5 bellard
#include <sys/mman.h>
40 f1510b2c bellard
#include <sys/ioctl.h>
41 f1510b2c bellard
#include <sys/socket.h>
42 c94c8d64 bellard
#include <netinet/in.h>
43 9d728e8c bellard
#include <dirent.h>
44 7c9d8e07 bellard
#include <netdb.h>
45 7d3505c5 bellard
#ifdef _BSD
46 7d3505c5 bellard
#include <sys/stat.h>
47 83fb7adf bellard
#ifndef __APPLE__
48 7d3505c5 bellard
#include <libutil.h>
49 83fb7adf bellard
#endif
50 7d3505c5 bellard
#else
51 ec530c81 bellard
#ifndef __sun__
52 f1510b2c bellard
#include <linux/if.h>
53 f1510b2c bellard
#include <linux/if_tun.h>
54 7d3505c5 bellard
#include <pty.h>
55 7d3505c5 bellard
#include <malloc.h>
56 fd872598 bellard
#include <linux/rtc.h>
57 e57a8c0e bellard
#include <linux/ppdev.h>
58 5867c88a ths
#include <linux/parport.h>
59 d5d10bc3 ths
#else
60 d5d10bc3 ths
#include <sys/stat.h>
61 d5d10bc3 ths
#include <sys/ethernet.h>
62 d5d10bc3 ths
#include <sys/sockio.h>
63 d5d10bc3 ths
#include <arpa/inet.h>
64 d5d10bc3 ths
#include <netinet/arp.h>
65 d5d10bc3 ths
#include <netinet/in.h>
66 d5d10bc3 ths
#include <netinet/in_systm.h>
67 d5d10bc3 ths
#include <netinet/ip.h>
68 d5d10bc3 ths
#include <netinet/ip_icmp.h> // must come after ip.h
69 d5d10bc3 ths
#include <netinet/udp.h>
70 d5d10bc3 ths
#include <netinet/tcp.h>
71 d5d10bc3 ths
#include <net/if.h>
72 d5d10bc3 ths
#include <syslog.h>
73 d5d10bc3 ths
#include <stropts.h>
74 67b915a5 bellard
#endif
75 7d3505c5 bellard
#endif
76 ec530c81 bellard
#endif
77 67b915a5 bellard
78 c20709aa bellard
#if defined(CONFIG_SLIRP)
79 c20709aa bellard
#include "libslirp.h"
80 c20709aa bellard
#endif
81 c20709aa bellard
82 67b915a5 bellard
#ifdef _WIN32
83 7d3505c5 bellard
#include <malloc.h>
84 67b915a5 bellard
#include <sys/timeb.h>
85 67b915a5 bellard
#include <windows.h>
86 67b915a5 bellard
#define getopt_long_only getopt_long
87 67b915a5 bellard
#define memalign(align, size) malloc(size)
88 67b915a5 bellard
#endif
89 67b915a5 bellard
90 6ca957f0 bellard
#include "qemu_socket.h"
91 6ca957f0 bellard
92 73332e5c bellard
#ifdef CONFIG_SDL
93 96bcd4f8 bellard
#ifdef __APPLE__
94 83fb7adf bellard
#include <SDL/SDL.h>
95 96bcd4f8 bellard
#endif
96 73332e5c bellard
#endif /* CONFIG_SDL */
97 0824d6fc bellard
98 5b0753e0 bellard
#ifdef CONFIG_COCOA
99 5b0753e0 bellard
#undef main
100 5b0753e0 bellard
#define main qemu_main
101 5b0753e0 bellard
#endif /* CONFIG_COCOA */
102 5b0753e0 bellard
103 0824d6fc bellard
#include "disas.h"
104 fc01f7e7 bellard
105 8a7ddc38 bellard
#include "exec-all.h"
106 0824d6fc bellard
107 5a67135a bellard
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
108 a14d6c8c pbrook
#ifdef __sun__
109 a14d6c8c pbrook
#define SMBD_COMMAND "/usr/sfw/sbin/smbd"
110 a14d6c8c pbrook
#else
111 a14d6c8c pbrook
#define SMBD_COMMAND "/usr/sbin/smbd"
112 a14d6c8c pbrook
#endif
113 f1510b2c bellard
114 0824d6fc bellard
//#define DEBUG_UNUSED_IOPORT
115 fd872598 bellard
//#define DEBUG_IOPORT
116 330d0414 bellard
117 bb551faa bellard
#define PHYS_RAM_MAX_SIZE (2047 * 1024 * 1024)
118 7916e224 bellard
119 77d4bc34 bellard
#ifdef TARGET_PPC
120 77d4bc34 bellard
#define DEFAULT_RAM_SIZE 144
121 77d4bc34 bellard
#else
122 1bfe856e bellard
#define DEFAULT_RAM_SIZE 128
123 77d4bc34 bellard
#endif
124 8a7ddc38 bellard
/* in ms */
125 8a7ddc38 bellard
#define GUI_REFRESH_INTERVAL 30
126 313aa567 bellard
127 0d92ed30 pbrook
/* Max number of USB devices that can be specified on the commandline.  */
128 0d92ed30 pbrook
#define MAX_USB_CMDLINE 8
129 0d92ed30 pbrook
130 7dea1da4 bellard
/* XXX: use a two level table to limit memory usage */
131 7dea1da4 bellard
#define MAX_IOPORTS 65536
132 0824d6fc bellard
133 80cabfad bellard
const char *bios_dir = CONFIG_QEMU_SHAREDIR;
134 0824d6fc bellard
char phys_ram_file[1024];
135 c4b1fcc0 bellard
void *ioport_opaque[MAX_IOPORTS];
136 fc01f7e7 bellard
IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
137 fc01f7e7 bellard
IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
138 faea38e7 bellard
/* Note: bs_table[MAX_DISKS] is a dummy block driver if none available
139 faea38e7 bellard
   to store the VM snapshots */
140 faea38e7 bellard
BlockDriverState *bs_table[MAX_DISKS + 1], *fd_table[MAX_FD];
141 a1bb27b1 pbrook
BlockDriverState *sd_bdrv;
142 faea38e7 bellard
/* point to the block driver where the snapshots are managed */
143 faea38e7 bellard
BlockDriverState *bs_snapshots;
144 313aa567 bellard
int vga_ram_size;
145 313aa567 bellard
static DisplayState display_state;
146 a20dd508 bellard
int nographic;
147 3d11d0eb bellard
const char* keyboard_layout = NULL;
148 313aa567 bellard
int64_t ticks_per_sec;
149 36b486bb bellard
int boot_device = 'c';
150 0ced6589 bellard
int ram_size;
151 80cabfad bellard
int pit_min_timer_count = 0;
152 c4b1fcc0 bellard
int nb_nics;
153 7c9d8e07 bellard
NICInfo nd_table[MAX_NICS];
154 8a7ddc38 bellard
QEMUTimer *gui_timer;
155 8a7ddc38 bellard
int vm_running;
156 ee22c2f7 bellard
int rtc_utc = 1;
157 1bfe856e bellard
int cirrus_vga_enabled = 1;
158 d34cab9f ths
int vmsvga_enabled = 0;
159 d827220b bellard
#ifdef TARGET_SPARC
160 d827220b bellard
int graphic_width = 1024;
161 d827220b bellard
int graphic_height = 768;
162 d827220b bellard
#else
163 1bfe856e bellard
int graphic_width = 800;
164 1bfe856e bellard
int graphic_height = 600;
165 d827220b bellard
#endif
166 e9b137c2 bellard
int graphic_depth = 15;
167 d63d307f bellard
int full_screen = 0;
168 43523e93 ths
int no_frame = 0;
169 667accab ths
int no_quit = 0;
170 8d11df9e bellard
CharDriverState *serial_hds[MAX_SERIAL_PORTS];
171 6508fe59 bellard
CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
172 a09db21f bellard
#ifdef TARGET_I386
173 a09db21f bellard
int win2k_install_hack = 0;
174 a09db21f bellard
#endif
175 bb36d470 bellard
int usb_enabled = 0;
176 7c9d8e07 bellard
static VLANState *first_vlan;
177 6a00d601 bellard
int smp_cpus = 1;
178 73fc9742 ths
const char *vnc_display;
179 d3e9db93 bellard
#if defined(TARGET_SPARC)
180 ba3c64fb bellard
#define MAX_CPUS 16
181 d3e9db93 bellard
#elif defined(TARGET_I386)
182 d3e9db93 bellard
#define MAX_CPUS 255
183 ba3c64fb bellard
#else
184 d3e9db93 bellard
#define MAX_CPUS 1
185 ba3c64fb bellard
#endif
186 6515b203 bellard
int acpi_enabled = 1;
187 52ca8d6a bellard
int fd_bootchk = 1;
188 d1beab82 bellard
int no_reboot = 0;
189 71e3ceb8 ths
int daemonize = 0;
190 9ae02555 ths
const char *option_rom[MAX_OPTION_ROMS];
191 9ae02555 ths
int nb_option_roms;
192 8e71621f pbrook
int semihosting_enabled = 0;
193 3c07f8e8 pbrook
int autostart = 1;
194 c35734b2 ths
const char *qemu_name;
195 0824d6fc bellard
196 0824d6fc bellard
/***********************************************************/
197 26aa7d72 bellard
/* x86 ISA bus support */
198 26aa7d72 bellard
199 26aa7d72 bellard
target_phys_addr_t isa_mem_base = 0;
200 3de388f6 bellard
PicState2 *isa_pic;
201 0824d6fc bellard
202 c4b1fcc0 bellard
uint32_t default_ioport_readb(void *opaque, uint32_t address)
203 0824d6fc bellard
{
204 0824d6fc bellard
#ifdef DEBUG_UNUSED_IOPORT
205 1196be37 ths
    fprintf(stderr, "unused inb: port=0x%04x\n", address);
206 0824d6fc bellard
#endif
207 fc01f7e7 bellard
    return 0xff;
208 0824d6fc bellard
}
209 0824d6fc bellard
210 c4b1fcc0 bellard
void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
211 0824d6fc bellard
{
212 0824d6fc bellard
#ifdef DEBUG_UNUSED_IOPORT
213 1196be37 ths
    fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);
214 0824d6fc bellard
#endif
215 0824d6fc bellard
}
216 0824d6fc bellard
217 0824d6fc bellard
/* default is to make two byte accesses */
218 c4b1fcc0 bellard
uint32_t default_ioport_readw(void *opaque, uint32_t address)
219 0824d6fc bellard
{
220 0824d6fc bellard
    uint32_t data;
221 db45c29a bellard
    data = ioport_read_table[0][address](ioport_opaque[address], address);
222 db45c29a bellard
    address = (address + 1) & (MAX_IOPORTS - 1);
223 db45c29a bellard
    data |= ioport_read_table[0][address](ioport_opaque[address], address) << 8;
224 0824d6fc bellard
    return data;
225 0824d6fc bellard
}
226 0824d6fc bellard
227 c4b1fcc0 bellard
void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
228 0824d6fc bellard
{
229 db45c29a bellard
    ioport_write_table[0][address](ioport_opaque[address], address, data & 0xff);
230 db45c29a bellard
    address = (address + 1) & (MAX_IOPORTS - 1);
231 db45c29a bellard
    ioport_write_table[0][address](ioport_opaque[address], address, (data >> 8) & 0xff);
232 0824d6fc bellard
}
233 0824d6fc bellard
234 c4b1fcc0 bellard
uint32_t default_ioport_readl(void *opaque, uint32_t address)
235 0824d6fc bellard
{
236 fc01f7e7 bellard
#ifdef DEBUG_UNUSED_IOPORT
237 1196be37 ths
    fprintf(stderr, "unused inl: port=0x%04x\n", address);
238 fc01f7e7 bellard
#endif
239 fc01f7e7 bellard
    return 0xffffffff;
240 0824d6fc bellard
}
241 0824d6fc bellard
242 c4b1fcc0 bellard
void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
243 0824d6fc bellard
{
244 fc01f7e7 bellard
#ifdef DEBUG_UNUSED_IOPORT
245 1196be37 ths
    fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);
246 fc01f7e7 bellard
#endif
247 0824d6fc bellard
}
248 0824d6fc bellard
249 fc01f7e7 bellard
void init_ioports(void)
250 0824d6fc bellard
{
251 0824d6fc bellard
    int i;
252 0824d6fc bellard
253 fc01f7e7 bellard
    for(i = 0; i < MAX_IOPORTS; i++) {
254 fc01f7e7 bellard
        ioport_read_table[0][i] = default_ioport_readb;
255 fc01f7e7 bellard
        ioport_write_table[0][i] = default_ioport_writeb;
256 fc01f7e7 bellard
        ioport_read_table[1][i] = default_ioport_readw;
257 fc01f7e7 bellard
        ioport_write_table[1][i] = default_ioport_writew;
258 fc01f7e7 bellard
        ioport_read_table[2][i] = default_ioport_readl;
259 fc01f7e7 bellard
        ioport_write_table[2][i] = default_ioport_writel;
260 fc01f7e7 bellard
    }
261 0824d6fc bellard
}
262 0824d6fc bellard
263 fc01f7e7 bellard
/* size is the word size in byte */
264 c4b1fcc0 bellard
int register_ioport_read(int start, int length, int size, 
265 c4b1fcc0 bellard
                         IOPortReadFunc *func, void *opaque)
266 f1510b2c bellard
{
267 fc01f7e7 bellard
    int i, bsize;
268 f1510b2c bellard
269 c4b1fcc0 bellard
    if (size == 1) {
270 fc01f7e7 bellard
        bsize = 0;
271 c4b1fcc0 bellard
    } else if (size == 2) {
272 fc01f7e7 bellard
        bsize = 1;
273 c4b1fcc0 bellard
    } else if (size == 4) {
274 fc01f7e7 bellard
        bsize = 2;
275 c4b1fcc0 bellard
    } else {
276 c4b1fcc0 bellard
        hw_error("register_ioport_read: invalid size");
277 fc01f7e7 bellard
        return -1;
278 c4b1fcc0 bellard
    }
279 c4b1fcc0 bellard
    for(i = start; i < start + length; i += size) {
280 fc01f7e7 bellard
        ioport_read_table[bsize][i] = func;
281 c4b1fcc0 bellard
        if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
282 c4b1fcc0 bellard
            hw_error("register_ioport_read: invalid opaque");
283 c4b1fcc0 bellard
        ioport_opaque[i] = opaque;
284 c4b1fcc0 bellard
    }
285 f1510b2c bellard
    return 0;
286 f1510b2c bellard
}
287 f1510b2c bellard
288 fc01f7e7 bellard
/* size is the word size in byte */
289 c4b1fcc0 bellard
int register_ioport_write(int start, int length, int size, 
290 c4b1fcc0 bellard
                          IOPortWriteFunc *func, void *opaque)
291 f1510b2c bellard
{
292 fc01f7e7 bellard
    int i, bsize;
293 f1510b2c bellard
294 c4b1fcc0 bellard
    if (size == 1) {
295 fc01f7e7 bellard
        bsize = 0;
296 c4b1fcc0 bellard
    } else if (size == 2) {
297 fc01f7e7 bellard
        bsize = 1;
298 c4b1fcc0 bellard
    } else if (size == 4) {
299 fc01f7e7 bellard
        bsize = 2;
300 c4b1fcc0 bellard
    } else {
301 c4b1fcc0 bellard
        hw_error("register_ioport_write: invalid size");
302 fc01f7e7 bellard
        return -1;
303 c4b1fcc0 bellard
    }
304 c4b1fcc0 bellard
    for(i = start; i < start + length; i += size) {
305 fc01f7e7 bellard
        ioport_write_table[bsize][i] = func;
306 c4b1fcc0 bellard
        if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
307 52f61fde ths
            hw_error("register_ioport_write: invalid opaque");
308 c4b1fcc0 bellard
        ioport_opaque[i] = opaque;
309 c4b1fcc0 bellard
    }
310 f1510b2c bellard
    return 0;
311 f1510b2c bellard
}
312 f1510b2c bellard
313 69b91039 bellard
void isa_unassign_ioport(int start, int length)
314 69b91039 bellard
{
315 69b91039 bellard
    int i;
316 69b91039 bellard
317 69b91039 bellard
    for(i = start; i < start + length; i++) {
318 69b91039 bellard
        ioport_read_table[0][i] = default_ioport_readb;
319 69b91039 bellard
        ioport_read_table[1][i] = default_ioport_readw;
320 69b91039 bellard
        ioport_read_table[2][i] = default_ioport_readl;
321 69b91039 bellard
322 69b91039 bellard
        ioport_write_table[0][i] = default_ioport_writeb;
323 69b91039 bellard
        ioport_write_table[1][i] = default_ioport_writew;
324 69b91039 bellard
        ioport_write_table[2][i] = default_ioport_writel;
325 69b91039 bellard
    }
326 69b91039 bellard
}
327 69b91039 bellard
328 20f32282 bellard
/***********************************************************/
329 20f32282 bellard
330 c45886db bellard
void cpu_outb(CPUState *env, int addr, int val)
331 0824d6fc bellard
{
332 fd872598 bellard
#ifdef DEBUG_IOPORT
333 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
334 fd872598 bellard
        fprintf(logfile, "outb: %04x %02x\n", addr, val);
335 fd872598 bellard
#endif    
336 c4b1fcc0 bellard
    ioport_write_table[0][addr](ioport_opaque[addr], addr, val);
337 89bfc105 bellard
#ifdef USE_KQEMU
338 89bfc105 bellard
    if (env)
339 89bfc105 bellard
        env->last_io_time = cpu_get_time_fast();
340 89bfc105 bellard
#endif
341 0824d6fc bellard
}
342 0824d6fc bellard
343 c45886db bellard
void cpu_outw(CPUState *env, int addr, int val)
344 0824d6fc bellard
{
345 fd872598 bellard
#ifdef DEBUG_IOPORT
346 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
347 fd872598 bellard
        fprintf(logfile, "outw: %04x %04x\n", addr, val);
348 fd872598 bellard
#endif    
349 c4b1fcc0 bellard
    ioport_write_table[1][addr](ioport_opaque[addr], addr, val);
350 89bfc105 bellard
#ifdef USE_KQEMU
351 89bfc105 bellard
    if (env)
352 89bfc105 bellard
        env->last_io_time = cpu_get_time_fast();
353 89bfc105 bellard
#endif
354 0824d6fc bellard
}
355 0824d6fc bellard
356 c45886db bellard
void cpu_outl(CPUState *env, int addr, int val)
357 0824d6fc bellard
{
358 fd872598 bellard
#ifdef DEBUG_IOPORT
359 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
360 fd872598 bellard
        fprintf(logfile, "outl: %04x %08x\n", addr, val);
361 fd872598 bellard
#endif
362 c4b1fcc0 bellard
    ioport_write_table[2][addr](ioport_opaque[addr], addr, val);
363 89bfc105 bellard
#ifdef USE_KQEMU
364 89bfc105 bellard
    if (env)
365 89bfc105 bellard
        env->last_io_time = cpu_get_time_fast();
366 89bfc105 bellard
#endif
367 0824d6fc bellard
}
368 0824d6fc bellard
369 c45886db bellard
int cpu_inb(CPUState *env, int addr)
370 0824d6fc bellard
{
371 fd872598 bellard
    int val;
372 fd872598 bellard
    val = ioport_read_table[0][addr](ioport_opaque[addr], addr);
373 fd872598 bellard
#ifdef DEBUG_IOPORT
374 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
375 fd872598 bellard
        fprintf(logfile, "inb : %04x %02x\n", addr, val);
376 fd872598 bellard
#endif
377 89bfc105 bellard
#ifdef USE_KQEMU
378 89bfc105 bellard
    if (env)
379 89bfc105 bellard
        env->last_io_time = cpu_get_time_fast();
380 89bfc105 bellard
#endif
381 fd872598 bellard
    return val;
382 0824d6fc bellard
}
383 0824d6fc bellard
384 c45886db bellard
int cpu_inw(CPUState *env, int addr)
385 0824d6fc bellard
{
386 fd872598 bellard
    int val;
387 fd872598 bellard
    val = ioport_read_table[1][addr](ioport_opaque[addr], addr);
388 fd872598 bellard
#ifdef DEBUG_IOPORT
389 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
390 fd872598 bellard
        fprintf(logfile, "inw : %04x %04x\n", addr, val);
391 fd872598 bellard
#endif
392 89bfc105 bellard
#ifdef USE_KQEMU
393 89bfc105 bellard
    if (env)
394 89bfc105 bellard
        env->last_io_time = cpu_get_time_fast();
395 89bfc105 bellard
#endif
396 fd872598 bellard
    return val;
397 0824d6fc bellard
}
398 0824d6fc bellard
399 c45886db bellard
int cpu_inl(CPUState *env, int addr)
400 0824d6fc bellard
{
401 fd872598 bellard
    int val;
402 fd872598 bellard
    val = ioport_read_table[2][addr](ioport_opaque[addr], addr);
403 fd872598 bellard
#ifdef DEBUG_IOPORT
404 fd872598 bellard
    if (loglevel & CPU_LOG_IOPORT)
405 fd872598 bellard
        fprintf(logfile, "inl : %04x %08x\n", addr, val);
406 fd872598 bellard
#endif
407 89bfc105 bellard
#ifdef USE_KQEMU
408 89bfc105 bellard
    if (env)
409 89bfc105 bellard
        env->last_io_time = cpu_get_time_fast();
410 89bfc105 bellard
#endif
411 fd872598 bellard
    return val;
412 0824d6fc bellard
}
413 0824d6fc bellard
414 0824d6fc bellard
/***********************************************************/
415 0824d6fc bellard
void hw_error(const char *fmt, ...)
416 0824d6fc bellard
{
417 0824d6fc bellard
    va_list ap;
418 6a00d601 bellard
    CPUState *env;
419 0824d6fc bellard
420 0824d6fc bellard
    va_start(ap, fmt);
421 0824d6fc bellard
    fprintf(stderr, "qemu: hardware error: ");
422 0824d6fc bellard
    vfprintf(stderr, fmt, ap);
423 0824d6fc bellard
    fprintf(stderr, "\n");
424 6a00d601 bellard
    for(env = first_cpu; env != NULL; env = env->next_cpu) {
425 6a00d601 bellard
        fprintf(stderr, "CPU #%d:\n", env->cpu_index);
426 0824d6fc bellard
#ifdef TARGET_I386
427 6a00d601 bellard
        cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
428 c45886db bellard
#else
429 6a00d601 bellard
        cpu_dump_state(env, stderr, fprintf, 0);
430 0824d6fc bellard
#endif
431 6a00d601 bellard
    }
432 0824d6fc bellard
    va_end(ap);
433 0824d6fc bellard
    abort();
434 0824d6fc bellard
}
435 0824d6fc bellard
436 8a7ddc38 bellard
/***********************************************************/
437 63066f4f bellard
/* keyboard/mouse */
438 63066f4f bellard
439 63066f4f bellard
static QEMUPutKBDEvent *qemu_put_kbd_event;
440 63066f4f bellard
static void *qemu_put_kbd_event_opaque;
441 455204eb ths
static QEMUPutMouseEntry *qemu_put_mouse_event_head;
442 455204eb ths
static QEMUPutMouseEntry *qemu_put_mouse_event_current;
443 63066f4f bellard
444 63066f4f bellard
void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
445 63066f4f bellard
{
446 63066f4f bellard
    qemu_put_kbd_event_opaque = opaque;
447 63066f4f bellard
    qemu_put_kbd_event = func;
448 63066f4f bellard
}
449 63066f4f bellard
450 455204eb ths
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
451 455204eb ths
                                                void *opaque, int absolute,
452 455204eb ths
                                                const char *name)
453 63066f4f bellard
{
454 455204eb ths
    QEMUPutMouseEntry *s, *cursor;
455 455204eb ths
456 455204eb ths
    s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
457 455204eb ths
    if (!s)
458 455204eb ths
        return NULL;
459 455204eb ths
460 455204eb ths
    s->qemu_put_mouse_event = func;
461 455204eb ths
    s->qemu_put_mouse_event_opaque = opaque;
462 455204eb ths
    s->qemu_put_mouse_event_absolute = absolute;
463 455204eb ths
    s->qemu_put_mouse_event_name = qemu_strdup(name);
464 455204eb ths
    s->next = NULL;
465 455204eb ths
466 455204eb ths
    if (!qemu_put_mouse_event_head) {
467 455204eb ths
        qemu_put_mouse_event_head = qemu_put_mouse_event_current = s;
468 455204eb ths
        return s;
469 455204eb ths
    }
470 455204eb ths
471 455204eb ths
    cursor = qemu_put_mouse_event_head;
472 455204eb ths
    while (cursor->next != NULL)
473 455204eb ths
        cursor = cursor->next;
474 455204eb ths
475 455204eb ths
    cursor->next = s;
476 455204eb ths
    qemu_put_mouse_event_current = s;
477 455204eb ths
478 455204eb ths
    return s;
479 455204eb ths
}
480 455204eb ths
481 455204eb ths
void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
482 455204eb ths
{
483 455204eb ths
    QEMUPutMouseEntry *prev = NULL, *cursor;
484 455204eb ths
485 455204eb ths
    if (!qemu_put_mouse_event_head || entry == NULL)
486 455204eb ths
        return;
487 455204eb ths
488 455204eb ths
    cursor = qemu_put_mouse_event_head;
489 455204eb ths
    while (cursor != NULL && cursor != entry) {
490 455204eb ths
        prev = cursor;
491 455204eb ths
        cursor = cursor->next;
492 455204eb ths
    }
493 455204eb ths
494 455204eb ths
    if (cursor == NULL) // does not exist or list empty
495 455204eb ths
        return;
496 455204eb ths
    else if (prev == NULL) { // entry is head
497 455204eb ths
        qemu_put_mouse_event_head = cursor->next;
498 455204eb ths
        if (qemu_put_mouse_event_current == entry)
499 455204eb ths
            qemu_put_mouse_event_current = cursor->next;
500 455204eb ths
        qemu_free(entry->qemu_put_mouse_event_name);
501 455204eb ths
        qemu_free(entry);
502 455204eb ths
        return;
503 455204eb ths
    }
504 455204eb ths
505 455204eb ths
    prev->next = entry->next;
506 455204eb ths
507 455204eb ths
    if (qemu_put_mouse_event_current == entry)
508 455204eb ths
        qemu_put_mouse_event_current = prev;
509 455204eb ths
510 455204eb ths
    qemu_free(entry->qemu_put_mouse_event_name);
511 455204eb ths
    qemu_free(entry);
512 63066f4f bellard
}
513 63066f4f bellard
514 63066f4f bellard
void kbd_put_keycode(int keycode)
515 63066f4f bellard
{
516 63066f4f bellard
    if (qemu_put_kbd_event) {
517 63066f4f bellard
        qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
518 63066f4f bellard
    }
519 63066f4f bellard
}
520 63066f4f bellard
521 63066f4f bellard
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
522 63066f4f bellard
{
523 455204eb ths
    QEMUPutMouseEvent *mouse_event;
524 455204eb ths
    void *mouse_event_opaque;
525 455204eb ths
526 455204eb ths
    if (!qemu_put_mouse_event_current) {
527 455204eb ths
        return;
528 455204eb ths
    }
529 455204eb ths
530 455204eb ths
    mouse_event =
531 455204eb ths
        qemu_put_mouse_event_current->qemu_put_mouse_event;
532 455204eb ths
    mouse_event_opaque =
533 455204eb ths
        qemu_put_mouse_event_current->qemu_put_mouse_event_opaque;
534 455204eb ths
535 455204eb ths
    if (mouse_event) {
536 455204eb ths
        mouse_event(mouse_event_opaque, dx, dy, dz, buttons_state);
537 63066f4f bellard
    }
538 63066f4f bellard
}
539 63066f4f bellard
540 09b26c5e bellard
int kbd_mouse_is_absolute(void)
541 09b26c5e bellard
{
542 455204eb ths
    if (!qemu_put_mouse_event_current)
543 455204eb ths
        return 0;
544 455204eb ths
545 455204eb ths
    return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
546 455204eb ths
}
547 455204eb ths
548 d34cab9f ths
void (*kbd_mouse_set)(int x, int y, int on) = NULL;
549 d34cab9f ths
void (*kbd_cursor_define)(int width, int height, int bpp, int hot_x, int hot_y,
550 d34cab9f ths
                          uint8_t *image, uint8_t *mask) = NULL;
551 d34cab9f ths
552 455204eb ths
void do_info_mice(void)
553 455204eb ths
{
554 455204eb ths
    QEMUPutMouseEntry *cursor;
555 455204eb ths
    int index = 0;
556 455204eb ths
557 455204eb ths
    if (!qemu_put_mouse_event_head) {
558 455204eb ths
        term_printf("No mouse devices connected\n");
559 455204eb ths
        return;
560 455204eb ths
    }
561 455204eb ths
562 455204eb ths
    term_printf("Mouse devices available:\n");
563 455204eb ths
    cursor = qemu_put_mouse_event_head;
564 455204eb ths
    while (cursor != NULL) {
565 455204eb ths
        term_printf("%c Mouse #%d: %s\n",
566 455204eb ths
                    (cursor == qemu_put_mouse_event_current ? '*' : ' '),
567 455204eb ths
                    index, cursor->qemu_put_mouse_event_name);
568 455204eb ths
        index++;
569 455204eb ths
        cursor = cursor->next;
570 455204eb ths
    }
571 455204eb ths
}
572 455204eb ths
573 455204eb ths
void do_mouse_set(int index)
574 455204eb ths
{
575 455204eb ths
    QEMUPutMouseEntry *cursor;
576 455204eb ths
    int i = 0;
577 455204eb ths
578 455204eb ths
    if (!qemu_put_mouse_event_head) {
579 455204eb ths
        term_printf("No mouse devices connected\n");
580 455204eb ths
        return;
581 455204eb ths
    }
582 455204eb ths
583 455204eb ths
    cursor = qemu_put_mouse_event_head;
584 455204eb ths
    while (cursor != NULL && index != i) {
585 455204eb ths
        i++;
586 455204eb ths
        cursor = cursor->next;
587 455204eb ths
    }
588 455204eb ths
589 455204eb ths
    if (cursor != NULL)
590 455204eb ths
        qemu_put_mouse_event_current = cursor;
591 455204eb ths
    else
592 455204eb ths
        term_printf("Mouse at given index not found\n");
593 09b26c5e bellard
}
594 09b26c5e bellard
595 1dce7c3c bellard
/* compute with 96 bit intermediate result: (a*b)/c */
596 1dce7c3c bellard
uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
597 0824d6fc bellard
{
598 1dce7c3c bellard
    union {
599 1dce7c3c bellard
        uint64_t ll;
600 1dce7c3c bellard
        struct {
601 1dce7c3c bellard
#ifdef WORDS_BIGENDIAN
602 1dce7c3c bellard
            uint32_t high, low;
603 1dce7c3c bellard
#else
604 1dce7c3c bellard
            uint32_t low, high;
605 1dce7c3c bellard
#endif            
606 1dce7c3c bellard
        } l;
607 1dce7c3c bellard
    } u, res;
608 1dce7c3c bellard
    uint64_t rl, rh;
609 0824d6fc bellard
610 1dce7c3c bellard
    u.ll = a;
611 1dce7c3c bellard
    rl = (uint64_t)u.l.low * (uint64_t)b;
612 1dce7c3c bellard
    rh = (uint64_t)u.l.high * (uint64_t)b;
613 1dce7c3c bellard
    rh += (rl >> 32);
614 1dce7c3c bellard
    res.l.high = rh / c;
615 1dce7c3c bellard
    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
616 1dce7c3c bellard
    return res.ll;
617 34865134 bellard
}
618 34865134 bellard
619 1dce7c3c bellard
/***********************************************************/
620 1dce7c3c bellard
/* real time host monotonic timer */
621 34865134 bellard
622 1dce7c3c bellard
#define QEMU_TIMER_BASE 1000000000LL
623 34865134 bellard
624 1dce7c3c bellard
#ifdef WIN32
625 0824d6fc bellard
626 1dce7c3c bellard
static int64_t clock_freq;
627 1115dde7 bellard
628 1dce7c3c bellard
static void init_get_clock(void)
629 1115dde7 bellard
{
630 a8e5ac33 bellard
    LARGE_INTEGER freq;
631 a8e5ac33 bellard
    int ret;
632 1dce7c3c bellard
    ret = QueryPerformanceFrequency(&freq);
633 1dce7c3c bellard
    if (ret == 0) {
634 1dce7c3c bellard
        fprintf(stderr, "Could not calibrate ticks\n");
635 1dce7c3c bellard
        exit(1);
636 1dce7c3c bellard
    }
637 1dce7c3c bellard
    clock_freq = freq.QuadPart;
638 1115dde7 bellard
}
639 1115dde7 bellard
640 1dce7c3c bellard
static int64_t get_clock(void)
641 b8076a74 bellard
{
642 1dce7c3c bellard
    LARGE_INTEGER ti;
643 1dce7c3c bellard
    QueryPerformanceCounter(&ti);
644 1dce7c3c bellard
    return muldiv64(ti.QuadPart, QEMU_TIMER_BASE, clock_freq);
645 b8076a74 bellard
}
646 b8076a74 bellard
647 1dce7c3c bellard
#else
648 90cb9493 bellard
649 1dce7c3c bellard
static int use_rt_clock;
650 1dce7c3c bellard
651 1dce7c3c bellard
static void init_get_clock(void)
652 90cb9493 bellard
{
653 1dce7c3c bellard
    use_rt_clock = 0;
654 1dce7c3c bellard
#if defined(__linux__)
655 1dce7c3c bellard
    {
656 1dce7c3c bellard
        struct timespec ts;
657 1dce7c3c bellard
        if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
658 1dce7c3c bellard
            use_rt_clock = 1;
659 1dce7c3c bellard
        }
660 1dce7c3c bellard
    }
661 1dce7c3c bellard
#endif
662 90cb9493 bellard
}
663 90cb9493 bellard
664 1dce7c3c bellard
static int64_t get_clock(void)
665 fdbb4691 bellard
{
666 1dce7c3c bellard
#if defined(__linux__)
667 1dce7c3c bellard
    if (use_rt_clock) {
668 1dce7c3c bellard
        struct timespec ts;
669 1dce7c3c bellard
        clock_gettime(CLOCK_MONOTONIC, &ts);
670 1dce7c3c bellard
        return ts.tv_sec * 1000000000LL + ts.tv_nsec;
671 1dce7c3c bellard
    } else 
672 fdbb4691 bellard
#endif
673 1dce7c3c bellard
    {
674 1dce7c3c bellard
        /* XXX: using gettimeofday leads to problems if the date
675 1dce7c3c bellard
           changes, so it should be avoided. */
676 1dce7c3c bellard
        struct timeval tv;
677 1dce7c3c bellard
        gettimeofday(&tv, NULL);
678 1dce7c3c bellard
        return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
679 1dce7c3c bellard
    }
680 fdbb4691 bellard
}
681 fdbb4691 bellard
682 34865134 bellard
#endif
683 34865134 bellard
684 1dce7c3c bellard
/***********************************************************/
685 1dce7c3c bellard
/* guest cycle counter */
686 1dce7c3c bellard
687 eade0f19 bellard
static int64_t cpu_ticks_prev;
688 34865134 bellard
static int64_t cpu_ticks_offset;
689 1dce7c3c bellard
static int64_t cpu_clock_offset;
690 8a7ddc38 bellard
static int cpu_ticks_enabled;
691 34865134 bellard
692 1dce7c3c bellard
/* return the host CPU cycle counter and handle stop/restart */
693 1dce7c3c bellard
int64_t cpu_get_ticks(void)
694 34865134 bellard
{
695 8a7ddc38 bellard
    if (!cpu_ticks_enabled) {
696 8a7ddc38 bellard
        return cpu_ticks_offset;
697 8a7ddc38 bellard
    } else {
698 eade0f19 bellard
        int64_t ticks;
699 eade0f19 bellard
        ticks = cpu_get_real_ticks();
700 eade0f19 bellard
        if (cpu_ticks_prev > ticks) {
701 eade0f19 bellard
            /* Note: non increasing ticks may happen if the host uses
702 eade0f19 bellard
               software suspend */
703 eade0f19 bellard
            cpu_ticks_offset += cpu_ticks_prev - ticks;
704 eade0f19 bellard
        }
705 eade0f19 bellard
        cpu_ticks_prev = ticks;
706 eade0f19 bellard
        return ticks + cpu_ticks_offset;
707 8a7ddc38 bellard
    }
708 34865134 bellard
}
709 34865134 bellard
710 1dce7c3c bellard
/* return the host CPU monotonic timer and handle stop/restart */
711 1dce7c3c bellard
static int64_t cpu_get_clock(void)
712 1dce7c3c bellard
{
713 1dce7c3c bellard
    int64_t ti;
714 1dce7c3c bellard
    if (!cpu_ticks_enabled) {
715 1dce7c3c bellard
        return cpu_clock_offset;
716 1dce7c3c bellard
    } else {
717 1dce7c3c bellard
        ti = get_clock();
718 1dce7c3c bellard
        return ti + cpu_clock_offset;
719 1dce7c3c bellard
    }
720 1dce7c3c bellard
}
721 1dce7c3c bellard
722 34865134 bellard
/* enable cpu_get_ticks() */
723 34865134 bellard
void cpu_enable_ticks(void)
724 34865134 bellard
{
725 8a7ddc38 bellard
    if (!cpu_ticks_enabled) {
726 8a7ddc38 bellard
        cpu_ticks_offset -= cpu_get_real_ticks();
727 1dce7c3c bellard
        cpu_clock_offset -= get_clock();
728 8a7ddc38 bellard
        cpu_ticks_enabled = 1;
729 8a7ddc38 bellard
    }
730 34865134 bellard
}
731 34865134 bellard
732 34865134 bellard
/* disable cpu_get_ticks() : the clock is stopped. You must not call
733 34865134 bellard
   cpu_get_ticks() after that.  */
734 34865134 bellard
void cpu_disable_ticks(void)
735 34865134 bellard
{
736 8a7ddc38 bellard
    if (cpu_ticks_enabled) {
737 8a7ddc38 bellard
        cpu_ticks_offset = cpu_get_ticks();
738 1dce7c3c bellard
        cpu_clock_offset = cpu_get_clock();
739 8a7ddc38 bellard
        cpu_ticks_enabled = 0;
740 8a7ddc38 bellard
    }
741 34865134 bellard
}
742 34865134 bellard
743 1dce7c3c bellard
/***********************************************************/
744 1dce7c3c bellard
/* timers */
745 1dce7c3c bellard
 
746 8a7ddc38 bellard
#define QEMU_TIMER_REALTIME 0
747 8a7ddc38 bellard
#define QEMU_TIMER_VIRTUAL  1
748 8a7ddc38 bellard
749 8a7ddc38 bellard
struct QEMUClock {
750 8a7ddc38 bellard
    int type;
751 8a7ddc38 bellard
    /* XXX: add frequency */
752 8a7ddc38 bellard
};
753 8a7ddc38 bellard
754 8a7ddc38 bellard
struct QEMUTimer {
755 8a7ddc38 bellard
    QEMUClock *clock;
756 8a7ddc38 bellard
    int64_t expire_time;
757 8a7ddc38 bellard
    QEMUTimerCB *cb;
758 8a7ddc38 bellard
    void *opaque;
759 8a7ddc38 bellard
    struct QEMUTimer *next;
760 8a7ddc38 bellard
};
761 8a7ddc38 bellard
762 8a7ddc38 bellard
QEMUClock *rt_clock;
763 8a7ddc38 bellard
QEMUClock *vm_clock;
764 8a7ddc38 bellard
765 8a7ddc38 bellard
static QEMUTimer *active_timers[2];
766 40c3bac3 bellard
#ifdef _WIN32
767 40c3bac3 bellard
static MMRESULT timerID;
768 06d9f2f7 bellard
static HANDLE host_alarm = NULL;
769 06d9f2f7 bellard
static unsigned int period = 1;
770 40c3bac3 bellard
#else
771 8a7ddc38 bellard
/* frequency of the times() clock tick */
772 8a7ddc38 bellard
static int timer_freq;
773 67b915a5 bellard
#endif
774 8a7ddc38 bellard
775 8a7ddc38 bellard
QEMUClock *qemu_new_clock(int type)
776 8a7ddc38 bellard
{
777 8a7ddc38 bellard
    QEMUClock *clock;
778 8a7ddc38 bellard
    clock = qemu_mallocz(sizeof(QEMUClock));
779 8a7ddc38 bellard
    if (!clock)
780 8a7ddc38 bellard
        return NULL;
781 8a7ddc38 bellard
    clock->type = type;
782 8a7ddc38 bellard
    return clock;
783 8a7ddc38 bellard
}
784 8a7ddc38 bellard
785 8a7ddc38 bellard
QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque)
786 8a7ddc38 bellard
{
787 8a7ddc38 bellard
    QEMUTimer *ts;
788 8a7ddc38 bellard
789 8a7ddc38 bellard
    ts = qemu_mallocz(sizeof(QEMUTimer));
790 8a7ddc38 bellard
    ts->clock = clock;
791 8a7ddc38 bellard
    ts->cb = cb;
792 8a7ddc38 bellard
    ts->opaque = opaque;
793 8a7ddc38 bellard
    return ts;
794 8a7ddc38 bellard
}
795 8a7ddc38 bellard
796 8a7ddc38 bellard
void qemu_free_timer(QEMUTimer *ts)
797 8a7ddc38 bellard
{
798 8a7ddc38 bellard
    qemu_free(ts);
799 8a7ddc38 bellard
}
800 8a7ddc38 bellard
801 8a7ddc38 bellard
/* stop a timer, but do not dealloc it */
802 8a7ddc38 bellard
void qemu_del_timer(QEMUTimer *ts)
803 8a7ddc38 bellard
{
804 8a7ddc38 bellard
    QEMUTimer **pt, *t;
805 8a7ddc38 bellard
806 8a7ddc38 bellard
    /* NOTE: this code must be signal safe because
807 8a7ddc38 bellard
       qemu_timer_expired() can be called from a signal. */
808 8a7ddc38 bellard
    pt = &active_timers[ts->clock->type];
809 8a7ddc38 bellard
    for(;;) {
810 8a7ddc38 bellard
        t = *pt;
811 8a7ddc38 bellard
        if (!t)
812 8a7ddc38 bellard
            break;
813 8a7ddc38 bellard
        if (t == ts) {
814 8a7ddc38 bellard
            *pt = t->next;
815 8a7ddc38 bellard
            break;
816 8a7ddc38 bellard
        }
817 8a7ddc38 bellard
        pt = &t->next;
818 8a7ddc38 bellard
    }
819 8a7ddc38 bellard
}
820 8a7ddc38 bellard
821 8a7ddc38 bellard
/* modify the current timer so that it will be fired when current_time
822 8a7ddc38 bellard
   >= expire_time. The corresponding callback will be called. */
823 8a7ddc38 bellard
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
824 8a7ddc38 bellard
{
825 8a7ddc38 bellard
    QEMUTimer **pt, *t;
826 8a7ddc38 bellard
827 8a7ddc38 bellard
    qemu_del_timer(ts);
828 8a7ddc38 bellard
829 8a7ddc38 bellard
    /* add the timer in the sorted list */
830 8a7ddc38 bellard
    /* NOTE: this code must be signal safe because
831 8a7ddc38 bellard
       qemu_timer_expired() can be called from a signal. */
832 8a7ddc38 bellard
    pt = &active_timers[ts->clock->type];
833 8a7ddc38 bellard
    for(;;) {
834 8a7ddc38 bellard
        t = *pt;
835 8a7ddc38 bellard
        if (!t)
836 8a7ddc38 bellard
            break;
837 8a7ddc38 bellard
        if (t->expire_time > expire_time) 
838 8a7ddc38 bellard
            break;
839 8a7ddc38 bellard
        pt = &t->next;
840 8a7ddc38 bellard
    }
841 8a7ddc38 bellard
    ts->expire_time = expire_time;
842 8a7ddc38 bellard
    ts->next = *pt;
843 8a7ddc38 bellard
    *pt = ts;
844 8a7ddc38 bellard
}
845 8a7ddc38 bellard
846 8a7ddc38 bellard
int qemu_timer_pending(QEMUTimer *ts)
847 8a7ddc38 bellard
{
848 8a7ddc38 bellard
    QEMUTimer *t;
849 8a7ddc38 bellard
    for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
850 8a7ddc38 bellard
        if (t == ts)
851 8a7ddc38 bellard
            return 1;
852 8a7ddc38 bellard
    }
853 8a7ddc38 bellard
    return 0;
854 8a7ddc38 bellard
}
855 8a7ddc38 bellard
856 8a7ddc38 bellard
static inline int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
857 8a7ddc38 bellard
{
858 8a7ddc38 bellard
    if (!timer_head)
859 8a7ddc38 bellard
        return 0;
860 8a7ddc38 bellard
    return (timer_head->expire_time <= current_time);
861 8a7ddc38 bellard
}
862 8a7ddc38 bellard
863 8a7ddc38 bellard
static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
864 8a7ddc38 bellard
{
865 8a7ddc38 bellard
    QEMUTimer *ts;
866 8a7ddc38 bellard
    
867 8a7ddc38 bellard
    for(;;) {
868 8a7ddc38 bellard
        ts = *ptimer_head;
869 e95c8d51 bellard
        if (!ts || ts->expire_time > current_time)
870 8a7ddc38 bellard
            break;
871 8a7ddc38 bellard
        /* remove timer from the list before calling the callback */
872 8a7ddc38 bellard
        *ptimer_head = ts->next;
873 8a7ddc38 bellard
        ts->next = NULL;
874 8a7ddc38 bellard
        
875 8a7ddc38 bellard
        /* run the callback (the timer list can be modified) */
876 8a7ddc38 bellard
        ts->cb(ts->opaque);
877 8a7ddc38 bellard
    }
878 8a7ddc38 bellard
}
879 8a7ddc38 bellard
880 8a7ddc38 bellard
int64_t qemu_get_clock(QEMUClock *clock)
881 8a7ddc38 bellard
{
882 8a7ddc38 bellard
    switch(clock->type) {
883 8a7ddc38 bellard
    case QEMU_TIMER_REALTIME:
884 1dce7c3c bellard
        return get_clock() / 1000000;
885 8a7ddc38 bellard
    default:
886 8a7ddc38 bellard
    case QEMU_TIMER_VIRTUAL:
887 1dce7c3c bellard
        return cpu_get_clock();
888 8a7ddc38 bellard
    }
889 8a7ddc38 bellard
}
890 8a7ddc38 bellard
891 1dce7c3c bellard
static void init_timers(void)
892 1dce7c3c bellard
{
893 1dce7c3c bellard
    init_get_clock();
894 1dce7c3c bellard
    ticks_per_sec = QEMU_TIMER_BASE;
895 1dce7c3c bellard
    rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
896 1dce7c3c bellard
    vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
897 1dce7c3c bellard
}
898 1dce7c3c bellard
899 8a7ddc38 bellard
/* save a timer */
900 8a7ddc38 bellard
void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
901 8a7ddc38 bellard
{
902 8a7ddc38 bellard
    uint64_t expire_time;
903 8a7ddc38 bellard
904 8a7ddc38 bellard
    if (qemu_timer_pending(ts)) {
905 8a7ddc38 bellard
        expire_time = ts->expire_time;
906 8a7ddc38 bellard
    } else {
907 8a7ddc38 bellard
        expire_time = -1;
908 8a7ddc38 bellard
    }
909 8a7ddc38 bellard
    qemu_put_be64(f, expire_time);
910 8a7ddc38 bellard
}
911 8a7ddc38 bellard
912 8a7ddc38 bellard
void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
913 8a7ddc38 bellard
{
914 8a7ddc38 bellard
    uint64_t expire_time;
915 8a7ddc38 bellard
916 8a7ddc38 bellard
    expire_time = qemu_get_be64(f);
917 8a7ddc38 bellard
    if (expire_time != -1) {
918 8a7ddc38 bellard
        qemu_mod_timer(ts, expire_time);
919 8a7ddc38 bellard
    } else {
920 8a7ddc38 bellard
        qemu_del_timer(ts);
921 8a7ddc38 bellard
    }
922 8a7ddc38 bellard
}
923 8a7ddc38 bellard
924 8a7ddc38 bellard
static void timer_save(QEMUFile *f, void *opaque)
925 8a7ddc38 bellard
{
926 8a7ddc38 bellard
    if (cpu_ticks_enabled) {
927 8a7ddc38 bellard
        hw_error("cannot save state if virtual timers are running");
928 8a7ddc38 bellard
    }
929 8a7ddc38 bellard
    qemu_put_be64s(f, &cpu_ticks_offset);
930 8a7ddc38 bellard
    qemu_put_be64s(f, &ticks_per_sec);
931 c88676f8 bellard
    qemu_put_be64s(f, &cpu_clock_offset);
932 8a7ddc38 bellard
}
933 8a7ddc38 bellard
934 8a7ddc38 bellard
static int timer_load(QEMUFile *f, void *opaque, int version_id)
935 8a7ddc38 bellard
{
936 c88676f8 bellard
    if (version_id != 1 && version_id != 2)
937 8a7ddc38 bellard
        return -EINVAL;
938 8a7ddc38 bellard
    if (cpu_ticks_enabled) {
939 8a7ddc38 bellard
        return -EINVAL;
940 8a7ddc38 bellard
    }
941 8a7ddc38 bellard
    qemu_get_be64s(f, &cpu_ticks_offset);
942 8a7ddc38 bellard
    qemu_get_be64s(f, &ticks_per_sec);
943 c88676f8 bellard
    if (version_id == 2) {
944 c88676f8 bellard
        qemu_get_be64s(f, &cpu_clock_offset);
945 c88676f8 bellard
    }
946 8a7ddc38 bellard
    return 0;
947 8a7ddc38 bellard
}
948 8a7ddc38 bellard
949 67b915a5 bellard
#ifdef _WIN32
950 67b915a5 bellard
void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg, 
951 67b915a5 bellard
                                 DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
952 67b915a5 bellard
#else
953 8a7ddc38 bellard
static void host_alarm_handler(int host_signum)
954 67b915a5 bellard
#endif
955 8a7ddc38 bellard
{
956 02ba45c5 bellard
#if 0
957 02ba45c5 bellard
#define DISP_FREQ 1000
958 02ba45c5 bellard
    {
959 02ba45c5 bellard
        static int64_t delta_min = INT64_MAX;
960 02ba45c5 bellard
        static int64_t delta_max, delta_cum, last_clock, delta, ti;
961 02ba45c5 bellard
        static int count;
962 02ba45c5 bellard
        ti = qemu_get_clock(vm_clock);
963 02ba45c5 bellard
        if (last_clock != 0) {
964 02ba45c5 bellard
            delta = ti - last_clock;
965 02ba45c5 bellard
            if (delta < delta_min)
966 02ba45c5 bellard
                delta_min = delta;
967 02ba45c5 bellard
            if (delta > delta_max)
968 02ba45c5 bellard
                delta_max = delta;
969 02ba45c5 bellard
            delta_cum += delta;
970 02ba45c5 bellard
            if (++count == DISP_FREQ) {
971 26a76461 bellard
                printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
972 02ba45c5 bellard
                       muldiv64(delta_min, 1000000, ticks_per_sec),
973 02ba45c5 bellard
                       muldiv64(delta_max, 1000000, ticks_per_sec),
974 02ba45c5 bellard
                       muldiv64(delta_cum, 1000000 / DISP_FREQ, ticks_per_sec),
975 02ba45c5 bellard
                       (double)ticks_per_sec / ((double)delta_cum / DISP_FREQ));
976 02ba45c5 bellard
                count = 0;
977 02ba45c5 bellard
                delta_min = INT64_MAX;
978 02ba45c5 bellard
                delta_max = 0;
979 02ba45c5 bellard
                delta_cum = 0;
980 02ba45c5 bellard
            }
981 02ba45c5 bellard
        }
982 02ba45c5 bellard
        last_clock = ti;
983 02ba45c5 bellard
    }
984 02ba45c5 bellard
#endif
985 8a7ddc38 bellard
    if (qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
986 8a7ddc38 bellard
                           qemu_get_clock(vm_clock)) ||
987 8a7ddc38 bellard
        qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
988 8a7ddc38 bellard
                           qemu_get_clock(rt_clock))) {
989 06d9f2f7 bellard
#ifdef _WIN32
990 06d9f2f7 bellard
        SetEvent(host_alarm);
991 06d9f2f7 bellard
#endif
992 6a00d601 bellard
        CPUState *env = cpu_single_env;
993 6a00d601 bellard
        if (env) {
994 6a00d601 bellard
            /* stop the currently executing cpu because a timer occured */
995 6a00d601 bellard
            cpu_interrupt(env, CPU_INTERRUPT_EXIT);
996 a332e112 bellard
#ifdef USE_KQEMU
997 6a00d601 bellard
            if (env->kqemu_enabled) {
998 6a00d601 bellard
                kqemu_cpu_interrupt(env);
999 6a00d601 bellard
            }
1000 a332e112 bellard
#endif
1001 6a00d601 bellard
        }
1002 8a7ddc38 bellard
    }
1003 8a7ddc38 bellard
}
1004 8a7ddc38 bellard
1005 fd872598 bellard
#ifndef _WIN32
1006 fd872598 bellard
1007 829309c7 bellard
#if defined(__linux__)
1008 829309c7 bellard
1009 fd872598 bellard
#define RTC_FREQ 1024
1010 fd872598 bellard
1011 fd872598 bellard
static int rtc_fd;
1012 829309c7 bellard
1013 fd872598 bellard
static int start_rtc_timer(void)
1014 fd872598 bellard
{
1015 fd872598 bellard
    rtc_fd = open("/dev/rtc", O_RDONLY);
1016 fd872598 bellard
    if (rtc_fd < 0)
1017 fd872598 bellard
        return -1;
1018 fd872598 bellard
    if (ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
1019 fd872598 bellard
        fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
1020 fd872598 bellard
                "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
1021 fd872598 bellard
                "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
1022 fd872598 bellard
        goto fail;
1023 fd872598 bellard
    }
1024 fd872598 bellard
    if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
1025 fd872598 bellard
    fail:
1026 fd872598 bellard
        close(rtc_fd);
1027 fd872598 bellard
        return -1;
1028 fd872598 bellard
    }
1029 fd872598 bellard
    pit_min_timer_count = PIT_FREQ / RTC_FREQ;
1030 fd872598 bellard
    return 0;
1031 fd872598 bellard
}
1032 fd872598 bellard
1033 829309c7 bellard
#else
1034 829309c7 bellard
1035 829309c7 bellard
static int start_rtc_timer(void)
1036 829309c7 bellard
{
1037 829309c7 bellard
    return -1;
1038 829309c7 bellard
}
1039 829309c7 bellard
1040 829309c7 bellard
#endif /* !defined(__linux__) */
1041 829309c7 bellard
1042 829309c7 bellard
#endif /* !defined(_WIN32) */
1043 fd872598 bellard
1044 1dce7c3c bellard
static void init_timer_alarm(void)
1045 8a7ddc38 bellard
{
1046 67b915a5 bellard
#ifdef _WIN32
1047 67b915a5 bellard
    {
1048 67b915a5 bellard
        int count=0;
1049 06d9f2f7 bellard
        TIMECAPS tc;
1050 06d9f2f7 bellard
1051 06d9f2f7 bellard
        ZeroMemory(&tc, sizeof(TIMECAPS));
1052 06d9f2f7 bellard
        timeGetDevCaps(&tc, sizeof(TIMECAPS));
1053 06d9f2f7 bellard
        if (period < tc.wPeriodMin)
1054 06d9f2f7 bellard
            period = tc.wPeriodMin;
1055 06d9f2f7 bellard
        timeBeginPeriod(period);
1056 1d14ffa9 bellard
        timerID = timeSetEvent(1,     // interval (ms)
1057 06d9f2f7 bellard
                               period,     // resolution
1058 40c3bac3 bellard
                               host_alarm_handler, // function
1059 40c3bac3 bellard
                               (DWORD)&count,  // user parameter
1060 40c3bac3 bellard
                               TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
1061 67b915a5 bellard
         if( !timerID ) {
1062 67b915a5 bellard
            perror("failed timer alarm");
1063 67b915a5 bellard
            exit(1);
1064 67b915a5 bellard
         }
1065 06d9f2f7 bellard
        host_alarm = CreateEvent(NULL, FALSE, FALSE, NULL);
1066 06d9f2f7 bellard
        if (!host_alarm) {
1067 06d9f2f7 bellard
            perror("failed CreateEvent");
1068 06d9f2f7 bellard
            exit(1);
1069 06d9f2f7 bellard
        }
1070 a18e524a bellard
        qemu_add_wait_object(host_alarm, NULL, NULL);
1071 67b915a5 bellard
    }
1072 67b915a5 bellard
    pit_min_timer_count = ((uint64_t)10000 * PIT_FREQ) / 1000000;
1073 67b915a5 bellard
#else
1074 67b915a5 bellard
    {
1075 67b915a5 bellard
        struct sigaction act;
1076 67b915a5 bellard
        struct itimerval itv;
1077 67b915a5 bellard
        
1078 67b915a5 bellard
        /* get times() syscall frequency */
1079 67b915a5 bellard
        timer_freq = sysconf(_SC_CLK_TCK);
1080 67b915a5 bellard
        
1081 67b915a5 bellard
        /* timer signal */
1082 67b915a5 bellard
        sigfillset(&act.sa_mask);
1083 a09db21f bellard
       act.sa_flags = 0;
1084 8a7ddc38 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
1085 67b915a5 bellard
        act.sa_flags |= SA_ONSTACK;
1086 67b915a5 bellard
#endif
1087 67b915a5 bellard
        act.sa_handler = host_alarm_handler;
1088 67b915a5 bellard
        sigaction(SIGALRM, &act, NULL);
1089 fd872598 bellard
1090 67b915a5 bellard
        itv.it_interval.tv_sec = 0;
1091 d79284e0 bellard
        itv.it_interval.tv_usec = 999; /* for i386 kernel 2.6 to get 1 ms */
1092 67b915a5 bellard
        itv.it_value.tv_sec = 0;
1093 67b915a5 bellard
        itv.it_value.tv_usec = 10 * 1000;
1094 67b915a5 bellard
        setitimer(ITIMER_REAL, &itv, NULL);
1095 67b915a5 bellard
        /* we probe the tick duration of the kernel to inform the user if
1096 67b915a5 bellard
           the emulated kernel requested a too high timer frequency */
1097 67b915a5 bellard
        getitimer(ITIMER_REAL, &itv);
1098 fd872598 bellard
1099 83fb7adf bellard
#if defined(__linux__)
1100 29e3055c bellard
        /* XXX: force /dev/rtc usage because even 2.6 kernels may not
1101 29e3055c bellard
           have timers with 1 ms resolution. The correct solution will
1102 29e3055c bellard
           be to use the POSIX real time timers available in recent
1103 29e3055c bellard
           2.6 kernels */
1104 29e3055c bellard
        if (itv.it_interval.tv_usec > 1000 || 1) {
1105 fd872598 bellard
            /* try to use /dev/rtc to have a faster timer */
1106 fd872598 bellard
            if (start_rtc_timer() < 0)
1107 fd872598 bellard
                goto use_itimer;
1108 fd872598 bellard
            /* disable itimer */
1109 fd872598 bellard
            itv.it_interval.tv_sec = 0;
1110 fd872598 bellard
            itv.it_interval.tv_usec = 0;
1111 fd872598 bellard
            itv.it_value.tv_sec = 0;
1112 fd872598 bellard
            itv.it_value.tv_usec = 0;
1113 fd872598 bellard
            setitimer(ITIMER_REAL, &itv, NULL);
1114 fd872598 bellard
1115 fd872598 bellard
            /* use the RTC */
1116 a1968d71 bellard
            sigaction(SIGIO, &act, NULL);
1117 fd872598 bellard
            fcntl(rtc_fd, F_SETFL, O_ASYNC);
1118 fd872598 bellard
            fcntl(rtc_fd, F_SETOWN, getpid());
1119 83fb7adf bellard
        } else 
1120 83fb7adf bellard
#endif /* defined(__linux__) */
1121 83fb7adf bellard
        {
1122 fd872598 bellard
        use_itimer:
1123 fd872598 bellard
            pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * 
1124 fd872598 bellard
                                   PIT_FREQ) / 1000000;
1125 fd872598 bellard
        }
1126 67b915a5 bellard
    }
1127 8a7ddc38 bellard
#endif
1128 8a7ddc38 bellard
}
1129 8a7ddc38 bellard
1130 40c3bac3 bellard
void quit_timers(void)
1131 40c3bac3 bellard
{
1132 40c3bac3 bellard
#ifdef _WIN32
1133 40c3bac3 bellard
    timeKillEvent(timerID);
1134 06d9f2f7 bellard
    timeEndPeriod(period);
1135 06d9f2f7 bellard
    if (host_alarm) {
1136 06d9f2f7 bellard
        CloseHandle(host_alarm);
1137 06d9f2f7 bellard
        host_alarm = NULL;
1138 06d9f2f7 bellard
    }
1139 40c3bac3 bellard
#endif
1140 40c3bac3 bellard
}
1141 40c3bac3 bellard
1142 c4b1fcc0 bellard
/***********************************************************/
1143 82c643ff bellard
/* character device */
1144 313aa567 bellard
1145 e5b0bc44 pbrook
static void qemu_chr_event(CharDriverState *s, int event)
1146 e5b0bc44 pbrook
{
1147 e5b0bc44 pbrook
    if (!s->chr_event)
1148 e5b0bc44 pbrook
        return;
1149 e5b0bc44 pbrook
    s->chr_event(s->handler_opaque, event);
1150 e5b0bc44 pbrook
}
1151 e5b0bc44 pbrook
1152 86e94dea ths
static void qemu_chr_reset_bh(void *opaque)
1153 86e94dea ths
{
1154 86e94dea ths
    CharDriverState *s = opaque;
1155 e5b0bc44 pbrook
    qemu_chr_event(s, CHR_EVENT_RESET);
1156 86e94dea ths
    qemu_bh_delete(s->bh);
1157 86e94dea ths
    s->bh = NULL;
1158 86e94dea ths
}
1159 86e94dea ths
1160 86e94dea ths
void qemu_chr_reset(CharDriverState *s)
1161 86e94dea ths
{
1162 86e94dea ths
    if (s->bh == NULL) {
1163 86e94dea ths
        s->bh = qemu_bh_new(qemu_chr_reset_bh, s);
1164 86e94dea ths
        qemu_bh_schedule(s->bh);
1165 86e94dea ths
    }
1166 86e94dea ths
}
1167 86e94dea ths
1168 82c643ff bellard
int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
1169 82c643ff bellard
{
1170 82c643ff bellard
    return s->chr_write(s, buf, len);
1171 82c643ff bellard
}
1172 67b915a5 bellard
1173 e57a8c0e bellard
int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg)
1174 f8d179e3 bellard
{
1175 e57a8c0e bellard
    if (!s->chr_ioctl)
1176 e57a8c0e bellard
        return -ENOTSUP;
1177 e57a8c0e bellard
    return s->chr_ioctl(s, cmd, arg);
1178 f8d179e3 bellard
}
1179 f8d179e3 bellard
1180 e5b0bc44 pbrook
int qemu_chr_can_read(CharDriverState *s)
1181 e5b0bc44 pbrook
{
1182 e5b0bc44 pbrook
    if (!s->chr_can_read)
1183 e5b0bc44 pbrook
        return 0;
1184 e5b0bc44 pbrook
    return s->chr_can_read(s->handler_opaque);
1185 e5b0bc44 pbrook
}
1186 e5b0bc44 pbrook
1187 e5b0bc44 pbrook
void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)
1188 e5b0bc44 pbrook
{
1189 e5b0bc44 pbrook
    s->chr_read(s->handler_opaque, buf, len);
1190 e5b0bc44 pbrook
}
1191 e5b0bc44 pbrook
1192 e5b0bc44 pbrook
1193 82c643ff bellard
void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
1194 67b915a5 bellard
{
1195 82c643ff bellard
    char buf[4096];
1196 82c643ff bellard
    va_list ap;
1197 82c643ff bellard
    va_start(ap, fmt);
1198 82c643ff bellard
    vsnprintf(buf, sizeof(buf), fmt, ap);
1199 82c643ff bellard
    qemu_chr_write(s, buf, strlen(buf));
1200 82c643ff bellard
    va_end(ap);
1201 67b915a5 bellard
}
1202 67b915a5 bellard
1203 5905b2e5 bellard
void qemu_chr_send_event(CharDriverState *s, int event)
1204 5905b2e5 bellard
{
1205 5905b2e5 bellard
    if (s->chr_send_event)
1206 5905b2e5 bellard
        s->chr_send_event(s, event);
1207 5905b2e5 bellard
}
1208 5905b2e5 bellard
1209 e5b0bc44 pbrook
void qemu_chr_add_handlers(CharDriverState *s, 
1210 e5b0bc44 pbrook
                           IOCanRWHandler *fd_can_read, 
1211 e5b0bc44 pbrook
                           IOReadHandler *fd_read,
1212 e5b0bc44 pbrook
                           IOEventHandler *fd_event,
1213 e5b0bc44 pbrook
                           void *opaque)
1214 82c643ff bellard
{
1215 e5b0bc44 pbrook
    s->chr_can_read = fd_can_read;
1216 e5b0bc44 pbrook
    s->chr_read = fd_read;
1217 e5b0bc44 pbrook
    s->chr_event = fd_event;
1218 e5b0bc44 pbrook
    s->handler_opaque = opaque;
1219 e5b0bc44 pbrook
    if (s->chr_update_read_handler)
1220 e5b0bc44 pbrook
        s->chr_update_read_handler(s);
1221 82c643ff bellard
}
1222 82c643ff bellard
             
1223 82c643ff bellard
static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1224 313aa567 bellard
{
1225 82c643ff bellard
    return len;
1226 82c643ff bellard
}
1227 82c643ff bellard
1228 52f61fde ths
static CharDriverState *qemu_chr_open_null(void)
1229 82c643ff bellard
{
1230 82c643ff bellard
    CharDriverState *chr;
1231 82c643ff bellard
1232 82c643ff bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
1233 82c643ff bellard
    if (!chr)
1234 82c643ff bellard
        return NULL;
1235 82c643ff bellard
    chr->chr_write = null_chr_write;
1236 82c643ff bellard
    return chr;
1237 82c643ff bellard
}
1238 82c643ff bellard
1239 20d8a3ed ths
/* MUX driver for serial I/O splitting */
1240 20d8a3ed ths
static int term_timestamps;
1241 20d8a3ed ths
static int64_t term_timestamps_start;
1242 9c1de612 ths
#define MAX_MUX 4
1243 20d8a3ed ths
typedef struct {
1244 20d8a3ed ths
    IOCanRWHandler *chr_can_read[MAX_MUX];
1245 20d8a3ed ths
    IOReadHandler *chr_read[MAX_MUX];
1246 20d8a3ed ths
    IOEventHandler *chr_event[MAX_MUX];
1247 20d8a3ed ths
    void *ext_opaque[MAX_MUX];
1248 20d8a3ed ths
    CharDriverState *drv;
1249 20d8a3ed ths
    int mux_cnt;
1250 20d8a3ed ths
    int term_got_escape;
1251 20d8a3ed ths
    int max_size;
1252 20d8a3ed ths
} MuxDriver;
1253 20d8a3ed ths
1254 20d8a3ed ths
1255 20d8a3ed ths
static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1256 20d8a3ed ths
{
1257 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1258 20d8a3ed ths
    int ret;
1259 20d8a3ed ths
    if (!term_timestamps) {
1260 20d8a3ed ths
        ret = d->drv->chr_write(d->drv, buf, len);
1261 20d8a3ed ths
    } else {
1262 20d8a3ed ths
        int i;
1263 20d8a3ed ths
1264 20d8a3ed ths
        ret = 0;
1265 20d8a3ed ths
        for(i = 0; i < len; i++) {
1266 20d8a3ed ths
            ret += d->drv->chr_write(d->drv, buf+i, 1);
1267 20d8a3ed ths
            if (buf[i] == '\n') {
1268 20d8a3ed ths
                char buf1[64];
1269 20d8a3ed ths
                int64_t ti;
1270 20d8a3ed ths
                int secs;
1271 20d8a3ed ths
1272 20d8a3ed ths
                ti = get_clock();
1273 20d8a3ed ths
                if (term_timestamps_start == -1)
1274 20d8a3ed ths
                    term_timestamps_start = ti;
1275 20d8a3ed ths
                ti -= term_timestamps_start;
1276 20d8a3ed ths
                secs = ti / 1000000000;
1277 20d8a3ed ths
                snprintf(buf1, sizeof(buf1),
1278 20d8a3ed ths
                         "[%02d:%02d:%02d.%03d] ",
1279 20d8a3ed ths
                         secs / 3600,
1280 20d8a3ed ths
                         (secs / 60) % 60,
1281 20d8a3ed ths
                         secs % 60,
1282 20d8a3ed ths
                         (int)((ti / 1000000) % 1000));
1283 20d8a3ed ths
                d->drv->chr_write(d->drv, buf1, strlen(buf1));
1284 20d8a3ed ths
            }
1285 20d8a3ed ths
        }
1286 20d8a3ed ths
    }
1287 20d8a3ed ths
    return ret;
1288 20d8a3ed ths
}
1289 20d8a3ed ths
1290 20d8a3ed ths
static char *mux_help[] = {
1291 20d8a3ed ths
    "% h    print this help\n\r",
1292 20d8a3ed ths
    "% x    exit emulator\n\r",
1293 20d8a3ed ths
    "% s    save disk data back to file (if -snapshot)\n\r",
1294 20d8a3ed ths
    "% t    toggle console timestamps\n\r"
1295 20d8a3ed ths
    "% b    send break (magic sysrq)\n\r",
1296 20d8a3ed ths
    "% c    switch between console and monitor\n\r",
1297 20d8a3ed ths
    "% %  sends %\n\r",
1298 20d8a3ed ths
    NULL
1299 20d8a3ed ths
};
1300 20d8a3ed ths
1301 20d8a3ed ths
static int term_escape_char = 0x01; /* ctrl-a is used for escape */
1302 20d8a3ed ths
static void mux_print_help(CharDriverState *chr)
1303 20d8a3ed ths
{
1304 20d8a3ed ths
    int i, j;
1305 20d8a3ed ths
    char ebuf[15] = "Escape-Char";
1306 20d8a3ed ths
    char cbuf[50] = "\n\r";
1307 20d8a3ed ths
1308 20d8a3ed ths
    if (term_escape_char > 0 && term_escape_char < 26) {
1309 20d8a3ed ths
        sprintf(cbuf,"\n\r");
1310 20d8a3ed ths
        sprintf(ebuf,"C-%c", term_escape_char - 1 + 'a');
1311 20d8a3ed ths
    } else {
1312 20d8a3ed ths
        sprintf(cbuf,"\n\rEscape-Char set to Ascii: 0x%02x\n\r\n\r", term_escape_char);
1313 20d8a3ed ths
    }
1314 20d8a3ed ths
    chr->chr_write(chr, cbuf, strlen(cbuf));
1315 20d8a3ed ths
    for (i = 0; mux_help[i] != NULL; i++) {
1316 20d8a3ed ths
        for (j=0; mux_help[i][j] != '\0'; j++) {
1317 20d8a3ed ths
            if (mux_help[i][j] == '%')
1318 20d8a3ed ths
                chr->chr_write(chr, ebuf, strlen(ebuf));
1319 20d8a3ed ths
            else
1320 20d8a3ed ths
                chr->chr_write(chr, &mux_help[i][j], 1);
1321 20d8a3ed ths
        }
1322 20d8a3ed ths
    }
1323 20d8a3ed ths
}
1324 20d8a3ed ths
1325 20d8a3ed ths
static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
1326 20d8a3ed ths
{
1327 20d8a3ed ths
    if (d->term_got_escape) {
1328 20d8a3ed ths
        d->term_got_escape = 0;
1329 20d8a3ed ths
        if (ch == term_escape_char)
1330 20d8a3ed ths
            goto send_char;
1331 20d8a3ed ths
        switch(ch) {
1332 20d8a3ed ths
        case '?':
1333 20d8a3ed ths
        case 'h':
1334 20d8a3ed ths
            mux_print_help(chr);
1335 20d8a3ed ths
            break;
1336 20d8a3ed ths
        case 'x':
1337 20d8a3ed ths
            {
1338 20d8a3ed ths
                 char *term =  "QEMU: Terminated\n\r";
1339 20d8a3ed ths
                 chr->chr_write(chr,term,strlen(term));
1340 20d8a3ed ths
                 exit(0);
1341 20d8a3ed ths
                 break;
1342 20d8a3ed ths
            }
1343 20d8a3ed ths
        case 's':
1344 20d8a3ed ths
            {
1345 20d8a3ed ths
                int i;
1346 20d8a3ed ths
                for (i = 0; i < MAX_DISKS; i++) {
1347 20d8a3ed ths
                    if (bs_table[i])
1348 20d8a3ed ths
                        bdrv_commit(bs_table[i]);
1349 20d8a3ed ths
                }
1350 20d8a3ed ths
            }
1351 20d8a3ed ths
            break;
1352 20d8a3ed ths
        case 'b':
1353 20d8a3ed ths
            if (chr->chr_event)
1354 20d8a3ed ths
                chr->chr_event(chr->opaque, CHR_EVENT_BREAK);
1355 20d8a3ed ths
            break;
1356 20d8a3ed ths
        case 'c':
1357 20d8a3ed ths
            /* Switch to the next registered device */
1358 20d8a3ed ths
            chr->focus++;
1359 20d8a3ed ths
            if (chr->focus >= d->mux_cnt)
1360 20d8a3ed ths
                chr->focus = 0;
1361 20d8a3ed ths
            break;
1362 20d8a3ed ths
       case 't':
1363 20d8a3ed ths
           term_timestamps = !term_timestamps;
1364 20d8a3ed ths
           term_timestamps_start = -1;
1365 20d8a3ed ths
           break;
1366 20d8a3ed ths
        }
1367 20d8a3ed ths
    } else if (ch == term_escape_char) {
1368 20d8a3ed ths
        d->term_got_escape = 1;
1369 20d8a3ed ths
    } else {
1370 20d8a3ed ths
    send_char:
1371 20d8a3ed ths
        return 1;
1372 20d8a3ed ths
    }
1373 20d8a3ed ths
    return 0;
1374 20d8a3ed ths
}
1375 20d8a3ed ths
1376 20d8a3ed ths
static int mux_chr_can_read(void *opaque)
1377 20d8a3ed ths
{
1378 20d8a3ed ths
    CharDriverState *chr = opaque;
1379 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1380 20d8a3ed ths
    if (d->chr_can_read[chr->focus])
1381 20d8a3ed ths
       return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]);
1382 20d8a3ed ths
    return 0;
1383 20d8a3ed ths
}
1384 20d8a3ed ths
1385 20d8a3ed ths
static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
1386 20d8a3ed ths
{
1387 20d8a3ed ths
    CharDriverState *chr = opaque;
1388 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1389 20d8a3ed ths
    int i;
1390 20d8a3ed ths
    for(i = 0; i < size; i++)
1391 20d8a3ed ths
        if (mux_proc_byte(chr, d, buf[i]))
1392 20d8a3ed ths
            d->chr_read[chr->focus](d->ext_opaque[chr->focus], &buf[i], 1);
1393 20d8a3ed ths
}
1394 20d8a3ed ths
1395 20d8a3ed ths
static void mux_chr_event(void *opaque, int event)
1396 20d8a3ed ths
{
1397 20d8a3ed ths
    CharDriverState *chr = opaque;
1398 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1399 20d8a3ed ths
    int i;
1400 20d8a3ed ths
1401 20d8a3ed ths
    /* Send the event to all registered listeners */
1402 20d8a3ed ths
    for (i = 0; i < d->mux_cnt; i++)
1403 20d8a3ed ths
        if (d->chr_event[i])
1404 20d8a3ed ths
            d->chr_event[i](d->ext_opaque[i], event);
1405 20d8a3ed ths
}
1406 20d8a3ed ths
1407 20d8a3ed ths
static void mux_chr_update_read_handler(CharDriverState *chr)
1408 20d8a3ed ths
{
1409 20d8a3ed ths
    MuxDriver *d = chr->opaque;
1410 20d8a3ed ths
1411 20d8a3ed ths
    if (d->mux_cnt >= MAX_MUX) {
1412 20d8a3ed ths
        fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");
1413 20d8a3ed ths
        return;
1414 20d8a3ed ths
    }
1415 20d8a3ed ths
    d->ext_opaque[d->mux_cnt] = chr->handler_opaque;
1416 20d8a3ed ths
    d->chr_can_read[d->mux_cnt] = chr->chr_can_read;
1417 20d8a3ed ths
    d->chr_read[d->mux_cnt] = chr->chr_read;
1418 20d8a3ed ths
    d->chr_event[d->mux_cnt] = chr->chr_event;
1419 20d8a3ed ths
    /* Fix up the real driver with mux routines */
1420 20d8a3ed ths
    if (d->mux_cnt == 0) {
1421 20d8a3ed ths
        qemu_chr_add_handlers(d->drv, mux_chr_can_read, mux_chr_read,
1422 20d8a3ed ths
                              mux_chr_event, chr);
1423 20d8a3ed ths
    }
1424 20d8a3ed ths
    chr->focus = d->mux_cnt;
1425 20d8a3ed ths
    d->mux_cnt++;
1426 20d8a3ed ths
}
1427 20d8a3ed ths
1428 20d8a3ed ths
CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
1429 20d8a3ed ths
{
1430 20d8a3ed ths
    CharDriverState *chr;
1431 20d8a3ed ths
    MuxDriver *d;
1432 20d8a3ed ths
1433 20d8a3ed ths
    chr = qemu_mallocz(sizeof(CharDriverState));
1434 20d8a3ed ths
    if (!chr)
1435 20d8a3ed ths
        return NULL;
1436 20d8a3ed ths
    d = qemu_mallocz(sizeof(MuxDriver));
1437 20d8a3ed ths
    if (!d) {
1438 20d8a3ed ths
        free(chr);
1439 20d8a3ed ths
        return NULL;
1440 20d8a3ed ths
    }
1441 20d8a3ed ths
1442 20d8a3ed ths
    chr->opaque = d;
1443 20d8a3ed ths
    d->drv = drv;
1444 20d8a3ed ths
    chr->focus = -1;
1445 20d8a3ed ths
    chr->chr_write = mux_chr_write;
1446 20d8a3ed ths
    chr->chr_update_read_handler = mux_chr_update_read_handler;
1447 20d8a3ed ths
    return chr;
1448 20d8a3ed ths
}
1449 20d8a3ed ths
1450 20d8a3ed ths
1451 fd1dff4b bellard
#ifdef _WIN32
1452 82c643ff bellard
1453 fd1dff4b bellard
static void socket_cleanup(void)
1454 fd1dff4b bellard
{
1455 fd1dff4b bellard
    WSACleanup();
1456 fd1dff4b bellard
}
1457 82c643ff bellard
1458 fd1dff4b bellard
static int socket_init(void)
1459 fd1dff4b bellard
{
1460 fd1dff4b bellard
    WSADATA Data;
1461 fd1dff4b bellard
    int ret, err;
1462 fd1dff4b bellard
1463 fd1dff4b bellard
    ret = WSAStartup(MAKEWORD(2,2), &Data);
1464 fd1dff4b bellard
    if (ret != 0) {
1465 fd1dff4b bellard
        err = WSAGetLastError();
1466 fd1dff4b bellard
        fprintf(stderr, "WSAStartup: %d\n", err);
1467 fd1dff4b bellard
        return -1;
1468 fd1dff4b bellard
    }
1469 fd1dff4b bellard
    atexit(socket_cleanup);
1470 fd1dff4b bellard
    return 0;
1471 fd1dff4b bellard
}
1472 fd1dff4b bellard
1473 fd1dff4b bellard
static int send_all(int fd, const uint8_t *buf, int len1)
1474 fd1dff4b bellard
{
1475 fd1dff4b bellard
    int ret, len;
1476 fd1dff4b bellard
    
1477 fd1dff4b bellard
    len = len1;
1478 fd1dff4b bellard
    while (len > 0) {
1479 fd1dff4b bellard
        ret = send(fd, buf, len, 0);
1480 fd1dff4b bellard
        if (ret < 0) {
1481 fd1dff4b bellard
            int errno;
1482 fd1dff4b bellard
            errno = WSAGetLastError();
1483 fd1dff4b bellard
            if (errno != WSAEWOULDBLOCK) {
1484 fd1dff4b bellard
                return -1;
1485 fd1dff4b bellard
            }
1486 fd1dff4b bellard
        } else if (ret == 0) {
1487 fd1dff4b bellard
            break;
1488 fd1dff4b bellard
        } else {
1489 fd1dff4b bellard
            buf += ret;
1490 fd1dff4b bellard
            len -= ret;
1491 fd1dff4b bellard
        }
1492 fd1dff4b bellard
    }
1493 fd1dff4b bellard
    return len1 - len;
1494 fd1dff4b bellard
}
1495 fd1dff4b bellard
1496 fd1dff4b bellard
void socket_set_nonblock(int fd)
1497 fd1dff4b bellard
{
1498 fd1dff4b bellard
    unsigned long opt = 1;
1499 fd1dff4b bellard
    ioctlsocket(fd, FIONBIO, &opt);
1500 fd1dff4b bellard
}
1501 fd1dff4b bellard
1502 fd1dff4b bellard
#else
1503 fd1dff4b bellard
1504 1d96905d bellard
static int unix_write(int fd, const uint8_t *buf, int len1)
1505 1d96905d bellard
{
1506 1d96905d bellard
    int ret, len;
1507 1d96905d bellard
1508 1d96905d bellard
    len = len1;
1509 1d96905d bellard
    while (len > 0) {
1510 1d96905d bellard
        ret = write(fd, buf, len);
1511 1d96905d bellard
        if (ret < 0) {
1512 1d96905d bellard
            if (errno != EINTR && errno != EAGAIN)
1513 1d96905d bellard
                return -1;
1514 1d96905d bellard
        } else if (ret == 0) {
1515 1d96905d bellard
            break;
1516 1d96905d bellard
        } else {
1517 1d96905d bellard
            buf += ret;
1518 1d96905d bellard
            len -= ret;
1519 1d96905d bellard
        }
1520 1d96905d bellard
    }
1521 1d96905d bellard
    return len1 - len;
1522 1d96905d bellard
}
1523 1d96905d bellard
1524 fd1dff4b bellard
static inline int send_all(int fd, const uint8_t *buf, int len1)
1525 fd1dff4b bellard
{
1526 fd1dff4b bellard
    return unix_write(fd, buf, len1);
1527 fd1dff4b bellard
}
1528 fd1dff4b bellard
1529 fd1dff4b bellard
void socket_set_nonblock(int fd)
1530 fd1dff4b bellard
{
1531 fd1dff4b bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
1532 fd1dff4b bellard
}
1533 fd1dff4b bellard
#endif /* !_WIN32 */
1534 fd1dff4b bellard
1535 fd1dff4b bellard
#ifndef _WIN32
1536 fd1dff4b bellard
1537 fd1dff4b bellard
typedef struct {
1538 fd1dff4b bellard
    int fd_in, fd_out;
1539 fd1dff4b bellard
    int max_size;
1540 fd1dff4b bellard
} FDCharDriver;
1541 fd1dff4b bellard
1542 20d8a3ed ths
#define STDIO_MAX_CLIENTS 1
1543 20d8a3ed ths
static int stdio_nb_clients = 0;
1544 fd1dff4b bellard
1545 82c643ff bellard
static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
1546 82c643ff bellard
{
1547 82c643ff bellard
    FDCharDriver *s = chr->opaque;
1548 1d96905d bellard
    return unix_write(s->fd_out, buf, len);
1549 82c643ff bellard
}
1550 82c643ff bellard
1551 7c9d8e07 bellard
static int fd_chr_read_poll(void *opaque)
1552 7c9d8e07 bellard
{
1553 7c9d8e07 bellard
    CharDriverState *chr = opaque;
1554 7c9d8e07 bellard
    FDCharDriver *s = chr->opaque;
1555 7c9d8e07 bellard
1556 e5b0bc44 pbrook
    s->max_size = qemu_chr_can_read(chr);
1557 7c9d8e07 bellard
    return s->max_size;
1558 7c9d8e07 bellard
}
1559 7c9d8e07 bellard
1560 7c9d8e07 bellard
static void fd_chr_read(void *opaque)
1561 7c9d8e07 bellard
{
1562 7c9d8e07 bellard
    CharDriverState *chr = opaque;
1563 7c9d8e07 bellard
    FDCharDriver *s = chr->opaque;
1564 7c9d8e07 bellard
    int size, len;
1565 7c9d8e07 bellard
    uint8_t buf[1024];
1566 7c9d8e07 bellard
    
1567 7c9d8e07 bellard
    len = sizeof(buf);
1568 7c9d8e07 bellard
    if (len > s->max_size)
1569 7c9d8e07 bellard
        len = s->max_size;
1570 7c9d8e07 bellard
    if (len == 0)
1571 7c9d8e07 bellard
        return;
1572 7c9d8e07 bellard
    size = read(s->fd_in, buf, len);
1573 188157fe pbrook
    if (size == 0) {
1574 188157fe pbrook
        /* FD has been closed. Remove it from the active list.  */
1575 188157fe pbrook
        qemu_set_fd_handler2(s->fd_in, NULL, NULL, NULL, NULL);
1576 188157fe pbrook
        return;
1577 188157fe pbrook
    }
1578 7c9d8e07 bellard
    if (size > 0) {
1579 e5b0bc44 pbrook
        qemu_chr_read(chr, buf, size);
1580 7c9d8e07 bellard
    }
1581 7c9d8e07 bellard
}
1582 7c9d8e07 bellard
1583 e5b0bc44 pbrook
static void fd_chr_update_read_handler(CharDriverState *chr)
1584 82c643ff bellard
{
1585 82c643ff bellard
    FDCharDriver *s = chr->opaque;
1586 82c643ff bellard
1587 f8d179e3 bellard
    if (s->fd_in >= 0) {
1588 f8d179e3 bellard
        if (nographic && s->fd_in == 0) {
1589 f8d179e3 bellard
        } else {
1590 7c9d8e07 bellard
            qemu_set_fd_handler2(s->fd_in, fd_chr_read_poll, 
1591 7c9d8e07 bellard
                                 fd_chr_read, NULL, chr);
1592 f8d179e3 bellard
        }
1593 82c643ff bellard
    }
1594 82c643ff bellard
}
1595 82c643ff bellard
1596 82c643ff bellard
/* open a character device to a unix fd */
1597 52f61fde ths
static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
1598 82c643ff bellard
{
1599 82c643ff bellard
    CharDriverState *chr;
1600 82c643ff bellard
    FDCharDriver *s;
1601 82c643ff bellard
1602 82c643ff bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
1603 82c643ff bellard
    if (!chr)
1604 82c643ff bellard
        return NULL;
1605 82c643ff bellard
    s = qemu_mallocz(sizeof(FDCharDriver));
1606 82c643ff bellard
    if (!s) {
1607 82c643ff bellard
        free(chr);
1608 82c643ff bellard
        return NULL;
1609 82c643ff bellard
    }
1610 82c643ff bellard
    s->fd_in = fd_in;
1611 82c643ff bellard
    s->fd_out = fd_out;
1612 82c643ff bellard
    chr->opaque = s;
1613 82c643ff bellard
    chr->chr_write = fd_chr_write;
1614 e5b0bc44 pbrook
    chr->chr_update_read_handler = fd_chr_update_read_handler;
1615 86e94dea ths
1616 86e94dea ths
    qemu_chr_reset(chr);
1617 86e94dea ths
1618 82c643ff bellard
    return chr;
1619 82c643ff bellard
}
1620 82c643ff bellard
1621 52f61fde ths
static CharDriverState *qemu_chr_open_file_out(const char *file_out)
1622 f8d179e3 bellard
{
1623 f8d179e3 bellard
    int fd_out;
1624 f8d179e3 bellard
1625 89ba1a73 pbrook
    fd_out = open(file_out, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666);
1626 f8d179e3 bellard
    if (fd_out < 0)
1627 f8d179e3 bellard
        return NULL;
1628 f8d179e3 bellard
    return qemu_chr_open_fd(-1, fd_out);
1629 f8d179e3 bellard
}
1630 f8d179e3 bellard
1631 52f61fde ths
static CharDriverState *qemu_chr_open_pipe(const char *filename)
1632 f8d179e3 bellard
{
1633 c26c1c4b ths
    int fd_in, fd_out;
1634 c26c1c4b ths
    char filename_in[256], filename_out[256];
1635 c26c1c4b ths
1636 c26c1c4b ths
    snprintf(filename_in, 256, "%s.in", filename);
1637 c26c1c4b ths
    snprintf(filename_out, 256, "%s.out", filename);
1638 c26c1c4b ths
    fd_in = open(filename_in, O_RDWR | O_BINARY);
1639 c26c1c4b ths
    fd_out = open(filename_out, O_RDWR | O_BINARY);
1640 c26c1c4b ths
    if (fd_in < 0 || fd_out < 0) {
1641 c26c1c4b ths
        if (fd_in >= 0)
1642 c26c1c4b ths
            close(fd_in);
1643 c26c1c4b ths
        if (fd_out >= 0)
1644 c26c1c4b ths
            close(fd_out);
1645 c26c1c4b ths
        fd_in = fd_out = open(filename, O_RDWR | O_BINARY);
1646 c26c1c4b ths
        if (fd_in < 0)
1647 c26c1c4b ths
            return NULL;
1648 c26c1c4b ths
    }
1649 c26c1c4b ths
    return qemu_chr_open_fd(fd_in, fd_out);
1650 f8d179e3 bellard
}
1651 f8d179e3 bellard
1652 f8d179e3 bellard
1653 82c643ff bellard
/* for STDIO, we handle the case where several clients use it
1654 82c643ff bellard
   (nographic mode) */
1655 82c643ff bellard
1656 aa0bc6b6 bellard
#define TERM_FIFO_MAX_SIZE 1
1657 aa0bc6b6 bellard
1658 aa0bc6b6 bellard
static uint8_t term_fifo[TERM_FIFO_MAX_SIZE];
1659 1dce7c3c bellard
static int term_fifo_size;
1660 330d0414 bellard
1661 7c9d8e07 bellard
static int stdio_read_poll(void *opaque)
1662 82c643ff bellard
{
1663 20d8a3ed ths
    CharDriverState *chr = opaque;
1664 aa0bc6b6 bellard
1665 20d8a3ed ths
    /* try to flush the queue if needed */
1666 20d8a3ed ths
    if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) {
1667 20d8a3ed ths
        qemu_chr_read(chr, term_fifo, 1);
1668 20d8a3ed ths
        term_fifo_size = 0;
1669 aa0bc6b6 bellard
    }
1670 20d8a3ed ths
    /* see if we can absorb more chars */
1671 20d8a3ed ths
    if (term_fifo_size == 0)
1672 20d8a3ed ths
        return 1;
1673 20d8a3ed ths
    else
1674 20d8a3ed ths
        return 0;
1675 82c643ff bellard
}
1676 82c643ff bellard
1677 7c9d8e07 bellard
static void stdio_read(void *opaque)
1678 82c643ff bellard
{
1679 7c9d8e07 bellard
    int size;
1680 7c9d8e07 bellard
    uint8_t buf[1];
1681 20d8a3ed ths
    CharDriverState *chr = opaque;
1682 20d8a3ed ths
1683 7c9d8e07 bellard
    size = read(0, buf, 1);
1684 519945df pbrook
    if (size == 0) {
1685 519945df pbrook
        /* stdin has been closed. Remove it from the active list.  */
1686 519945df pbrook
        qemu_set_fd_handler2(0, NULL, NULL, NULL, NULL);
1687 519945df pbrook
        return;
1688 519945df pbrook
    }
1689 20d8a3ed ths
    if (size > 0) {
1690 20d8a3ed ths
        if (qemu_chr_can_read(chr) > 0) {
1691 20d8a3ed ths
            qemu_chr_read(chr, buf, 1);
1692 20d8a3ed ths
        } else if (term_fifo_size == 0) {
1693 20d8a3ed ths
            term_fifo[term_fifo_size++] = buf[0];
1694 1dce7c3c bellard
        }
1695 1dce7c3c bellard
    }
1696 1dce7c3c bellard
}
1697 1dce7c3c bellard
1698 8d11df9e bellard
/* init terminal so that we can grab keys */
1699 8d11df9e bellard
static struct termios oldtty;
1700 8d11df9e bellard
static int old_fd0_flags;
1701 8d11df9e bellard
1702 8d11df9e bellard
static void term_exit(void)
1703 8d11df9e bellard
{
1704 8d11df9e bellard
    tcsetattr (0, TCSANOW, &oldtty);
1705 8d11df9e bellard
    fcntl(0, F_SETFL, old_fd0_flags);
1706 8d11df9e bellard
}
1707 8d11df9e bellard
1708 8d11df9e bellard
static void term_init(void)
1709 8d11df9e bellard
{
1710 8d11df9e bellard
    struct termios tty;
1711 8d11df9e bellard
1712 8d11df9e bellard
    tcgetattr (0, &tty);
1713 8d11df9e bellard
    oldtty = tty;
1714 8d11df9e bellard
    old_fd0_flags = fcntl(0, F_GETFL);
1715 8d11df9e bellard
1716 8d11df9e bellard
    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
1717 8d11df9e bellard
                          |INLCR|IGNCR|ICRNL|IXON);
1718 8d11df9e bellard
    tty.c_oflag |= OPOST;
1719 8d11df9e bellard
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
1720 8d11df9e bellard
    /* if graphical mode, we allow Ctrl-C handling */
1721 8d11df9e bellard
    if (nographic)
1722 8d11df9e bellard
        tty.c_lflag &= ~ISIG;
1723 8d11df9e bellard
    tty.c_cflag &= ~(CSIZE|PARENB);
1724 8d11df9e bellard
    tty.c_cflag |= CS8;
1725 8d11df9e bellard
    tty.c_cc[VMIN] = 1;
1726 8d11df9e bellard
    tty.c_cc[VTIME] = 0;
1727 8d11df9e bellard
    
1728 8d11df9e bellard
    tcsetattr (0, TCSANOW, &tty);
1729 8d11df9e bellard
1730 8d11df9e bellard
    atexit(term_exit);
1731 8d11df9e bellard
1732 8d11df9e bellard
    fcntl(0, F_SETFL, O_NONBLOCK);
1733 8d11df9e bellard
}
1734 8d11df9e bellard
1735 52f61fde ths
static CharDriverState *qemu_chr_open_stdio(void)
1736 82c643ff bellard
{
1737 82c643ff bellard
    CharDriverState *chr;
1738 82c643ff bellard
1739 20d8a3ed ths
    if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
1740 20d8a3ed ths
        return NULL;
1741 20d8a3ed ths
    chr = qemu_chr_open_fd(0, 1);
1742 20d8a3ed ths
    qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr);
1743 20d8a3ed ths
    stdio_nb_clients++;
1744 20d8a3ed ths
    term_init();
1745 20d8a3ed ths
1746 82c643ff bellard
    return chr;
1747 82c643ff bellard
}
1748 82c643ff bellard
1749 82c643ff bellard
#if defined(__linux__)
1750 52f61fde ths
static CharDriverState *qemu_chr_open_pty(void)
1751 82c643ff bellard
{
1752 91fc2119 bellard
    struct termios tty;
1753 82c643ff bellard
    char slave_name[1024];
1754 82c643ff bellard
    int master_fd, slave_fd;
1755 82c643ff bellard
    
1756 82c643ff bellard
    /* Not satisfying */
1757 82c643ff bellard
    if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
1758 82c643ff bellard
        return NULL;
1759 82c643ff bellard
    }
1760 91fc2119 bellard
    
1761 91fc2119 bellard
    /* Disabling local echo and line-buffered output */
1762 91fc2119 bellard
    tcgetattr (master_fd, &tty);
1763 91fc2119 bellard
    tty.c_lflag &= ~(ECHO|ICANON|ISIG);
1764 91fc2119 bellard
    tty.c_cc[VMIN] = 1;
1765 91fc2119 bellard
    tty.c_cc[VTIME] = 0;
1766 91fc2119 bellard
    tcsetattr (master_fd, TCSAFLUSH, &tty);
1767 91fc2119 bellard
1768 82c643ff bellard
    fprintf(stderr, "char device redirected to %s\n", slave_name);
1769 82c643ff bellard
    return qemu_chr_open_fd(master_fd, master_fd);
1770 82c643ff bellard
}
1771 f8d179e3 bellard
1772 f8d179e3 bellard
static void tty_serial_init(int fd, int speed, 
1773 f8d179e3 bellard
                            int parity, int data_bits, int stop_bits)
1774 f8d179e3 bellard
{
1775 f8d179e3 bellard
    struct termios tty;
1776 f8d179e3 bellard
    speed_t spd;
1777 f8d179e3 bellard
1778 e57a8c0e bellard
#if 0
1779 e57a8c0e bellard
    printf("tty_serial_init: speed=%d parity=%c data=%d stop=%d\n", 
1780 e57a8c0e bellard
           speed, parity, data_bits, stop_bits);
1781 e57a8c0e bellard
#endif
1782 e57a8c0e bellard
    tcgetattr (fd, &tty);
1783 f8d179e3 bellard
1784 f8d179e3 bellard
    switch(speed) {
1785 f8d179e3 bellard
    case 50:
1786 f8d179e3 bellard
        spd = B50;
1787 f8d179e3 bellard
        break;
1788 f8d179e3 bellard
    case 75:
1789 f8d179e3 bellard
        spd = B75;
1790 f8d179e3 bellard
        break;
1791 f8d179e3 bellard
    case 300:
1792 f8d179e3 bellard
        spd = B300;
1793 f8d179e3 bellard
        break;
1794 f8d179e3 bellard
    case 600:
1795 f8d179e3 bellard
        spd = B600;
1796 f8d179e3 bellard
        break;
1797 f8d179e3 bellard
    case 1200:
1798 f8d179e3 bellard
        spd = B1200;
1799 f8d179e3 bellard
        break;
1800 f8d179e3 bellard
    case 2400:
1801 f8d179e3 bellard
        spd = B2400;
1802 f8d179e3 bellard
        break;
1803 f8d179e3 bellard
    case 4800:
1804 f8d179e3 bellard
        spd = B4800;
1805 f8d179e3 bellard
        break;
1806 f8d179e3 bellard
    case 9600:
1807 f8d179e3 bellard
        spd = B9600;
1808 f8d179e3 bellard
        break;
1809 f8d179e3 bellard
    case 19200:
1810 f8d179e3 bellard
        spd = B19200;
1811 f8d179e3 bellard
        break;
1812 f8d179e3 bellard
    case 38400:
1813 f8d179e3 bellard
        spd = B38400;
1814 f8d179e3 bellard
        break;
1815 f8d179e3 bellard
    case 57600:
1816 f8d179e3 bellard
        spd = B57600;
1817 f8d179e3 bellard
        break;
1818 f8d179e3 bellard
    default:
1819 f8d179e3 bellard
    case 115200:
1820 f8d179e3 bellard
        spd = B115200;
1821 f8d179e3 bellard
        break;
1822 f8d179e3 bellard
    }
1823 f8d179e3 bellard
1824 f8d179e3 bellard
    cfsetispeed(&tty, spd);
1825 f8d179e3 bellard
    cfsetospeed(&tty, spd);
1826 f8d179e3 bellard
1827 f8d179e3 bellard
    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
1828 f8d179e3 bellard
                          |INLCR|IGNCR|ICRNL|IXON);
1829 f8d179e3 bellard
    tty.c_oflag |= OPOST;
1830 f8d179e3 bellard
    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
1831 094eed6c bellard
    tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB);
1832 f8d179e3 bellard
    switch(data_bits) {
1833 f8d179e3 bellard
    default:
1834 f8d179e3 bellard
    case 8:
1835 f8d179e3 bellard
        tty.c_cflag |= CS8;
1836 f8d179e3 bellard
        break;
1837 f8d179e3 bellard
    case 7:
1838 f8d179e3 bellard
        tty.c_cflag |= CS7;
1839 f8d179e3 bellard
        break;
1840 f8d179e3 bellard
    case 6:
1841 f8d179e3 bellard
        tty.c_cflag |= CS6;
1842 f8d179e3 bellard
        break;
1843 f8d179e3 bellard
    case 5:
1844 f8d179e3 bellard
        tty.c_cflag |= CS5;
1845 f8d179e3 bellard
        break;
1846 f8d179e3 bellard
    }
1847 f8d179e3 bellard
    switch(parity) {
1848 f8d179e3 bellard
    default:
1849 f8d179e3 bellard
    case 'N':
1850 f8d179e3 bellard
        break;
1851 f8d179e3 bellard
    case 'E':
1852 f8d179e3 bellard
        tty.c_cflag |= PARENB;
1853 f8d179e3 bellard
        break;
1854 f8d179e3 bellard
    case 'O':
1855 f8d179e3 bellard
        tty.c_cflag |= PARENB | PARODD;
1856 f8d179e3 bellard
        break;
1857 f8d179e3 bellard
    }
1858 094eed6c bellard
    if (stop_bits == 2)
1859 094eed6c bellard
        tty.c_cflag |= CSTOPB;
1860 f8d179e3 bellard
    
1861 f8d179e3 bellard
    tcsetattr (fd, TCSANOW, &tty);
1862 f8d179e3 bellard
}
1863 f8d179e3 bellard
1864 e57a8c0e bellard
static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg)
1865 f8d179e3 bellard
{
1866 f8d179e3 bellard
    FDCharDriver *s = chr->opaque;
1867 e57a8c0e bellard
    
1868 e57a8c0e bellard
    switch(cmd) {
1869 e57a8c0e bellard
    case CHR_IOCTL_SERIAL_SET_PARAMS:
1870 e57a8c0e bellard
        {
1871 e57a8c0e bellard
            QEMUSerialSetParams *ssp = arg;
1872 e57a8c0e bellard
            tty_serial_init(s->fd_in, ssp->speed, ssp->parity, 
1873 e57a8c0e bellard
                            ssp->data_bits, ssp->stop_bits);
1874 e57a8c0e bellard
        }
1875 e57a8c0e bellard
        break;
1876 e57a8c0e bellard
    case CHR_IOCTL_SERIAL_SET_BREAK:
1877 e57a8c0e bellard
        {
1878 e57a8c0e bellard
            int enable = *(int *)arg;
1879 e57a8c0e bellard
            if (enable)
1880 e57a8c0e bellard
                tcsendbreak(s->fd_in, 1);
1881 e57a8c0e bellard
        }
1882 e57a8c0e bellard
        break;
1883 e57a8c0e bellard
    default:
1884 e57a8c0e bellard
        return -ENOTSUP;
1885 e57a8c0e bellard
    }
1886 e57a8c0e bellard
    return 0;
1887 f8d179e3 bellard
}
1888 f8d179e3 bellard
1889 52f61fde ths
static CharDriverState *qemu_chr_open_tty(const char *filename)
1890 f8d179e3 bellard
{
1891 f8d179e3 bellard
    CharDriverState *chr;
1892 f8d179e3 bellard
    int fd;
1893 f8d179e3 bellard
1894 e57a8c0e bellard
    fd = open(filename, O_RDWR | O_NONBLOCK);
1895 f8d179e3 bellard
    if (fd < 0)
1896 f8d179e3 bellard
        return NULL;
1897 f8d179e3 bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
1898 f8d179e3 bellard
    tty_serial_init(fd, 115200, 'N', 8, 1);
1899 f8d179e3 bellard
    chr = qemu_chr_open_fd(fd, fd);
1900 f8d179e3 bellard
    if (!chr)
1901 f8d179e3 bellard
        return NULL;
1902 e57a8c0e bellard
    chr->chr_ioctl = tty_serial_ioctl;
1903 86e94dea ths
    qemu_chr_reset(chr);
1904 e57a8c0e bellard
    return chr;
1905 e57a8c0e bellard
}
1906 e57a8c0e bellard
1907 5867c88a ths
typedef struct {
1908 5867c88a ths
    int fd;
1909 5867c88a ths
    int mode;
1910 5867c88a ths
} ParallelCharDriver;
1911 5867c88a ths
1912 5867c88a ths
static int pp_hw_mode(ParallelCharDriver *s, uint16_t mode)
1913 5867c88a ths
{
1914 5867c88a ths
    if (s->mode != mode) {
1915 5867c88a ths
        int m = mode;
1916 5867c88a ths
        if (ioctl(s->fd, PPSETMODE, &m) < 0)
1917 5867c88a ths
            return 0;
1918 5867c88a ths
        s->mode = mode;
1919 5867c88a ths
    }
1920 5867c88a ths
    return 1;
1921 5867c88a ths
}
1922 5867c88a ths
1923 e57a8c0e bellard
static int pp_ioctl(CharDriverState *chr, int cmd, void *arg)
1924 e57a8c0e bellard
{
1925 5867c88a ths
    ParallelCharDriver *drv = chr->opaque;
1926 5867c88a ths
    int fd = drv->fd;
1927 e57a8c0e bellard
    uint8_t b;
1928 e57a8c0e bellard
1929 e57a8c0e bellard
    switch(cmd) {
1930 e57a8c0e bellard
    case CHR_IOCTL_PP_READ_DATA:
1931 e57a8c0e bellard
        if (ioctl(fd, PPRDATA, &b) < 0)
1932 e57a8c0e bellard
            return -ENOTSUP;
1933 e57a8c0e bellard
        *(uint8_t *)arg = b;
1934 e57a8c0e bellard
        break;
1935 e57a8c0e bellard
    case CHR_IOCTL_PP_WRITE_DATA:
1936 e57a8c0e bellard
        b = *(uint8_t *)arg;
1937 e57a8c0e bellard
        if (ioctl(fd, PPWDATA, &b) < 0)
1938 e57a8c0e bellard
            return -ENOTSUP;
1939 e57a8c0e bellard
        break;
1940 e57a8c0e bellard
    case CHR_IOCTL_PP_READ_CONTROL:
1941 e57a8c0e bellard
        if (ioctl(fd, PPRCONTROL, &b) < 0)
1942 e57a8c0e bellard
            return -ENOTSUP;
1943 5867c88a ths
        /* Linux gives only the lowest bits, and no way to know data
1944 5867c88a ths
           direction! For better compatibility set the fixed upper
1945 5867c88a ths
           bits. */
1946 5867c88a ths
        *(uint8_t *)arg = b | 0xc0;
1947 e57a8c0e bellard
        break;
1948 e57a8c0e bellard
    case CHR_IOCTL_PP_WRITE_CONTROL:
1949 e57a8c0e bellard
        b = *(uint8_t *)arg;
1950 e57a8c0e bellard
        if (ioctl(fd, PPWCONTROL, &b) < 0)
1951 e57a8c0e bellard
            return -ENOTSUP;
1952 e57a8c0e bellard
        break;
1953 e57a8c0e bellard
    case CHR_IOCTL_PP_READ_STATUS:
1954 e57a8c0e bellard
        if (ioctl(fd, PPRSTATUS, &b) < 0)
1955 e57a8c0e bellard
            return -ENOTSUP;
1956 e57a8c0e bellard
        *(uint8_t *)arg = b;
1957 e57a8c0e bellard
        break;
1958 5867c88a ths
    case CHR_IOCTL_PP_EPP_READ_ADDR:
1959 5867c88a ths
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
1960 5867c88a ths
            struct ParallelIOArg *parg = arg;
1961 5867c88a ths
            int n = read(fd, parg->buffer, parg->count);
1962 5867c88a ths
            if (n != parg->count) {
1963 5867c88a ths
                return -EIO;
1964 5867c88a ths
            }
1965 5867c88a ths
        }
1966 5867c88a ths
        break;
1967 5867c88a ths
    case CHR_IOCTL_PP_EPP_READ:
1968 5867c88a ths
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
1969 5867c88a ths
            struct ParallelIOArg *parg = arg;
1970 5867c88a ths
            int n = read(fd, parg->buffer, parg->count);
1971 5867c88a ths
            if (n != parg->count) {
1972 5867c88a ths
                return -EIO;
1973 5867c88a ths
            }
1974 5867c88a ths
        }
1975 5867c88a ths
        break;
1976 5867c88a ths
    case CHR_IOCTL_PP_EPP_WRITE_ADDR:
1977 5867c88a ths
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP|IEEE1284_ADDR)) {
1978 5867c88a ths
            struct ParallelIOArg *parg = arg;
1979 5867c88a ths
            int n = write(fd, parg->buffer, parg->count);
1980 5867c88a ths
            if (n != parg->count) {
1981 5867c88a ths
                return -EIO;
1982 5867c88a ths
            }
1983 5867c88a ths
        }
1984 5867c88a ths
        break;
1985 5867c88a ths
    case CHR_IOCTL_PP_EPP_WRITE:
1986 5867c88a ths
        if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
1987 5867c88a ths
            struct ParallelIOArg *parg = arg;
1988 5867c88a ths
            int n = write(fd, parg->buffer, parg->count);
1989 5867c88a ths
            if (n != parg->count) {
1990 5867c88a ths
                return -EIO;
1991 5867c88a ths
            }
1992 5867c88a ths
        }
1993 5867c88a ths
        break;
1994 e57a8c0e bellard
    default:
1995 e57a8c0e bellard
        return -ENOTSUP;
1996 e57a8c0e bellard
    }
1997 e57a8c0e bellard
    return 0;
1998 e57a8c0e bellard
}
1999 e57a8c0e bellard
2000 5867c88a ths
static void pp_close(CharDriverState *chr)
2001 5867c88a ths
{
2002 5867c88a ths
    ParallelCharDriver *drv = chr->opaque;
2003 5867c88a ths
    int fd = drv->fd;
2004 5867c88a ths
2005 5867c88a ths
    pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
2006 5867c88a ths
    ioctl(fd, PPRELEASE);
2007 5867c88a ths
    close(fd);
2008 5867c88a ths
    qemu_free(drv);
2009 5867c88a ths
}
2010 5867c88a ths
2011 52f61fde ths
static CharDriverState *qemu_chr_open_pp(const char *filename)
2012 e57a8c0e bellard
{
2013 e57a8c0e bellard
    CharDriverState *chr;
2014 5867c88a ths
    ParallelCharDriver *drv;
2015 e57a8c0e bellard
    int fd;
2016 e57a8c0e bellard
2017 e57a8c0e bellard
    fd = open(filename, O_RDWR);
2018 e57a8c0e bellard
    if (fd < 0)
2019 e57a8c0e bellard
        return NULL;
2020 e57a8c0e bellard
2021 e57a8c0e bellard
    if (ioctl(fd, PPCLAIM) < 0) {
2022 e57a8c0e bellard
        close(fd);
2023 e57a8c0e bellard
        return NULL;
2024 e57a8c0e bellard
    }
2025 e57a8c0e bellard
2026 5867c88a ths
    drv = qemu_mallocz(sizeof(ParallelCharDriver));
2027 5867c88a ths
    if (!drv) {
2028 5867c88a ths
        close(fd);
2029 5867c88a ths
        return NULL;
2030 5867c88a ths
    }
2031 5867c88a ths
    drv->fd = fd;
2032 5867c88a ths
    drv->mode = IEEE1284_MODE_COMPAT;
2033 5867c88a ths
2034 e57a8c0e bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2035 e57a8c0e bellard
    if (!chr) {
2036 5867c88a ths
        qemu_free(drv);
2037 e57a8c0e bellard
        close(fd);
2038 e57a8c0e bellard
        return NULL;
2039 e57a8c0e bellard
    }
2040 e57a8c0e bellard
    chr->chr_write = null_chr_write;
2041 e57a8c0e bellard
    chr->chr_ioctl = pp_ioctl;
2042 5867c88a ths
    chr->chr_close = pp_close;
2043 5867c88a ths
    chr->opaque = drv;
2044 86e94dea ths
2045 86e94dea ths
    qemu_chr_reset(chr);
2046 86e94dea ths
2047 f8d179e3 bellard
    return chr;
2048 f8d179e3 bellard
}
2049 f8d179e3 bellard
2050 82c643ff bellard
#else
2051 52f61fde ths
static CharDriverState *qemu_chr_open_pty(void)
2052 82c643ff bellard
{
2053 82c643ff bellard
    return NULL;
2054 82c643ff bellard
}
2055 67b915a5 bellard
#endif
2056 67b915a5 bellard
2057 82c643ff bellard
#endif /* !defined(_WIN32) */
2058 82c643ff bellard
2059 f331110f bellard
#ifdef _WIN32
2060 f331110f bellard
typedef struct {
2061 f331110f bellard
    int max_size;
2062 f331110f bellard
    HANDLE hcom, hrecv, hsend;
2063 f331110f bellard
    OVERLAPPED orecv, osend;
2064 f331110f bellard
    BOOL fpipe;
2065 f331110f bellard
    DWORD len;
2066 f331110f bellard
} WinCharState;
2067 f331110f bellard
2068 f331110f bellard
#define NSENDBUF 2048
2069 f331110f bellard
#define NRECVBUF 2048
2070 f331110f bellard
#define MAXCONNECT 1
2071 f331110f bellard
#define NTIMEOUT 5000
2072 f331110f bellard
2073 f331110f bellard
static int win_chr_poll(void *opaque);
2074 f331110f bellard
static int win_chr_pipe_poll(void *opaque);
2075 f331110f bellard
2076 087f4ae0 ths
static void win_chr_close(CharDriverState *chr)
2077 f331110f bellard
{
2078 087f4ae0 ths
    WinCharState *s = chr->opaque;
2079 087f4ae0 ths
2080 f331110f bellard
    if (s->hsend) {
2081 f331110f bellard
        CloseHandle(s->hsend);
2082 f331110f bellard
        s->hsend = NULL;
2083 f331110f bellard
    }
2084 f331110f bellard
    if (s->hrecv) {
2085 f331110f bellard
        CloseHandle(s->hrecv);
2086 f331110f bellard
        s->hrecv = NULL;
2087 f331110f bellard
    }
2088 f331110f bellard
    if (s->hcom) {
2089 f331110f bellard
        CloseHandle(s->hcom);
2090 f331110f bellard
        s->hcom = NULL;
2091 f331110f bellard
    }
2092 f331110f bellard
    if (s->fpipe)
2093 087f4ae0 ths
        qemu_del_polling_cb(win_chr_pipe_poll, chr);
2094 f331110f bellard
    else
2095 087f4ae0 ths
        qemu_del_polling_cb(win_chr_poll, chr);
2096 f331110f bellard
}
2097 f331110f bellard
2098 087f4ae0 ths
static int win_chr_init(CharDriverState *chr, const char *filename)
2099 f331110f bellard
{
2100 f331110f bellard
    WinCharState *s = chr->opaque;
2101 f331110f bellard
    COMMCONFIG comcfg;
2102 f331110f bellard
    COMMTIMEOUTS cto = { 0, 0, 0, 0, 0};
2103 f331110f bellard
    COMSTAT comstat;
2104 f331110f bellard
    DWORD size;
2105 f331110f bellard
    DWORD err;
2106 f331110f bellard
    
2107 f331110f bellard
    s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
2108 f331110f bellard
    if (!s->hsend) {
2109 f331110f bellard
        fprintf(stderr, "Failed CreateEvent\n");
2110 f331110f bellard
        goto fail;
2111 f331110f bellard
    }
2112 f331110f bellard
    s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
2113 f331110f bellard
    if (!s->hrecv) {
2114 f331110f bellard
        fprintf(stderr, "Failed CreateEvent\n");
2115 f331110f bellard
        goto fail;
2116 f331110f bellard
    }
2117 f331110f bellard
2118 f331110f bellard
    s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
2119 f331110f bellard
                      OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
2120 f331110f bellard
    if (s->hcom == INVALID_HANDLE_VALUE) {
2121 f331110f bellard
        fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError());
2122 f331110f bellard
        s->hcom = NULL;
2123 f331110f bellard
        goto fail;
2124 f331110f bellard
    }
2125 f331110f bellard
    
2126 f331110f bellard
    if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
2127 f331110f bellard
        fprintf(stderr, "Failed SetupComm\n");
2128 f331110f bellard
        goto fail;
2129 f331110f bellard
    }
2130 f331110f bellard
    
2131 f331110f bellard
    ZeroMemory(&comcfg, sizeof(COMMCONFIG));
2132 f331110f bellard
    size = sizeof(COMMCONFIG);
2133 f331110f bellard
    GetDefaultCommConfig(filename, &comcfg, &size);
2134 f331110f bellard
    comcfg.dcb.DCBlength = sizeof(DCB);
2135 f331110f bellard
    CommConfigDialog(filename, NULL, &comcfg);
2136 f331110f bellard
2137 f331110f bellard
    if (!SetCommState(s->hcom, &comcfg.dcb)) {
2138 f331110f bellard
        fprintf(stderr, "Failed SetCommState\n");
2139 f331110f bellard
        goto fail;
2140 f331110f bellard
    }
2141 f331110f bellard
2142 f331110f bellard
    if (!SetCommMask(s->hcom, EV_ERR)) {
2143 f331110f bellard
        fprintf(stderr, "Failed SetCommMask\n");
2144 f331110f bellard
        goto fail;
2145 f331110f bellard
    }
2146 f331110f bellard
2147 f331110f bellard
    cto.ReadIntervalTimeout = MAXDWORD;
2148 f331110f bellard
    if (!SetCommTimeouts(s->hcom, &cto)) {
2149 f331110f bellard
        fprintf(stderr, "Failed SetCommTimeouts\n");
2150 f331110f bellard
        goto fail;
2151 f331110f bellard
    }
2152 f331110f bellard
    
2153 f331110f bellard
    if (!ClearCommError(s->hcom, &err, &comstat)) {
2154 f331110f bellard
        fprintf(stderr, "Failed ClearCommError\n");
2155 f331110f bellard
        goto fail;
2156 f331110f bellard
    }
2157 087f4ae0 ths
    qemu_add_polling_cb(win_chr_poll, chr);
2158 f331110f bellard
    return 0;
2159 f331110f bellard
2160 f331110f bellard
 fail:
2161 087f4ae0 ths
    win_chr_close(chr);
2162 f331110f bellard
    return -1;
2163 f331110f bellard
}
2164 f331110f bellard
2165 f331110f bellard
static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1)
2166 f331110f bellard
{
2167 f331110f bellard
    WinCharState *s = chr->opaque;
2168 f331110f bellard
    DWORD len, ret, size, err;
2169 f331110f bellard
2170 f331110f bellard
    len = len1;
2171 f331110f bellard
    ZeroMemory(&s->osend, sizeof(s->osend));
2172 f331110f bellard
    s->osend.hEvent = s->hsend;
2173 f331110f bellard
    while (len > 0) {
2174 f331110f bellard
        if (s->hsend)
2175 f331110f bellard
            ret = WriteFile(s->hcom, buf, len, &size, &s->osend);
2176 f331110f bellard
        else
2177 f331110f bellard
            ret = WriteFile(s->hcom, buf, len, &size, NULL);
2178 f331110f bellard
        if (!ret) {
2179 f331110f bellard
            err = GetLastError();
2180 f331110f bellard
            if (err == ERROR_IO_PENDING) {
2181 f331110f bellard
                ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE);
2182 f331110f bellard
                if (ret) {
2183 f331110f bellard
                    buf += size;
2184 f331110f bellard
                    len -= size;
2185 f331110f bellard
                } else {
2186 f331110f bellard
                    break;
2187 f331110f bellard
                }
2188 f331110f bellard
            } else {
2189 f331110f bellard
                break;
2190 f331110f bellard
            }
2191 f331110f bellard
        } else {
2192 f331110f bellard
            buf += size;
2193 f331110f bellard
            len -= size;
2194 f331110f bellard
        }
2195 f331110f bellard
    }
2196 f331110f bellard
    return len1 - len;
2197 f331110f bellard
}
2198 f331110f bellard
2199 087f4ae0 ths
static int win_chr_read_poll(CharDriverState *chr)
2200 f331110f bellard
{
2201 087f4ae0 ths
    WinCharState *s = chr->opaque;
2202 087f4ae0 ths
2203 087f4ae0 ths
    s->max_size = qemu_chr_can_read(chr);
2204 f331110f bellard
    return s->max_size;
2205 f331110f bellard
}
2206 e5b0bc44 pbrook
2207 087f4ae0 ths
static void win_chr_readfile(CharDriverState *chr)
2208 f331110f bellard
{
2209 087f4ae0 ths
    WinCharState *s = chr->opaque;
2210 f331110f bellard
    int ret, err;
2211 f331110f bellard
    uint8_t buf[1024];
2212 f331110f bellard
    DWORD size;
2213 f331110f bellard
    
2214 f331110f bellard
    ZeroMemory(&s->orecv, sizeof(s->orecv));
2215 f331110f bellard
    s->orecv.hEvent = s->hrecv;
2216 f331110f bellard
    ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv);
2217 f331110f bellard
    if (!ret) {
2218 f331110f bellard
        err = GetLastError();
2219 f331110f bellard
        if (err == ERROR_IO_PENDING) {
2220 f331110f bellard
            ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE);
2221 f331110f bellard
        }
2222 f331110f bellard
    }
2223 f331110f bellard
2224 f331110f bellard
    if (size > 0) {
2225 087f4ae0 ths
        qemu_chr_read(chr, buf, size);
2226 f331110f bellard
    }
2227 f331110f bellard
}
2228 f331110f bellard
2229 087f4ae0 ths
static void win_chr_read(CharDriverState *chr)
2230 f331110f bellard
{
2231 087f4ae0 ths
    WinCharState *s = chr->opaque;
2232 087f4ae0 ths
2233 f331110f bellard
    if (s->len > s->max_size)
2234 f331110f bellard
        s->len = s->max_size;
2235 f331110f bellard
    if (s->len == 0)
2236 f331110f bellard
        return;
2237 f331110f bellard
    
2238 087f4ae0 ths
    win_chr_readfile(chr);
2239 f331110f bellard
}
2240 f331110f bellard
2241 f331110f bellard
static int win_chr_poll(void *opaque)
2242 f331110f bellard
{
2243 087f4ae0 ths
    CharDriverState *chr = opaque;
2244 087f4ae0 ths
    WinCharState *s = chr->opaque;
2245 f331110f bellard
    COMSTAT status;
2246 f331110f bellard
    DWORD comerr;
2247 f331110f bellard
    
2248 f331110f bellard
    ClearCommError(s->hcom, &comerr, &status);
2249 f331110f bellard
    if (status.cbInQue > 0) {
2250 f331110f bellard
        s->len = status.cbInQue;
2251 087f4ae0 ths
        win_chr_read_poll(chr);
2252 087f4ae0 ths
        win_chr_read(chr);
2253 f331110f bellard
        return 1;
2254 f331110f bellard
    }
2255 f331110f bellard
    return 0;
2256 f331110f bellard
}
2257 f331110f bellard
2258 52f61fde ths
static CharDriverState *qemu_chr_open_win(const char *filename)
2259 f331110f bellard
{
2260 f331110f bellard
    CharDriverState *chr;
2261 f331110f bellard
    WinCharState *s;
2262 f331110f bellard
    
2263 f331110f bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2264 f331110f bellard
    if (!chr)
2265 f331110f bellard
        return NULL;
2266 f331110f bellard
    s = qemu_mallocz(sizeof(WinCharState));
2267 f331110f bellard
    if (!s) {
2268 f331110f bellard
        free(chr);
2269 f331110f bellard
        return NULL;
2270 f331110f bellard
    }
2271 f331110f bellard
    chr->opaque = s;
2272 f331110f bellard
    chr->chr_write = win_chr_write;
2273 f331110f bellard
    chr->chr_close = win_chr_close;
2274 f331110f bellard
2275 087f4ae0 ths
    if (win_chr_init(chr, filename) < 0) {
2276 f331110f bellard
        free(s);
2277 f331110f bellard
        free(chr);
2278 f331110f bellard
        return NULL;
2279 f331110f bellard
    }
2280 86e94dea ths
    qemu_chr_reset(chr);
2281 f331110f bellard
    return chr;
2282 f331110f bellard
}
2283 f331110f bellard
2284 f331110f bellard
static int win_chr_pipe_poll(void *opaque)
2285 f331110f bellard
{
2286 087f4ae0 ths
    CharDriverState *chr = opaque;
2287 087f4ae0 ths
    WinCharState *s = chr->opaque;
2288 f331110f bellard
    DWORD size;
2289 f331110f bellard
2290 f331110f bellard
    PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
2291 f331110f bellard
    if (size > 0) {
2292 f331110f bellard
        s->len = size;
2293 087f4ae0 ths
        win_chr_read_poll(chr);
2294 087f4ae0 ths
        win_chr_read(chr);
2295 f331110f bellard
        return 1;
2296 f331110f bellard
    }
2297 f331110f bellard
    return 0;
2298 f331110f bellard
}
2299 f331110f bellard
2300 087f4ae0 ths
static int win_chr_pipe_init(CharDriverState *chr, const char *filename)
2301 f331110f bellard
{
2302 087f4ae0 ths
    WinCharState *s = chr->opaque;
2303 f331110f bellard
    OVERLAPPED ov;
2304 f331110f bellard
    int ret;
2305 f331110f bellard
    DWORD size;
2306 f331110f bellard
    char openname[256];
2307 f331110f bellard
    
2308 f331110f bellard
    s->fpipe = TRUE;
2309 f331110f bellard
2310 f331110f bellard
    s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
2311 f331110f bellard
    if (!s->hsend) {
2312 f331110f bellard
        fprintf(stderr, "Failed CreateEvent\n");
2313 f331110f bellard
        goto fail;
2314 f331110f bellard
    }
2315 f331110f bellard
    s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
2316 f331110f bellard
    if (!s->hrecv) {
2317 f331110f bellard
        fprintf(stderr, "Failed CreateEvent\n");
2318 f331110f bellard
        goto fail;
2319 f331110f bellard
    }
2320 f331110f bellard
    
2321 f331110f bellard
    snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename);
2322 f331110f bellard
    s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
2323 f331110f bellard
                              PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
2324 f331110f bellard
                              PIPE_WAIT,
2325 f331110f bellard
                              MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
2326 f331110f bellard
    if (s->hcom == INVALID_HANDLE_VALUE) {
2327 f331110f bellard
        fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError());
2328 f331110f bellard
        s->hcom = NULL;
2329 f331110f bellard
        goto fail;
2330 f331110f bellard
    }
2331 f331110f bellard
2332 f331110f bellard
    ZeroMemory(&ov, sizeof(ov));
2333 f331110f bellard
    ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
2334 f331110f bellard
    ret = ConnectNamedPipe(s->hcom, &ov);
2335 f331110f bellard
    if (ret) {
2336 f331110f bellard
        fprintf(stderr, "Failed ConnectNamedPipe\n");
2337 f331110f bellard
        goto fail;
2338 f331110f bellard
    }
2339 f331110f bellard
2340 f331110f bellard
    ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
2341 f331110f bellard
    if (!ret) {
2342 f331110f bellard
        fprintf(stderr, "Failed GetOverlappedResult\n");
2343 f331110f bellard
        if (ov.hEvent) {
2344 f331110f bellard
            CloseHandle(ov.hEvent);
2345 f331110f bellard
            ov.hEvent = NULL;
2346 f331110f bellard
        }
2347 f331110f bellard
        goto fail;
2348 f331110f bellard
    }
2349 f331110f bellard
2350 f331110f bellard
    if (ov.hEvent) {
2351 f331110f bellard
        CloseHandle(ov.hEvent);
2352 f331110f bellard
        ov.hEvent = NULL;
2353 f331110f bellard
    }
2354 087f4ae0 ths
    qemu_add_polling_cb(win_chr_pipe_poll, chr);
2355 f331110f bellard
    return 0;
2356 f331110f bellard
2357 f331110f bellard
 fail:
2358 087f4ae0 ths
    win_chr_close(chr);
2359 f331110f bellard
    return -1;
2360 f331110f bellard
}
2361 f331110f bellard
2362 f331110f bellard
2363 52f61fde ths
static CharDriverState *qemu_chr_open_win_pipe(const char *filename)
2364 f331110f bellard
{
2365 f331110f bellard
    CharDriverState *chr;
2366 f331110f bellard
    WinCharState *s;
2367 f331110f bellard
2368 f331110f bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2369 f331110f bellard
    if (!chr)
2370 f331110f bellard
        return NULL;
2371 f331110f bellard
    s = qemu_mallocz(sizeof(WinCharState));
2372 f331110f bellard
    if (!s) {
2373 f331110f bellard
        free(chr);
2374 f331110f bellard
        return NULL;
2375 f331110f bellard
    }
2376 f331110f bellard
    chr->opaque = s;
2377 f331110f bellard
    chr->chr_write = win_chr_write;
2378 f331110f bellard
    chr->chr_close = win_chr_close;
2379 f331110f bellard
    
2380 087f4ae0 ths
    if (win_chr_pipe_init(chr, filename) < 0) {
2381 f331110f bellard
        free(s);
2382 f331110f bellard
        free(chr);
2383 f331110f bellard
        return NULL;
2384 f331110f bellard
    }
2385 86e94dea ths
    qemu_chr_reset(chr);
2386 f331110f bellard
    return chr;
2387 f331110f bellard
}
2388 f331110f bellard
2389 52f61fde ths
static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
2390 f331110f bellard
{
2391 f331110f bellard
    CharDriverState *chr;
2392 f331110f bellard
    WinCharState *s;
2393 f331110f bellard
2394 f331110f bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2395 f331110f bellard
    if (!chr)
2396 f331110f bellard
        return NULL;
2397 f331110f bellard
    s = qemu_mallocz(sizeof(WinCharState));
2398 f331110f bellard
    if (!s) {
2399 f331110f bellard
        free(chr);
2400 f331110f bellard
        return NULL;
2401 f331110f bellard
    }
2402 f331110f bellard
    s->hcom = fd_out;
2403 f331110f bellard
    chr->opaque = s;
2404 f331110f bellard
    chr->chr_write = win_chr_write;
2405 86e94dea ths
    qemu_chr_reset(chr);
2406 f331110f bellard
    return chr;
2407 f331110f bellard
}
2408 f331110f bellard
    
2409 52f61fde ths
static CharDriverState *qemu_chr_open_win_file_out(const char *file_out)
2410 f331110f bellard
{
2411 f331110f bellard
    HANDLE fd_out;
2412 f331110f bellard
    
2413 f331110f bellard
    fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
2414 f331110f bellard
                        OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2415 f331110f bellard
    if (fd_out == INVALID_HANDLE_VALUE)
2416 f331110f bellard
        return NULL;
2417 f331110f bellard
2418 f331110f bellard
    return qemu_chr_open_win_file(fd_out);
2419 f331110f bellard
}
2420 f331110f bellard
#endif
2421 f331110f bellard
2422 0bab00f3 bellard
/***********************************************************/
2423 0bab00f3 bellard
/* UDP Net console */
2424 0bab00f3 bellard
2425 0bab00f3 bellard
typedef struct {
2426 0bab00f3 bellard
    int fd;
2427 0bab00f3 bellard
    struct sockaddr_in daddr;
2428 0bab00f3 bellard
    char buf[1024];
2429 0bab00f3 bellard
    int bufcnt;
2430 0bab00f3 bellard
    int bufptr;
2431 0bab00f3 bellard
    int max_size;
2432 0bab00f3 bellard
} NetCharDriver;
2433 0bab00f3 bellard
2434 0bab00f3 bellard
static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2435 0bab00f3 bellard
{
2436 0bab00f3 bellard
    NetCharDriver *s = chr->opaque;
2437 0bab00f3 bellard
2438 0bab00f3 bellard
    return sendto(s->fd, buf, len, 0,
2439 0bab00f3 bellard
                  (struct sockaddr *)&s->daddr, sizeof(struct sockaddr_in));
2440 0bab00f3 bellard
}
2441 0bab00f3 bellard
2442 0bab00f3 bellard
static int udp_chr_read_poll(void *opaque)
2443 0bab00f3 bellard
{
2444 0bab00f3 bellard
    CharDriverState *chr = opaque;
2445 0bab00f3 bellard
    NetCharDriver *s = chr->opaque;
2446 0bab00f3 bellard
2447 e5b0bc44 pbrook
    s->max_size = qemu_chr_can_read(chr);
2448 0bab00f3 bellard
2449 0bab00f3 bellard
    /* If there were any stray characters in the queue process them
2450 0bab00f3 bellard
     * first
2451 0bab00f3 bellard
     */
2452 0bab00f3 bellard
    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
2453 e5b0bc44 pbrook
        qemu_chr_read(chr, &s->buf[s->bufptr], 1);
2454 0bab00f3 bellard
        s->bufptr++;
2455 e5b0bc44 pbrook
        s->max_size = qemu_chr_can_read(chr);
2456 0bab00f3 bellard
    }
2457 0bab00f3 bellard
    return s->max_size;
2458 0bab00f3 bellard
}
2459 0bab00f3 bellard
2460 0bab00f3 bellard
static void udp_chr_read(void *opaque)
2461 0bab00f3 bellard
{
2462 0bab00f3 bellard
    CharDriverState *chr = opaque;
2463 0bab00f3 bellard
    NetCharDriver *s = chr->opaque;
2464 0bab00f3 bellard
2465 0bab00f3 bellard
    if (s->max_size == 0)
2466 0bab00f3 bellard
        return;
2467 0bab00f3 bellard
    s->bufcnt = recv(s->fd, s->buf, sizeof(s->buf), 0);
2468 0bab00f3 bellard
    s->bufptr = s->bufcnt;
2469 0bab00f3 bellard
    if (s->bufcnt <= 0)
2470 0bab00f3 bellard
        return;
2471 0bab00f3 bellard
2472 0bab00f3 bellard
    s->bufptr = 0;
2473 0bab00f3 bellard
    while (s->max_size > 0 && s->bufptr < s->bufcnt) {
2474 e5b0bc44 pbrook
        qemu_chr_read(chr, &s->buf[s->bufptr], 1);
2475 0bab00f3 bellard
        s->bufptr++;
2476 e5b0bc44 pbrook
        s->max_size = qemu_chr_can_read(chr);
2477 0bab00f3 bellard
    }
2478 0bab00f3 bellard
}
2479 0bab00f3 bellard
2480 e5b0bc44 pbrook
static void udp_chr_update_read_handler(CharDriverState *chr)
2481 0bab00f3 bellard
{
2482 0bab00f3 bellard
    NetCharDriver *s = chr->opaque;
2483 0bab00f3 bellard
2484 0bab00f3 bellard
    if (s->fd >= 0) {
2485 0bab00f3 bellard
        qemu_set_fd_handler2(s->fd, udp_chr_read_poll,
2486 0bab00f3 bellard
                             udp_chr_read, NULL, chr);
2487 0bab00f3 bellard
    }
2488 0bab00f3 bellard
}
2489 0bab00f3 bellard
2490 0bab00f3 bellard
int parse_host_port(struct sockaddr_in *saddr, const char *str);
2491 52f61fde ths
#ifndef _WIN32
2492 52f61fde ths
static int parse_unix_path(struct sockaddr_un *uaddr, const char *str);
2493 52f61fde ths
#endif
2494 951f1351 bellard
int parse_host_src_port(struct sockaddr_in *haddr,
2495 951f1351 bellard
                        struct sockaddr_in *saddr,
2496 951f1351 bellard
                        const char *str);
2497 0bab00f3 bellard
2498 52f61fde ths
static CharDriverState *qemu_chr_open_udp(const char *def)
2499 0bab00f3 bellard
{
2500 0bab00f3 bellard
    CharDriverState *chr = NULL;
2501 0bab00f3 bellard
    NetCharDriver *s = NULL;
2502 0bab00f3 bellard
    int fd = -1;
2503 951f1351 bellard
    struct sockaddr_in saddr;
2504 0bab00f3 bellard
2505 0bab00f3 bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2506 0bab00f3 bellard
    if (!chr)
2507 0bab00f3 bellard
        goto return_err;
2508 0bab00f3 bellard
    s = qemu_mallocz(sizeof(NetCharDriver));
2509 0bab00f3 bellard
    if (!s)
2510 0bab00f3 bellard
        goto return_err;
2511 0bab00f3 bellard
2512 0bab00f3 bellard
    fd = socket(PF_INET, SOCK_DGRAM, 0);
2513 0bab00f3 bellard
    if (fd < 0) {
2514 0bab00f3 bellard
        perror("socket(PF_INET, SOCK_DGRAM)");
2515 0bab00f3 bellard
        goto return_err;
2516 0bab00f3 bellard
    }
2517 0bab00f3 bellard
2518 951f1351 bellard
    if (parse_host_src_port(&s->daddr, &saddr, def) < 0) {
2519 951f1351 bellard
        printf("Could not parse: %s\n", def);
2520 951f1351 bellard
        goto return_err;
2521 0bab00f3 bellard
    }
2522 0bab00f3 bellard
2523 951f1351 bellard
    if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
2524 0bab00f3 bellard
    {
2525 0bab00f3 bellard
        perror("bind");
2526 0bab00f3 bellard
        goto return_err;
2527 0bab00f3 bellard
    }
2528 0bab00f3 bellard
2529 0bab00f3 bellard
    s->fd = fd;
2530 0bab00f3 bellard
    s->bufcnt = 0;
2531 0bab00f3 bellard
    s->bufptr = 0;
2532 0bab00f3 bellard
    chr->opaque = s;
2533 0bab00f3 bellard
    chr->chr_write = udp_chr_write;
2534 e5b0bc44 pbrook
    chr->chr_update_read_handler = udp_chr_update_read_handler;
2535 0bab00f3 bellard
    return chr;
2536 0bab00f3 bellard
2537 0bab00f3 bellard
return_err:
2538 0bab00f3 bellard
    if (chr)
2539 0bab00f3 bellard
        free(chr);
2540 0bab00f3 bellard
    if (s)
2541 0bab00f3 bellard
        free(s);
2542 0bab00f3 bellard
    if (fd >= 0)
2543 0bab00f3 bellard
        closesocket(fd);
2544 0bab00f3 bellard
    return NULL;
2545 0bab00f3 bellard
}
2546 0bab00f3 bellard
2547 0bab00f3 bellard
/***********************************************************/
2548 0bab00f3 bellard
/* TCP Net console */
2549 0bab00f3 bellard
2550 0bab00f3 bellard
typedef struct {
2551 0bab00f3 bellard
    int fd, listen_fd;
2552 0bab00f3 bellard
    int connected;
2553 0bab00f3 bellard
    int max_size;
2554 951f1351 bellard
    int do_telnetopt;
2555 e5b0bc44 pbrook
    int do_nodelay;
2556 ffd843bc ths
    int is_unix;
2557 0bab00f3 bellard
} TCPCharDriver;
2558 0bab00f3 bellard
2559 0bab00f3 bellard
static void tcp_chr_accept(void *opaque);
2560 0bab00f3 bellard
2561 0bab00f3 bellard
static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
2562 0bab00f3 bellard
{
2563 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
2564 0bab00f3 bellard
    if (s->connected) {
2565 0bab00f3 bellard
        return send_all(s->fd, buf, len);
2566 0bab00f3 bellard
    } else {
2567 0bab00f3 bellard
        /* XXX: indicate an error ? */
2568 0bab00f3 bellard
        return len;
2569 0bab00f3 bellard
    }
2570 0bab00f3 bellard
}
2571 0bab00f3 bellard
2572 0bab00f3 bellard
static int tcp_chr_read_poll(void *opaque)
2573 0bab00f3 bellard
{
2574 0bab00f3 bellard
    CharDriverState *chr = opaque;
2575 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
2576 0bab00f3 bellard
    if (!s->connected)
2577 0bab00f3 bellard
        return 0;
2578 e5b0bc44 pbrook
    s->max_size = qemu_chr_can_read(chr);
2579 0bab00f3 bellard
    return s->max_size;
2580 0bab00f3 bellard
}
2581 0bab00f3 bellard
2582 951f1351 bellard
#define IAC 255
2583 951f1351 bellard
#define IAC_BREAK 243
2584 951f1351 bellard
static void tcp_chr_process_IAC_bytes(CharDriverState *chr,
2585 951f1351 bellard
                                      TCPCharDriver *s,
2586 951f1351 bellard
                                      char *buf, int *size)
2587 951f1351 bellard
{
2588 951f1351 bellard
    /* Handle any telnet client's basic IAC options to satisfy char by
2589 951f1351 bellard
     * char mode with no echo.  All IAC options will be removed from
2590 951f1351 bellard
     * the buf and the do_telnetopt variable will be used to track the
2591 951f1351 bellard
     * state of the width of the IAC information.
2592 951f1351 bellard
     *
2593 951f1351 bellard
     * IAC commands come in sets of 3 bytes with the exception of the
2594 951f1351 bellard
     * "IAC BREAK" command and the double IAC.
2595 951f1351 bellard
     */
2596 951f1351 bellard
2597 951f1351 bellard
    int i;
2598 951f1351 bellard
    int j = 0;
2599 951f1351 bellard
2600 951f1351 bellard
    for (i = 0; i < *size; i++) {
2601 951f1351 bellard
        if (s->do_telnetopt > 1) {
2602 951f1351 bellard
            if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {
2603 951f1351 bellard
                /* Double IAC means send an IAC */
2604 951f1351 bellard
                if (j != i)
2605 951f1351 bellard
                    buf[j] = buf[i];
2606 951f1351 bellard
                j++;
2607 951f1351 bellard
                s->do_telnetopt = 1;
2608 951f1351 bellard
            } else {
2609 951f1351 bellard
                if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {
2610 951f1351 bellard
                    /* Handle IAC break commands by sending a serial break */
2611 e5b0bc44 pbrook
                    qemu_chr_event(chr, CHR_EVENT_BREAK);
2612 951f1351 bellard
                    s->do_telnetopt++;
2613 951f1351 bellard
                }
2614 951f1351 bellard
                s->do_telnetopt++;
2615 951f1351 bellard
            }
2616 951f1351 bellard
            if (s->do_telnetopt >= 4) {
2617 951f1351 bellard
                s->do_telnetopt = 1;
2618 951f1351 bellard
            }
2619 951f1351 bellard
        } else {
2620 951f1351 bellard
            if ((unsigned char)buf[i] == IAC) {
2621 951f1351 bellard
                s->do_telnetopt = 2;
2622 951f1351 bellard
            } else {
2623 951f1351 bellard
                if (j != i)
2624 951f1351 bellard
                    buf[j] = buf[i];
2625 951f1351 bellard
                j++;
2626 951f1351 bellard
            }
2627 951f1351 bellard
        }
2628 951f1351 bellard
    }
2629 951f1351 bellard
    *size = j;
2630 951f1351 bellard
}
2631 951f1351 bellard
2632 0bab00f3 bellard
static void tcp_chr_read(void *opaque)
2633 0bab00f3 bellard
{
2634 0bab00f3 bellard
    CharDriverState *chr = opaque;
2635 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
2636 0bab00f3 bellard
    uint8_t buf[1024];
2637 0bab00f3 bellard
    int len, size;
2638 0bab00f3 bellard
2639 0bab00f3 bellard
    if (!s->connected || s->max_size <= 0)
2640 0bab00f3 bellard
        return;
2641 0bab00f3 bellard
    len = sizeof(buf);
2642 0bab00f3 bellard
    if (len > s->max_size)
2643 0bab00f3 bellard
        len = s->max_size;
2644 0bab00f3 bellard
    size = recv(s->fd, buf, len, 0);
2645 0bab00f3 bellard
    if (size == 0) {
2646 0bab00f3 bellard
        /* connection closed */
2647 0bab00f3 bellard
        s->connected = 0;
2648 0bab00f3 bellard
        if (s->listen_fd >= 0) {
2649 0bab00f3 bellard
            qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
2650 0bab00f3 bellard
        }
2651 0bab00f3 bellard
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
2652 0bab00f3 bellard
        closesocket(s->fd);
2653 0bab00f3 bellard
        s->fd = -1;
2654 0bab00f3 bellard
    } else if (size > 0) {
2655 951f1351 bellard
        if (s->do_telnetopt)
2656 951f1351 bellard
            tcp_chr_process_IAC_bytes(chr, s, buf, &size);
2657 951f1351 bellard
        if (size > 0)
2658 e5b0bc44 pbrook
            qemu_chr_read(chr, buf, size);
2659 0bab00f3 bellard
    }
2660 0bab00f3 bellard
}
2661 0bab00f3 bellard
2662 0bab00f3 bellard
static void tcp_chr_connect(void *opaque)
2663 0bab00f3 bellard
{
2664 0bab00f3 bellard
    CharDriverState *chr = opaque;
2665 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
2666 0bab00f3 bellard
2667 0bab00f3 bellard
    s->connected = 1;
2668 0bab00f3 bellard
    qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
2669 0bab00f3 bellard
                         tcp_chr_read, NULL, chr);
2670 86e94dea ths
    qemu_chr_reset(chr);
2671 0bab00f3 bellard
}
2672 0bab00f3 bellard
2673 951f1351 bellard
#define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;
2674 951f1351 bellard
static void tcp_chr_telnet_init(int fd)
2675 951f1351 bellard
{
2676 951f1351 bellard
    char buf[3];
2677 951f1351 bellard
    /* Send the telnet negotion to put telnet in binary, no echo, single char mode */
2678 951f1351 bellard
    IACSET(buf, 0xff, 0xfb, 0x01);  /* IAC WILL ECHO */
2679 951f1351 bellard
    send(fd, (char *)buf, 3, 0);
2680 951f1351 bellard
    IACSET(buf, 0xff, 0xfb, 0x03);  /* IAC WILL Suppress go ahead */
2681 951f1351 bellard
    send(fd, (char *)buf, 3, 0);
2682 951f1351 bellard
    IACSET(buf, 0xff, 0xfb, 0x00);  /* IAC WILL Binary */
2683 951f1351 bellard
    send(fd, (char *)buf, 3, 0);
2684 951f1351 bellard
    IACSET(buf, 0xff, 0xfd, 0x00);  /* IAC DO Binary */
2685 951f1351 bellard
    send(fd, (char *)buf, 3, 0);
2686 951f1351 bellard
}
2687 951f1351 bellard
2688 f7499989 pbrook
static void socket_set_nodelay(int fd)
2689 f7499989 pbrook
{
2690 f7499989 pbrook
    int val = 1;
2691 f7499989 pbrook
    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
2692 f7499989 pbrook
}
2693 f7499989 pbrook
2694 0bab00f3 bellard
static void tcp_chr_accept(void *opaque)
2695 0bab00f3 bellard
{
2696 0bab00f3 bellard
    CharDriverState *chr = opaque;
2697 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
2698 0bab00f3 bellard
    struct sockaddr_in saddr;
2699 ffd843bc ths
#ifndef _WIN32
2700 ffd843bc ths
    struct sockaddr_un uaddr;
2701 ffd843bc ths
#endif
2702 ffd843bc ths
    struct sockaddr *addr;
2703 0bab00f3 bellard
    socklen_t len;
2704 0bab00f3 bellard
    int fd;
2705 0bab00f3 bellard
2706 0bab00f3 bellard
    for(;;) {
2707 ffd843bc ths
#ifndef _WIN32
2708 ffd843bc ths
        if (s->is_unix) {
2709 ffd843bc ths
            len = sizeof(uaddr);
2710 ffd843bc ths
            addr = (struct sockaddr *)&uaddr;
2711 ffd843bc ths
        } else
2712 ffd843bc ths
#endif
2713 ffd843bc ths
        {
2714 ffd843bc ths
            len = sizeof(saddr);
2715 ffd843bc ths
            addr = (struct sockaddr *)&saddr;
2716 ffd843bc ths
        }
2717 ffd843bc ths
        fd = accept(s->listen_fd, addr, &len);
2718 0bab00f3 bellard
        if (fd < 0 && errno != EINTR) {
2719 0bab00f3 bellard
            return;
2720 0bab00f3 bellard
        } else if (fd >= 0) {
2721 951f1351 bellard
            if (s->do_telnetopt)
2722 951f1351 bellard
                tcp_chr_telnet_init(fd);
2723 0bab00f3 bellard
            break;
2724 0bab00f3 bellard
        }
2725 0bab00f3 bellard
    }
2726 0bab00f3 bellard
    socket_set_nonblock(fd);
2727 f7499989 pbrook
    if (s->do_nodelay)
2728 f7499989 pbrook
        socket_set_nodelay(fd);
2729 0bab00f3 bellard
    s->fd = fd;
2730 0bab00f3 bellard
    qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
2731 0bab00f3 bellard
    tcp_chr_connect(chr);
2732 0bab00f3 bellard
}
2733 0bab00f3 bellard
2734 0bab00f3 bellard
static void tcp_chr_close(CharDriverState *chr)
2735 0bab00f3 bellard
{
2736 0bab00f3 bellard
    TCPCharDriver *s = chr->opaque;
2737 0bab00f3 bellard
    if (s->fd >= 0)
2738 0bab00f3 bellard
        closesocket(s->fd);
2739 0bab00f3 bellard
    if (s->listen_fd >= 0)
2740 0bab00f3 bellard
        closesocket(s->listen_fd);
2741 0bab00f3 bellard
    qemu_free(s);
2742 0bab00f3 bellard
}
2743 0bab00f3 bellard
2744 0bab00f3 bellard
static CharDriverState *qemu_chr_open_tcp(const char *host_str, 
2745 ffd843bc ths
                                          int is_telnet,
2746 ffd843bc ths
                                          int is_unix)
2747 0bab00f3 bellard
{
2748 0bab00f3 bellard
    CharDriverState *chr = NULL;
2749 0bab00f3 bellard
    TCPCharDriver *s = NULL;
2750 0bab00f3 bellard
    int fd = -1, ret, err, val;
2751 951f1351 bellard
    int is_listen = 0;
2752 951f1351 bellard
    int is_waitconnect = 1;
2753 f7499989 pbrook
    int do_nodelay = 0;
2754 951f1351 bellard
    const char *ptr;
2755 0bab00f3 bellard
    struct sockaddr_in saddr;
2756 ffd843bc ths
#ifndef _WIN32
2757 ffd843bc ths
    struct sockaddr_un uaddr;
2758 ffd843bc ths
#endif
2759 ffd843bc ths
    struct sockaddr *addr;
2760 ffd843bc ths
    socklen_t addrlen;
2761 0bab00f3 bellard
2762 ffd843bc ths
#ifndef _WIN32
2763 ffd843bc ths
    if (is_unix) {
2764 ffd843bc ths
        addr = (struct sockaddr *)&uaddr;
2765 ffd843bc ths
        addrlen = sizeof(uaddr);
2766 ffd843bc ths
        if (parse_unix_path(&uaddr, host_str) < 0)
2767 ffd843bc ths
            goto fail;
2768 ffd843bc ths
    } else
2769 ffd843bc ths
#endif
2770 ffd843bc ths
    {
2771 ffd843bc ths
        addr = (struct sockaddr *)&saddr;
2772 ffd843bc ths
        addrlen = sizeof(saddr);
2773 ffd843bc ths
        if (parse_host_port(&saddr, host_str) < 0)
2774 ffd843bc ths
            goto fail;
2775 ffd843bc ths
    }
2776 0bab00f3 bellard
2777 951f1351 bellard
    ptr = host_str;
2778 951f1351 bellard
    while((ptr = strchr(ptr,','))) {
2779 951f1351 bellard
        ptr++;
2780 951f1351 bellard
        if (!strncmp(ptr,"server",6)) {
2781 951f1351 bellard
            is_listen = 1;
2782 951f1351 bellard
        } else if (!strncmp(ptr,"nowait",6)) {
2783 951f1351 bellard
            is_waitconnect = 0;
2784 f7499989 pbrook
        } else if (!strncmp(ptr,"nodelay",6)) {
2785 f7499989 pbrook
            do_nodelay = 1;
2786 951f1351 bellard
        } else {
2787 951f1351 bellard
            printf("Unknown option: %s\n", ptr);
2788 951f1351 bellard
            goto fail;
2789 951f1351 bellard
        }
2790 951f1351 bellard
    }
2791 951f1351 bellard
    if (!is_listen)
2792 951f1351 bellard
        is_waitconnect = 0;
2793 951f1351 bellard
2794 0bab00f3 bellard
    chr = qemu_mallocz(sizeof(CharDriverState));
2795 0bab00f3 bellard
    if (!chr)
2796 0bab00f3 bellard
        goto fail;
2797 0bab00f3 bellard
    s = qemu_mallocz(sizeof(TCPCharDriver));
2798 0bab00f3 bellard
    if (!s)
2799 0bab00f3 bellard
        goto fail;
2800 ffd843bc ths
2801 ffd843bc ths
#ifndef _WIN32
2802 ffd843bc ths
    if (is_unix)
2803 ffd843bc ths
        fd = socket(PF_UNIX, SOCK_STREAM, 0);
2804 ffd843bc ths
    else
2805 ffd843bc ths
#endif
2806 ffd843bc ths
        fd = socket(PF_INET, SOCK_STREAM, 0);
2807 ffd843bc ths
        
2808 0bab00f3 bellard
    if (fd < 0) 
2809 0bab00f3 bellard
        goto fail;
2810 951f1351 bellard
2811 951f1351 bellard
    if (!is_waitconnect)
2812 951f1351 bellard
        socket_set_nonblock(fd);
2813 0bab00f3 bellard
2814 0bab00f3 bellard
    s->connected = 0;
2815 0bab00f3 bellard
    s->fd = -1;
2816 0bab00f3 bellard
    s->listen_fd = -1;
2817 ffd843bc ths
    s->is_unix = is_unix;
2818 f7499989 pbrook
    s->do_nodelay = do_nodelay && !is_unix;
2819 ffd843bc ths
2820 ffd843bc ths
    chr->opaque = s;
2821 ffd843bc ths
    chr->chr_write = tcp_chr_write;
2822 ffd843bc ths
    chr->chr_close = tcp_chr_close;
2823 ffd843bc ths
2824 0bab00f3 bellard
    if (is_listen) {
2825 0bab00f3 bellard
        /* allow fast reuse */
2826 ffd843bc ths
#ifndef _WIN32
2827 ffd843bc ths
        if (is_unix) {
2828 ffd843bc ths
            char path[109];
2829 ffd843bc ths
            strncpy(path, uaddr.sun_path, 108);
2830 ffd843bc ths
            path[108] = 0;
2831 ffd843bc ths
            unlink(path);
2832 ffd843bc ths
        } else
2833 ffd843bc ths
#endif
2834 ffd843bc ths
        {
2835 ffd843bc ths
            val = 1;
2836 ffd843bc ths
            setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
2837 ffd843bc ths
        }
2838 0bab00f3 bellard
        
2839 ffd843bc ths
        ret = bind(fd, addr, addrlen);
2840 ffd843bc ths
        if (ret < 0)
2841 0bab00f3 bellard
            goto fail;
2842 ffd843bc ths
2843 0bab00f3 bellard
        ret = listen(fd, 0);
2844 0bab00f3 bellard
        if (ret < 0)
2845 0bab00f3 bellard
            goto fail;
2846 ffd843bc ths
2847 0bab00f3 bellard
        s->listen_fd = fd;
2848 0bab00f3 bellard
        qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);
2849 951f1351 bellard
        if (is_telnet)
2850 951f1351 bellard
            s->do_telnetopt = 1;
2851 0bab00f3 bellard
    } else {
2852 0bab00f3 bellard
        for(;;) {
2853 ffd843bc ths
            ret = connect(fd, addr, addrlen);
2854 0bab00f3 bellard
            if (ret < 0) {
2855 0bab00f3 bellard
                err = socket_error();
2856 0bab00f3 bellard
                if (err == EINTR || err == EWOULDBLOCK) {
2857 0bab00f3 bellard
                } else if (err == EINPROGRESS) {
2858 0bab00f3 bellard
                    break;
2859 f5b12268 ths
#ifdef _WIN32
2860 f5b12268 ths
                } else if (err == WSAEALREADY) {
2861 f5b12268 ths
                    break;
2862 f5b12268 ths
#endif
2863 0bab00f3 bellard
                } else {
2864 0bab00f3 bellard
                    goto fail;
2865 0bab00f3 bellard
                }
2866 0bab00f3 bellard
            } else {
2867 0bab00f3 bellard
                s->connected = 1;
2868 0bab00f3 bellard
                break;
2869 0bab00f3 bellard
            }
2870 0bab00f3 bellard
        }
2871 0bab00f3 bellard
        s->fd = fd;
2872 f7499989 pbrook
        socket_set_nodelay(fd);
2873 0bab00f3 bellard
        if (s->connected)
2874 0bab00f3 bellard
            tcp_chr_connect(chr);
2875 0bab00f3 bellard
        else
2876 0bab00f3 bellard
            qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr);
2877 0bab00f3 bellard
    }
2878 0bab00f3 bellard
    
2879 951f1351 bellard
    if (is_listen && is_waitconnect) {
2880 951f1351 bellard
        printf("QEMU waiting for connection on: %s\n", host_str);
2881 951f1351 bellard
        tcp_chr_accept(chr);
2882 951f1351 bellard
        socket_set_nonblock(s->listen_fd);
2883 951f1351 bellard
    }
2884 951f1351 bellard
2885 0bab00f3 bellard
    return chr;
2886 0bab00f3 bellard
 fail:
2887 0bab00f3 bellard
    if (fd >= 0)
2888 0bab00f3 bellard
        closesocket(fd);
2889 0bab00f3 bellard
    qemu_free(s);
2890 0bab00f3 bellard
    qemu_free(chr);
2891 0bab00f3 bellard
    return NULL;
2892 0bab00f3 bellard
}
2893 0bab00f3 bellard
2894 82c643ff bellard
CharDriverState *qemu_chr_open(const char *filename)
2895 82c643ff bellard
{
2896 f8d179e3 bellard
    const char *p;
2897 fd1dff4b bellard
2898 82c643ff bellard
    if (!strcmp(filename, "vc")) {
2899 82c643ff bellard
        return text_console_init(&display_state);
2900 82c643ff bellard
    } else if (!strcmp(filename, "null")) {
2901 82c643ff bellard
        return qemu_chr_open_null();
2902 7664728b bellard
    } else 
2903 0bab00f3 bellard
    if (strstart(filename, "tcp:", &p)) {
2904 ffd843bc ths
        return qemu_chr_open_tcp(p, 0, 0);
2905 0bab00f3 bellard
    } else
2906 951f1351 bellard
    if (strstart(filename, "telnet:", &p)) {
2907 ffd843bc ths
        return qemu_chr_open_tcp(p, 1, 0);
2908 0bab00f3 bellard
    } else
2909 0bab00f3 bellard
    if (strstart(filename, "udp:", &p)) {
2910 0bab00f3 bellard
        return qemu_chr_open_udp(p);
2911 0bab00f3 bellard
    } else
2912 20d8a3ed ths
    if (strstart(filename, "mon:", &p)) {
2913 20d8a3ed ths
        CharDriverState *drv = qemu_chr_open(p);
2914 20d8a3ed ths
        if (drv) {
2915 20d8a3ed ths
            drv = qemu_chr_open_mux(drv);
2916 20d8a3ed ths
            monitor_init(drv, !nographic);
2917 20d8a3ed ths
            return drv;
2918 20d8a3ed ths
        }
2919 20d8a3ed ths
        printf("Unable to open driver: %s\n", p);
2920 20d8a3ed ths
        return 0;
2921 20d8a3ed ths
    } else
2922 7664728b bellard
#ifndef _WIN32
2923 ffd843bc ths
    if (strstart(filename, "unix:", &p)) {
2924 ffd843bc ths
        return qemu_chr_open_tcp(p, 0, 1);
2925 ffd843bc ths
    } else if (strstart(filename, "file:", &p)) {
2926 f8d179e3 bellard
        return qemu_chr_open_file_out(p);
2927 f8d179e3 bellard
    } else if (strstart(filename, "pipe:", &p)) {
2928 f8d179e3 bellard
        return qemu_chr_open_pipe(p);
2929 7664728b bellard
    } else if (!strcmp(filename, "pty")) {
2930 82c643ff bellard
        return qemu_chr_open_pty();
2931 82c643ff bellard
    } else if (!strcmp(filename, "stdio")) {
2932 82c643ff bellard
        return qemu_chr_open_stdio();
2933 82c643ff bellard
    } else 
2934 82c643ff bellard
#endif
2935 f8d179e3 bellard
#if defined(__linux__)
2936 e57a8c0e bellard
    if (strstart(filename, "/dev/parport", NULL)) {
2937 e57a8c0e bellard
        return qemu_chr_open_pp(filename);
2938 e57a8c0e bellard
    } else 
2939 f8d179e3 bellard
    if (strstart(filename, "/dev/", NULL)) {
2940 f8d179e3 bellard
        return qemu_chr_open_tty(filename);
2941 f8d179e3 bellard
    } else 
2942 f8d179e3 bellard
#endif
2943 f331110f bellard
#ifdef _WIN32
2944 f331110f bellard
    if (strstart(filename, "COM", NULL)) {
2945 f331110f bellard
        return qemu_chr_open_win(filename);
2946 f331110f bellard
    } else
2947 f331110f bellard
    if (strstart(filename, "pipe:", &p)) {
2948 f331110f bellard
        return qemu_chr_open_win_pipe(p);
2949 f331110f bellard
    } else
2950 f331110f bellard
    if (strstart(filename, "file:", &p)) {
2951 f331110f bellard
        return qemu_chr_open_win_file_out(p);
2952 f331110f bellard
    }
2953 f331110f bellard
#endif
2954 82c643ff bellard
    {
2955 82c643ff bellard
        return NULL;
2956 82c643ff bellard
    }
2957 82c643ff bellard
}
2958 82c643ff bellard
2959 f331110f bellard
void qemu_chr_close(CharDriverState *chr)
2960 f331110f bellard
{
2961 f331110f bellard
    if (chr->chr_close)
2962 f331110f bellard
        chr->chr_close(chr);
2963 f331110f bellard
}
2964 f331110f bellard
2965 80cabfad bellard
/***********************************************************/
2966 7c9d8e07 bellard
/* network device redirectors */
2967 330d0414 bellard
2968 c20709aa bellard
void hex_dump(FILE *f, const uint8_t *buf, int size)
2969 c20709aa bellard
{
2970 c20709aa bellard
    int len, i, j, c;
2971 c20709aa bellard
2972 c20709aa bellard
    for(i=0;i<size;i+=16) {
2973 c20709aa bellard
        len = size - i;
2974 c20709aa bellard
        if (len > 16)
2975 c20709aa bellard
            len = 16;
2976 c20709aa bellard
        fprintf(f, "%08x ", i);
2977 c20709aa bellard
        for(j=0;j<16;j++) {
2978 c20709aa bellard
            if (j < len)
2979 c20709aa bellard
                fprintf(f, " %02x", buf[i+j]);
2980 c20709aa bellard
            else
2981 c20709aa bellard
                fprintf(f, "   ");
2982 c20709aa bellard
        }
2983 c20709aa bellard
        fprintf(f, " ");
2984 c20709aa bellard
        for(j=0;j<len;j++) {
2985 c20709aa bellard
            c = buf[i+j];
2986 c20709aa bellard
            if (c < ' ' || c > '~')
2987 c20709aa bellard
                c = '.';
2988 c20709aa bellard
            fprintf(f, "%c", c);
2989 c20709aa bellard
        }
2990 c20709aa bellard
        fprintf(f, "\n");
2991 c20709aa bellard
    }
2992 c20709aa bellard
}
2993 c20709aa bellard
2994 7c9d8e07 bellard
static int parse_macaddr(uint8_t *macaddr, const char *p)
2995 c20709aa bellard
{
2996 7c9d8e07 bellard
    int i;
2997 7c9d8e07 bellard
    for(i = 0; i < 6; i++) {
2998 7c9d8e07 bellard
        macaddr[i] = strtol(p, (char **)&p, 16);
2999 7c9d8e07 bellard
        if (i == 5) {
3000 7c9d8e07 bellard
            if (*p != '\0') 
3001 7c9d8e07 bellard
                return -1;
3002 7c9d8e07 bellard
        } else {
3003 7c9d8e07 bellard
            if (*p != ':') 
3004 7c9d8e07 bellard
                return -1;
3005 7c9d8e07 bellard
            p++;
3006 7c9d8e07 bellard
        }
3007 7c9d8e07 bellard
    }
3008 7c9d8e07 bellard
    return 0;
3009 c20709aa bellard
}
3010 67b915a5 bellard
3011 7c9d8e07 bellard
static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
3012 67b915a5 bellard
{
3013 7c9d8e07 bellard
    const char *p, *p1;
3014 7c9d8e07 bellard
    int len;
3015 7c9d8e07 bellard
    p = *pp;
3016 7c9d8e07 bellard
    p1 = strchr(p, sep);
3017 7c9d8e07 bellard
    if (!p1)
3018 7c9d8e07 bellard
        return -1;
3019 7c9d8e07 bellard
    len = p1 - p;
3020 7c9d8e07 bellard
    p1++;
3021 7c9d8e07 bellard
    if (buf_size > 0) {
3022 7c9d8e07 bellard
        if (len > buf_size - 1)
3023 7c9d8e07 bellard
            len = buf_size - 1;
3024 7c9d8e07 bellard
        memcpy(buf, p, len);
3025 7c9d8e07 bellard
        buf[len] = '\0';
3026 7c9d8e07 bellard
    }
3027 7c9d8e07 bellard
    *pp = p1;
3028 7c9d8e07 bellard
    return 0;
3029 c20709aa bellard
}
3030 c20709aa bellard
3031 951f1351 bellard
int parse_host_src_port(struct sockaddr_in *haddr,
3032 951f1351 bellard
                        struct sockaddr_in *saddr,
3033 951f1351 bellard
                        const char *input_str)
3034 951f1351 bellard
{
3035 951f1351 bellard
    char *str = strdup(input_str);
3036 951f1351 bellard
    char *host_str = str;
3037 951f1351 bellard
    char *src_str;
3038 951f1351 bellard
    char *ptr;
3039 951f1351 bellard
3040 951f1351 bellard
    /*
3041 951f1351 bellard
     * Chop off any extra arguments at the end of the string which
3042 951f1351 bellard
     * would start with a comma, then fill in the src port information
3043 951f1351 bellard
     * if it was provided else use the "any address" and "any port".
3044 951f1351 bellard
     */
3045 951f1351 bellard
    if ((ptr = strchr(str,',')))
3046 951f1351 bellard
        *ptr = '\0';
3047 951f1351 bellard
3048 951f1351 bellard
    if ((src_str = strchr(input_str,'@'))) {
3049 951f1351 bellard
        *src_str = '\0';
3050 951f1351 bellard
        src_str++;
3051 951f1351 bellard
    }
3052 951f1351 bellard
3053 951f1351 bellard
    if (parse_host_port(haddr, host_str) < 0)
3054 951f1351 bellard
        goto fail;
3055 951f1351 bellard
3056 951f1351 bellard
    if (!src_str || *src_str == '\0')
3057 951f1351 bellard
        src_str = ":0";
3058 951f1351 bellard
3059 951f1351 bellard
    if (parse_host_port(saddr, src_str) < 0)
3060 951f1351 bellard
        goto fail;
3061 951f1351 bellard
3062 951f1351 bellard
    free(str);
3063 951f1351 bellard
    return(0);
3064 951f1351 bellard
3065 951f1351 bellard
fail:
3066 951f1351 bellard
    free(str);
3067 951f1351 bellard
    return -1;
3068 951f1351 bellard
}
3069 951f1351 bellard
3070 7c9d8e07 bellard
int parse_host_port(struct sockaddr_in *saddr, const char *str)
3071 7c9d8e07 bellard
{
3072 7c9d8e07 bellard
    char buf[512];
3073 7c9d8e07 bellard
    struct hostent *he;
3074 7c9d8e07 bellard
    const char *p, *r;
3075 7c9d8e07 bellard
    int port;
3076 7c9d8e07 bellard
3077 7c9d8e07 bellard
    p = str;
3078 7c9d8e07 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3079 7c9d8e07 bellard
        return -1;
3080 7c9d8e07 bellard
    saddr->sin_family = AF_INET;
3081 7c9d8e07 bellard
    if (buf[0] == '\0') {
3082 7c9d8e07 bellard
        saddr->sin_addr.s_addr = 0;
3083 7c9d8e07 bellard
    } else {
3084 7c9d8e07 bellard
        if (isdigit(buf[0])) {
3085 7c9d8e07 bellard
            if (!inet_aton(buf, &saddr->sin_addr))
3086 7c9d8e07 bellard
                return -1;
3087 7c9d8e07 bellard
        } else {
3088 7c9d8e07 bellard
            if ((he = gethostbyname(buf)) == NULL)
3089 7c9d8e07 bellard
                return - 1;
3090 7c9d8e07 bellard
            saddr->sin_addr = *(struct in_addr *)he->h_addr;
3091 7c9d8e07 bellard
        }
3092 7c9d8e07 bellard
    }
3093 7c9d8e07 bellard
    port = strtol(p, (char **)&r, 0);
3094 7c9d8e07 bellard
    if (r == p)
3095 7c9d8e07 bellard
        return -1;
3096 7c9d8e07 bellard
    saddr->sin_port = htons(port);
3097 7c9d8e07 bellard
    return 0;
3098 7c9d8e07 bellard
}
3099 c20709aa bellard
3100 52f61fde ths
#ifndef _WIN32
3101 52f61fde ths
static int parse_unix_path(struct sockaddr_un *uaddr, const char *str)
3102 ffd843bc ths
{
3103 ffd843bc ths
    const char *p;
3104 ffd843bc ths
    int len;
3105 ffd843bc ths
3106 ffd843bc ths
    len = MIN(108, strlen(str));
3107 ffd843bc ths
    p = strchr(str, ',');
3108 ffd843bc ths
    if (p)
3109 ffd843bc ths
        len = MIN(len, p - str);
3110 ffd843bc ths
3111 ffd843bc ths
    memset(uaddr, 0, sizeof(*uaddr));
3112 ffd843bc ths
3113 ffd843bc ths
    uaddr->sun_family = AF_UNIX;
3114 ffd843bc ths
    memcpy(uaddr->sun_path, str, len);
3115 ffd843bc ths
3116 ffd843bc ths
    return 0;
3117 ffd843bc ths
}
3118 52f61fde ths
#endif
3119 ffd843bc ths
3120 7c9d8e07 bellard
/* find or alloc a new VLAN */
3121 7c9d8e07 bellard
VLANState *qemu_find_vlan(int id)
3122 c20709aa bellard
{
3123 7c9d8e07 bellard
    VLANState **pvlan, *vlan;
3124 7c9d8e07 bellard
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
3125 7c9d8e07 bellard
        if (vlan->id == id)
3126 7c9d8e07 bellard
            return vlan;
3127 7c9d8e07 bellard
    }
3128 7c9d8e07 bellard
    vlan = qemu_mallocz(sizeof(VLANState));
3129 7c9d8e07 bellard
    if (!vlan)
3130 7c9d8e07 bellard
        return NULL;
3131 7c9d8e07 bellard
    vlan->id = id;
3132 7c9d8e07 bellard
    vlan->next = NULL;
3133 7c9d8e07 bellard
    pvlan = &first_vlan;
3134 7c9d8e07 bellard
    while (*pvlan != NULL)
3135 7c9d8e07 bellard
        pvlan = &(*pvlan)->next;
3136 7c9d8e07 bellard
    *pvlan = vlan;
3137 7c9d8e07 bellard
    return vlan;
3138 c20709aa bellard
}
3139 c20709aa bellard
3140 7c9d8e07 bellard
VLANClientState *qemu_new_vlan_client(VLANState *vlan,
3141 d861b05e pbrook
                                      IOReadHandler *fd_read,
3142 d861b05e pbrook
                                      IOCanRWHandler *fd_can_read,
3143 d861b05e pbrook
                                      void *opaque)
3144 c20709aa bellard
{
3145 7c9d8e07 bellard
    VLANClientState *vc, **pvc;
3146 7c9d8e07 bellard
    vc = qemu_mallocz(sizeof(VLANClientState));
3147 7c9d8e07 bellard
    if (!vc)
3148 7c9d8e07 bellard
        return NULL;
3149 7c9d8e07 bellard
    vc->fd_read = fd_read;
3150 d861b05e pbrook
    vc->fd_can_read = fd_can_read;
3151 7c9d8e07 bellard
    vc->opaque = opaque;
3152 7c9d8e07 bellard
    vc->vlan = vlan;
3153 7c9d8e07 bellard
3154 7c9d8e07 bellard
    vc->next = NULL;
3155 7c9d8e07 bellard
    pvc = &vlan->first_client;
3156 7c9d8e07 bellard
    while (*pvc != NULL)
3157 7c9d8e07 bellard
        pvc = &(*pvc)->next;
3158 7c9d8e07 bellard
    *pvc = vc;
3159 7c9d8e07 bellard
    return vc;
3160 c20709aa bellard
}
3161 c20709aa bellard
3162 d861b05e pbrook
int qemu_can_send_packet(VLANClientState *vc1)
3163 d861b05e pbrook
{
3164 d861b05e pbrook
    VLANState *vlan = vc1->vlan;
3165 d861b05e pbrook
    VLANClientState *vc;
3166 d861b05e pbrook
3167 d861b05e pbrook
    for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
3168 d861b05e pbrook
        if (vc != vc1) {
3169 d861b05e pbrook
            if (vc->fd_can_read && !vc->fd_can_read(vc->opaque))
3170 d861b05e pbrook
                return 0;
3171 d861b05e pbrook
        }
3172 d861b05e pbrook
    }
3173 d861b05e pbrook
    return 1;
3174 d861b05e pbrook
}
3175 d861b05e pbrook
3176 7c9d8e07 bellard
void qemu_send_packet(VLANClientState *vc1, const uint8_t *buf, int size)
3177 c20709aa bellard
{
3178 7c9d8e07 bellard
    VLANState *vlan = vc1->vlan;
3179 7c9d8e07 bellard
    VLANClientState *vc;
3180 7c9d8e07 bellard
3181 7c9d8e07 bellard
#if 0
3182 7c9d8e07 bellard
    printf("vlan %d send:\n", vlan->id);
3183 7c9d8e07 bellard
    hex_dump(stdout, buf, size);
3184 7c9d8e07 bellard
#endif
3185 7c9d8e07 bellard
    for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
3186 7c9d8e07 bellard
        if (vc != vc1) {
3187 7c9d8e07 bellard
            vc->fd_read(vc->opaque, buf, size);
3188 7c9d8e07 bellard
        }
3189 7c9d8e07 bellard
    }
3190 67b915a5 bellard
}
3191 67b915a5 bellard
3192 c20709aa bellard
#if defined(CONFIG_SLIRP)
3193 c20709aa bellard
3194 c20709aa bellard
/* slirp network adapter */
3195 c20709aa bellard
3196 c20709aa bellard
static int slirp_inited;
3197 7c9d8e07 bellard
static VLANClientState *slirp_vc;
3198 c20709aa bellard
3199 c20709aa bellard
int slirp_can_output(void)
3200 c20709aa bellard
{
3201 3b7f5d47 pbrook
    return !slirp_vc || qemu_can_send_packet(slirp_vc);
3202 c20709aa bellard
}
3203 c20709aa bellard
3204 c20709aa bellard
void slirp_output(const uint8_t *pkt, int pkt_len)
3205 67b915a5 bellard
{
3206 c20709aa bellard
#if 0
3207 7c9d8e07 bellard
    printf("slirp output:\n");
3208 c20709aa bellard
    hex_dump(stdout, pkt, pkt_len);
3209 c20709aa bellard
#endif
3210 3b7f5d47 pbrook
    if (!slirp_vc)
3211 3b7f5d47 pbrook
        return;
3212 7c9d8e07 bellard
    qemu_send_packet(slirp_vc, pkt, pkt_len);
3213 67b915a5 bellard
}
3214 67b915a5 bellard
3215 7c9d8e07 bellard
static void slirp_receive(void *opaque, const uint8_t *buf, int size)
3216 c20709aa bellard
{
3217 c20709aa bellard
#if 0
3218 7c9d8e07 bellard
    printf("slirp input:\n");
3219 c20709aa bellard
    hex_dump(stdout, buf, size);
3220 c20709aa bellard
#endif
3221 c20709aa bellard
    slirp_input(buf, size);
3222 c20709aa bellard
}
3223 c20709aa bellard
3224 7c9d8e07 bellard
static int net_slirp_init(VLANState *vlan)
3225 c20709aa bellard
{
3226 c20709aa bellard
    if (!slirp_inited) {
3227 c20709aa bellard
        slirp_inited = 1;
3228 c20709aa bellard
        slirp_init();
3229 c20709aa bellard
    }
3230 7c9d8e07 bellard
    slirp_vc = qemu_new_vlan_client(vlan, 
3231 d861b05e pbrook
                                    slirp_receive, NULL, NULL);
3232 7c9d8e07 bellard
    snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector");
3233 9bf05444 bellard
    return 0;
3234 9bf05444 bellard
}
3235 9bf05444 bellard
3236 9bf05444 bellard
static void net_slirp_redir(const char *redir_str)
3237 9bf05444 bellard
{
3238 9bf05444 bellard
    int is_udp;
3239 9bf05444 bellard
    char buf[256], *r;
3240 9bf05444 bellard
    const char *p;
3241 9bf05444 bellard
    struct in_addr guest_addr;
3242 9bf05444 bellard
    int host_port, guest_port;
3243 9bf05444 bellard
    
3244 9bf05444 bellard
    if (!slirp_inited) {
3245 9bf05444 bellard
        slirp_inited = 1;
3246 9bf05444 bellard
        slirp_init();
3247 9bf05444 bellard
    }
3248 9bf05444 bellard
3249 9bf05444 bellard
    p = redir_str;
3250 9bf05444 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3251 9bf05444 bellard
        goto fail;
3252 9bf05444 bellard
    if (!strcmp(buf, "tcp")) {
3253 9bf05444 bellard
        is_udp = 0;
3254 9bf05444 bellard
    } else if (!strcmp(buf, "udp")) {
3255 9bf05444 bellard
        is_udp = 1;
3256 9bf05444 bellard
    } else {
3257 9bf05444 bellard
        goto fail;
3258 9bf05444 bellard
    }
3259 9bf05444 bellard
3260 9bf05444 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3261 9bf05444 bellard
        goto fail;
3262 9bf05444 bellard
    host_port = strtol(buf, &r, 0);
3263 9bf05444 bellard
    if (r == buf)
3264 9bf05444 bellard
        goto fail;
3265 9bf05444 bellard
3266 9bf05444 bellard
    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
3267 9bf05444 bellard
        goto fail;
3268 9bf05444 bellard
    if (buf[0] == '\0') {
3269 9bf05444 bellard
        pstrcpy(buf, sizeof(buf), "10.0.2.15");
3270 9bf05444 bellard
    }
3271 9bf05444 bellard
    if (!inet_aton(buf, &guest_addr))
3272 9bf05444 bellard
        goto fail;
3273 9bf05444 bellard
    
3274 9bf05444 bellard
    guest_port = strtol(p, &r, 0);
3275 9bf05444 bellard
    if (r == p)
3276 9bf05444 bellard
        goto fail;
3277 9bf05444 bellard
    
3278 9bf05444 bellard
    if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
3279 9bf05444 bellard
        fprintf(stderr, "qemu: could not set up redirection\n");
3280 9bf05444 bellard
        exit(1);
3281 9bf05444 bellard
    }
3282 9bf05444 bellard
    return;
3283 9bf05444 bellard
 fail:
3284 9bf05444 bellard
    fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
3285 9bf05444 bellard
    exit(1);
3286 9bf05444 bellard
}
3287 9d728e8c bellard
    
3288 c94c8d64 bellard
#ifndef _WIN32
3289 c94c8d64 bellard
3290 9d728e8c bellard
char smb_dir[1024];
3291 9d728e8c bellard
3292 9d728e8c bellard
static void smb_exit(void)
3293 9d728e8c bellard
{
3294 9d728e8c bellard
    DIR *d;
3295 9d728e8c bellard
    struct dirent *de;
3296 9d728e8c bellard
    char filename[1024];
3297 9d728e8c bellard
3298 9d728e8c bellard
    /* erase all the files in the directory */
3299 9d728e8c bellard
    d = opendir(smb_dir);
3300 9d728e8c bellard
    for(;;) {
3301 9d728e8c bellard
        de = readdir(d);
3302 9d728e8c bellard
        if (!de)
3303 9d728e8c bellard
            break;
3304 9d728e8c bellard
        if (strcmp(de->d_name, ".") != 0 &&
3305 9d728e8c bellard
            strcmp(de->d_name, "..") != 0) {
3306 9d728e8c bellard
            snprintf(filename, sizeof(filename), "%s/%s", 
3307 9d728e8c bellard
                     smb_dir, de->d_name);
3308 9d728e8c bellard
            unlink(filename);
3309 9d728e8c bellard
        }
3310 9d728e8c bellard
    }
3311 03ffbb69 bellard
    closedir(d);
3312 9d728e8c bellard
    rmdir(smb_dir);
3313 9d728e8c bellard
}
3314 9d728e8c bellard
3315 9d728e8c bellard
/* automatic user mode samba server configuration */
3316 9d728e8c bellard
void net_slirp_smb(const char *exported_dir)
3317 9d728e8c bellard
{
3318 9d728e8c bellard
    char smb_conf[1024];
3319 9d728e8c bellard
    char smb_cmdline[1024];
3320 9d728e8c bellard
    FILE *f;
3321 9d728e8c bellard
3322 9d728e8c bellard
    if (!slirp_inited) {
3323 9d728e8c bellard
        slirp_inited = 1;
3324 9d728e8c bellard
        slirp_init();
3325 9d728e8c bellard
    }
3326 9d728e8c bellard
3327 9d728e8c bellard
    /* XXX: better tmp dir construction */
3328 9d728e8c bellard
    snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%d", getpid());
3329 9d728e8c bellard
    if (mkdir(smb_dir, 0700) < 0) {
3330 9d728e8c bellard
        fprintf(stderr, "qemu: could not create samba server dir '%s'\n", smb_dir);
3331 9d728e8c bellard
        exit(1);
3332 9d728e8c bellard
    }
3333 9d728e8c bellard
    snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf");
3334 9d728e8c bellard
    
3335 9d728e8c bellard
    f = fopen(smb_conf, "w");
3336 9d728e8c bellard
    if (!f) {
3337 9d728e8c bellard
        fprintf(stderr, "qemu: could not create samba server configuration file '%s'\n", smb_conf);
3338 9d728e8c bellard
        exit(1);
3339 9d728e8c bellard
    }
3340 9d728e8c bellard
    fprintf(f, 
3341 9d728e8c bellard
            "[global]\n"
3342 157777ef bellard
            "private dir=%s\n"
3343 157777ef bellard
            "smb ports=0\n"
3344 157777ef bellard
            "socket address=127.0.0.1\n"
3345 9d728e8c bellard
            "pid directory=%s\n"
3346 9d728e8c bellard
            "lock directory=%s\n"
3347 9d728e8c bellard
            "log file=%s/log.smbd\n"
3348 9d728e8c bellard
            "smb passwd file=%s/smbpasswd\n"
3349 03ffbb69 bellard
            "security = share\n"
3350 9d728e8c bellard
            "[qemu]\n"
3351 9d728e8c bellard
            "path=%s\n"
3352 9d728e8c bellard
            "read only=no\n"
3353 9d728e8c bellard
            "guest ok=yes\n",
3354 9d728e8c bellard
            smb_dir,
3355 157777ef bellard
            smb_dir,
3356 9d728e8c bellard
            smb_dir,
3357 9d728e8c bellard
            smb_dir,
3358 9d728e8c bellard
            smb_dir,
3359 9d728e8c bellard
            exported_dir
3360 9d728e8c bellard
            );
3361 9d728e8c bellard
    fclose(f);
3362 9d728e8c bellard
    atexit(smb_exit);
3363 9d728e8c bellard
3364 a14d6c8c pbrook
    snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
3365 a14d6c8c pbrook
             SMBD_COMMAND, smb_conf);
3366 9d728e8c bellard
    
3367 9d728e8c bellard
    slirp_add_exec(0, smb_cmdline, 4, 139);
3368 9d728e8c bellard
}
3369 9bf05444 bellard
3370 c94c8d64 bellard
#endif /* !defined(_WIN32) */
3371 c94c8d64 bellard
3372 c20709aa bellard
#endif /* CONFIG_SLIRP */
3373 c20709aa bellard
3374 c20709aa bellard
#if !defined(_WIN32)
3375 7c9d8e07 bellard
3376 7c9d8e07 bellard
typedef struct TAPState {
3377 7c9d8e07 bellard
    VLANClientState *vc;
3378 7c9d8e07 bellard
    int fd;
3379 7c9d8e07 bellard
} TAPState;
3380 7c9d8e07 bellard
3381 7c9d8e07 bellard
static void tap_receive(void *opaque, const uint8_t *buf, int size)
3382 7c9d8e07 bellard
{
3383 7c9d8e07 bellard
    TAPState *s = opaque;
3384 7c9d8e07 bellard
    int ret;
3385 7c9d8e07 bellard
    for(;;) {
3386 7c9d8e07 bellard
        ret = write(s->fd, buf, size);
3387 7c9d8e07 bellard
        if (ret < 0 && (errno == EINTR || errno == EAGAIN)) {
3388 7c9d8e07 bellard
        } else {
3389 7c9d8e07 bellard
            break;
3390 7c9d8e07 bellard
        }
3391 7c9d8e07 bellard
    }
3392 7c9d8e07 bellard
}
3393 7c9d8e07 bellard
3394 7c9d8e07 bellard
static void tap_send(void *opaque)
3395 7c9d8e07 bellard
{
3396 7c9d8e07 bellard
    TAPState *s = opaque;
3397 7c9d8e07 bellard
    uint8_t buf[4096];
3398 7c9d8e07 bellard
    int size;
3399 7c9d8e07 bellard
3400 d5d10bc3 ths
#ifdef __sun__
3401 d5d10bc3 ths
    struct strbuf sbuf;
3402 d5d10bc3 ths
    int f = 0;
3403 d5d10bc3 ths
    sbuf.maxlen = sizeof(buf);
3404 d5d10bc3 ths
    sbuf.buf = buf;
3405 d5d10bc3 ths
    size = getmsg(s->fd, NULL, &sbuf, &f) >=0 ? sbuf.len : -1;
3406 d5d10bc3 ths
#else
3407 7c9d8e07 bellard
    size = read(s->fd, buf, sizeof(buf));
3408 d5d10bc3 ths
#endif
3409 7c9d8e07 bellard
    if (size > 0) {
3410 7c9d8e07 bellard
        qemu_send_packet(s->vc, buf, size);
3411 7c9d8e07 bellard
    }
3412 7c9d8e07 bellard
}
3413 7c9d8e07 bellard
3414 7c9d8e07 bellard
/* fd support */
3415 7c9d8e07 bellard
3416 7c9d8e07 bellard
static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
3417 7c9d8e07 bellard
{
3418 7c9d8e07 bellard
    TAPState *s;
3419 7c9d8e07 bellard
3420 7c9d8e07 bellard
    s = qemu_mallocz(sizeof(TAPState));
3421 7c9d8e07 bellard
    if (!s)
3422 7c9d8e07 bellard
        return NULL;
3423 7c9d8e07 bellard
    s->fd = fd;
3424 d861b05e pbrook
    s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
3425 7c9d8e07 bellard
    qemu_set_fd_handler(s->fd, tap_send, NULL, s);
3426 7c9d8e07 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
3427 7c9d8e07 bellard
    return s;
3428 7c9d8e07 bellard
}
3429 7c9d8e07 bellard
3430 7d3505c5 bellard
#ifdef _BSD
3431 7c9d8e07 bellard
static int tap_open(char *ifname, int ifname_size)
3432 7d3505c5 bellard
{
3433 7d3505c5 bellard
    int fd;
3434 7d3505c5 bellard
    char *dev;
3435 7d3505c5 bellard
    struct stat s;
3436 67b915a5 bellard
3437 7d3505c5 bellard
    fd = open("/dev/tap", O_RDWR);
3438 7d3505c5 bellard
    if (fd < 0) {
3439 7d3505c5 bellard
        fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
3440 7d3505c5 bellard
        return -1;
3441 7d3505c5 bellard
    }
3442 7d3505c5 bellard
3443 7d3505c5 bellard
    fstat(fd, &s);
3444 7d3505c5 bellard
    dev = devname(s.st_rdev, S_IFCHR);
3445 7d3505c5 bellard
    pstrcpy(ifname, ifname_size, dev);
3446 7d3505c5 bellard
3447 7d3505c5 bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
3448 7d3505c5 bellard
    return fd;
3449 7d3505c5 bellard
}
3450 ec530c81 bellard
#elif defined(__sun__)
3451 d5d10bc3 ths
#define TUNNEWPPA       (('T'<<16) | 0x0001)
3452 d5d10bc3 ths
/* 
3453 d5d10bc3 ths
 * Allocate TAP device, returns opened fd. 
3454 d5d10bc3 ths
 * Stores dev name in the first arg(must be large enough).
3455 d5d10bc3 ths
 */  
3456 d5d10bc3 ths
int tap_alloc(char *dev)
3457 d5d10bc3 ths
{
3458 d5d10bc3 ths
    int tap_fd, if_fd, ppa = -1;
3459 d5d10bc3 ths
    static int ip_fd = 0;
3460 d5d10bc3 ths
    char *ptr;
3461 d5d10bc3 ths
3462 d5d10bc3 ths
    static int arp_fd = 0;
3463 d5d10bc3 ths
    int ip_muxid, arp_muxid;
3464 d5d10bc3 ths
    struct strioctl  strioc_if, strioc_ppa;
3465 d5d10bc3 ths
    int link_type = I_PLINK;;
3466 d5d10bc3 ths
    struct lifreq ifr;
3467 d5d10bc3 ths
    char actual_name[32] = "";
3468 d5d10bc3 ths
3469 d5d10bc3 ths
    memset(&ifr, 0x0, sizeof(ifr));
3470 d5d10bc3 ths
3471 d5d10bc3 ths
    if( *dev ){
3472 d5d10bc3 ths
       ptr = dev;        
3473 d5d10bc3 ths
       while( *ptr && !isdigit((int)*ptr) ) ptr++; 
3474 d5d10bc3 ths
       ppa = atoi(ptr);
3475 d5d10bc3 ths
    }
3476 d5d10bc3 ths
3477 d5d10bc3 ths
    /* Check if IP device was opened */
3478 d5d10bc3 ths
    if( ip_fd )
3479 d5d10bc3 ths
       close(ip_fd);
3480 d5d10bc3 ths
3481 d5d10bc3 ths
    if( (ip_fd = open("/dev/udp", O_RDWR, 0)) < 0){
3482 d5d10bc3 ths
       syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)");
3483 d5d10bc3 ths
       return -1;
3484 d5d10bc3 ths
    }
3485 d5d10bc3 ths
3486 d5d10bc3 ths
    if( (tap_fd = open("/dev/tap", O_RDWR, 0)) < 0){
3487 d5d10bc3 ths
       syslog(LOG_ERR, "Can't open /dev/tap");
3488 d5d10bc3 ths
       return -1;
3489 d5d10bc3 ths
    }
3490 d5d10bc3 ths
3491 d5d10bc3 ths
    /* Assign a new PPA and get its unit number. */
3492 d5d10bc3 ths
    strioc_ppa.ic_cmd = TUNNEWPPA;
3493 d5d10bc3 ths
    strioc_ppa.ic_timout = 0;
3494 d5d10bc3 ths
    strioc_ppa.ic_len = sizeof(ppa);
3495 d5d10bc3 ths
    strioc_ppa.ic_dp = (char *)&ppa;
3496 d5d10bc3 ths
    if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0)
3497 d5d10bc3 ths
       syslog (LOG_ERR, "Can't assign new interface");
3498 d5d10bc3 ths
3499 d5d10bc3 ths
    if( (if_fd = open("/dev/tap", O_RDWR, 0)) < 0){
3500 d5d10bc3 ths
       syslog(LOG_ERR, "Can't open /dev/tap (2)");
3501 d5d10bc3 ths
       return -1;
3502 d5d10bc3 ths
    }
3503 d5d10bc3 ths
    if(ioctl(if_fd, I_PUSH, "ip") < 0){
3504 d5d10bc3 ths
       syslog(LOG_ERR, "Can't push IP module");
3505 d5d10bc3 ths
       return -1;
3506 d5d10bc3 ths
    }
3507 d5d10bc3 ths
3508 d5d10bc3 ths
    if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
3509 d5d10bc3 ths
        syslog(LOG_ERR, "Can't get flags\n");
3510 d5d10bc3 ths
3511 d5d10bc3 ths
    snprintf (actual_name, 32, "tap%d", ppa);
3512 d5d10bc3 ths
    strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
3513 d5d10bc3 ths
3514 d5d10bc3 ths
    ifr.lifr_ppa = ppa;
3515 d5d10bc3 ths
    /* Assign ppa according to the unit number returned by tun device */
3516 d5d10bc3 ths
3517 d5d10bc3 ths
    if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0)
3518 d5d10bc3 ths
        syslog (LOG_ERR, "Can't set PPA %d", ppa);
3519 d5d10bc3 ths
    if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
3520 d5d10bc3 ths
        syslog (LOG_ERR, "Can't get flags\n");
3521 d5d10bc3 ths
    /* Push arp module to if_fd */
3522 d5d10bc3 ths
    if (ioctl (if_fd, I_PUSH, "arp") < 0)
3523 d5d10bc3 ths
        syslog (LOG_ERR, "Can't push ARP module (2)");
3524 d5d10bc3 ths
3525 d5d10bc3 ths
    /* Push arp module to ip_fd */
3526 d5d10bc3 ths
    if (ioctl (ip_fd, I_POP, NULL) < 0)
3527 d5d10bc3 ths
        syslog (LOG_ERR, "I_POP failed\n");
3528 d5d10bc3 ths
    if (ioctl (ip_fd, I_PUSH, "arp") < 0)
3529 d5d10bc3 ths
        syslog (LOG_ERR, "Can't push ARP module (3)\n");
3530 d5d10bc3 ths
    /* Open arp_fd */
3531 d5d10bc3 ths
    if ((arp_fd = open ("/dev/tap", O_RDWR, 0)) < 0)
3532 d5d10bc3 ths
       syslog (LOG_ERR, "Can't open %s\n", "/dev/tap");
3533 d5d10bc3 ths
3534 d5d10bc3 ths
    /* Set ifname to arp */
3535 d5d10bc3 ths
    strioc_if.ic_cmd = SIOCSLIFNAME;
3536 d5d10bc3 ths
    strioc_if.ic_timout = 0;
3537 d5d10bc3 ths
    strioc_if.ic_len = sizeof(ifr);
3538 d5d10bc3 ths
    strioc_if.ic_dp = (char *)&ifr;
3539 d5d10bc3 ths
    if (ioctl(arp_fd, I_STR, &strioc_if) < 0){
3540 d5d10bc3 ths
        syslog (LOG_ERR, "Can't set ifname to arp\n");
3541 d5d10bc3 ths
    }
3542 d5d10bc3 ths
3543 d5d10bc3 ths
    if((ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0){
3544 d5d10bc3 ths
       syslog(LOG_ERR, "Can't link TAP device to IP");
3545 d5d10bc3 ths
       return -1;
3546 d5d10bc3 ths
    }
3547 d5d10bc3 ths
3548 d5d10bc3 ths
    if ((arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0)
3549 d5d10bc3 ths
        syslog (LOG_ERR, "Can't link TAP device to ARP");
3550 d5d10bc3 ths
3551 d5d10bc3 ths
    close (if_fd);
3552 d5d10bc3 ths
3553 d5d10bc3 ths
    memset(&ifr, 0x0, sizeof(ifr));
3554 d5d10bc3 ths
    strncpy (ifr.lifr_name, actual_name, sizeof (ifr.lifr_name));
3555 d5d10bc3 ths
    ifr.lifr_ip_muxid  = ip_muxid;
3556 d5d10bc3 ths
    ifr.lifr_arp_muxid = arp_muxid;
3557 d5d10bc3 ths
3558 d5d10bc3 ths
    if (ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0)
3559 d5d10bc3 ths
    {
3560 d5d10bc3 ths
      ioctl (ip_fd, I_PUNLINK , arp_muxid);
3561 d5d10bc3 ths
      ioctl (ip_fd, I_PUNLINK, ip_muxid);
3562 d5d10bc3 ths
      syslog (LOG_ERR, "Can't set multiplexor id");
3563 d5d10bc3 ths
    }
3564 d5d10bc3 ths
3565 d5d10bc3 ths
    sprintf(dev, "tap%d", ppa);
3566 d5d10bc3 ths
    return tap_fd;
3567 d5d10bc3 ths
}
3568 d5d10bc3 ths
3569 ec530c81 bellard
static int tap_open(char *ifname, int ifname_size)
3570 ec530c81 bellard
{
3571 d5d10bc3 ths
    char  dev[10]="";
3572 d5d10bc3 ths
    int fd;
3573 d5d10bc3 ths
    if( (fd = tap_alloc(dev)) < 0 ){
3574 d5d10bc3 ths
       fprintf(stderr, "Cannot allocate TAP device\n");
3575 d5d10bc3 ths
       return -1;
3576 d5d10bc3 ths
    }
3577 d5d10bc3 ths
    pstrcpy(ifname, ifname_size, dev);
3578 d5d10bc3 ths
    fcntl(fd, F_SETFL, O_NONBLOCK);
3579 d5d10bc3 ths
    return fd;
3580 ec530c81 bellard
}
3581 7d3505c5 bellard
#else
3582 7c9d8e07 bellard
static int tap_open(char *ifname, int ifname_size)
3583 330d0414 bellard
{
3584 80cabfad bellard
    struct ifreq ifr;
3585 c4b1fcc0 bellard
    int fd, ret;
3586 80cabfad bellard
    
3587 80cabfad bellard
    fd = open("/dev/net/tun", O_RDWR);
3588 80cabfad bellard
    if (fd < 0) {
3589 80cabfad bellard
        fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
3590 80cabfad bellard
        return -1;
3591 330d0414 bellard
    }
3592 80cabfad bellard
    memset(&ifr, 0, sizeof(ifr));
3593 80cabfad bellard
    ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
3594 7c9d8e07 bellard
    if (ifname[0] != '\0')
3595 7c9d8e07 bellard
        pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
3596 7c9d8e07 bellard
    else
3597 7c9d8e07 bellard
        pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
3598 80cabfad bellard
    ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
3599 80cabfad bellard
    if (ret != 0) {
3600 80cabfad bellard
        fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
3601 80cabfad bellard
        close(fd);
3602 80cabfad bellard
        return -1;
3603 80cabfad bellard
    }
3604 c4b1fcc0 bellard
    pstrcpy(ifname, ifname_size, ifr.ifr_name);
3605 80cabfad bellard
    fcntl(fd, F_SETFL, O_NONBLOCK);
3606 c4b1fcc0 bellard
    return fd;
3607 c4b1fcc0 bellard
}
3608 7d3505c5 bellard
#endif
3609 330d0414 bellard
3610 7c9d8e07 bellard
static int net_tap_init(VLANState *vlan, const char *ifname1,
3611 7c9d8e07 bellard
                        const char *setup_script)
3612 7c9d8e07 bellard
{
3613 7c9d8e07 bellard
    TAPState *s;
3614 7c9d8e07 bellard
    int pid, status, fd;
3615 7c9d8e07 bellard
    char *args[3];
3616 7c9d8e07 bellard
    char **parg;
3617 7c9d8e07 bellard
    char ifname[128];
3618 7c9d8e07 bellard
3619 7c9d8e07 bellard
    if (ifname1 != NULL)
3620 7c9d8e07 bellard
        pstrcpy(ifname, sizeof(ifname), ifname1);
3621 7c9d8e07 bellard
    else
3622 7c9d8e07 bellard
        ifname[0] = '\0';
3623 7c9d8e07 bellard
    fd = tap_open(ifname, sizeof(ifname));
3624 7c9d8e07 bellard
    if (fd < 0)
3625 7c9d8e07 bellard
        return -1;
3626 7c9d8e07 bellard
3627 6a1cbf68 ths
    if (!setup_script || !strcmp(setup_script, "no"))
3628 7c9d8e07 bellard
        setup_script = "";
3629 7c9d8e07 bellard
    if (setup_script[0] != '\0') {
3630 7c9d8e07 bellard
        /* try to launch network init script */
3631 7c9d8e07 bellard
        pid = fork();
3632 7c9d8e07 bellard
        if (pid >= 0) {
3633 7c9d8e07 bellard
            if (pid == 0) {
3634 50d3eeae ths
                int open_max = sysconf (_SC_OPEN_MAX), i;
3635 50d3eeae ths
                for (i = 0; i < open_max; i++)
3636 50d3eeae ths
                    if (i != STDIN_FILENO &&
3637 50d3eeae ths
                        i != STDOUT_FILENO &&
3638 50d3eeae ths
                        i != STDERR_FILENO &&
3639 50d3eeae ths
                        i != fd)
3640 50d3eeae ths
                        close(i);
3641 50d3eeae ths
3642 7c9d8e07 bellard
                parg = args;
3643 7c9d8e07 bellard
                *parg++ = (char *)setup_script;
3644 7c9d8e07 bellard
                *parg++ = ifname;
3645 7c9d8e07 bellard
                *parg++ = NULL;
3646 7c9d8e07 bellard
                execv(setup_script, args);
3647 4a38940d bellard
                _exit(1);
3648 7c9d8e07 bellard
            }
3649 7c9d8e07 bellard
            while (waitpid(pid, &status, 0) != pid);
3650 7c9d8e07 bellard
            if (!WIFEXITED(status) ||
3651 7c9d8e07 bellard
                WEXITSTATUS(status) != 0) {
3652 7c9d8e07 bellard
                fprintf(stderr, "%s: could not launch network script\n",
3653 7c9d8e07 bellard
                        setup_script);
3654 7c9d8e07 bellard
                return -1;
3655 7c9d8e07 bellard
            }
3656 7c9d8e07 bellard
        }
3657 7c9d8e07 bellard
    }
3658 7c9d8e07 bellard
    s = net_tap_fd_init(vlan, fd);
3659 7c9d8e07 bellard
    if (!s)
3660 7c9d8e07 bellard
        return -1;
3661 7c9d8e07 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str), 
3662 7c9d8e07 bellard
             "tap: ifname=%s setup_script=%s", ifname, setup_script);
3663 7c9d8e07 bellard
    return 0;
3664 7c9d8e07 bellard
}
3665 7c9d8e07 bellard
3666 fd1dff4b bellard
#endif /* !_WIN32 */
3667 fd1dff4b bellard
3668 7c9d8e07 bellard
/* network connection */
3669 7c9d8e07 bellard
typedef struct NetSocketState {
3670 7c9d8e07 bellard
    VLANClientState *vc;
3671 7c9d8e07 bellard
    int fd;
3672 7c9d8e07 bellard
    int state; /* 0 = getting length, 1 = getting data */
3673 7c9d8e07 bellard
    int index;
3674 7c9d8e07 bellard
    int packet_len;
3675 7c9d8e07 bellard
    uint8_t buf[4096];
3676 3d830459 bellard
    struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
3677 7c9d8e07 bellard
} NetSocketState;
3678 7c9d8e07 bellard
3679 7c9d8e07 bellard
typedef struct NetSocketListenState {
3680 7c9d8e07 bellard
    VLANState *vlan;
3681 7c9d8e07 bellard
    int fd;
3682 7c9d8e07 bellard
} NetSocketListenState;
3683 7c9d8e07 bellard
3684 7c9d8e07 bellard
/* XXX: we consider we can send the whole packet without blocking */
3685 7c9d8e07 bellard
static void net_socket_receive(void *opaque, const uint8_t *buf, int size)
3686 c20709aa bellard
{
3687 7c9d8e07 bellard
    NetSocketState *s = opaque;
3688 7c9d8e07 bellard
    uint32_t len;
3689 7c9d8e07 bellard
    len = htonl(size);
3690 7c9d8e07 bellard
3691 fd1dff4b bellard
    send_all(s->fd, (const uint8_t *)&len, sizeof(len));
3692 fd1dff4b bellard
    send_all(s->fd, buf, size);
3693 c20709aa bellard
}
3694 c20709aa bellard
3695 3d830459 bellard
static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size)
3696 3d830459 bellard
{
3697 3d830459 bellard
    NetSocketState *s = opaque;
3698 3d830459 bellard
    sendto(s->fd, buf, size, 0, 
3699 3d830459 bellard
           (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
3700 3d830459 bellard
}
3701 3d830459 bellard
3702 7c9d8e07 bellard
static void net_socket_send(void *opaque)
3703 c4b1fcc0 bellard
{
3704 7c9d8e07 bellard
    NetSocketState *s = opaque;
3705 fd1dff4b bellard
    int l, size, err;
3706 7c9d8e07 bellard
    uint8_t buf1[4096];
3707 7c9d8e07 bellard
    const uint8_t *buf;
3708 7c9d8e07 bellard
3709 fd1dff4b bellard
    size = recv(s->fd, buf1, sizeof(buf1), 0);
3710 fd1dff4b bellard
    if (size < 0) {
3711 fd1dff4b bellard
        err = socket_error();
3712 fd1dff4b bellard
        if (err != EWOULDBLOCK) 
3713 fd1dff4b bellard
            goto eoc;
3714 fd1dff4b bellard
    } else if (size == 0) {
3715 7c9d8e07 bellard
        /* end of connection */
3716 fd1dff4b bellard
    eoc:
3717 7c9d8e07 bellard
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
3718 fd1dff4b bellard
        closesocket(s->fd);
3719 7c9d8e07 bellard
        return;
3720 7c9d8e07 bellard
    }
3721 7c9d8e07 bellard
    buf = buf1;
3722 7c9d8e07 bellard
    while (size > 0) {
3723 7c9d8e07 bellard
        /* reassemble a packet from the network */
3724 7c9d8e07 bellard
        switch(s->state) {
3725 7c9d8e07 bellard
        case 0:
3726 7c9d8e07 bellard
            l = 4 - s->index;
3727 7c9d8e07 bellard
            if (l > size)
3728 7c9d8e07 bellard
                l = size;
3729 7c9d8e07 bellard
            memcpy(s->buf + s->index, buf, l);
3730 7c9d8e07 bellard
            buf += l;
3731 7c9d8e07 bellard
            size -= l;
3732 7c9d8e07 bellard
            s->index += l;
3733 7c9d8e07 bellard
            if (s->index == 4) {
3734 7c9d8e07 bellard
                /* got length */
3735 7c9d8e07 bellard
                s->packet_len = ntohl(*(uint32_t *)s->buf);
3736 7c9d8e07 bellard
                s->index = 0;
3737 7c9d8e07 bellard
                s->state = 1;
3738 7c9d8e07 bellard
            }
3739 7c9d8e07 bellard
            break;
3740 7c9d8e07 bellard
        case 1:
3741 7c9d8e07 bellard
            l = s->packet_len - s->index;
3742 7c9d8e07 bellard
            if (l > size)
3743 7c9d8e07 bellard
                l = size;
3744 7c9d8e07 bellard
            memcpy(s->buf + s->index, buf, l);
3745 7c9d8e07 bellard
            s->index += l;
3746 7c9d8e07 bellard
            buf += l;
3747 7c9d8e07 bellard
            size -= l;
3748 7c9d8e07 bellard
            if (s->index >= s->packet_len) {
3749 7c9d8e07 bellard
                qemu_send_packet(s->vc, s->buf, s->packet_len);
3750 7c9d8e07 bellard
                s->index = 0;
3751 7c9d8e07 bellard
                s->state = 0;
3752 7c9d8e07 bellard
            }
3753 7c9d8e07 bellard
            break;
3754 7c9d8e07 bellard
        }
3755 7c9d8e07 bellard
    }
3756 c20709aa bellard
}
3757 c20709aa bellard
3758 3d830459 bellard
static void net_socket_send_dgram(void *opaque)
3759 3d830459 bellard
{
3760 3d830459 bellard
    NetSocketState *s = opaque;
3761 3d830459 bellard
    int size;
3762 3d830459 bellard
3763 3d830459 bellard
    size = recv(s->fd, s->buf, sizeof(s->buf), 0);
3764 3d830459 bellard
    if (size < 0) 
3765 3d830459 bellard
        return;
3766 3d830459 bellard
    if (size == 0) {
3767 3d830459 bellard
        /* end of connection */
3768 3d830459 bellard
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
3769 3d830459 bellard
        return;
3770 3d830459 bellard
    }
3771 3d830459 bellard
    qemu_send_packet(s->vc, s->buf, size);
3772 3d830459 bellard
}
3773 3d830459 bellard
3774 3d830459 bellard
static int net_socket_mcast_create(struct sockaddr_in *mcastaddr)
3775 3d830459 bellard
{
3776 3d830459 bellard
    struct ip_mreq imr;
3777 3d830459 bellard
    int fd;
3778 3d830459 bellard
    int val, ret;
3779 3d830459 bellard
    if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
3780 3d830459 bellard
        fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n",
3781 fd1dff4b bellard
                inet_ntoa(mcastaddr->sin_addr), 
3782 fd1dff4b bellard
                (int)ntohl(mcastaddr->sin_addr.s_addr));
3783 3d830459 bellard
        return -1;
3784 3d830459 bellard
3785 3d830459 bellard
    }
3786 3d830459 bellard
    fd = socket(PF_INET, SOCK_DGRAM, 0);
3787 3d830459 bellard
    if (fd < 0) {
3788 3d830459 bellard
        perror("socket(PF_INET, SOCK_DGRAM)");
3789 3d830459 bellard
        return -1;
3790 3d830459 bellard
    }
3791 3d830459 bellard
3792 fd1dff4b bellard
    val = 1;
3793 fd1dff4b bellard
    ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 
3794 fd1dff4b bellard
                   (const char *)&val, sizeof(val));
3795 fd1dff4b bellard
    if (ret < 0) {
3796 fd1dff4b bellard
        perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
3797 fd1dff4b bellard
        goto fail;
3798 fd1dff4b bellard
    }
3799 fd1dff4b bellard
3800 fd1dff4b bellard
    ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr));
3801 fd1dff4b bellard
    if (ret < 0) {
3802 fd1dff4b bellard
        perror("bind");
3803 fd1dff4b bellard
        goto fail;
3804 fd1dff4b bellard
    }
3805 fd1dff4b bellard
    
3806 3d830459 bellard
    /* Add host to multicast group */
3807 3d830459 bellard
    imr.imr_multiaddr = mcastaddr->sin_addr;
3808 3d830459 bellard
    imr.imr_interface.s_addr = htonl(INADDR_ANY);
3809 3d830459 bellard
3810 fd1dff4b bellard
    ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, 
3811 fd1dff4b bellard
                     (const char *)&imr, sizeof(struct ip_mreq));
3812 3d830459 bellard
    if (ret < 0) {
3813 3d830459 bellard
        perror("setsockopt(IP_ADD_MEMBERSHIP)");
3814 3d830459 bellard
        goto fail;
3815 3d830459 bellard
    }
3816 3d830459 bellard
3817 3d830459 bellard
    /* Force mcast msgs to loopback (eg. several QEMUs in same host */
3818 3d830459 bellard
    val = 1;
3819 fd1dff4b bellard
    ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, 
3820 fd1dff4b bellard
                   (const char *)&val, sizeof(val));
3821 3d830459 bellard
    if (ret < 0) {
3822 3d830459 bellard
        perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
3823 3d830459 bellard
        goto fail;
3824 3d830459 bellard
    }
3825 3d830459 bellard
3826 fd1dff4b bellard
    socket_set_nonblock(fd);
3827 3d830459 bellard
    return fd;
3828 3d830459 bellard
fail:
3829 0bab00f3 bellard
    if (fd >= 0) 
3830 0bab00f3 bellard
        closesocket(fd);
3831 3d830459 bellard
    return -1;
3832 3d830459 bellard
}
3833 3d830459 bellard
3834 3d830459 bellard
static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan, int fd, 
3835 3d830459 bellard
                                          int is_connected)
3836 3d830459 bellard
{
3837 3d830459 bellard
    struct sockaddr_in saddr;
3838 3d830459 bellard
    int newfd;
3839 3d830459 bellard
    socklen_t saddr_len;
3840 3d830459 bellard
    NetSocketState *s;
3841 3d830459 bellard
3842 3d830459 bellard
    /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
3843 3d830459 bellard
     * Because this may be "shared" socket from a "master" process, datagrams would be recv() 
3844 3d830459 bellard
     * by ONLY ONE process: we must "clone" this dgram socket --jjo
3845 3d830459 bellard
     */
3846 3d830459 bellard
3847 3d830459 bellard
    if (is_connected) {
3848 3d830459 bellard
        if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
3849 3d830459 bellard
            /* must be bound */
3850 3d830459 bellard
            if (saddr.sin_addr.s_addr==0) {
3851 3d830459 bellard
                fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, cannot setup multicast dst addr\n",
3852 3d830459 bellard
                        fd);
3853 3d830459 bellard
                return NULL;
3854 3d830459 bellard
            }
3855 3d830459 bellard
            /* clone dgram socket */
3856 3d830459 bellard
            newfd = net_socket_mcast_create(&saddr);
3857 3d830459 bellard
            if (newfd < 0) {
3858 3d830459 bellard
                /* error already reported by net_socket_mcast_create() */
3859 3d830459 bellard
                close(fd);
3860 3d830459 bellard
                return NULL;
3861 3d830459 bellard
            }
3862 3d830459 bellard
            /* clone newfd to fd, close newfd */
3863 3d830459 bellard
            dup2(newfd, fd);
3864 3d830459 bellard
            close(newfd);
3865 3d830459 bellard
        
3866 3d830459 bellard
        } else {
3867 3d830459 bellard
            fprintf(stderr, "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
3868 3d830459 bellard
                    fd, strerror(errno));
3869 3d830459 bellard
            return NULL;
3870 3d830459 bellard
        }
3871 3d830459 bellard
    }
3872 3d830459 bellard
3873 3d830459 bellard
    s = qemu_mallocz(sizeof(NetSocketState));
3874 3d830459 bellard
    if (!s)
3875 3d830459 bellard
        return NULL;
3876 3d830459 bellard
    s->fd = fd;
3877 3d830459 bellard
3878 d861b05e pbrook
    s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, NULL, s);
3879 3d830459 bellard
    qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
3880 3d830459 bellard
3881 3d830459 bellard
    /* mcast: save bound address as dst */
3882 3d830459 bellard
    if (is_connected) s->dgram_dst=saddr;
3883 3d830459 bellard
3884 3d830459 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
3885 3d830459 bellard
            "socket: fd=%d (%s mcast=%s:%d)", 
3886 3d830459 bellard
            fd, is_connected? "cloned" : "",
3887 3d830459 bellard
            inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
3888 3d830459 bellard
    return s;
3889 3d830459 bellard
}
3890 3d830459 bellard
3891 7c9d8e07 bellard
static void net_socket_connect(void *opaque)
3892 c20709aa bellard
{
3893 7c9d8e07 bellard
    NetSocketState *s = opaque;
3894 7c9d8e07 bellard
    qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
3895 7c9d8e07 bellard
}
3896 c4b1fcc0 bellard
3897 3d830459 bellard
static NetSocketState *net_socket_fd_init_stream(VLANState *vlan, int fd, 
3898 7c9d8e07 bellard
                                          int is_connected)
3899 7c9d8e07 bellard
{
3900 7c9d8e07 bellard
    NetSocketState *s;
3901 7c9d8e07 bellard
    s = qemu_mallocz(sizeof(NetSocketState));
3902 7c9d8e07 bellard
    if (!s)
3903 7c9d8e07 bellard
        return NULL;
3904 7c9d8e07 bellard
    s->fd = fd;
3905 7c9d8e07 bellard
    s->vc = qemu_new_vlan_client(vlan, 
3906 d861b05e pbrook
                                 net_socket_receive, NULL, s);
3907 7c9d8e07 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
3908 7c9d8e07 bellard
             "socket: fd=%d", fd);
3909 7c9d8e07 bellard
    if (is_connected) {
3910 7c9d8e07 bellard
        net_socket_connect(s);
3911 7c9d8e07 bellard
    } else {
3912 7c9d8e07 bellard
        qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s);
3913 7c9d8e07 bellard
    }
3914 7c9d8e07 bellard
    return s;
3915 7c9d8e07 bellard
}
3916 c4b1fcc0 bellard
3917 3d830459 bellard
static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd, 
3918 3d830459 bellard
                                          int is_connected)
3919 3d830459 bellard
{
3920 3d830459 bellard
    int so_type=-1, optlen=sizeof(so_type);
3921 3d830459 bellard
3922 fd1dff4b bellard
    if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type, &optlen)< 0) {
3923 3d830459 bellard
        fprintf(stderr, "qemu: error: setsockopt(SO_TYPE) for fd=%d failed\n", fd);
3924 3d830459 bellard
        return NULL;
3925 3d830459 bellard
    }
3926 3d830459 bellard
    switch(so_type) {
3927 3d830459 bellard
    case SOCK_DGRAM:
3928 3d830459 bellard
        return net_socket_fd_init_dgram(vlan, fd, is_connected);
3929 3d830459 bellard
    case SOCK_STREAM:
3930 3d830459 bellard
        return net_socket_fd_init_stream(vlan, fd, is_connected);
3931 3d830459 bellard
    default:
3932 3d830459 bellard
        /* who knows ... this could be a eg. a pty, do warn and continue as stream */
3933 3d830459 bellard
        fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd);
3934 3d830459 bellard
        return net_socket_fd_init_stream(vlan, fd, is_connected);
3935 3d830459 bellard
    }
3936 3d830459 bellard
    return NULL;
3937 3d830459 bellard
}
3938 3d830459 bellard
3939 7c9d8e07 bellard
static void net_socket_accept(void *opaque)
3940 7c9d8e07 bellard
{
3941 7c9d8e07 bellard
    NetSocketListenState *s = opaque;    
3942 7c9d8e07 bellard
    NetSocketState *s1;
3943 7c9d8e07 bellard
    struct sockaddr_in saddr;
3944 7c9d8e07 bellard
    socklen_t len;
3945 7c9d8e07 bellard
    int fd;
3946 7c9d8e07 bellard
3947 7c9d8e07 bellard
    for(;;) {
3948 7c9d8e07 bellard
        len = sizeof(saddr);
3949 7c9d8e07 bellard
        fd = accept(s->fd, (struct sockaddr *)&saddr, &len);
3950 7c9d8e07 bellard
        if (fd < 0 && errno != EINTR) {
3951 7c9d8e07 bellard
            return;
3952 7c9d8e07 bellard
        } else if (fd >= 0) {
3953 7c9d8e07 bellard
            break;
3954 80cabfad bellard
        }
3955 330d0414 bellard
    }
3956 7c9d8e07 bellard
    s1 = net_socket_fd_init(s->vlan, fd, 1); 
3957 7c9d8e07 bellard
    if (!s1) {
3958 0bab00f3 bellard
        closesocket(fd);
3959 7c9d8e07 bellard
    } else {
3960 7c9d8e07 bellard
        snprintf(s1->vc->info_str, sizeof(s1->vc->info_str),
3961 7c9d8e07 bellard
                 "socket: connection from %s:%d", 
3962 7c9d8e07 bellard
                 inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
3963 7c9d8e07 bellard
    }
3964 7c9d8e07 bellard
}
3965 7c9d8e07 bellard
3966 7c9d8e07 bellard
static int net_socket_listen_init(VLANState *vlan, const char *host_str)
3967 7c9d8e07 bellard
{
3968 7c9d8e07 bellard
    NetSocketListenState *s;
3969 7c9d8e07 bellard
    int fd, val, ret;
3970 7c9d8e07 bellard
    struct sockaddr_in saddr;
3971 7c9d8e07 bellard
3972 7c9d8e07 bellard
    if (parse_host_port(&saddr, host_str) < 0)
3973 7c9d8e07 bellard
        return -1;
3974 7c9d8e07 bellard
    
3975 7c9d8e07 bellard
    s = qemu_mallocz(sizeof(NetSocketListenState));
3976 7c9d8e07 bellard
    if (!s)
3977 7c9d8e07 bellard
        return -1;
3978 7c9d8e07 bellard
3979 7c9d8e07 bellard
    fd = socket(PF_INET, SOCK_STREAM, 0);
3980 7c9d8e07 bellard
    if (fd < 0) {
3981 7c9d8e07 bellard
        perror("socket");
3982 7c9d8e07 bellard
        return -1;
3983 7c9d8e07 bellard
    }
3984 fd1dff4b bellard
    socket_set_nonblock(fd);
3985 7c9d8e07 bellard
3986 7c9d8e07 bellard
    /* allow fast reuse */
3987 7c9d8e07 bellard
    val = 1;
3988 fd1dff4b bellard
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
3989 7c9d8e07 bellard
    
3990 7c9d8e07 bellard
    ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
3991 7c9d8e07 bellard
    if (ret < 0) {
3992 7c9d8e07 bellard
        perror("bind");
3993 7c9d8e07 bellard
        return -1;
3994 7c9d8e07 bellard
    }
3995 7c9d8e07 bellard
    ret = listen(fd, 0);
3996 7c9d8e07 bellard
    if (ret < 0) {
3997 7c9d8e07 bellard
        perror("listen");
3998 7c9d8e07 bellard
        return -1;
3999 7c9d8e07 bellard
    }
4000 7c9d8e07 bellard
    s->vlan = vlan;
4001 7c9d8e07 bellard
    s->fd = fd;
4002 7c9d8e07 bellard
    qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
4003 80cabfad bellard
    return 0;
4004 330d0414 bellard
}
4005 330d0414 bellard
4006 7c9d8e07 bellard
static int net_socket_connect_init(VLANState *vlan, const char *host_str)
4007 330d0414 bellard
{
4008 7c9d8e07 bellard
    NetSocketState *s;
4009 fd1dff4b bellard
    int fd, connected, ret, err;
4010 7c9d8e07 bellard
    struct sockaddr_in saddr;
4011 7c9d8e07 bellard
4012 7c9d8e07 bellard
    if (parse_host_port(&saddr, host_str) < 0)
4013 7c9d8e07 bellard
        return -1;
4014 7c9d8e07 bellard
4015 7c9d8e07 bellard
    fd = socket(PF_INET, SOCK_STREAM, 0);
4016 7c9d8e07 bellard
    if (fd < 0) {
4017 7c9d8e07 bellard
        perror("socket");
4018 7c9d8e07 bellard
        return -1;
4019 7c9d8e07 bellard
    }
4020 fd1dff4b bellard
    socket_set_nonblock(fd);
4021 7c9d8e07 bellard
4022 7c9d8e07 bellard
    connected = 0;
4023 7c9d8e07 bellard
    for(;;) {
4024 7c9d8e07 bellard
        ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
4025 7c9d8e07 bellard
        if (ret < 0) {
4026 fd1dff4b bellard
            err = socket_error();
4027 fd1dff4b bellard
            if (err == EINTR || err == EWOULDBLOCK) {
4028 fd1dff4b bellard
            } else if (err == EINPROGRESS) {
4029 7c9d8e07 bellard
                break;
4030 f5b12268 ths
#ifdef _WIN32
4031 f5b12268 ths
            } else if (err == WSAEALREADY) {
4032 f5b12268 ths
                break;
4033 f5b12268 ths
#endif
4034 7c9d8e07 bellard
            } else {
4035 7c9d8e07 bellard
                perror("connect");
4036 fd1dff4b bellard
                closesocket(fd);
4037 7c9d8e07 bellard
                return -1;
4038 7c9d8e07 bellard
            }
4039 7c9d8e07 bellard
        } else {
4040 7c9d8e07 bellard
            connected = 1;
4041 7c9d8e07 bellard
            break;
4042 7c9d8e07 bellard
        }
4043 7c9d8e07 bellard
    }
4044 7c9d8e07 bellard
    s = net_socket_fd_init(vlan, fd, connected);
4045 7c9d8e07 bellard
    if (!s)
4046 7c9d8e07 bellard
        return -1;
4047 7c9d8e07 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4048 7c9d8e07 bellard
             "socket: connect to %s:%d", 
4049 7c9d8e07 bellard
             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4050 c20709aa bellard
    return 0;
4051 80cabfad bellard
}
4052 330d0414 bellard
4053 3d830459 bellard
static int net_socket_mcast_init(VLANState *vlan, const char *host_str)
4054 3d830459 bellard
{
4055 3d830459 bellard
    NetSocketState *s;
4056 3d830459 bellard
    int fd;
4057 3d830459 bellard
    struct sockaddr_in saddr;
4058 3d830459 bellard
4059 3d830459 bellard
    if (parse_host_port(&saddr, host_str) < 0)
4060 3d830459 bellard
        return -1;
4061 3d830459 bellard
4062 3d830459 bellard
4063 3d830459 bellard
    fd = net_socket_mcast_create(&saddr);
4064 3d830459 bellard
    if (fd < 0)
4065 3d830459 bellard
        return -1;
4066 3d830459 bellard
4067 3d830459 bellard
    s = net_socket_fd_init(vlan, fd, 0);
4068 3d830459 bellard
    if (!s)
4069 3d830459 bellard
        return -1;
4070 3d830459 bellard
4071 3d830459 bellard
    s->dgram_dst = saddr;
4072 3d830459 bellard
    
4073 3d830459 bellard
    snprintf(s->vc->info_str, sizeof(s->vc->info_str),
4074 3d830459 bellard
             "socket: mcast=%s:%d", 
4075 3d830459 bellard
             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
4076 3d830459 bellard
    return 0;
4077 3d830459 bellard
4078 3d830459 bellard
}
4079 3d830459 bellard
4080 7c9d8e07 bellard
static int get_param_value(char *buf, int buf_size,
4081 7c9d8e07 bellard
                           const char *tag, const char *str)
4082 7c9d8e07 bellard
{
4083 7c9d8e07 bellard
    const char *p;
4084 7c9d8e07 bellard
    char *q;
4085 7c9d8e07 bellard
    char option[128];
4086 7c9d8e07 bellard
4087 7c9d8e07 bellard
    p = str;
4088 7c9d8e07 bellard
    for(;;) {
4089 7c9d8e07 bellard
        q = option;
4090 7c9d8e07 bellard
        while (*p != '\0' && *p != '=') {
4091 7c9d8e07 bellard
            if ((q - option) < sizeof(option) - 1)
4092 7c9d8e07 bellard
                *q++ = *p;
4093 7c9d8e07 bellard
            p++;
4094 7c9d8e07 bellard
        }
4095 7c9d8e07 bellard
        *q = '\0';
4096 7c9d8e07 bellard
        if (*p != '=')
4097 7c9d8e07 bellard
            break;
4098 7c9d8e07 bellard
        p++;
4099 7c9d8e07 bellard
        if (!strcmp(tag, option)) {
4100 7c9d8e07 bellard
            q = buf;
4101 7c9d8e07 bellard
            while (*p != '\0' && *p != ',') {
4102 7c9d8e07 bellard
                if ((q - buf) < buf_size - 1)
4103 7c9d8e07 bellard
                    *q++ = *p;
4104 7c9d8e07 bellard
                p++;
4105 7c9d8e07 bellard
            }
4106 7c9d8e07 bellard
            *q = '\0';
4107 7c9d8e07 bellard
            return q - buf;
4108 7c9d8e07 bellard
        } else {
4109 7c9d8e07 bellard
            while (*p != '\0' && *p != ',') {
4110 7c9d8e07 bellard
                p++;
4111 7c9d8e07 bellard
            }
4112 7c9d8e07 bellard
        }
4113 7c9d8e07 bellard
        if (*p != ',')
4114 7c9d8e07 bellard
            break;
4115 7c9d8e07 bellard
        p++;
4116 7c9d8e07 bellard
    }
4117 7c9d8e07 bellard
    return 0;
4118 7c9d8e07 bellard
}
4119 7c9d8e07 bellard
4120 52f61fde ths
static int net_client_init(const char *str)
4121 7c9d8e07 bellard
{
4122 7c9d8e07 bellard
    const char *p;
4123 7c9d8e07 bellard
    char *q;
4124 7c9d8e07 bellard
    char device[64];
4125 7c9d8e07 bellard
    char buf[1024];
4126 7c9d8e07 bellard
    int vlan_id, ret;
4127 7c9d8e07 bellard
    VLANState *vlan;
4128 7c9d8e07 bellard
4129 7c9d8e07 bellard
    p = str;
4130 7c9d8e07 bellard
    q = device;
4131 7c9d8e07 bellard
    while (*p != '\0' && *p != ',') {
4132 7c9d8e07 bellard
        if ((q - device) < sizeof(device) - 1)
4133 7c9d8e07 bellard
            *q++ = *p;
4134 7c9d8e07 bellard
        p++;
4135 7c9d8e07 bellard
    }
4136 7c9d8e07 bellard
    *q = '\0';
4137 7c9d8e07 bellard
    if (*p == ',')
4138 7c9d8e07 bellard
        p++;
4139 7c9d8e07 bellard
    vlan_id = 0;
4140 7c9d8e07 bellard
    if (get_param_value(buf, sizeof(buf), "vlan", p)) {
4141 7c9d8e07 bellard
        vlan_id = strtol(buf, NULL, 0);
4142 7c9d8e07 bellard
    }
4143 7c9d8e07 bellard
    vlan = qemu_find_vlan(vlan_id);
4144 7c9d8e07 bellard
    if (!vlan) {
4145 7c9d8e07 bellard
        fprintf(stderr, "Could not create vlan %d\n", vlan_id);
4146 7c9d8e07 bellard
        return -1;
4147 7c9d8e07 bellard
    }
4148 7c9d8e07 bellard
    if (!strcmp(device, "nic")) {
4149 7c9d8e07 bellard
        NICInfo *nd;
4150 7c9d8e07 bellard
        uint8_t *macaddr;
4151 7c9d8e07 bellard
4152 7c9d8e07 bellard
        if (nb_nics >= MAX_NICS) {
4153 7c9d8e07 bellard
            fprintf(stderr, "Too Many NICs\n");
4154 7c9d8e07 bellard
            return -1;
4155 7c9d8e07 bellard
        }
4156 7c9d8e07 bellard
        nd = &nd_table[nb_nics];
4157 7c9d8e07 bellard
        macaddr = nd->macaddr;
4158 7c9d8e07 bellard
        macaddr[0] = 0x52;
4159 7c9d8e07 bellard
        macaddr[1] = 0x54;
4160 7c9d8e07 bellard
        macaddr[2] = 0x00;
4161 7c9d8e07 bellard
        macaddr[3] = 0x12;
4162 7c9d8e07 bellard
        macaddr[4] = 0x34;
4163 7c9d8e07 bellard
        macaddr[5] = 0x56 + nb_nics;
4164 7c9d8e07 bellard
4165 7c9d8e07 bellard
        if (get_param_value(buf, sizeof(buf), "macaddr", p)) {
4166 7c9d8e07 bellard
            if (parse_macaddr(macaddr, buf) < 0) {
4167 7c9d8e07 bellard
                fprintf(stderr, "invalid syntax for ethernet address\n");
4168 7c9d8e07 bellard
                return -1;
4169 7c9d8e07 bellard
            }
4170 7c9d8e07 bellard
        }
4171 a41b2ff2 pbrook
        if (get_param_value(buf, sizeof(buf), "model", p)) {
4172 a41b2ff2 pbrook
            nd->model = strdup(buf);
4173 a41b2ff2 pbrook
        }
4174 7c9d8e07 bellard
        nd->vlan = vlan;
4175 7c9d8e07 bellard
        nb_nics++;
4176 7c9d8e07 bellard
        ret = 0;
4177 7c9d8e07 bellard
    } else
4178 7c9d8e07 bellard
    if (!strcmp(device, "none")) {
4179 7c9d8e07 bellard
        /* does nothing. It is needed to signal that no network cards
4180 7c9d8e07 bellard
           are wanted */
4181 7c9d8e07 bellard
        ret = 0;
4182 7c9d8e07 bellard
    } else
4183 7c9d8e07 bellard
#ifdef CONFIG_SLIRP
4184 7c9d8e07 bellard
    if (!strcmp(device, "user")) {
4185 115defd1 pbrook
        if (get_param_value(buf, sizeof(buf), "hostname", p)) {
4186 3f423c9c bellard
            pstrcpy(slirp_hostname, sizeof(slirp_hostname), buf);
4187 115defd1 pbrook
        }
4188 7c9d8e07 bellard
        ret = net_slirp_init(vlan);
4189 7c9d8e07 bellard
    } else
4190 7c9d8e07 bellard
#endif
4191 7fb843f8 bellard
#ifdef _WIN32
4192 7fb843f8 bellard
    if (!strcmp(device, "tap")) {
4193 7fb843f8 bellard
        char ifname[64];
4194 7fb843f8 bellard
        if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
4195 7fb843f8 bellard
            fprintf(stderr, "tap: no interface name\n");
4196 7fb843f8 bellard
            return -1;
4197 7fb843f8 bellard
        }
4198 7fb843f8 bellard
        ret = tap_win32_init(vlan, ifname);
4199 7fb843f8 bellard
    } else
4200 7fb843f8 bellard
#else
4201 7c9d8e07 bellard
    if (!strcmp(device, "tap")) {
4202 7c9d8e07 bellard
        char ifname[64];
4203 7c9d8e07 bellard
        char setup_script[1024];
4204 7c9d8e07 bellard
        int fd;
4205 7c9d8e07 bellard
        if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
4206 7c9d8e07 bellard
            fd = strtol(buf, NULL, 0);
4207 7c9d8e07 bellard
            ret = -1;
4208 7c9d8e07 bellard
            if (net_tap_fd_init(vlan, fd))
4209 7c9d8e07 bellard
                ret = 0;
4210 7c9d8e07 bellard
        } else {
4211 bf8c5342 bellard
            if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
4212 bf8c5342 bellard
                ifname[0] = '\0';
4213 bf8c5342 bellard
            }
4214 7c9d8e07 bellard
            if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
4215 7c9d8e07 bellard
                pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
4216 7c9d8e07 bellard
            }
4217 7c9d8e07 bellard
            ret = net_tap_init(vlan, ifname, setup_script);
4218 7c9d8e07 bellard
        }
4219 7c9d8e07 bellard
    } else
4220 fd1dff4b bellard
#endif
4221 7c9d8e07 bellard
    if (!strcmp(device, "socket")) {
4222 7c9d8e07 bellard
        if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
4223 7c9d8e07 bellard
            int fd;
4224 7c9d8e07 bellard
            fd = strtol(buf, NULL, 0);
4225 7c9d8e07 bellard
            ret = -1;
4226 7c9d8e07 bellard
            if (net_socket_fd_init(vlan, fd, 1))
4227 7c9d8e07 bellard
                ret = 0;
4228 7c9d8e07 bellard
        } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {
4229 7c9d8e07 bellard
            ret = net_socket_listen_init(vlan, buf);
4230 7c9d8e07 bellard
        } else if (get_param_value(buf, sizeof(buf), "connect", p) > 0) {
4231 7c9d8e07 bellard
            ret = net_socket_connect_init(vlan, buf);
4232 3d830459 bellard
        } else if (get_param_value(buf, sizeof(buf), "mcast", p) > 0) {
4233 3d830459 bellard
            ret = net_socket_mcast_init(vlan, buf);
4234 7c9d8e07 bellard
        } else {
4235 7c9d8e07 bellard
            fprintf(stderr, "Unknown socket options: %s\n", p);
4236 7c9d8e07 bellard
            return -1;
4237 7c9d8e07 bellard
        }
4238 7c9d8e07 bellard
    } else
4239 7c9d8e07 bellard
    {
4240 7c9d8e07 bellard
        fprintf(stderr, "Unknown network device: %s\n", device);
4241 7c9d8e07 bellard
        return -1;
4242 7c9d8e07 bellard
    }
4243 7c9d8e07 bellard
    if (ret < 0) {
4244 7c9d8e07 bellard
        fprintf(stderr, "Could not initialize device '%s'\n", device);
4245 7c9d8e07 bellard
    }
4246 7c9d8e07 bellard
    
4247 7c9d8e07 bellard
    return ret;
4248 7c9d8e07 bellard
}
4249 7c9d8e07 bellard
4250 7c9d8e07 bellard
void do_info_network(void)
4251 7c9d8e07 bellard
{
4252 7c9d8e07 bellard
    VLANState *vlan;
4253 7c9d8e07 bellard
    VLANClientState *vc;
4254 7c9d8e07 bellard
4255 7c9d8e07 bellard
    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {
4256 7c9d8e07 bellard
        term_printf("VLAN %d devices:\n", vlan->id);
4257 7c9d8e07 bellard
        for(vc = vlan->first_client; vc != NULL; vc = vc->next)
4258 7c9d8e07 bellard
            term_printf("  %s\n", vc->info_str);
4259 7c9d8e07 bellard
    }
4260 7c9d8e07 bellard
}
4261 42550fde ths
4262 330d0414 bellard
/***********************************************************/
4263 a594cfbf bellard
/* USB devices */
4264 a594cfbf bellard
4265 0d92ed30 pbrook
static USBPort *used_usb_ports;
4266 0d92ed30 pbrook
static USBPort *free_usb_ports;
4267 0d92ed30 pbrook
4268 0d92ed30 pbrook
/* ??? Maybe change this to register a hub to keep track of the topology.  */
4269 0d92ed30 pbrook
void qemu_register_usb_port(USBPort *port, void *opaque, int index,
4270 0d92ed30 pbrook
                            usb_attachfn attach)
4271 0d92ed30 pbrook
{
4272 0d92ed30 pbrook
    port->opaque = opaque;
4273 0d92ed30 pbrook
    port->index = index;
4274 0d92ed30 pbrook
    port->attach = attach;
4275 0d92ed30 pbrook
    port->next = free_usb_ports;
4276 0d92ed30 pbrook
    free_usb_ports = port;
4277 0d92ed30 pbrook
}
4278 0d92ed30 pbrook
4279 a594cfbf bellard
static int usb_device_add(const char *devname)
4280 a594cfbf bellard
{
4281 a594cfbf bellard
    const char *p;
4282 a594cfbf bellard
    USBDevice *dev;
4283 0d92ed30 pbrook
    USBPort *port;
4284 a594cfbf bellard
4285 0d92ed30 pbrook
    if (!free_usb_ports)
4286 a594cfbf bellard
        return -1;
4287 a594cfbf bellard
4288 a594cfbf bellard
    if (strstart(devname, "host:", &p)) {
4289 a594cfbf bellard
        dev = usb_host_device_open(p);
4290 a594cfbf bellard
    } else if (!strcmp(devname, "mouse")) {
4291 a594cfbf bellard
        dev = usb_mouse_init();
4292 09b26c5e bellard
    } else if (!strcmp(devname, "tablet")) {
4293 09b26c5e bellard
        dev = usb_tablet_init();
4294 2e5d83bb pbrook
    } else if (strstart(devname, "disk:", &p)) {
4295 2e5d83bb pbrook
        dev = usb_msd_init(p);
4296 a594cfbf bellard
    } else {
4297 a594cfbf bellard
        return -1;
4298 a594cfbf bellard
    }
4299 0d92ed30 pbrook
    if (!dev)
4300 0d92ed30 pbrook
        return -1;
4301 0d92ed30 pbrook
4302 0d92ed30 pbrook
    /* Find a USB port to add the device to.  */
4303 0d92ed30 pbrook
    port = free_usb_ports;
4304 0d92ed30 pbrook
    if (!port->next) {
4305 0d92ed30 pbrook
        USBDevice *hub;
4306 0d92ed30 pbrook
4307 0d92ed30 pbrook
        /* Create a new hub and chain it on.  */
4308 0d92ed30 pbrook
        free_usb_ports = NULL;
4309 0d92ed30 pbrook
        port->next = used_usb_ports;
4310 0d92ed30 pbrook
        used_usb_ports = port;
4311 0d92ed30 pbrook
4312 0d92ed30 pbrook
        hub = usb_hub_init(VM_USB_HUB_SIZE);
4313 0d92ed30 pbrook
        usb_attach(port, hub);
4314 0d92ed30 pbrook
        port = free_usb_ports;
4315 0d92ed30 pbrook
    }
4316 0d92ed30 pbrook
4317 0d92ed30 pbrook
    free_usb_ports = port->next;
4318 0d92ed30 pbrook
    port->next = used_usb_ports;
4319 0d92ed30 pbrook
    used_usb_ports = port;
4320 0d92ed30 pbrook
    usb_attach(port, dev);
4321 a594cfbf bellard
    return 0;
4322 a594cfbf bellard
}
4323 a594cfbf bellard
4324 a594cfbf bellard
static int usb_device_del(const char *devname)
4325 a594cfbf bellard
{
4326 0d92ed30 pbrook
    USBPort *port;
4327 0d92ed30 pbrook
    USBPort **lastp;
4328 059809e4 bellard
    USBDevice *dev;
4329 0d92ed30 pbrook
    int bus_num, addr;
4330 a594cfbf bellard
    const char *p;
4331 a594cfbf bellard
4332 0d92ed30 pbrook
    if (!used_usb_ports)
4333 a594cfbf bellard
        return -1;
4334 a594cfbf bellard
4335 a594cfbf bellard
    p = strchr(devname, '.');
4336 a594cfbf bellard
    if (!p) 
4337 a594cfbf bellard
        return -1;
4338 a594cfbf bellard
    bus_num = strtoul(devname, NULL, 0);
4339 a594cfbf bellard
    addr = strtoul(p + 1, NULL, 0);
4340 a594cfbf bellard
    if (bus_num != 0)
4341 a594cfbf bellard
        return -1;
4342 0d92ed30 pbrook
4343 0d92ed30 pbrook
    lastp = &used_usb_ports;
4344 0d92ed30 pbrook
    port = used_usb_ports;
4345 0d92ed30 pbrook
    while (port && port->dev->addr != addr) {
4346 0d92ed30 pbrook
        lastp = &port->next;
4347 0d92ed30 pbrook
        port = port->next;
4348 a594cfbf bellard
    }
4349 0d92ed30 pbrook
4350 0d92ed30 pbrook
    if (!port)
4351 a594cfbf bellard
        return -1;
4352 0d92ed30 pbrook
4353 059809e4 bellard
    dev = port->dev;
4354 0d92ed30 pbrook
    *lastp = port->next;
4355 0d92ed30 pbrook
    usb_attach(port, NULL);
4356 059809e4 bellard
    dev->handle_destroy(dev);
4357 0d92ed30 pbrook
    port->next = free_usb_ports;
4358 0d92ed30 pbrook
    free_usb_ports = port;
4359 a594cfbf bellard
    return 0;
4360 a594cfbf bellard
}
4361 a594cfbf bellard
4362 a594cfbf bellard
void do_usb_add(const char *devname)
4363 a594cfbf bellard
{
4364 a594cfbf bellard
    int ret;
4365 a594cfbf bellard
    ret = usb_device_add(devname);
4366 a594cfbf bellard
    if (ret < 0) 
4367 a594cfbf bellard
        term_printf("Could not add USB device '%s'\n", devname);
4368 a594cfbf bellard
}
4369 a594cfbf bellard
4370 a594cfbf bellard
void do_usb_del(const char *devname)
4371 a594cfbf bellard
{
4372 a594cfbf bellard
    int ret;
4373 a594cfbf bellard
    ret = usb_device_del(devname);
4374 a594cfbf bellard
    if (ret < 0) 
4375 a594cfbf bellard
        term_printf("Could not remove USB device '%s'\n", devname);
4376 a594cfbf bellard
}
4377 a594cfbf bellard
4378 a594cfbf bellard
void usb_info(void)
4379 a594cfbf bellard
{
4380 a594cfbf bellard
    USBDevice *dev;
4381 0d92ed30 pbrook
    USBPort *port;
4382 a594cfbf bellard
    const char *speed_str;
4383 a594cfbf bellard
4384 0d92ed30 pbrook
    if (!usb_enabled) {
4385 a594cfbf bellard
        term_printf("USB support not enabled\n");
4386 a594cfbf bellard
        return;
4387 a594cfbf bellard
    }
4388 a594cfbf bellard
4389 0d92ed30 pbrook
    for (port = used_usb_ports; port; port = port->next) {
4390 0d92ed30 pbrook
        dev = port->dev;
4391 0d92ed30 pbrook
        if (!dev)
4392 0d92ed30 pbrook
            continue;
4393 0d92ed30 pbrook
        switch(dev->speed) {
4394 0d92ed30 pbrook
        case USB_SPEED_LOW: 
4395 0d92ed30 pbrook
            speed_str = "1.5"; 
4396 0d92ed30 pbrook
            break;
4397 0d92ed30 pbrook
        case USB_SPEED_FULL: 
4398 0d92ed30 pbrook
            speed_str = "12"; 
4399 0d92ed30 pbrook
            break;
4400 0d92ed30 pbrook
        case USB_SPEED_HIGH: 
4401 0d92ed30 pbrook
            speed_str = "480"; 
4402 0d92ed30 pbrook
            break;
4403 0d92ed30 pbrook
        default:
4404 0d92ed30 pbrook
            speed_str = "?"; 
4405 0d92ed30 pbrook
            break;
4406 a594cfbf bellard
        }
4407 1f6e24e7 bellard
        term_printf("  Device %d.%d, Speed %s Mb/s, Product %s\n", 
4408 1f6e24e7 bellard
                    0, dev->addr, speed_str, dev->devname);
4409 a594cfbf bellard
    }
4410 a594cfbf bellard
}
4411 a594cfbf bellard
4412 f7cce898 bellard
/***********************************************************/
4413 313aa567 bellard
/* dumb display */
4414 313aa567 bellard
4415 313aa567 bellard
static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
4416 313aa567 bellard
{
4417 313aa567 bellard
}
4418 313aa567 bellard
4419 313aa567 bellard
static void dumb_resize(DisplayState *ds, int w, int h)
4420 313aa567 bellard
{
4421 313aa567 bellard
}
4422 313aa567 bellard
4423 313aa567 bellard
static void dumb_refresh(DisplayState *ds)
4424 313aa567 bellard
{
4425 95219897 pbrook
    vga_hw_update();
4426 313aa567 bellard
}
4427 313aa567 bellard
4428 313aa567 bellard
void dumb_display_init(DisplayState *ds)
4429 313aa567 bellard
{
4430 313aa567 bellard
    ds->data = NULL;
4431 313aa567 bellard
    ds->linesize = 0;
4432 313aa567 bellard
    ds->depth = 0;
4433 313aa567 bellard
    ds->dpy_update = dumb_update;
4434 313aa567 bellard
    ds->dpy_resize = dumb_resize;
4435 313aa567 bellard
    ds->dpy_refresh = dumb_refresh;
4436 313aa567 bellard
}
4437 313aa567 bellard
4438 8a7ddc38 bellard
/***********************************************************/
4439 8a7ddc38 bellard
/* I/O handling */
4440 0824d6fc bellard
4441 c4b1fcc0 bellard
#define MAX_IO_HANDLERS 64
4442 c4b1fcc0 bellard
4443 c4b1fcc0 bellard
typedef struct IOHandlerRecord {
4444 c4b1fcc0 bellard
    int fd;
4445 7c9d8e07 bellard
    IOCanRWHandler *fd_read_poll;
4446 7c9d8e07 bellard
    IOHandler *fd_read;
4447 7c9d8e07 bellard
    IOHandler *fd_write;
4448 cafffd40 ths
    int deleted;
4449 c4b1fcc0 bellard
    void *opaque;
4450 c4b1fcc0 bellard
    /* temporary data */
4451 c4b1fcc0 bellard
    struct pollfd *ufd;
4452 8a7ddc38 bellard
    struct IOHandlerRecord *next;
4453 c4b1fcc0 bellard
} IOHandlerRecord;
4454 c4b1fcc0 bellard
4455 8a7ddc38 bellard
static IOHandlerRecord *first_io_handler;
4456 c4b1fcc0 bellard
4457 7c9d8e07 bellard
/* XXX: fd_read_poll should be suppressed, but an API change is
4458 7c9d8e07 bellard
   necessary in the character devices to suppress fd_can_read(). */
4459 7c9d8e07 bellard
int qemu_set_fd_handler2(int fd, 
4460 7c9d8e07 bellard
                         IOCanRWHandler *fd_read_poll, 
4461 7c9d8e07 bellard
                         IOHandler *fd_read, 
4462 7c9d8e07 bellard
                         IOHandler *fd_write, 
4463 7c9d8e07 bellard
                         void *opaque)
4464 c4b1fcc0 bellard
{
4465 7c9d8e07 bellard
    IOHandlerRecord **pioh, *ioh;
4466 c4b1fcc0 bellard
4467 7c9d8e07 bellard
    if (!fd_read && !fd_write) {
4468 7c9d8e07 bellard
        pioh = &first_io_handler;
4469 7c9d8e07 bellard
        for(;;) {
4470 7c9d8e07 bellard
            ioh = *pioh;
4471 7c9d8e07 bellard
            if (ioh == NULL)
4472 7c9d8e07 bellard
                break;
4473 7c9d8e07 bellard
            if (ioh->fd == fd) {
4474 cafffd40 ths
                ioh->deleted = 1;
4475 7c9d8e07 bellard
                break;
4476 7c9d8e07 bellard
            }
4477 7c9d8e07 bellard
            pioh = &ioh->next;
4478 7c9d8e07 bellard
        }
4479 7c9d8e07 bellard
    } else {
4480 7c9d8e07 bellard
        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
4481 7c9d8e07 bellard
            if (ioh->fd == fd)
4482 7c9d8e07 bellard
                goto found;
4483 7c9d8e07 bellard
        }
4484 7c9d8e07 bellard
        ioh = qemu_mallocz(sizeof(IOHandlerRecord));
4485 7c9d8e07 bellard
        if (!ioh)
4486 7c9d8e07 bellard
            return -1;
4487 7c9d8e07 bellard
        ioh->next = first_io_handler;
4488 7c9d8e07 bellard
        first_io_handler = ioh;
4489 7c9d8e07 bellard
    found:
4490 7c9d8e07 bellard
        ioh->fd = fd;
4491 7c9d8e07 bellard
        ioh->fd_read_poll = fd_read_poll;
4492 7c9d8e07 bellard
        ioh->fd_read = fd_read;
4493 7c9d8e07 bellard
        ioh->fd_write = fd_write;
4494 7c9d8e07 bellard
        ioh->opaque = opaque;
4495 cafffd40 ths
        ioh->deleted = 0;
4496 7c9d8e07 bellard
    }
4497 c4b1fcc0 bellard
    return 0;
4498 c4b1fcc0 bellard
}
4499 c4b1fcc0 bellard
4500 7c9d8e07 bellard
int qemu_set_fd_handler(int fd, 
4501 7c9d8e07 bellard
                        IOHandler *fd_read, 
4502 7c9d8e07 bellard
                        IOHandler *fd_write, 
4503 7c9d8e07 bellard
                        void *opaque)
4504 8a7ddc38 bellard
{
4505 7c9d8e07 bellard
    return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
4506 8a7ddc38 bellard
}
4507 8a7ddc38 bellard
4508 8a7ddc38 bellard
/***********************************************************/
4509 f331110f bellard
/* Polling handling */
4510 f331110f bellard
4511 f331110f bellard
typedef struct PollingEntry {
4512 f331110f bellard
    PollingFunc *func;
4513 f331110f bellard
    void *opaque;
4514 f331110f bellard
    struct PollingEntry *next;
4515 f331110f bellard
} PollingEntry;
4516 f331110f bellard
4517 f331110f bellard
static PollingEntry *first_polling_entry;
4518 f331110f bellard
4519 f331110f bellard
int qemu_add_polling_cb(PollingFunc *func, void *opaque)
4520 f331110f bellard
{
4521 f331110f bellard
    PollingEntry **ppe, *pe;
4522 f331110f bellard
    pe = qemu_mallocz(sizeof(PollingEntry));
4523 f331110f bellard
    if (!pe)
4524 f331110f bellard
        return -1;
4525 f331110f bellard
    pe->func = func;
4526 f331110f bellard
    pe->opaque = opaque;
4527 f331110f bellard
    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
4528 f331110f bellard
    *ppe = pe;
4529 f331110f bellard
    return 0;
4530 f331110f bellard
}
4531 f331110f bellard
4532 f331110f bellard
void qemu_del_polling_cb(PollingFunc *func, void *opaque)
4533 f331110f bellard
{
4534 f331110f bellard
    PollingEntry **ppe, *pe;
4535 f331110f bellard
    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
4536 f331110f bellard
        pe = *ppe;
4537 f331110f bellard
        if (pe->func == func && pe->opaque == opaque) {
4538 f331110f bellard
            *ppe = pe->next;
4539 f331110f bellard
            qemu_free(pe);
4540 f331110f bellard
            break;
4541 f331110f bellard
        }
4542 f331110f bellard
    }
4543 f331110f bellard
}
4544 f331110f bellard
4545 a18e524a bellard
#ifdef _WIN32
4546 a18e524a bellard
/***********************************************************/
4547 a18e524a bellard
/* Wait objects support */
4548 a18e524a bellard
typedef struct WaitObjects {
4549 a18e524a bellard
    int num;
4550 a18e524a bellard
    HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
4551 a18e524a bellard
    WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
4552 a18e524a bellard
    void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
4553 a18e524a bellard
} WaitObjects;
4554 a18e524a bellard
4555 a18e524a bellard
static WaitObjects wait_objects = {0};
4556 a18e524a bellard
    
4557 a18e524a bellard
int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
4558 a18e524a bellard
{
4559 a18e524a bellard
    WaitObjects *w = &wait_objects;
4560 a18e524a bellard
4561 a18e524a bellard
    if (w->num >= MAXIMUM_WAIT_OBJECTS)
4562 a18e524a bellard
        return -1;
4563 a18e524a bellard
    w->events[w->num] = handle;
4564 a18e524a bellard
    w->func[w->num] = func;
4565 a18e524a bellard
    w->opaque[w->num] = opaque;
4566 a18e524a bellard
    w->num++;
4567 a18e524a bellard
    return 0;
4568 a18e524a bellard
}
4569 a18e524a bellard
4570 a18e524a bellard
void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
4571 a18e524a bellard
{
4572 a18e524a bellard
    int i, found;
4573 a18e524a bellard
    WaitObjects *w = &wait_objects;
4574 a18e524a bellard
4575 a18e524a bellard
    found = 0;
4576 a18e524a bellard
    for (i = 0; i < w->num; i++) {
4577 a18e524a bellard
        if (w->events[i] == handle)
4578 a18e524a bellard
            found = 1;
4579 a18e524a bellard
        if (found) {
4580 a18e524a bellard
            w->events[i] = w->events[i + 1];
4581 a18e524a bellard
            w->func[i] = w->func[i + 1];
4582 a18e524a bellard
            w->opaque[i] = w->opaque[i + 1];
4583 a18e524a bellard
        }            
4584 a18e524a bellard
    }
4585 a18e524a bellard
    if (found)
4586 a18e524a bellard
        w->num--;
4587 a18e524a bellard
}
4588 a18e524a bellard
#endif
4589 a18e524a bellard
4590 f331110f bellard
/***********************************************************/
4591 8a7ddc38 bellard
/* savevm/loadvm support */
4592 8a7ddc38 bellard
4593 faea38e7 bellard
#define IO_BUF_SIZE 32768
4594 faea38e7 bellard
4595 faea38e7 bellard
struct QEMUFile {
4596 faea38e7 bellard
    FILE *outfile;
4597 faea38e7 bellard
    BlockDriverState *bs;
4598 faea38e7 bellard
    int is_file;
4599 faea38e7 bellard
    int is_writable;
4600 faea38e7 bellard
    int64_t base_offset;
4601 faea38e7 bellard
    int64_t buf_offset; /* start of buffer when writing, end of buffer
4602 faea38e7 bellard
                           when reading */
4603 faea38e7 bellard
    int buf_index;
4604 faea38e7 bellard
    int buf_size; /* 0 when writing */
4605 faea38e7 bellard
    uint8_t buf[IO_BUF_SIZE];
4606 faea38e7 bellard
};
4607 faea38e7 bellard
4608 faea38e7 bellard
QEMUFile *qemu_fopen(const char *filename, const char *mode)
4609 faea38e7 bellard
{
4610 faea38e7 bellard
    QEMUFile *f;
4611 faea38e7 bellard
4612 faea38e7 bellard
    f = qemu_mallocz(sizeof(QEMUFile));
4613 faea38e7 bellard
    if (!f)
4614 faea38e7 bellard
        return NULL;
4615 faea38e7 bellard
    if (!strcmp(mode, "wb")) {
4616 faea38e7 bellard
        f->is_writable = 1;
4617 faea38e7 bellard
    } else if (!strcmp(mode, "rb")) {
4618 faea38e7 bellard
        f->is_writable = 0;
4619 faea38e7 bellard
    } else {
4620 faea38e7 bellard
        goto fail;
4621 faea38e7 bellard
    }
4622 faea38e7 bellard
    f->outfile = fopen(filename, mode);
4623 faea38e7 bellard
    if (!f->outfile)
4624 faea38e7 bellard
        goto fail;
4625 faea38e7 bellard
    f->is_file = 1;
4626 faea38e7 bellard
    return f;
4627 faea38e7 bellard
 fail:
4628 faea38e7 bellard
    if (f->outfile)
4629 faea38e7 bellard
        fclose(f->outfile);
4630 faea38e7 bellard
    qemu_free(f);
4631 faea38e7 bellard
    return NULL;
4632 faea38e7 bellard
}
4633 faea38e7 bellard
4634 faea38e7 bellard
QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_writable)
4635 faea38e7 bellard
{
4636 faea38e7 bellard
    QEMUFile *f;
4637 faea38e7 bellard
4638 faea38e7 bellard
    f = qemu_mallocz(sizeof(QEMUFile));
4639 faea38e7 bellard
    if (!f)
4640 faea38e7 bellard
        return NULL;
4641 faea38e7 bellard
    f->is_file = 0;
4642 faea38e7 bellard
    f->bs = bs;
4643 faea38e7 bellard
    f->is_writable = is_writable;
4644 faea38e7 bellard
    f->base_offset = offset;
4645 faea38e7 bellard
    return f;
4646 faea38e7 bellard
}
4647 faea38e7 bellard
4648 faea38e7 bellard
void qemu_fflush(QEMUFile *f)
4649 faea38e7 bellard
{
4650 faea38e7 bellard
    if (!f->is_writable)
4651 faea38e7 bellard
        return;
4652 faea38e7 bellard
    if (f->buf_index > 0) {
4653 faea38e7 bellard
        if (f->is_file) {
4654 faea38e7 bellard
            fseek(f->outfile, f->buf_offset, SEEK_SET);
4655 faea38e7 bellard
            fwrite(f->buf, 1, f->buf_index, f->outfile);
4656 faea38e7 bellard
        } else {
4657 faea38e7 bellard
            bdrv_pwrite(f->bs, f->base_offset + f->buf_offset, 
4658 faea38e7 bellard
                        f->buf, f->buf_index);
4659 faea38e7 bellard
        }
4660 faea38e7 bellard
        f->buf_offset += f->buf_index;
4661 faea38e7 bellard
        f->buf_index = 0;
4662 faea38e7 bellard
    }
4663 faea38e7 bellard
}
4664 faea38e7 bellard
4665 faea38e7 bellard
static void qemu_fill_buffer(QEMUFile *f)
4666 faea38e7 bellard
{
4667 faea38e7 bellard
    int len;
4668 faea38e7 bellard
4669 faea38e7 bellard
    if (f->is_writable)
4670 faea38e7 bellard
        return;
4671 faea38e7 bellard
    if (f->is_file) {
4672 faea38e7 bellard
        fseek(f->outfile, f->buf_offset, SEEK_SET);
4673 faea38e7 bellard
        len = fread(f->buf, 1, IO_BUF_SIZE, f->outfile);
4674 faea38e7 bellard
        if (len < 0)
4675 faea38e7 bellard
            len = 0;
4676 faea38e7 bellard
    } else {
4677 faea38e7 bellard
        len = bdrv_pread(f->bs, f->base_offset + f->buf_offset, 
4678 faea38e7 bellard
                         f->buf, IO_BUF_SIZE);
4679 faea38e7 bellard
        if (len < 0)
4680 faea38e7 bellard
            len = 0;
4681 faea38e7 bellard
    }
4682 faea38e7 bellard
    f->buf_index = 0;
4683 faea38e7 bellard
    f->buf_size = len;
4684 faea38e7 bellard
    f->buf_offset += len;
4685 faea38e7 bellard
}
4686 faea38e7 bellard
4687 faea38e7 bellard
void qemu_fclose(QEMUFile *f)
4688 faea38e7 bellard
{
4689 faea38e7 bellard
    if (f->is_writable)
4690 faea38e7 bellard
        qemu_fflush(f);
4691 faea38e7 bellard
    if (f->is_file) {
4692 faea38e7 bellard
        fclose(f->outfile);
4693 faea38e7 bellard
    }
4694 faea38e7 bellard
    qemu_free(f);
4695 faea38e7 bellard
}
4696 faea38e7 bellard
4697 8a7ddc38 bellard
void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
4698 b4608c04 bellard
{
4699 faea38e7 bellard
    int l;
4700 faea38e7 bellard
    while (size > 0) {
4701 faea38e7 bellard
        l = IO_BUF_SIZE - f->buf_index;
4702 faea38e7 bellard
        if (l > size)
4703 faea38e7 bellard
            l = size;
4704 faea38e7 bellard
        memcpy(f->buf + f->buf_index, buf, l);
4705 faea38e7 bellard
        f->buf_index += l;
4706 faea38e7 bellard
        buf += l;
4707 faea38e7 bellard
        size -= l;
4708 faea38e7 bellard
        if (f->buf_index >= IO_BUF_SIZE)
4709 faea38e7 bellard
            qemu_fflush(f);
4710 faea38e7 bellard
    }
4711 b4608c04 bellard
}
4712 b4608c04 bellard
4713 8a7ddc38 bellard
void qemu_put_byte(QEMUFile *f, int v)
4714 b4608c04 bellard
{
4715 faea38e7 bellard
    f->buf[f->buf_index++] = v;
4716 faea38e7 bellard
    if (f->buf_index >= IO_BUF_SIZE)
4717 faea38e7 bellard
        qemu_fflush(f);
4718 faea38e7 bellard
}
4719 faea38e7 bellard
4720 faea38e7 bellard
int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1)
4721 faea38e7 bellard
{
4722 faea38e7 bellard
    int size, l;
4723 faea38e7 bellard
4724 faea38e7 bellard
    size = size1;
4725 faea38e7 bellard
    while (size > 0) {
4726 faea38e7 bellard
        l = f->buf_size - f->buf_index;
4727 faea38e7 bellard
        if (l == 0) {
4728 faea38e7 bellard
            qemu_fill_buffer(f);
4729 faea38e7 bellard
            l = f->buf_size - f->buf_index;
4730 faea38e7 bellard
            if (l == 0)
4731 faea38e7 bellard
                break;
4732 faea38e7 bellard
        }
4733 faea38e7 bellard
        if (l > size)
4734 faea38e7 bellard
            l = size;
4735 faea38e7 bellard
        memcpy(buf, f->buf + f->buf_index, l);
4736 faea38e7 bellard
        f->buf_index += l;
4737 faea38e7 bellard
        buf += l;
4738 faea38e7 bellard
        size -= l;
4739 faea38e7 bellard
    }
4740 faea38e7 bellard
    return size1 - size;
4741 faea38e7 bellard
}
4742 faea38e7 bellard
4743 faea38e7 bellard
int qemu_get_byte(QEMUFile *f)
4744 faea38e7 bellard
{
4745 faea38e7 bellard
    if (f->buf_index >= f->buf_size) {
4746 faea38e7 bellard
        qemu_fill_buffer(f);
4747 faea38e7 bellard
        if (f->buf_index >= f->buf_size)
4748 faea38e7 bellard
            return 0;
4749 faea38e7 bellard
    }
4750 faea38e7 bellard
    return f->buf[f->buf_index++];
4751 faea38e7 bellard
}
4752 faea38e7 bellard
4753 faea38e7 bellard
int64_t qemu_ftell(QEMUFile *f)
4754 faea38e7 bellard
{
4755 faea38e7 bellard
    return f->buf_offset - f->buf_size + f->buf_index;
4756 faea38e7 bellard
}
4757 faea38e7 bellard
4758 faea38e7 bellard
int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
4759 faea38e7 bellard
{
4760 faea38e7 bellard
    if (whence == SEEK_SET) {
4761 faea38e7 bellard
        /* nothing to do */
4762 faea38e7 bellard
    } else if (whence == SEEK_CUR) {
4763 faea38e7 bellard
        pos += qemu_ftell(f);
4764 faea38e7 bellard
    } else {
4765 faea38e7 bellard
        /* SEEK_END not supported */
4766 faea38e7 bellard
        return -1;
4767 faea38e7 bellard
    }
4768 faea38e7 bellard
    if (f->is_writable) {
4769 faea38e7 bellard
        qemu_fflush(f);
4770 faea38e7 bellard
        f->buf_offset = pos;
4771 faea38e7 bellard
    } else {
4772 faea38e7 bellard
        f->buf_offset = pos;
4773 faea38e7 bellard
        f->buf_index = 0;
4774 faea38e7 bellard
        f->buf_size = 0;
4775 faea38e7 bellard
    }
4776 faea38e7 bellard
    return pos;
4777 8a7ddc38 bellard
}
4778 8a7ddc38 bellard
4779 8a7ddc38 bellard
void qemu_put_be16(QEMUFile *f, unsigned int v)
4780 8a7ddc38 bellard
{
4781 8a7ddc38 bellard
    qemu_put_byte(f, v >> 8);
4782 8a7ddc38 bellard
    qemu_put_byte(f, v);
4783 8a7ddc38 bellard
}
4784 8a7ddc38 bellard
4785 8a7ddc38 bellard
void qemu_put_be32(QEMUFile *f, unsigned int v)
4786 8a7ddc38 bellard
{
4787 8a7ddc38 bellard
    qemu_put_byte(f, v >> 24);
4788 8a7ddc38 bellard
    qemu_put_byte(f, v >> 16);
4789 8a7ddc38 bellard
    qemu_put_byte(f, v >> 8);
4790 8a7ddc38 bellard
    qemu_put_byte(f, v);
4791 8a7ddc38 bellard
}
4792 8a7ddc38 bellard
4793 8a7ddc38 bellard
void qemu_put_be64(QEMUFile *f, uint64_t v)
4794 8a7ddc38 bellard
{
4795 8a7ddc38 bellard
    qemu_put_be32(f, v >> 32);
4796 8a7ddc38 bellard
    qemu_put_be32(f, v);
4797 8a7ddc38 bellard
}
4798 8a7ddc38 bellard
4799 8a7ddc38 bellard
unsigned int qemu_get_be16(QEMUFile *f)
4800 8a7ddc38 bellard
{
4801 8a7ddc38 bellard
    unsigned int v;
4802 8a7ddc38 bellard
    v = qemu_get_byte(f) << 8;
4803 8a7ddc38 bellard
    v |= qemu_get_byte(f);
4804 8a7ddc38 bellard
    return v;
4805 8a7ddc38 bellard
}
4806 8a7ddc38 bellard
4807 8a7ddc38 bellard
unsigned int qemu_get_be32(QEMUFile *f)
4808 8a7ddc38 bellard
{
4809 8a7ddc38 bellard
    unsigned int v;
4810 8a7ddc38 bellard
    v = qemu_get_byte(f) << 24;
4811 8a7ddc38 bellard
    v |= qemu_get_byte(f) << 16;
4812 8a7ddc38 bellard
    v |= qemu_get_byte(f) << 8;
4813 8a7ddc38 bellard
    v |= qemu_get_byte(f);
4814 8a7ddc38 bellard
    return v;
4815 8a7ddc38 bellard
}
4816 8a7ddc38 bellard
4817 8a7ddc38 bellard
uint64_t qemu_get_be64(QEMUFile *f)
4818 8a7ddc38 bellard
{
4819 8a7ddc38 bellard
    uint64_t v;
4820 8a7ddc38 bellard
    v = (uint64_t)qemu_get_be32(f) << 32;
4821 8a7ddc38 bellard
    v |= qemu_get_be32(f);
4822 8a7ddc38 bellard
    return v;
4823 8a7ddc38 bellard
}
4824 8a7ddc38 bellard
4825 8a7ddc38 bellard
typedef struct SaveStateEntry {
4826 8a7ddc38 bellard
    char idstr[256];
4827 8a7ddc38 bellard
    int instance_id;
4828 8a7ddc38 bellard
    int version_id;
4829 8a7ddc38 bellard
    SaveStateHandler *save_state;
4830 8a7ddc38 bellard
    LoadStateHandler *load_state;
4831 8a7ddc38 bellard
    void *opaque;
4832 8a7ddc38 bellard
    struct SaveStateEntry *next;
4833 8a7ddc38 bellard
} SaveStateEntry;
4834 b4608c04 bellard
4835 8a7ddc38 bellard
static SaveStateEntry *first_se;
4836 8a7ddc38 bellard
4837 8a7ddc38 bellard
int register_savevm(const char *idstr, 
4838 8a7ddc38 bellard
                    int instance_id, 
4839 8a7ddc38 bellard
                    int version_id,
4840 8a7ddc38 bellard
                    SaveStateHandler *save_state,
4841 8a7ddc38 bellard
                    LoadStateHandler *load_state,
4842 8a7ddc38 bellard
                    void *opaque)
4843 8a7ddc38 bellard
{
4844 8a7ddc38 bellard
    SaveStateEntry *se, **pse;
4845 8a7ddc38 bellard
4846 8a7ddc38 bellard
    se = qemu_malloc(sizeof(SaveStateEntry));
4847 8a7ddc38 bellard
    if (!se)
4848 8a7ddc38 bellard
        return -1;
4849 8a7ddc38 bellard
    pstrcpy(se->idstr, sizeof(se->idstr), idstr);
4850 8a7ddc38 bellard
    se->instance_id = instance_id;
4851 8a7ddc38 bellard
    se->version_id = version_id;
4852 8a7ddc38 bellard
    se->save_state = save_state;
4853 8a7ddc38 bellard
    se->load_state = load_state;
4854 8a7ddc38 bellard
    se->opaque = opaque;
4855 8a7ddc38 bellard
    se->next = NULL;
4856 8a7ddc38 bellard
4857 8a7ddc38 bellard
    /* add at the end of list */
4858 8a7ddc38 bellard
    pse = &first_se;
4859 8a7ddc38 bellard
    while (*pse != NULL)
4860 8a7ddc38 bellard
        pse = &(*pse)->next;
4861 8a7ddc38 bellard
    *pse = se;
4862 8a7ddc38 bellard
    return 0;
4863 8a7ddc38 bellard
}
4864 8a7ddc38 bellard
4865 8a7ddc38 bellard
#define QEMU_VM_FILE_MAGIC   0x5145564d
4866 faea38e7 bellard
#define QEMU_VM_FILE_VERSION 0x00000002
4867 8a7ddc38 bellard
4868 faea38e7 bellard
int qemu_savevm_state(QEMUFile *f)
4869 8a7ddc38 bellard
{
4870 8a7ddc38 bellard
    SaveStateEntry *se;
4871 faea38e7 bellard
    int len, ret;
4872 faea38e7 bellard
    int64_t cur_pos, len_pos, total_len_pos;
4873 313aa567 bellard
4874 8a7ddc38 bellard
    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
4875 8a7ddc38 bellard
    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
4876 faea38e7 bellard
    total_len_pos = qemu_ftell(f);
4877 faea38e7 bellard
    qemu_put_be64(f, 0); /* total size */
4878 8a7ddc38 bellard
4879 8a7ddc38 bellard
    for(se = first_se; se != NULL; se = se->next) {
4880 8a7ddc38 bellard
        /* ID string */
4881 8a7ddc38 bellard
        len = strlen(se->idstr);
4882 8a7ddc38 bellard
        qemu_put_byte(f, len);
4883 8a7ddc38 bellard
        qemu_put_buffer(f, se->idstr, len);
4884 8a7ddc38 bellard
4885 8a7ddc38 bellard
        qemu_put_be32(f, se->instance_id);
4886 8a7ddc38 bellard
        qemu_put_be32(f, se->version_id);
4887 8a7ddc38 bellard
4888 8a7ddc38 bellard
        /* record size: filled later */
4889 faea38e7 bellard
        len_pos = qemu_ftell(f);
4890 8a7ddc38 bellard
        qemu_put_be32(f, 0);
4891 8a7ddc38 bellard
        
4892 8a7ddc38 bellard
        se->save_state(f, se->opaque);
4893 8a7ddc38 bellard
4894 8a7ddc38 bellard
        /* fill record size */
4895 faea38e7 bellard
        cur_pos = qemu_ftell(f);
4896 faea38e7 bellard
        len = cur_pos - len_pos - 4;
4897 faea38e7 bellard
        qemu_fseek(f, len_pos, SEEK_SET);
4898 8a7ddc38 bellard
        qemu_put_be32(f, len);
4899 faea38e7 bellard
        qemu_fseek(f, cur_pos, SEEK_SET);
4900 8a7ddc38 bellard
    }
4901 faea38e7 bellard
    cur_pos = qemu_ftell(f);
4902 faea38e7 bellard
    qemu_fseek(f, total_len_pos, SEEK_SET);
4903 faea38e7 bellard
    qemu_put_be64(f, cur_pos - total_len_pos - 8);
4904 faea38e7 bellard
    qemu_fseek(f, cur_pos, SEEK_SET);
4905 8a7ddc38 bellard
4906 8a7ddc38 bellard
    ret = 0;
4907 8a7ddc38 bellard
    return ret;
4908 8a7ddc38 bellard
}
4909 8a7ddc38 bellard
4910 8a7ddc38 bellard
static SaveStateEntry *find_se(const char *idstr, int instance_id)
4911 8a7ddc38 bellard
{
4912 8a7ddc38 bellard
    SaveStateEntry *se;
4913 8a7ddc38 bellard
4914 8a7ddc38 bellard
    for(se = first_se; se != NULL; se = se->next) {
4915 8a7ddc38 bellard
        if (!strcmp(se->idstr, idstr) && 
4916 8a7ddc38 bellard
            instance_id == se->instance_id)
4917 8a7ddc38 bellard
            return se;
4918 8a7ddc38 bellard
    }
4919 8a7ddc38 bellard
    return NULL;
4920 8a7ddc38 bellard
}
4921 8a7ddc38 bellard
4922 faea38e7 bellard
int qemu_loadvm_state(QEMUFile *f)
4923 8a7ddc38 bellard
{
4924 8a7ddc38 bellard
    SaveStateEntry *se;
4925 faea38e7 bellard
    int len, ret, instance_id, record_len, version_id;
4926 faea38e7 bellard
    int64_t total_len, end_pos, cur_pos;
4927 8a7ddc38 bellard
    unsigned int v;
4928 8a7ddc38 bellard
    char idstr[256];
4929 8a7ddc38 bellard
    
4930 8a7ddc38 bellard
    v = qemu_get_be32(f);
4931 8a7ddc38 bellard
    if (v != QEMU_VM_FILE_MAGIC)
4932 8a7ddc38 bellard
        goto fail;
4933 8a7ddc38 bellard
    v = qemu_get_be32(f);
4934 8a7ddc38 bellard
    if (v != QEMU_VM_FILE_VERSION) {
4935 8a7ddc38 bellard
    fail:
4936 8a7ddc38 bellard
        ret = -1;
4937 8a7ddc38 bellard
        goto the_end;
4938 8a7ddc38 bellard
    }
4939 faea38e7 bellard
    total_len = qemu_get_be64(f);
4940 faea38e7 bellard
    end_pos = total_len + qemu_ftell(f);
4941 b4608c04 bellard
    for(;;) {
4942 faea38e7 bellard
        if (qemu_ftell(f) >= end_pos)
4943 cd4c3e88 bellard
            break;
4944 faea38e7 bellard
        len = qemu_get_byte(f);
4945 8a7ddc38 bellard
        qemu_get_buffer(f, idstr, len);
4946 8a7ddc38 bellard
        idstr[len] = '\0';
4947 8a7ddc38 bellard
        instance_id = qemu_get_be32(f);
4948 8a7ddc38 bellard
        version_id = qemu_get_be32(f);
4949 8a7ddc38 bellard
        record_len = qemu_get_be32(f);
4950 8a7ddc38 bellard
#if 0
4951 8a7ddc38 bellard
        printf("idstr=%s instance=0x%x version=%d len=%d\n", 
4952 8a7ddc38 bellard
               idstr, instance_id, version_id, record_len);
4953 8a7ddc38 bellard
#endif
4954 faea38e7 bellard
        cur_pos = qemu_ftell(f);
4955 8a7ddc38 bellard
        se = find_se(idstr, instance_id);
4956 8a7ddc38 bellard
        if (!se) {
4957 8a7ddc38 bellard
            fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n", 
4958 8a7ddc38 bellard
                    instance_id, idstr);
4959 8a7ddc38 bellard
        } else {
4960 8a7ddc38 bellard
            ret = se->load_state(f, se->opaque, version_id);
4961 8a7ddc38 bellard
            if (ret < 0) {
4962 8a7ddc38 bellard
                fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n", 
4963 8a7ddc38 bellard
                        instance_id, idstr);
4964 8a7ddc38 bellard
            }
4965 34865134 bellard
        }
4966 8a7ddc38 bellard
        /* always seek to exact end of record */
4967 8a7ddc38 bellard
        qemu_fseek(f, cur_pos + record_len, SEEK_SET);
4968 8a7ddc38 bellard
    }
4969 8a7ddc38 bellard
    ret = 0;
4970 8a7ddc38 bellard
 the_end:
4971 faea38e7 bellard
    return ret;
4972 faea38e7 bellard
}
4973 faea38e7 bellard
4974 faea38e7 bellard
/* device can contain snapshots */
4975 faea38e7 bellard
static int bdrv_can_snapshot(BlockDriverState *bs)
4976 faea38e7 bellard
{
4977 faea38e7 bellard
    return (bs &&
4978 faea38e7 bellard
            !bdrv_is_removable(bs) &&
4979 faea38e7 bellard
            !bdrv_is_read_only(bs));
4980 faea38e7 bellard
}
4981 faea38e7 bellard
4982 faea38e7 bellard
/* device must be snapshots in order to have a reliable snapshot */
4983 faea38e7 bellard
static int bdrv_has_snapshot(BlockDriverState *bs)
4984 faea38e7 bellard
{
4985 faea38e7 bellard
    return (bs &&
4986 faea38e7 bellard
            !bdrv_is_removable(bs) &&
4987 faea38e7 bellard
            !bdrv_is_read_only(bs));
4988 faea38e7 bellard
}
4989 faea38e7 bellard
4990 faea38e7 bellard
static BlockDriverState *get_bs_snapshots(void)
4991 faea38e7 bellard
{
4992 faea38e7 bellard
    BlockDriverState *bs;
4993 faea38e7 bellard
    int i;
4994 faea38e7 bellard
4995 faea38e7 bellard
    if (bs_snapshots)
4996 faea38e7 bellard
        return bs_snapshots;
4997 faea38e7 bellard
    for(i = 0; i <= MAX_DISKS; i++) {
4998 faea38e7 bellard
        bs = bs_table[i];
4999 faea38e7 bellard
        if (bdrv_can_snapshot(bs))
5000 faea38e7 bellard
            goto ok;
5001 faea38e7 bellard
    }
5002 faea38e7 bellard
    return NULL;
5003 faea38e7 bellard
 ok:
5004 faea38e7 bellard
    bs_snapshots = bs;
5005 faea38e7 bellard
    return bs;
5006 faea38e7 bellard
}
5007 faea38e7 bellard
5008 faea38e7 bellard
static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
5009 faea38e7 bellard
                              const char *name)
5010 faea38e7 bellard
{
5011 faea38e7 bellard
    QEMUSnapshotInfo *sn_tab, *sn;
5012 faea38e7 bellard
    int nb_sns, i, ret;
5013 faea38e7 bellard
    
5014 faea38e7 bellard
    ret = -ENOENT;
5015 faea38e7 bellard
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
5016 faea38e7 bellard
    if (nb_sns < 0)
5017 faea38e7 bellard
        return ret;
5018 faea38e7 bellard
    for(i = 0; i < nb_sns; i++) {
5019 faea38e7 bellard
        sn = &sn_tab[i];
5020 faea38e7 bellard
        if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
5021 faea38e7 bellard
            *sn_info = *sn;
5022 faea38e7 bellard
            ret = 0;
5023 faea38e7 bellard
            break;
5024 faea38e7 bellard
        }
5025 faea38e7 bellard
    }
5026 faea38e7 bellard
    qemu_free(sn_tab);
5027 faea38e7 bellard
    return ret;
5028 faea38e7 bellard
}
5029 faea38e7 bellard
5030 faea38e7 bellard
void do_savevm(const char *name)
5031 faea38e7 bellard
{
5032 faea38e7 bellard
    BlockDriverState *bs, *bs1;
5033 faea38e7 bellard
    QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
5034 faea38e7 bellard
    int must_delete, ret, i;
5035 faea38e7 bellard
    BlockDriverInfo bdi1, *bdi = &bdi1;
5036 faea38e7 bellard
    QEMUFile *f;
5037 faea38e7 bellard
    int saved_vm_running;
5038 4c279bdf bellard
#ifdef _WIN32
5039 4c279bdf bellard
    struct _timeb tb;
5040 4c279bdf bellard
#else
5041 faea38e7 bellard
    struct timeval tv;
5042 4c279bdf bellard
#endif
5043 faea38e7 bellard
5044 faea38e7 bellard
    bs = get_bs_snapshots();
5045 faea38e7 bellard
    if (!bs) {
5046 faea38e7 bellard
        term_printf("No block device can accept snapshots\n");
5047 faea38e7 bellard
        return;
5048 faea38e7 bellard
    }
5049 faea38e7 bellard
5050 6192bc37 pbrook
    /* ??? Should this occur after vm_stop?  */
5051 6192bc37 pbrook
    qemu_aio_flush();
5052 6192bc37 pbrook
5053 faea38e7 bellard
    saved_vm_running = vm_running;
5054 faea38e7 bellard
    vm_stop(0);
5055 faea38e7 bellard
    
5056 faea38e7 bellard
    must_delete = 0;
5057 faea38e7 bellard
    if (name) {
5058 faea38e7 bellard
        ret = bdrv_snapshot_find(bs, old_sn, name);
5059 faea38e7 bellard
        if (ret >= 0) {
5060 faea38e7 bellard
            must_delete = 1;
5061 faea38e7 bellard
        }
5062 faea38e7 bellard
    }
5063 faea38e7 bellard
    memset(sn, 0, sizeof(*sn));
5064 faea38e7 bellard
    if (must_delete) {
5065 faea38e7 bellard
        pstrcpy(sn->name, sizeof(sn->name), old_sn->name);
5066 faea38e7 bellard
        pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str);
5067 faea38e7 bellard
    } else {
5068 faea38e7 bellard
        if (name)
5069 faea38e7 bellard
            pstrcpy(sn->name, sizeof(sn->name), name);
5070 faea38e7 bellard
    }
5071 faea38e7 bellard
5072 faea38e7 bellard
    /* fill auxiliary fields */
5073 4c279bdf bellard
#ifdef _WIN32
5074 4c279bdf bellard
    _ftime(&tb);
5075 4c279bdf bellard
    sn->date_sec = tb.time;
5076 4c279bdf bellard
    sn->date_nsec = tb.millitm * 1000000;
5077 4c279bdf bellard
#else
5078 faea38e7 bellard
    gettimeofday(&tv, NULL);
5079 faea38e7 bellard
    sn->date_sec = tv.tv_sec;
5080 faea38e7 bellard
    sn->date_nsec = tv.tv_usec * 1000;
5081 4c279bdf bellard
#endif
5082 faea38e7 bellard
    sn->vm_clock_nsec = qemu_get_clock(vm_clock);
5083 faea38e7 bellard
    
5084 faea38e7 bellard
    if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
5085 faea38e7 bellard
        term_printf("Device %s does not support VM state snapshots\n",
5086 faea38e7 bellard
                    bdrv_get_device_name(bs));
5087 faea38e7 bellard
        goto the_end;
5088 faea38e7 bellard
    }
5089 faea38e7 bellard
    
5090 faea38e7 bellard
    /* save the VM state */
5091 faea38e7 bellard
    f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 1);
5092 faea38e7 bellard
    if (!f) {
5093 faea38e7 bellard
        term_printf("Could not open VM state file\n");
5094 faea38e7 bellard
        goto the_end;
5095 faea38e7 bellard
    }
5096 faea38e7 bellard
    ret = qemu_savevm_state(f);
5097 faea38e7 bellard
    sn->vm_state_size = qemu_ftell(f);
5098 faea38e7 bellard
    qemu_fclose(f);
5099 faea38e7 bellard
    if (ret < 0) {
5100 faea38e7 bellard
        term_printf("Error %d while writing VM\n", ret);
5101 faea38e7 bellard
        goto the_end;
5102 faea38e7 bellard
    }
5103 faea38e7 bellard
    
5104 faea38e7 bellard
    /* create the snapshots */
5105 faea38e7 bellard
5106 faea38e7 bellard
    for(i = 0; i < MAX_DISKS; i++) {
5107 faea38e7 bellard
        bs1 = bs_table[i];
5108 faea38e7 bellard
        if (bdrv_has_snapshot(bs1)) {
5109 faea38e7 bellard
            if (must_delete) {
5110 faea38e7 bellard
                ret = bdrv_snapshot_delete(bs1, old_sn->id_str);
5111 faea38e7 bellard
                if (ret < 0) {
5112 faea38e7 bellard
                    term_printf("Error while deleting snapshot on '%s'\n",
5113 faea38e7 bellard
                                bdrv_get_device_name(bs1));
5114 faea38e7 bellard
                }
5115 faea38e7 bellard
            }
5116 faea38e7 bellard
            ret = bdrv_snapshot_create(bs1, sn);
5117 faea38e7 bellard
            if (ret < 0) {
5118 faea38e7 bellard
                term_printf("Error while creating snapshot on '%s'\n",
5119 faea38e7 bellard
                            bdrv_get_device_name(bs1));
5120 faea38e7 bellard
            }
5121 faea38e7 bellard
        }
5122 faea38e7 bellard
    }
5123 faea38e7 bellard
5124 faea38e7 bellard
 the_end:
5125 8a7ddc38 bellard
    if (saved_vm_running)
5126 8a7ddc38 bellard
        vm_start();
5127 faea38e7 bellard
}
5128 faea38e7 bellard
5129 faea38e7 bellard
void do_loadvm(const char *name)
5130 faea38e7 bellard
{
5131 faea38e7 bellard
    BlockDriverState *bs, *bs1;
5132 faea38e7 bellard
    BlockDriverInfo bdi1, *bdi = &bdi1;
5133 faea38e7 bellard
    QEMUFile *f;
5134 faea38e7 bellard
    int i, ret;
5135 faea38e7 bellard
    int saved_vm_running;
5136 faea38e7 bellard
5137 faea38e7 bellard
    bs = get_bs_snapshots();
5138 faea38e7 bellard
    if (!bs) {
5139 faea38e7 bellard
        term_printf("No block device supports snapshots\n");
5140 faea38e7 bellard
        return;
5141 faea38e7 bellard
    }
5142 faea38e7 bellard
    
5143 6192bc37 pbrook
    /* Flush all IO requests so they don't interfere with the new state.  */
5144 6192bc37 pbrook
    qemu_aio_flush();
5145 6192bc37 pbrook
5146 faea38e7 bellard
    saved_vm_running = vm_running;
5147 faea38e7 bellard
    vm_stop(0);
5148 faea38e7 bellard
5149 faea38e7 bellard
    for(i = 0; i <= MAX_DISKS; i++) {
5150 faea38e7 bellard
        bs1 = bs_table[i];
5151 faea38e7 bellard
        if (bdrv_has_snapshot(bs1)) {
5152 faea38e7 bellard
            ret = bdrv_snapshot_goto(bs1, name);
5153 faea38e7 bellard
            if (ret < 0) {
5154 faea38e7 bellard
                if (bs != bs1)
5155 faea38e7 bellard
                    term_printf("Warning: ");
5156 faea38e7 bellard
                switch(ret) {
5157 faea38e7 bellard
                case -ENOTSUP:
5158 faea38e7 bellard
                    term_printf("Snapshots not supported on device '%s'\n",
5159 faea38e7 bellard
                                bdrv_get_device_name(bs1));
5160 faea38e7 bellard
                    break;
5161 faea38e7 bellard
                case -ENOENT:
5162 faea38e7 bellard
                    term_printf("Could not find snapshot '%s' on device '%s'\n",
5163 faea38e7 bellard
                                name, bdrv_get_device_name(bs1));
5164 faea38e7 bellard
                    break;
5165 faea38e7 bellard
                default:
5166 faea38e7 bellard
                    term_printf("Error %d while activating snapshot on '%s'\n",
5167 faea38e7 bellard
                                ret, bdrv_get_device_name(bs1));
5168 faea38e7 bellard
                    break;
5169 faea38e7 bellard
                }
5170 faea38e7 bellard
                /* fatal on snapshot block device */
5171 faea38e7 bellard
                if (bs == bs1)
5172 faea38e7 bellard
                    goto the_end;
5173 faea38e7 bellard
            }
5174 faea38e7 bellard
        }
5175 faea38e7 bellard
    }
5176 faea38e7 bellard
5177 faea38e7 bellard
    if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
5178 faea38e7 bellard
        term_printf("Device %s does not support VM state snapshots\n",
5179 faea38e7 bellard
                    bdrv_get_device_name(bs));
5180 faea38e7 bellard
        return;
5181 faea38e7 bellard
    }
5182 faea38e7 bellard
    
5183 faea38e7 bellard
    /* restore the VM state */
5184 faea38e7 bellard
    f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 0);
5185 faea38e7 bellard
    if (!f) {
5186 faea38e7 bellard
        term_printf("Could not open VM state file\n");
5187 faea38e7 bellard
        goto the_end;
5188 faea38e7 bellard
    }
5189 faea38e7 bellard
    ret = qemu_loadvm_state(f);
5190 faea38e7 bellard
    qemu_fclose(f);
5191 faea38e7 bellard
    if (ret < 0) {
5192 faea38e7 bellard
        term_printf("Error %d while loading VM state\n", ret);
5193 faea38e7 bellard
    }
5194 faea38e7 bellard
 the_end:
5195 faea38e7 bellard
    if (saved_vm_running)
5196 faea38e7 bellard
        vm_start();
5197 faea38e7 bellard
}
5198 faea38e7 bellard
5199 faea38e7 bellard
void do_delvm(const char *name)
5200 faea38e7 bellard
{
5201 faea38e7 bellard
    BlockDriverState *bs, *bs1;
5202 faea38e7 bellard
    int i, ret;
5203 faea38e7 bellard
5204 faea38e7 bellard
    bs = get_bs_snapshots();
5205 faea38e7 bellard
    if (!bs) {
5206 faea38e7 bellard
        term_printf("No block device supports snapshots\n");
5207 faea38e7 bellard
        return;
5208 faea38e7 bellard
    }
5209 faea38e7 bellard
    
5210 faea38e7 bellard
    for(i = 0; i <= MAX_DISKS; i++) {
5211 faea38e7 bellard
        bs1 = bs_table[i];
5212 faea38e7 bellard
        if (bdrv_has_snapshot(bs1)) {
5213 faea38e7 bellard
            ret = bdrv_snapshot_delete(bs1, name);
5214 faea38e7 bellard
            if (ret < 0) {
5215 faea38e7 bellard
                if (ret == -ENOTSUP)
5216 faea38e7 bellard
                    term_printf("Snapshots not supported on device '%s'\n",
5217 faea38e7 bellard
                                bdrv_get_device_name(bs1));
5218 faea38e7 bellard
                else
5219 faea38e7 bellard
                    term_printf("Error %d while deleting snapshot on '%s'\n",
5220 faea38e7 bellard
                                ret, bdrv_get_device_name(bs1));
5221 faea38e7 bellard
            }
5222 faea38e7 bellard
        }
5223 faea38e7 bellard
    }
5224 faea38e7 bellard
}
5225 faea38e7 bellard
5226 faea38e7 bellard
void do_info_snapshots(void)
5227 faea38e7 bellard
{
5228 faea38e7 bellard
    BlockDriverState *bs, *bs1;
5229 faea38e7 bellard
    QEMUSnapshotInfo *sn_tab, *sn;
5230 faea38e7 bellard
    int nb_sns, i;
5231 faea38e7 bellard
    char buf[256];
5232 faea38e7 bellard
5233 faea38e7 bellard
    bs = get_bs_snapshots();
5234 faea38e7 bellard
    if (!bs) {
5235 faea38e7 bellard
        term_printf("No available block device supports snapshots\n");
5236 faea38e7 bellard
        return;
5237 faea38e7 bellard
    }
5238 faea38e7 bellard
    term_printf("Snapshot devices:");
5239 faea38e7 bellard
    for(i = 0; i <= MAX_DISKS; i++) {
5240 faea38e7 bellard
        bs1 = bs_table[i];
5241 faea38e7 bellard
        if (bdrv_has_snapshot(bs1)) {
5242 faea38e7 bellard
            if (bs == bs1)
5243 faea38e7 bellard
                term_printf(" %s", bdrv_get_device_name(bs1));
5244 faea38e7 bellard
        }
5245 faea38e7 bellard
    }
5246 faea38e7 bellard
    term_printf("\n");
5247 faea38e7 bellard
5248 faea38e7 bellard
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
5249 faea38e7 bellard
    if (nb_sns < 0) {
5250 faea38e7 bellard
        term_printf("bdrv_snapshot_list: error %d\n", nb_sns);
5251 faea38e7 bellard
        return;
5252 faea38e7 bellard
    }
5253 faea38e7 bellard
    term_printf("Snapshot list (from %s):\n", bdrv_get_device_name(bs));
5254 faea38e7 bellard
    term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));
5255 faea38e7 bellard
    for(i = 0; i < nb_sns; i++) {
5256 faea38e7 bellard
        sn = &sn_tab[i];
5257 faea38e7 bellard
        term_printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
5258 faea38e7 bellard
    }
5259 faea38e7 bellard
    qemu_free(sn_tab);
5260 8a7ddc38 bellard
}
5261 8a7ddc38 bellard
5262 8a7ddc38 bellard
/***********************************************************/
5263 8a7ddc38 bellard
/* cpu save/restore */
5264 8a7ddc38 bellard
5265 8a7ddc38 bellard
#if defined(TARGET_I386)
5266 8a7ddc38 bellard
5267 8a7ddc38 bellard
static void cpu_put_seg(QEMUFile *f, SegmentCache *dt)
5268 8a7ddc38 bellard
{
5269 02ba45c5 bellard
    qemu_put_be32(f, dt->selector);
5270 20f32282 bellard
    qemu_put_betl(f, dt->base);
5271 8a7ddc38 bellard
    qemu_put_be32(f, dt->limit);
5272 8a7ddc38 bellard
    qemu_put_be32(f, dt->flags);
5273 8a7ddc38 bellard
}
5274 8a7ddc38 bellard
5275 8a7ddc38 bellard
static void cpu_get_seg(QEMUFile *f, SegmentCache *dt)
5276 8a7ddc38 bellard
{
5277 02ba45c5 bellard
    dt->selector = qemu_get_be32(f);
5278 20f32282 bellard
    dt->base = qemu_get_betl(f);
5279 8a7ddc38 bellard
    dt->limit = qemu_get_be32(f);
5280 8a7ddc38 bellard
    dt->flags = qemu_get_be32(f);
5281 8a7ddc38 bellard
}
5282 8a7ddc38 bellard
5283 8a7ddc38 bellard
void cpu_save(QEMUFile *f, void *opaque)
5284 8a7ddc38 bellard
{
5285 8a7ddc38 bellard
    CPUState *env = opaque;
5286 664e0f19 bellard
    uint16_t fptag, fpus, fpuc, fpregs_format;
5287 8a7ddc38 bellard
    uint32_t hflags;
5288 8a7ddc38 bellard
    int i;
5289 664e0f19 bellard
    
5290 20f32282 bellard
    for(i = 0; i < CPU_NB_REGS; i++)
5291 20f32282 bellard
        qemu_put_betls(f, &env->regs[i]);
5292 20f32282 bellard
    qemu_put_betls(f, &env->eip);
5293 20f32282 bellard
    qemu_put_betls(f, &env->eflags);
5294 8a7ddc38 bellard
    hflags = env->hflags; /* XXX: suppress most of the redundant hflags */
5295 8a7ddc38 bellard
    qemu_put_be32s(f, &hflags);
5296 8a7ddc38 bellard
    
5297 8a7ddc38 bellard
    /* FPU */
5298 8a7ddc38 bellard
    fpuc = env->fpuc;
5299 8a7ddc38 bellard
    fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
5300 8a7ddc38 bellard
    fptag = 0;
5301 664e0f19 bellard
    for(i = 0; i < 8; i++) {
5302 664e0f19 bellard
        fptag |= ((!env->fptags[i]) << i);
5303 8a7ddc38 bellard
    }
5304 8a7ddc38 bellard
    
5305 8a7ddc38 bellard
    qemu_put_be16s(f, &fpuc);
5306 8a7ddc38 bellard
    qemu_put_be16s(f, &fpus);
5307 8a7ddc38 bellard
    qemu_put_be16s(f, &fptag);
5308 8a7ddc38 bellard
5309 664e0f19 bellard
#ifdef USE_X86LDOUBLE
5310 664e0f19 bellard
    fpregs_format = 0;
5311 664e0f19 bellard
#else
5312 664e0f19 bellard
    fpregs_format = 1;
5313 664e0f19 bellard
#endif
5314 664e0f19 bellard
    qemu_put_be16s(f, &fpregs_format);
5315 664e0f19 bellard
    
5316 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
5317 664e0f19 bellard
#ifdef USE_X86LDOUBLE
5318 8636b5d8 bellard
        {
5319 8636b5d8 bellard
            uint64_t mant;
5320 8636b5d8 bellard
            uint16_t exp;
5321 8636b5d8 bellard
            /* we save the real CPU data (in case of MMX usage only 'mant'
5322 8636b5d8 bellard
               contains the MMX register */
5323 8636b5d8 bellard
            cpu_get_fp80(&mant, &exp, env->fpregs[i].d);
5324 8636b5d8 bellard
            qemu_put_be64(f, mant);
5325 8636b5d8 bellard
            qemu_put_be16(f, exp);
5326 8636b5d8 bellard
        }
5327 664e0f19 bellard
#else
5328 664e0f19 bellard
        /* if we use doubles for float emulation, we save the doubles to
5329 664e0f19 bellard
           avoid losing information in case of MMX usage. It can give
5330 664e0f19 bellard
           problems if the image is restored on a CPU where long
5331 664e0f19 bellard
           doubles are used instead. */
5332 8636b5d8 bellard
        qemu_put_be64(f, env->fpregs[i].mmx.MMX_Q(0));
5333 664e0f19 bellard
#endif
5334 8a7ddc38 bellard
    }
5335 8a7ddc38 bellard
5336 8a7ddc38 bellard
    for(i = 0; i < 6; i++)
5337 8a7ddc38 bellard
        cpu_put_seg(f, &env->segs[i]);
5338 8a7ddc38 bellard
    cpu_put_seg(f, &env->ldt);
5339 8a7ddc38 bellard
    cpu_put_seg(f, &env->tr);
5340 8a7ddc38 bellard
    cpu_put_seg(f, &env->gdt);
5341 8a7ddc38 bellard
    cpu_put_seg(f, &env->idt);
5342 8a7ddc38 bellard
    
5343 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_cs);
5344 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_esp);
5345 8a7ddc38 bellard
    qemu_put_be32s(f, &env->sysenter_eip);
5346 8a7ddc38 bellard
    
5347 20f32282 bellard
    qemu_put_betls(f, &env->cr[0]);
5348 20f32282 bellard
    qemu_put_betls(f, &env->cr[2]);
5349 20f32282 bellard
    qemu_put_betls(f, &env->cr[3]);
5350 20f32282 bellard
    qemu_put_betls(f, &env->cr[4]);
5351 8a7ddc38 bellard
    
5352 8a7ddc38 bellard
    for(i = 0; i < 8; i++)
5353 20f32282 bellard
        qemu_put_betls(f, &env->dr[i]);
5354 8a7ddc38 bellard
5355 8a7ddc38 bellard
    /* MMU */
5356 8a7ddc38 bellard
    qemu_put_be32s(f, &env->a20_mask);
5357 02536f8b bellard
5358 664e0f19 bellard
    /* XMM */
5359 664e0f19 bellard
    qemu_put_be32s(f, &env->mxcsr);
5360 02536f8b bellard
    for(i = 0; i < CPU_NB_REGS; i++) {
5361 02536f8b bellard
        qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(0));
5362 02536f8b bellard
        qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(1));
5363 02536f8b bellard
    }
5364 02536f8b bellard
5365 664e0f19 bellard
#ifdef TARGET_X86_64
5366 02536f8b bellard
    qemu_put_be64s(f, &env->efer);
5367 02536f8b bellard
    qemu_put_be64s(f, &env->star);
5368 02536f8b bellard
    qemu_put_be64s(f, &env->lstar);
5369 02536f8b bellard
    qemu_put_be64s(f, &env->cstar);
5370 02536f8b bellard
    qemu_put_be64s(f, &env->fmask);
5371 02536f8b bellard
    qemu_put_be64s(f, &env->kernelgsbase);
5372 02536f8b bellard
#endif
5373 3b21e03e bellard
    qemu_put_be32s(f, &env->smbase);
5374 8a7ddc38 bellard
}
5375 8a7ddc38 bellard
5376 8636b5d8 bellard
#ifdef USE_X86LDOUBLE
5377 664e0f19 bellard
/* XXX: add that in a FPU generic layer */
5378 664e0f19 bellard
union x86_longdouble {
5379 664e0f19 bellard
    uint64_t mant;
5380 664e0f19 bellard
    uint16_t exp;
5381 664e0f19 bellard
};
5382 664e0f19 bellard
5383 664e0f19 bellard
#define MANTD1(fp)        (fp & ((1LL << 52) - 1))
5384 664e0f19 bellard
#define EXPBIAS1 1023
5385 664e0f19 bellard
#define EXPD1(fp)        ((fp >> 52) & 0x7FF)
5386 664e0f19 bellard
#define SIGND1(fp)        ((fp >> 32) & 0x80000000)
5387 664e0f19 bellard
5388 664e0f19 bellard
static void fp64_to_fp80(union x86_longdouble *p, uint64_t temp)
5389 664e0f19 bellard
{
5390 664e0f19 bellard
    int e;
5391 664e0f19 bellard
    /* mantissa */
5392 664e0f19 bellard
    p->mant = (MANTD1(temp) << 11) | (1LL << 63);
5393 664e0f19 bellard
    /* exponent + sign */
5394 664e0f19 bellard
    e = EXPD1(temp) - EXPBIAS1 + 16383;
5395 664e0f19 bellard
    e |= SIGND1(temp) >> 16;
5396 664e0f19 bellard
    p->exp = e;
5397 664e0f19 bellard
}
5398 8636b5d8 bellard
#endif
5399 664e0f19 bellard
5400 8a7ddc38 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
5401 8a7ddc38 bellard
{
5402 8a7ddc38 bellard
    CPUState *env = opaque;
5403 664e0f19 bellard
    int i, guess_mmx;
5404 8a7ddc38 bellard
    uint32_t hflags;
5405 664e0f19 bellard
    uint16_t fpus, fpuc, fptag, fpregs_format;
5406 8a7ddc38 bellard
5407 3b21e03e bellard
    if (version_id != 3 && version_id != 4)
5408 8a7ddc38 bellard
        return -EINVAL;
5409 20f32282 bellard
    for(i = 0; i < CPU_NB_REGS; i++)
5410 20f32282 bellard
        qemu_get_betls(f, &env->regs[i]);
5411 20f32282 bellard
    qemu_get_betls(f, &env->eip);
5412 20f32282 bellard
    qemu_get_betls(f, &env->eflags);
5413 8a7ddc38 bellard
    qemu_get_be32s(f, &hflags);
5414 8a7ddc38 bellard
5415 8a7ddc38 bellard
    qemu_get_be16s(f, &fpuc);
5416 8a7ddc38 bellard
    qemu_get_be16s(f, &fpus);
5417 8a7ddc38 bellard
    qemu_get_be16s(f, &fptag);
5418 664e0f19 bellard
    qemu_get_be16s(f, &fpregs_format);
5419 664e0f19 bellard
    
5420 664e0f19 bellard
    /* NOTE: we cannot always restore the FPU state if the image come
5421 664e0f19 bellard
       from a host with a different 'USE_X86LDOUBLE' define. We guess
5422 664e0f19 bellard
       if we are in an MMX state to restore correctly in that case. */
5423 664e0f19 bellard
    guess_mmx = ((fptag == 0xff) && (fpus & 0x3800) == 0);
5424 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
5425 8a7ddc38 bellard
        uint64_t mant;
5426 8a7ddc38 bellard
        uint16_t exp;
5427 664e0f19 bellard
        
5428 664e0f19 bellard
        switch(fpregs_format) {
5429 664e0f19 bellard
        case 0:
5430 664e0f19 bellard
            mant = qemu_get_be64(f);
5431 664e0f19 bellard
            exp = qemu_get_be16(f);
5432 664e0f19 bellard
#ifdef USE_X86LDOUBLE
5433 664e0f19 bellard
            env->fpregs[i].d = cpu_set_fp80(mant, exp);
5434 664e0f19 bellard
#else
5435 664e0f19 bellard
            /* difficult case */
5436 664e0f19 bellard
            if (guess_mmx)
5437 8636b5d8 bellard
                env->fpregs[i].mmx.MMX_Q(0) = mant;
5438 664e0f19 bellard
            else
5439 664e0f19 bellard
                env->fpregs[i].d = cpu_set_fp80(mant, exp);
5440 664e0f19 bellard
#endif
5441 664e0f19 bellard
            break;
5442 664e0f19 bellard
        case 1:
5443 664e0f19 bellard
            mant = qemu_get_be64(f);
5444 664e0f19 bellard
#ifdef USE_X86LDOUBLE
5445 8636b5d8 bellard
            {
5446 8636b5d8 bellard
                union x86_longdouble *p;
5447 8636b5d8 bellard
                /* difficult case */
5448 8636b5d8 bellard
                p = (void *)&env->fpregs[i];
5449 8636b5d8 bellard
                if (guess_mmx) {
5450 8636b5d8 bellard
                    p->mant = mant;
5451 8636b5d8 bellard
                    p->exp = 0xffff;
5452 8636b5d8 bellard
                } else {
5453 8636b5d8 bellard
                    fp64_to_fp80(p, mant);
5454 8636b5d8 bellard
                }
5455 664e0f19 bellard
            }
5456 664e0f19 bellard
#else
5457 8636b5d8 bellard
            env->fpregs[i].mmx.MMX_Q(0) = mant;
5458 664e0f19 bellard
#endif            
5459 664e0f19 bellard
            break;
5460 664e0f19 bellard
        default:
5461 664e0f19 bellard
            return -EINVAL;
5462 664e0f19 bellard
        }
5463 8a7ddc38 bellard
    }
5464 8a7ddc38 bellard
5465 8a7ddc38 bellard
    env->fpuc = fpuc;
5466 7a0e1f41 bellard
    /* XXX: restore FPU round state */
5467 8a7ddc38 bellard
    env->fpstt = (fpus >> 11) & 7;
5468 8a7ddc38 bellard
    env->fpus = fpus & ~0x3800;
5469 664e0f19 bellard
    fptag ^= 0xff;
5470 8a7ddc38 bellard
    for(i = 0; i < 8; i++) {
5471 664e0f19 bellard
        env->fptags[i] = (fptag >> i) & 1;
5472 8a7ddc38 bellard
    }
5473 8a7ddc38 bellard
    
5474 8a7ddc38 bellard
    for(i = 0; i < 6; i++)
5475 8a7ddc38 bellard
        cpu_get_seg(f, &env->segs[i]);
5476 8a7ddc38 bellard
    cpu_get_seg(f, &env->ldt);
5477 8a7ddc38 bellard
    cpu_get_seg(f, &env->tr);
5478 8a7ddc38 bellard
    cpu_get_seg(f, &env->gdt);
5479 8a7ddc38 bellard
    cpu_get_seg(f, &env->idt);
5480 8a7ddc38 bellard
    
5481 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_cs);
5482 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_esp);
5483 8a7ddc38 bellard
    qemu_get_be32s(f, &env->sysenter_eip);
5484 8a7ddc38 bellard
    
5485 20f32282 bellard
    qemu_get_betls(f, &env->cr[0]);
5486 20f32282 bellard
    qemu_get_betls(f, &env->cr[2]);
5487 20f32282 bellard
    qemu_get_betls(f, &env->cr[3]);
5488 20f32282 bellard
    qemu_get_betls(f, &env->cr[4]);
5489 8a7ddc38 bellard
    
5490 8a7ddc38 bellard
    for(i = 0; i < 8; i++)
5491 20f32282 bellard
        qemu_get_betls(f, &env->dr[i]);
5492 8a7ddc38 bellard
5493 8a7ddc38 bellard
    /* MMU */
5494 8a7ddc38 bellard
    qemu_get_be32s(f, &env->a20_mask);
5495 8a7ddc38 bellard
5496 664e0f19 bellard
    qemu_get_be32s(f, &env->mxcsr);
5497 02536f8b bellard
    for(i = 0; i < CPU_NB_REGS; i++) {
5498 02536f8b bellard
        qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0));
5499 02536f8b bellard
        qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1));
5500 02536f8b bellard
    }
5501 02536f8b bellard
5502 664e0f19 bellard
#ifdef TARGET_X86_64
5503 02536f8b bellard
    qemu_get_be64s(f, &env->efer);
5504 02536f8b bellard
    qemu_get_be64s(f, &env->star);
5505 02536f8b bellard
    qemu_get_be64s(f, &env->lstar);
5506 02536f8b bellard
    qemu_get_be64s(f, &env->cstar);
5507 02536f8b bellard
    qemu_get_be64s(f, &env->fmask);
5508 02536f8b bellard
    qemu_get_be64s(f, &env->kernelgsbase);
5509 02536f8b bellard
#endif
5510 3b21e03e bellard
    if (version_id >= 4) 
5511 3b21e03e bellard
        qemu_get_be32s(f, &env->smbase);
5512 02536f8b bellard
5513 8a7ddc38 bellard
    /* XXX: compute hflags from scratch, except for CPL and IIF */
5514 8a7ddc38 bellard
    env->hflags = hflags;
5515 8a7ddc38 bellard
    tlb_flush(env, 1);
5516 8a7ddc38 bellard
    return 0;
5517 8a7ddc38 bellard
}
5518 8a7ddc38 bellard
5519 a541f297 bellard
#elif defined(TARGET_PPC)
5520 a541f297 bellard
void cpu_save(QEMUFile *f, void *opaque)
5521 a541f297 bellard
{
5522 a541f297 bellard
}
5523 a541f297 bellard
5524 a541f297 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
5525 a541f297 bellard
{
5526 a541f297 bellard
    return 0;
5527 a541f297 bellard
}
5528 6af0bf9c bellard
5529 6af0bf9c bellard
#elif defined(TARGET_MIPS)
5530 6af0bf9c bellard
void cpu_save(QEMUFile *f, void *opaque)
5531 6af0bf9c bellard
{
5532 6af0bf9c bellard
}
5533 6af0bf9c bellard
5534 6af0bf9c bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
5535 6af0bf9c bellard
{
5536 6af0bf9c bellard
    return 0;
5537 6af0bf9c bellard
}
5538 6af0bf9c bellard
5539 e95c8d51 bellard
#elif defined(TARGET_SPARC)
5540 e95c8d51 bellard
void cpu_save(QEMUFile *f, void *opaque)
5541 e95c8d51 bellard
{
5542 e80cfcfc bellard
    CPUState *env = opaque;
5543 e80cfcfc bellard
    int i;
5544 e80cfcfc bellard
    uint32_t tmp;
5545 e80cfcfc bellard
5546 4fa5d772 bellard
    for(i = 0; i < 8; i++)
5547 4fa5d772 bellard
        qemu_put_betls(f, &env->gregs[i]);
5548 4fa5d772 bellard
    for(i = 0; i < NWINDOWS * 16; i++)
5549 4fa5d772 bellard
        qemu_put_betls(f, &env->regbase[i]);
5550 e80cfcfc bellard
5551 e80cfcfc bellard
    /* FPU */
5552 4fa5d772 bellard
    for(i = 0; i < TARGET_FPREGS; i++) {
5553 4fa5d772 bellard
        union {
5554 1bdb68ea bellard
            float32 f;
5555 1bdb68ea bellard
            uint32_t i;
5556 4fa5d772 bellard
        } u;
5557 4fa5d772 bellard
        u.f = env->fpr[i];
5558 1bdb68ea bellard
        qemu_put_be32(f, u.i);
5559 4fa5d772 bellard
    }
5560 4fa5d772 bellard
5561 4fa5d772 bellard
    qemu_put_betls(f, &env->pc);
5562 4fa5d772 bellard
    qemu_put_betls(f, &env->npc);
5563 4fa5d772 bellard
    qemu_put_betls(f, &env->y);
5564 e80cfcfc bellard
    tmp = GET_PSR(env);
5565 4fa5d772 bellard
    qemu_put_be32(f, tmp);
5566 3475187d bellard
    qemu_put_betls(f, &env->fsr);
5567 3475187d bellard
    qemu_put_betls(f, &env->tbr);
5568 3475187d bellard
#ifndef TARGET_SPARC64
5569 e80cfcfc bellard
    qemu_put_be32s(f, &env->wim);
5570 e80cfcfc bellard
    /* MMU */
5571 e80cfcfc bellard
    for(i = 0; i < 16; i++)
5572 e80cfcfc bellard
        qemu_put_be32s(f, &env->mmuregs[i]);
5573 3475187d bellard
#endif
5574 e95c8d51 bellard
}
5575 e95c8d51 bellard
5576 e95c8d51 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
5577 e95c8d51 bellard
{
5578 e80cfcfc bellard
    CPUState *env = opaque;
5579 e80cfcfc bellard
    int i;
5580 e80cfcfc bellard
    uint32_t tmp;
5581 e80cfcfc bellard
5582 4fa5d772 bellard
    for(i = 0; i < 8; i++)
5583 4fa5d772 bellard
        qemu_get_betls(f, &env->gregs[i]);
5584 4fa5d772 bellard
    for(i = 0; i < NWINDOWS * 16; i++)
5585 4fa5d772 bellard
        qemu_get_betls(f, &env->regbase[i]);
5586 e80cfcfc bellard
5587 e80cfcfc bellard
    /* FPU */
5588 4fa5d772 bellard
    for(i = 0; i < TARGET_FPREGS; i++) {
5589 4fa5d772 bellard
        union {
5590 1bdb68ea bellard
            float32 f;
5591 1bdb68ea bellard
            uint32_t i;
5592 4fa5d772 bellard
        } u;
5593 1bdb68ea bellard
        u.i = qemu_get_be32(f);
5594 4fa5d772 bellard
        env->fpr[i] = u.f;
5595 4fa5d772 bellard
    }
5596 4fa5d772 bellard
5597 4fa5d772 bellard
    qemu_get_betls(f, &env->pc);
5598 4fa5d772 bellard
    qemu_get_betls(f, &env->npc);
5599 4fa5d772 bellard
    qemu_get_betls(f, &env->y);
5600 4fa5d772 bellard
    tmp = qemu_get_be32(f);
5601 4fa5d772 bellard
    env->cwp = 0; /* needed to ensure that the wrapping registers are
5602 4fa5d772 bellard
                     correctly updated */
5603 e80cfcfc bellard
    PUT_PSR(env, tmp);
5604 3475187d bellard
    qemu_get_betls(f, &env->fsr);
5605 3475187d bellard
    qemu_get_betls(f, &env->tbr);
5606 3475187d bellard
#ifndef TARGET_SPARC64
5607 e80cfcfc bellard
    qemu_get_be32s(f, &env->wim);
5608 e80cfcfc bellard
    /* MMU */
5609 e80cfcfc bellard
    for(i = 0; i < 16; i++)
5610 e80cfcfc bellard
        qemu_get_be32s(f, &env->mmuregs[i]);
5611 3475187d bellard
#endif
5612 e80cfcfc bellard
    tlb_flush(env, 1);
5613 e95c8d51 bellard
    return 0;
5614 e95c8d51 bellard
}
5615 b5ff1b31 bellard
5616 b5ff1b31 bellard
#elif defined(TARGET_ARM)
5617 b5ff1b31 bellard
5618 b5ff1b31 bellard
/* ??? Need to implement these.  */
5619 b5ff1b31 bellard
void cpu_save(QEMUFile *f, void *opaque)
5620 b5ff1b31 bellard
{
5621 b5ff1b31 bellard
}
5622 b5ff1b31 bellard
5623 b5ff1b31 bellard
int cpu_load(QEMUFile *f, void *opaque, int version_id)
5624 b5ff1b31 bellard
{
5625 b5ff1b31 bellard
    return 0;
5626 b5ff1b31 bellard
}
5627 b5ff1b31 bellard
5628 8a7ddc38 bellard
#else
5629 8a7ddc38 bellard
5630 8a7ddc38 bellard
#warning No CPU save/restore functions
5631 8a7ddc38 bellard
5632 8a7ddc38 bellard
#endif
5633 8a7ddc38 bellard
5634 8a7ddc38 bellard
/***********************************************************/
5635 8a7ddc38 bellard
/* ram save/restore */
5636 8a7ddc38 bellard
5637 8a7ddc38 bellard
static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
5638 8a7ddc38 bellard
{
5639 8a7ddc38 bellard
    int v;
5640 8a7ddc38 bellard
5641 8a7ddc38 bellard
    v = qemu_get_byte(f);
5642 8a7ddc38 bellard
    switch(v) {
5643 8a7ddc38 bellard
    case 0:
5644 8a7ddc38 bellard
        if (qemu_get_buffer(f, buf, len) != len)
5645 8a7ddc38 bellard
            return -EIO;
5646 8a7ddc38 bellard
        break;
5647 8a7ddc38 bellard
    case 1:
5648 8a7ddc38 bellard
        v = qemu_get_byte(f);
5649 8a7ddc38 bellard
        memset(buf, v, len);
5650 8a7ddc38 bellard
        break;
5651 8a7ddc38 bellard
    default:
5652 8a7ddc38 bellard
        return -EINVAL;
5653 8a7ddc38 bellard
    }
5654 8a7ddc38 bellard
    return 0;
5655 8a7ddc38 bellard
}
5656 8a7ddc38 bellard
5657 c88676f8 bellard
static int ram_load_v1(QEMUFile *f, void *opaque)
5658 c88676f8 bellard
{
5659 c88676f8 bellard
    int i, ret;
5660 c88676f8 bellard
5661 c88676f8 bellard
    if (qemu_get_be32(f) != phys_ram_size)
5662 c88676f8 bellard
        return -EINVAL;
5663 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
5664 c88676f8 bellard
        ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
5665 c88676f8 bellard
        if (ret)
5666 c88676f8 bellard
            return ret;
5667 c88676f8 bellard
    }
5668 c88676f8 bellard
    return 0;
5669 c88676f8 bellard
}
5670 c88676f8 bellard
5671 c88676f8 bellard
#define BDRV_HASH_BLOCK_SIZE 1024
5672 c88676f8 bellard
#define IOBUF_SIZE 4096
5673 c88676f8 bellard
#define RAM_CBLOCK_MAGIC 0xfabe
5674 c88676f8 bellard
5675 c88676f8 bellard
typedef struct RamCompressState {
5676 c88676f8 bellard
    z_stream zstream;
5677 c88676f8 bellard
    QEMUFile *f;
5678 c88676f8 bellard
    uint8_t buf[IOBUF_SIZE];
5679 c88676f8 bellard
} RamCompressState;
5680 c88676f8 bellard
5681 c88676f8 bellard
static int ram_compress_open(RamCompressState *s, QEMUFile *f)
5682 c88676f8 bellard
{
5683 c88676f8 bellard
    int ret;
5684 c88676f8 bellard
    memset(s, 0, sizeof(*s));
5685 c88676f8 bellard
    s->f = f;
5686 c88676f8 bellard
    ret = deflateInit2(&s->zstream, 1,
5687 c88676f8 bellard
                       Z_DEFLATED, 15, 
5688 c88676f8 bellard
                       9, Z_DEFAULT_STRATEGY);
5689 c88676f8 bellard
    if (ret != Z_OK)
5690 c88676f8 bellard
        return -1;
5691 c88676f8 bellard
    s->zstream.avail_out = IOBUF_SIZE;
5692 c88676f8 bellard
    s->zstream.next_out = s->buf;
5693 c88676f8 bellard
    return 0;
5694 c88676f8 bellard
}
5695 c88676f8 bellard
5696 c88676f8 bellard
static void ram_put_cblock(RamCompressState *s, const uint8_t *buf, int len)
5697 c88676f8 bellard
{
5698 c88676f8 bellard
    qemu_put_be16(s->f, RAM_CBLOCK_MAGIC);
5699 c88676f8 bellard
    qemu_put_be16(s->f, len);
5700 c88676f8 bellard
    qemu_put_buffer(s->f, buf, len);
5701 c88676f8 bellard
}
5702 c88676f8 bellard
5703 c88676f8 bellard
static int ram_compress_buf(RamCompressState *s, const uint8_t *buf, int len)
5704 c88676f8 bellard
{
5705 c88676f8 bellard
    int ret;
5706 c88676f8 bellard
5707 c88676f8 bellard
    s->zstream.avail_in = len;
5708 c88676f8 bellard
    s->zstream.next_in = (uint8_t *)buf;
5709 c88676f8 bellard
    while (s->zstream.avail_in > 0) {
5710 c88676f8 bellard
        ret = deflate(&s->zstream, Z_NO_FLUSH);
5711 c88676f8 bellard
        if (ret != Z_OK)
5712 c88676f8 bellard
            return -1;
5713 c88676f8 bellard
        if (s->zstream.avail_out == 0) {
5714 c88676f8 bellard
            ram_put_cblock(s, s->buf, IOBUF_SIZE);
5715 c88676f8 bellard
            s->zstream.avail_out = IOBUF_SIZE;
5716 c88676f8 bellard
            s->zstream.next_out = s->buf;
5717 c88676f8 bellard
        }
5718 c88676f8 bellard
    }
5719 c88676f8 bellard
    return 0;
5720 c88676f8 bellard
}
5721 c88676f8 bellard
5722 c88676f8 bellard
static void ram_compress_close(RamCompressState *s)
5723 c88676f8 bellard
{
5724 c88676f8 bellard
    int len, ret;
5725 c88676f8 bellard
5726 c88676f8 bellard
    /* compress last bytes */
5727 c88676f8 bellard
    for(;;) {
5728 c88676f8 bellard
        ret = deflate(&s->zstream, Z_FINISH);
5729 c88676f8 bellard
        if (ret == Z_OK || ret == Z_STREAM_END) {
5730 c88676f8 bellard
            len = IOBUF_SIZE - s->zstream.avail_out;
5731 c88676f8 bellard
            if (len > 0) {
5732 c88676f8 bellard
                ram_put_cblock(s, s->buf, len);
5733 c88676f8 bellard
            }
5734 c88676f8 bellard
            s->zstream.avail_out = IOBUF_SIZE;
5735 c88676f8 bellard
            s->zstream.next_out = s->buf;
5736 c88676f8 bellard
            if (ret == Z_STREAM_END)
5737 c88676f8 bellard
                break;
5738 c88676f8 bellard
        } else {
5739 c88676f8 bellard
            goto fail;
5740 c88676f8 bellard
        }
5741 c88676f8 bellard
    }
5742 c88676f8 bellard
fail:
5743 c88676f8 bellard
    deflateEnd(&s->zstream);
5744 c88676f8 bellard
}
5745 c88676f8 bellard
5746 c88676f8 bellard
typedef struct RamDecompressState {
5747 c88676f8 bellard
    z_stream zstream;
5748 c88676f8 bellard
    QEMUFile *f;
5749 c88676f8 bellard
    uint8_t buf[IOBUF_SIZE];
5750 c88676f8 bellard
} RamDecompressState;
5751 c88676f8 bellard
5752 c88676f8 bellard
static int ram_decompress_open(RamDecompressState *s, QEMUFile *f)
5753 c88676f8 bellard
{
5754 c88676f8 bellard
    int ret;
5755 c88676f8 bellard
    memset(s, 0, sizeof(*s));
5756 c88676f8 bellard
    s->f = f;
5757 c88676f8 bellard
    ret = inflateInit(&s->zstream);
5758 c88676f8 bellard
    if (ret != Z_OK)
5759 c88676f8 bellard
        return -1;
5760 c88676f8 bellard
    return 0;
5761 c88676f8 bellard
}
5762 c88676f8 bellard
5763 c88676f8 bellard
static int ram_decompress_buf(RamDecompressState *s, uint8_t *buf, int len)
5764 c88676f8 bellard
{
5765 c88676f8 bellard
    int ret, clen;
5766 c88676f8 bellard
5767 c88676f8 bellard
    s->zstream.avail_out = len;
5768 c88676f8 bellard
    s->zstream.next_out = buf;
5769 c88676f8 bellard
    while (s->zstream.avail_out > 0) {
5770 c88676f8 bellard
        if (s->zstream.avail_in == 0) {
5771 c88676f8 bellard
            if (qemu_get_be16(s->f) != RAM_CBLOCK_MAGIC)
5772 c88676f8 bellard
                return -1;
5773 c88676f8 bellard
            clen = qemu_get_be16(s->f);
5774 c88676f8 bellard
            if (clen > IOBUF_SIZE)
5775 c88676f8 bellard
                return -1;
5776 c88676f8 bellard
            qemu_get_buffer(s->f, s->buf, clen);
5777 c88676f8 bellard
            s->zstream.avail_in = clen;
5778 c88676f8 bellard
            s->zstream.next_in = s->buf;
5779 c88676f8 bellard
        }
5780 c88676f8 bellard
        ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
5781 c88676f8 bellard
        if (ret != Z_OK && ret != Z_STREAM_END) {
5782 c88676f8 bellard
            return -1;
5783 c88676f8 bellard
        }
5784 c88676f8 bellard
    }
5785 c88676f8 bellard
    return 0;
5786 c88676f8 bellard
}
5787 c88676f8 bellard
5788 c88676f8 bellard
static void ram_decompress_close(RamDecompressState *s)
5789 c88676f8 bellard
{
5790 c88676f8 bellard
    inflateEnd(&s->zstream);
5791 c88676f8 bellard
}
5792 c88676f8 bellard
5793 8a7ddc38 bellard
static void ram_save(QEMUFile *f, void *opaque)
5794 8a7ddc38 bellard
{
5795 8a7ddc38 bellard
    int i;
5796 c88676f8 bellard
    RamCompressState s1, *s = &s1;
5797 c88676f8 bellard
    uint8_t buf[10];
5798 c88676f8 bellard
    
5799 8a7ddc38 bellard
    qemu_put_be32(f, phys_ram_size);
5800 c88676f8 bellard
    if (ram_compress_open(s, f) < 0)
5801 c88676f8 bellard
        return;
5802 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
5803 c88676f8 bellard
#if 0
5804 c88676f8 bellard
        if (tight_savevm_enabled) {
5805 c88676f8 bellard
            int64_t sector_num;
5806 c88676f8 bellard
            int j;
5807 c88676f8 bellard

5808 c88676f8 bellard
            /* find if the memory block is available on a virtual
5809 c88676f8 bellard
               block device */
5810 c88676f8 bellard
            sector_num = -1;
5811 c88676f8 bellard
            for(j = 0; j < MAX_DISKS; j++) {
5812 c88676f8 bellard
                if (bs_table[j]) {
5813 c88676f8 bellard
                    sector_num = bdrv_hash_find(bs_table[j], 
5814 c88676f8 bellard
                                                phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
5815 c88676f8 bellard
                    if (sector_num >= 0)
5816 c88676f8 bellard
                        break;
5817 c88676f8 bellard
                }
5818 c88676f8 bellard
            }
5819 c88676f8 bellard
            if (j == MAX_DISKS)
5820 c88676f8 bellard
                goto normal_compress;
5821 c88676f8 bellard
            buf[0] = 1;
5822 c88676f8 bellard
            buf[1] = j;
5823 c88676f8 bellard
            cpu_to_be64wu((uint64_t *)(buf + 2), sector_num);
5824 c88676f8 bellard
            ram_compress_buf(s, buf, 10);
5825 c88676f8 bellard
        } else 
5826 c88676f8 bellard
#endif
5827 c88676f8 bellard
        {
5828 c88676f8 bellard
            //        normal_compress:
5829 c88676f8 bellard
            buf[0] = 0;
5830 c88676f8 bellard
            ram_compress_buf(s, buf, 1);
5831 c88676f8 bellard
            ram_compress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE);
5832 c88676f8 bellard
        }
5833 8a7ddc38 bellard
    }
5834 c88676f8 bellard
    ram_compress_close(s);
5835 8a7ddc38 bellard
}
5836 8a7ddc38 bellard
5837 8a7ddc38 bellard
static int ram_load(QEMUFile *f, void *opaque, int version_id)
5838 8a7ddc38 bellard
{
5839 c88676f8 bellard
    RamDecompressState s1, *s = &s1;
5840 c88676f8 bellard
    uint8_t buf[10];
5841 c88676f8 bellard
    int i;
5842 8a7ddc38 bellard
5843 c88676f8 bellard
    if (version_id == 1)
5844 c88676f8 bellard
        return ram_load_v1(f, opaque);
5845 c88676f8 bellard
    if (version_id != 2)
5846 8a7ddc38 bellard
        return -EINVAL;
5847 8a7ddc38 bellard
    if (qemu_get_be32(f) != phys_ram_size)
5848 8a7ddc38 bellard
        return -EINVAL;
5849 c88676f8 bellard
    if (ram_decompress_open(s, f) < 0)
5850 c88676f8 bellard
        return -EINVAL;
5851 c88676f8 bellard
    for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
5852 c88676f8 bellard
        if (ram_decompress_buf(s, buf, 1) < 0) {
5853 c88676f8 bellard
            fprintf(stderr, "Error while reading ram block header\n");
5854 c88676f8 bellard
            goto error;
5855 c88676f8 bellard
        }
5856 c88676f8 bellard
        if (buf[0] == 0) {
5857 c88676f8 bellard
            if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) {
5858 c88676f8 bellard
                fprintf(stderr, "Error while reading ram block address=0x%08x", i);
5859 c88676f8 bellard
                goto error;
5860 c88676f8 bellard
            }
5861 c88676f8 bellard
        } else 
5862 c88676f8 bellard
#if 0
5863 c88676f8 bellard
        if (buf[0] == 1) {
5864 c88676f8 bellard
            int bs_index;
5865 c88676f8 bellard
            int64_t sector_num;
5866 c88676f8 bellard

5867 c88676f8 bellard
            ram_decompress_buf(s, buf + 1, 9);
5868 c88676f8 bellard
            bs_index = buf[1];
5869 c88676f8 bellard
            sector_num = be64_to_cpupu((const uint64_t *)(buf + 2));
5870 c88676f8 bellard
            if (bs_index >= MAX_DISKS || bs_table[bs_index] == NULL) {
5871 c88676f8 bellard
                fprintf(stderr, "Invalid block device index %d\n", bs_index);
5872 c88676f8 bellard
                goto error;
5873 c88676f8 bellard
            }
5874 c88676f8 bellard
            if (bdrv_read(bs_table[bs_index], sector_num, phys_ram_base + i, 
5875 c88676f8 bellard
                          BDRV_HASH_BLOCK_SIZE / 512) < 0) {
5876 c88676f8 bellard
                fprintf(stderr, "Error while reading sector %d:%" PRId64 "\n", 
5877 c88676f8 bellard
                        bs_index, sector_num);
5878 c88676f8 bellard
                goto error;
5879 c88676f8 bellard
            }
5880 c88676f8 bellard
        } else 
5881 c88676f8 bellard
#endif
5882 c88676f8 bellard
        {
5883 c88676f8 bellard
        error:
5884 c88676f8 bellard
            printf("Error block header\n");
5885 c88676f8 bellard
            return -EINVAL;
5886 c88676f8 bellard
        }
5887 8a7ddc38 bellard
    }
5888 c88676f8 bellard
    ram_decompress_close(s);
5889 8a7ddc38 bellard
    return 0;
5890 8a7ddc38 bellard
}
5891 8a7ddc38 bellard
5892 8a7ddc38 bellard
/***********************************************************/
5893 83f64091 bellard
/* bottom halves (can be seen as timers which expire ASAP) */
5894 83f64091 bellard
5895 83f64091 bellard
struct QEMUBH {
5896 83f64091 bellard
    QEMUBHFunc *cb;
5897 83f64091 bellard
    void *opaque;
5898 83f64091 bellard
    int scheduled;
5899 83f64091 bellard
    QEMUBH *next;
5900 83f64091 bellard
};
5901 83f64091 bellard
5902 83f64091 bellard
static QEMUBH *first_bh = NULL;
5903 83f64091 bellard
5904 83f64091 bellard
QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
5905 83f64091 bellard
{
5906 83f64091 bellard
    QEMUBH *bh;
5907 83f64091 bellard
    bh = qemu_mallocz(sizeof(QEMUBH));
5908 83f64091 bellard
    if (!bh)
5909 83f64091 bellard
        return NULL;
5910 83f64091 bellard
    bh->cb = cb;
5911 83f64091 bellard
    bh->opaque = opaque;
5912 83f64091 bellard
    return bh;
5913 83f64091 bellard
}
5914 83f64091 bellard
5915 6eb5733a bellard
int qemu_bh_poll(void)
5916 83f64091 bellard
{
5917 83f64091 bellard
    QEMUBH *bh, **pbh;
5918 6eb5733a bellard
    int ret;
5919 83f64091 bellard
5920 6eb5733a bellard
    ret = 0;
5921 83f64091 bellard
    for(;;) {
5922 83f64091 bellard
        pbh = &first_bh;
5923 83f64091 bellard
        bh = *pbh;
5924 83f64091 bellard
        if (!bh)
5925 83f64091 bellard
            break;
5926 6eb5733a bellard
        ret = 1;
5927 83f64091 bellard
        *pbh = bh->next;
5928 83f64091 bellard
        bh->scheduled = 0;
5929 83f64091 bellard
        bh->cb(bh->opaque);
5930 83f64091 bellard
    }
5931 6eb5733a bellard
    return ret;
5932 83f64091 bellard
}
5933 83f64091 bellard
5934 83f64091 bellard
void qemu_bh_schedule(QEMUBH *bh)
5935 83f64091 bellard
{
5936 83f64091 bellard
    CPUState *env = cpu_single_env;
5937 83f64091 bellard
    if (bh->scheduled)
5938 83f64091 bellard
        return;
5939 83f64091 bellard
    bh->scheduled = 1;
5940 83f64091 bellard
    bh->next = first_bh;
5941 83f64091 bellard
    first_bh = bh;
5942 83f64091 bellard
5943 83f64091 bellard
    /* stop the currently executing CPU to execute the BH ASAP */
5944 83f64091 bellard
    if (env) {
5945 83f64091 bellard
        cpu_interrupt(env, CPU_INTERRUPT_EXIT);
5946 83f64091 bellard
    }
5947 83f64091 bellard
}
5948 83f64091 bellard
5949 83f64091 bellard
void qemu_bh_cancel(QEMUBH *bh)
5950 83f64091 bellard
{
5951 83f64091 bellard
    QEMUBH **pbh;
5952 83f64091 bellard
    if (bh->scheduled) {
5953 83f64091 bellard
        pbh = &first_bh;
5954 83f64091 bellard
        while (*pbh != bh)
5955 83f64091 bellard
            pbh = &(*pbh)->next;
5956 83f64091 bellard
        *pbh = bh->next;
5957 83f64091 bellard
        bh->scheduled = 0;
5958 83f64091 bellard
    }
5959 83f64091 bellard
}
5960 83f64091 bellard
5961 83f64091 bellard
void qemu_bh_delete(QEMUBH *bh)
5962 83f64091 bellard
{
5963 83f64091 bellard
    qemu_bh_cancel(bh);
5964 83f64091 bellard
    qemu_free(bh);
5965 83f64091 bellard
}
5966 83f64091 bellard
5967 83f64091 bellard
/***********************************************************/
5968 cc1daa40 bellard
/* machine registration */
5969 cc1daa40 bellard
5970 cc1daa40 bellard
QEMUMachine *first_machine = NULL;
5971 cc1daa40 bellard
5972 cc1daa40 bellard
int qemu_register_machine(QEMUMachine *m)
5973 cc1daa40 bellard
{
5974 cc1daa40 bellard
    QEMUMachine **pm;
5975 cc1daa40 bellard
    pm = &first_machine;
5976 cc1daa40 bellard
    while (*pm != NULL)
5977 cc1daa40 bellard
        pm = &(*pm)->next;
5978 cc1daa40 bellard
    m->next = NULL;
5979 cc1daa40 bellard
    *pm = m;
5980 cc1daa40 bellard
    return 0;
5981 cc1daa40 bellard
}
5982 cc1daa40 bellard
5983 cc1daa40 bellard
QEMUMachine *find_machine(const char *name)
5984 cc1daa40 bellard
{
5985 cc1daa40 bellard
    QEMUMachine *m;
5986 cc1daa40 bellard
5987 cc1daa40 bellard
    for(m = first_machine; m != NULL; m = m->next) {
5988 cc1daa40 bellard
        if (!strcmp(m->name, name))
5989 cc1daa40 bellard
            return m;
5990 cc1daa40 bellard
    }
5991 cc1daa40 bellard
    return NULL;
5992 cc1daa40 bellard
}
5993 cc1daa40 bellard
5994 cc1daa40 bellard
/***********************************************************/
5995 8a7ddc38 bellard
/* main execution loop */
5996 8a7ddc38 bellard
5997 8a7ddc38 bellard
void gui_update(void *opaque)
5998 8a7ddc38 bellard
{
5999 8a7ddc38 bellard
    display_state.dpy_refresh(&display_state);
6000 8a7ddc38 bellard
    qemu_mod_timer(gui_timer, GUI_REFRESH_INTERVAL + qemu_get_clock(rt_clock));
6001 8a7ddc38 bellard
}
6002 8a7ddc38 bellard
6003 0bd48850 bellard
struct vm_change_state_entry {
6004 0bd48850 bellard
    VMChangeStateHandler *cb;
6005 0bd48850 bellard
    void *opaque;
6006 0bd48850 bellard
    LIST_ENTRY (vm_change_state_entry) entries;
6007 0bd48850 bellard
};
6008 0bd48850 bellard
6009 0bd48850 bellard
static LIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
6010 0bd48850 bellard
6011 0bd48850 bellard
VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
6012 0bd48850 bellard
                                                     void *opaque)
6013 0bd48850 bellard
{
6014 0bd48850 bellard
    VMChangeStateEntry *e;
6015 0bd48850 bellard
6016 0bd48850 bellard
    e = qemu_mallocz(sizeof (*e));
6017 0bd48850 bellard
    if (!e)
6018 0bd48850 bellard
        return NULL;
6019 0bd48850 bellard
6020 0bd48850 bellard
    e->cb = cb;
6021 0bd48850 bellard
    e->opaque = opaque;
6022 0bd48850 bellard
    LIST_INSERT_HEAD(&vm_change_state_head, e, entries);
6023 0bd48850 bellard
    return e;
6024 0bd48850 bellard
}
6025 0bd48850 bellard
6026 0bd48850 bellard
void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
6027 0bd48850 bellard
{
6028 0bd48850 bellard
    LIST_REMOVE (e, entries);
6029 0bd48850 bellard
    qemu_free (e);
6030 0bd48850 bellard
}
6031 0bd48850 bellard
6032 0bd48850 bellard
static void vm_state_notify(int running)
6033 0bd48850 bellard
{
6034 0bd48850 bellard
    VMChangeStateEntry *e;
6035 0bd48850 bellard
6036 0bd48850 bellard
    for (e = vm_change_state_head.lh_first; e; e = e->entries.le_next) {
6037 0bd48850 bellard
        e->cb(e->opaque, running);
6038 0bd48850 bellard
    }
6039 0bd48850 bellard
}
6040 0bd48850 bellard
6041 8a7ddc38 bellard
/* XXX: support several handlers */
6042 0bd48850 bellard
static VMStopHandler *vm_stop_cb;
6043 0bd48850 bellard
static void *vm_stop_opaque;
6044 8a7ddc38 bellard
6045 8a7ddc38 bellard
int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
6046 8a7ddc38 bellard
{
6047 8a7ddc38 bellard
    vm_stop_cb = cb;
6048 8a7ddc38 bellard
    vm_stop_opaque = opaque;
6049 8a7ddc38 bellard
    return 0;
6050 8a7ddc38 bellard
}
6051 8a7ddc38 bellard
6052 8a7ddc38 bellard
void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
6053 8a7ddc38 bellard
{
6054 8a7ddc38 bellard
    vm_stop_cb = NULL;
6055 8a7ddc38 bellard
}
6056 8a7ddc38 bellard
6057 8a7ddc38 bellard
void vm_start(void)
6058 8a7ddc38 bellard
{
6059 8a7ddc38 bellard
    if (!vm_running) {
6060 8a7ddc38 bellard
        cpu_enable_ticks();
6061 8a7ddc38 bellard
        vm_running = 1;
6062 0bd48850 bellard
        vm_state_notify(1);
6063 8a7ddc38 bellard
    }
6064 8a7ddc38 bellard
}
6065 8a7ddc38 bellard
6066 8a7ddc38 bellard
void vm_stop(int reason) 
6067 8a7ddc38 bellard
{
6068 8a7ddc38 bellard
    if (vm_running) {
6069 8a7ddc38 bellard
        cpu_disable_ticks();
6070 8a7ddc38 bellard
        vm_running = 0;
6071 8a7ddc38 bellard
        if (reason != 0) {
6072 8a7ddc38 bellard
            if (vm_stop_cb) {
6073 8a7ddc38 bellard
                vm_stop_cb(vm_stop_opaque, reason);
6074 8a7ddc38 bellard
            }
6075 34865134 bellard
        }
6076 0bd48850 bellard
        vm_state_notify(0);
6077 8a7ddc38 bellard
    }
6078 8a7ddc38 bellard
}
6079 8a7ddc38 bellard
6080 bb0c6722 bellard
/* reset/shutdown handler */
6081 bb0c6722 bellard
6082 bb0c6722 bellard
typedef struct QEMUResetEntry {
6083 bb0c6722 bellard
    QEMUResetHandler *func;
6084 bb0c6722 bellard
    void *opaque;
6085 bb0c6722 bellard
    struct QEMUResetEntry *next;
6086 bb0c6722 bellard
} QEMUResetEntry;
6087 bb0c6722 bellard
6088 bb0c6722 bellard
static QEMUResetEntry *first_reset_entry;
6089 bb0c6722 bellard
static int reset_requested;
6090 bb0c6722 bellard
static int shutdown_requested;
6091 3475187d bellard
static int powerdown_requested;
6092 bb0c6722 bellard
6093 bb0c6722 bellard
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
6094 bb0c6722 bellard
{
6095 bb0c6722 bellard
    QEMUResetEntry **pre, *re;
6096 bb0c6722 bellard
6097 bb0c6722 bellard
    pre = &first_reset_entry;
6098 bb0c6722 bellard
    while (*pre != NULL)
6099 bb0c6722 bellard
        pre = &(*pre)->next;
6100 bb0c6722 bellard
    re = qemu_mallocz(sizeof(QEMUResetEntry));
6101 bb0c6722 bellard
    re->func = func;
6102 bb0c6722 bellard
    re->opaque = opaque;
6103 bb0c6722 bellard
    re->next = NULL;
6104 bb0c6722 bellard
    *pre = re;
6105 bb0c6722 bellard
}
6106 bb0c6722 bellard
6107 52f61fde ths
static void qemu_system_reset(void)
6108 bb0c6722 bellard
{
6109 bb0c6722 bellard
    QEMUResetEntry *re;
6110 bb0c6722 bellard
6111 bb0c6722 bellard
    /* reset all devices */
6112 bb0c6722 bellard
    for(re = first_reset_entry; re != NULL; re = re->next) {
6113 bb0c6722 bellard
        re->func(re->opaque);
6114 bb0c6722 bellard
    }
6115 bb0c6722 bellard
}
6116 bb0c6722 bellard
6117 bb0c6722 bellard
void qemu_system_reset_request(void)
6118 bb0c6722 bellard
{
6119 d1beab82 bellard
    if (no_reboot) {
6120 d1beab82 bellard
        shutdown_requested = 1;
6121 d1beab82 bellard
    } else {
6122 d1beab82 bellard
        reset_requested = 1;
6123 d1beab82 bellard
    }
6124 6a00d601 bellard
    if (cpu_single_env)
6125 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
6126 bb0c6722 bellard
}
6127 bb0c6722 bellard
6128 bb0c6722 bellard
void qemu_system_shutdown_request(void)
6129 bb0c6722 bellard
{
6130 bb0c6722 bellard
    shutdown_requested = 1;
6131 6a00d601 bellard
    if (cpu_single_env)
6132 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
6133 bb0c6722 bellard
}
6134 bb0c6722 bellard
6135 3475187d bellard
void qemu_system_powerdown_request(void)
6136 3475187d bellard
{
6137 3475187d bellard
    powerdown_requested = 1;
6138 6a00d601 bellard
    if (cpu_single_env)
6139 6a00d601 bellard
        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
6140 bb0c6722 bellard
}
6141 bb0c6722 bellard
6142 5905b2e5 bellard
void main_loop_wait(int timeout)
6143 8a7ddc38 bellard
{
6144 cafffd40 ths
    IOHandlerRecord *ioh;
6145 e035649e bellard
    fd_set rfds, wfds, xfds;
6146 fd1dff4b bellard
    int ret, nfds;
6147 fd1dff4b bellard
    struct timeval tv;
6148 f331110f bellard
    PollingEntry *pe;
6149 f331110f bellard
6150 c4b1fcc0 bellard
6151 f331110f bellard
    /* XXX: need to suppress polling by better using win32 events */
6152 f331110f bellard
    ret = 0;
6153 f331110f bellard
    for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
6154 f331110f bellard
        ret |= pe->func(pe->opaque);
6155 f331110f bellard
    }
6156 38e205a2 bellard
#ifdef _WIN32
6157 f331110f bellard
    if (ret == 0 && timeout > 0) {
6158 a18e524a bellard
        int err;
6159 a18e524a bellard
        WaitObjects *w = &wait_objects;
6160 a18e524a bellard
        
6161 a18e524a bellard
        ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout);
6162 a18e524a bellard
        if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
6163 a18e524a bellard
            if (w->func[ret - WAIT_OBJECT_0])
6164 a18e524a bellard
                w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
6165 a18e524a bellard
        } else if (ret == WAIT_TIMEOUT) {
6166 a18e524a bellard
        } else {
6167 a18e524a bellard
            err = GetLastError();
6168 a18e524a bellard
            fprintf(stderr, "Wait error %d %d\n", ret, err);
6169 a18e524a bellard
        }
6170 f331110f bellard
    }
6171 fd1dff4b bellard
#endif
6172 fd1dff4b bellard
    /* poll any events */
6173 fd1dff4b bellard
    /* XXX: separate device handlers from system ones */
6174 fd1dff4b bellard
    nfds = -1;
6175 fd1dff4b bellard
    FD_ZERO(&rfds);
6176 fd1dff4b bellard
    FD_ZERO(&wfds);
6177 e035649e bellard
    FD_ZERO(&xfds);
6178 fd1dff4b bellard
    for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
6179 cafffd40 ths
        if (ioh->deleted)
6180 cafffd40 ths
            continue;
6181 fd1dff4b bellard
        if (ioh->fd_read &&
6182 fd1dff4b bellard
            (!ioh->fd_read_poll ||
6183 fd1dff4b bellard
             ioh->fd_read_poll(ioh->opaque) != 0)) {
6184 fd1dff4b bellard
            FD_SET(ioh->fd, &rfds);
6185 fd1dff4b bellard
            if (ioh->fd > nfds)
6186 fd1dff4b bellard
                nfds = ioh->fd;
6187 fd1dff4b bellard
        }
6188 fd1dff4b bellard
        if (ioh->fd_write) {
6189 fd1dff4b bellard
            FD_SET(ioh->fd, &wfds);
6190 fd1dff4b bellard
            if (ioh->fd > nfds)
6191 fd1dff4b bellard
                nfds = ioh->fd;
6192 fd1dff4b bellard
        }
6193 fd1dff4b bellard
    }
6194 fd1dff4b bellard
    
6195 fd1dff4b bellard
    tv.tv_sec = 0;
6196 fd1dff4b bellard
#ifdef _WIN32
6197 fd1dff4b bellard
    tv.tv_usec = 0;
6198 38e205a2 bellard
#else
6199 fd1dff4b bellard
    tv.tv_usec = timeout * 1000;
6200 fd1dff4b bellard
#endif
6201 e035649e bellard
#if defined(CONFIG_SLIRP)
6202 e035649e bellard
    if (slirp_inited) {
6203 e035649e bellard
        slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
6204 e035649e bellard
    }
6205 e035649e bellard
#endif
6206 e035649e bellard
    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
6207 fd1dff4b bellard
    if (ret > 0) {
6208 cafffd40 ths
        IOHandlerRecord **pioh;
6209 cafffd40 ths
6210 cafffd40 ths
        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
6211 cafffd40 ths
            if (ioh->deleted)
6212 cafffd40 ths
                continue;
6213 fd1dff4b bellard
            if (FD_ISSET(ioh->fd, &rfds)) {
6214 fd1dff4b bellard
                ioh->fd_read(ioh->opaque);
6215 7c9d8e07 bellard
            }
6216 fd1dff4b bellard
            if (FD_ISSET(ioh->fd, &wfds)) {
6217 fd1dff4b bellard
                ioh->fd_write(ioh->opaque);
6218 c4b1fcc0 bellard
            }
6219 b4608c04 bellard
        }
6220 cafffd40 ths
6221 cafffd40 ths
        /* remove deleted IO handlers */
6222 cafffd40 ths
        pioh = &first_io_handler;
6223 cafffd40 ths
        while (*pioh) {
6224 cafffd40 ths
            ioh = *pioh;
6225 cafffd40 ths
            if (ioh->deleted) {
6226 cafffd40 ths
                *pioh = ioh->next;
6227 cafffd40 ths
                qemu_free(ioh);
6228 cafffd40 ths
            } else 
6229 cafffd40 ths
                pioh = &ioh->next;
6230 cafffd40 ths
        }
6231 fd1dff4b bellard
    }
6232 c20709aa bellard
#if defined(CONFIG_SLIRP)
6233 fd1dff4b bellard
    if (slirp_inited) {
6234 e035649e bellard
        if (ret < 0) {
6235 e035649e bellard
            FD_ZERO(&rfds);
6236 e035649e bellard
            FD_ZERO(&wfds);
6237 e035649e bellard
            FD_ZERO(&xfds);
6238 c20709aa bellard
        }
6239 e035649e bellard
        slirp_select_poll(&rfds, &wfds, &xfds);
6240 fd1dff4b bellard
    }
6241 c20709aa bellard
#endif
6242 83f64091 bellard
    qemu_aio_poll();
6243 83f64091 bellard
    qemu_bh_poll();
6244 c20709aa bellard
6245 fd1dff4b bellard
    if (vm_running) {
6246 fd1dff4b bellard
        qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL], 
6247 fd1dff4b bellard
                        qemu_get_clock(vm_clock));
6248 fd1dff4b bellard
        /* run dma transfers, if any */
6249 fd1dff4b bellard
        DMA_run();
6250 fd1dff4b bellard
    }
6251 fd1dff4b bellard
    
6252 fd1dff4b bellard
    /* real time timers */
6253 fd1dff4b bellard
    qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME], 
6254 fd1dff4b bellard
                    qemu_get_clock(rt_clock));
6255 5905b2e5 bellard
}
6256 5905b2e5 bellard
6257 6a00d601 bellard
static CPUState *cur_cpu;
6258 6a00d601 bellard
6259 5905b2e5 bellard
int main_loop(void)
6260 5905b2e5 bellard
{
6261 5905b2e5 bellard
    int ret, timeout;
6262 89bfc105 bellard
#ifdef CONFIG_PROFILER
6263 89bfc105 bellard
    int64_t ti;
6264 89bfc105 bellard
#endif
6265 6a00d601 bellard
    CPUState *env;
6266 5905b2e5 bellard
6267 6a00d601 bellard
    cur_cpu = first_cpu;
6268 5905b2e5 bellard
    for(;;) {
6269 5905b2e5 bellard
        if (vm_running) {
6270 15a76449 bellard
6271 15a76449 bellard
            env = cur_cpu;
6272 15a76449 bellard
            for(;;) {
6273 15a76449 bellard
                /* get next cpu */
6274 15a76449 bellard
                env = env->next_cpu;
6275 15a76449 bellard
                if (!env)
6276 15a76449 bellard
                    env = first_cpu;
6277 89bfc105 bellard
#ifdef CONFIG_PROFILER
6278 89bfc105 bellard
                ti = profile_getclock();
6279 89bfc105 bellard
#endif
6280 6a00d601 bellard
                ret = cpu_exec(env);
6281 89bfc105 bellard
#ifdef CONFIG_PROFILER
6282 89bfc105 bellard
                qemu_time += profile_getclock() - ti;
6283 89bfc105 bellard
#endif
6284 bd967e05 pbrook
                if (ret == EXCP_HLT) {
6285 bd967e05 pbrook
                    /* Give the next CPU a chance to run.  */
6286 bd967e05 pbrook
                    cur_cpu = env;
6287 bd967e05 pbrook
                    continue;
6288 bd967e05 pbrook
                }
6289 15a76449 bellard
                if (ret != EXCP_HALTED)
6290 15a76449 bellard
                    break;
6291 15a76449 bellard
                /* all CPUs are halted ? */
6292 bd967e05 pbrook
                if (env == cur_cpu)
6293 15a76449 bellard
                    break;
6294 15a76449 bellard
            }
6295 15a76449 bellard
            cur_cpu = env;
6296 15a76449 bellard
6297 5905b2e5 bellard
            if (shutdown_requested) {
6298 3475187d bellard
                ret = EXCP_INTERRUPT;
6299 5905b2e5 bellard
                break;
6300 5905b2e5 bellard
            }
6301 5905b2e5 bellard
            if (reset_requested) {
6302 5905b2e5 bellard
                reset_requested = 0;
6303 5905b2e5 bellard
                qemu_system_reset();
6304 3475187d bellard
                ret = EXCP_INTERRUPT;
6305 3475187d bellard
            }
6306 3475187d bellard
            if (powerdown_requested) {
6307 3475187d bellard
                powerdown_requested = 0;
6308 3475187d bellard
                qemu_system_powerdown();
6309 3475187d bellard
                ret = EXCP_INTERRUPT;
6310 5905b2e5 bellard
            }
6311 5905b2e5 bellard
            if (ret == EXCP_DEBUG) {
6312 5905b2e5 bellard
                vm_stop(EXCP_DEBUG);
6313 5905b2e5 bellard
            }
6314 bd967e05 pbrook
            /* If all cpus are halted then wait until the next IRQ */
6315 5905b2e5 bellard
            /* XXX: use timeout computed from timers */
6316 bd967e05 pbrook
            if (ret == EXCP_HALTED)
6317 5905b2e5 bellard
                timeout = 10;
6318 5905b2e5 bellard
            else
6319 5905b2e5 bellard
                timeout = 0;
6320 5905b2e5 bellard
        } else {
6321 5905b2e5 bellard
            timeout = 10;
6322 5905b2e5 bellard
        }
6323 89bfc105 bellard
#ifdef CONFIG_PROFILER
6324 89bfc105 bellard
        ti = profile_getclock();
6325 89bfc105 bellard
#endif
6326 5905b2e5 bellard
        main_loop_wait(timeout);
6327 89bfc105 bellard
#ifdef CONFIG_PROFILER
6328 89bfc105 bellard
        dev_time += profile_getclock() - ti;
6329 89bfc105 bellard
#endif
6330 b4608c04 bellard
    }
6331 34865134 bellard
    cpu_disable_ticks();
6332 34865134 bellard
    return ret;
6333 b4608c04 bellard
}
6334 b4608c04 bellard
6335 0824d6fc bellard
void help(void)
6336 0824d6fc bellard
{
6337 84f2e8ef bellard
    printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2007 Fabrice Bellard\n"
6338 0db63474 bellard
           "usage: %s [options] [disk_image]\n"
6339 0824d6fc bellard
           "\n"
6340 a20dd508 bellard
           "'disk_image' is a raw hard image image for IDE hard disk 0\n"
6341 fc01f7e7 bellard
           "\n"
6342 a20dd508 bellard
           "Standard options:\n"
6343 cc1daa40 bellard
           "-M machine      select emulated machine (-M ? for list)\n"
6344 5adb4839 pbrook
           "-cpu cpu        select CPU (-cpu ? for list)\n"
6345 c45886db bellard
           "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n"
6346 36b486bb bellard
           "-hda/-hdb file  use 'file' as IDE hard disk 0/1 image\n"
6347 36b486bb bellard
           "-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image\n"
6348 c4b1fcc0 bellard
           "-cdrom file     use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
6349 a1bb27b1 pbrook
           "-sd file        use 'file' as SecureDigital card image\n"
6350 eec85c2a ths
           "-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n"
6351 667accab ths
           "-snapshot       write to temporary files instead of disk image files\n"
6352 667accab ths
#ifdef CONFIG_SDL
6353 43523e93 ths
           "-no-frame       open SDL window without a frame and window decorations\n"
6354 667accab ths
           "-no-quit        disable SDL window close capability\n"
6355 667accab ths
#endif
6356 52ca8d6a bellard
#ifdef TARGET_I386
6357 52ca8d6a bellard
           "-no-fd-bootchk  disable boot signature checking for floppy disks\n"
6358 52ca8d6a bellard
#endif
6359 a00bad7e bellard
           "-m megs         set virtual RAM size to megs MB [default=%d]\n"
6360 91fc2119 bellard
           "-smp n          set the number of CPUs to 'n' [default=1]\n"
6361 c4b1fcc0 bellard
           "-nographic      disable graphical output and redirect serial I/Os to console\n"
6362 4ca0074c bellard
#ifndef _WIN32
6363 667accab ths
           "-k language     use keyboard layout (for example \"fr\" for French)\n"
6364 4ca0074c bellard
#endif
6365 1d14ffa9 bellard
#ifdef HAS_AUDIO
6366 1d14ffa9 bellard
           "-audio-help     print list of audio drivers and their options\n"
6367 c0fe3827 bellard
           "-soundhw c1,... enable audio support\n"
6368 c0fe3827 bellard
           "                and only specified sound cards (comma separated list)\n"
6369 c0fe3827 bellard
           "                use -soundhw ? to get the list of supported cards\n"
6370 6a36d84e bellard
           "                use -soundhw all to enable all of them\n"
6371 1d14ffa9 bellard
#endif
6372 89980284 bellard
           "-localtime      set the real time clock to local time [default=utc]\n"
6373 d63d307f bellard
           "-full-screen    start in full screen\n"
6374 a09db21f bellard
#ifdef TARGET_I386
6375 a09db21f bellard
           "-win2k-hack     use it when installing Windows 2000 to avoid a disk full bug\n"
6376 a09db21f bellard
#endif
6377 b389dbfb bellard
           "-usb            enable the USB driver (will be the default soon)\n"
6378 b389dbfb bellard
           "-usbdevice name add the host or guest USB device 'name'\n"
6379 6f7e9aec bellard
#if defined(TARGET_PPC) || defined(TARGET_SPARC)
6380 6f7e9aec bellard
           "-g WxH[xDEPTH]  Set the initial graphical resolution and depth\n"
6381 bb0c6722 bellard
#endif
6382 c35734b2 ths
           "-name string    set the name of the guest\n"
6383 c4b1fcc0 bellard
           "\n"
6384 c4b1fcc0 bellard
           "Network options:\n"
6385 a41b2ff2 pbrook
           "-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
6386 7c9d8e07 bellard
           "                create a new Network Interface Card and connect it to VLAN 'n'\n"
6387 c20709aa bellard
#ifdef CONFIG_SLIRP
6388 115defd1 pbrook
           "-net user[,vlan=n][,hostname=host]\n"
6389 115defd1 pbrook
           "                connect the user mode network stack to VLAN 'n' and send\n"
6390 115defd1 pbrook
           "                hostname 'host' to DHCP clients\n"
6391 7c9d8e07 bellard
#endif
6392 7fb843f8 bellard
#ifdef _WIN32
6393 7fb843f8 bellard
           "-net tap[,vlan=n],ifname=name\n"
6394 7fb843f8 bellard
           "                connect the host TAP network interface to VLAN 'n'\n"
6395 7fb843f8 bellard
#else
6396 7c9d8e07 bellard
           "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file]\n"
6397 7c9d8e07 bellard
           "                connect the host TAP network interface to VLAN 'n' and use\n"
6398 7c9d8e07 bellard
           "                the network script 'file' (default=%s);\n"
6399 6a1cbf68 ths
           "                use 'script=no' to disable script execution;\n"
6400 7c9d8e07 bellard
           "                use 'fd=h' to connect to an already opened TAP interface\n"
6401 7fb843f8 bellard
#endif
6402 6a00d601 bellard
           "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
6403 7c9d8e07 bellard
           "                connect the vlan 'n' to another VLAN using a socket connection\n"
6404 3d830459 bellard
           "-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n"
6405 3d830459 bellard
           "                connect the vlan 'n' to multicast maddr and port\n"
6406 7c9d8e07 bellard
           "-net none       use it alone to have zero network devices; if no -net option\n"
6407 7c9d8e07 bellard
           "                is provided, the default is '-net nic -net user'\n"
6408 7c9d8e07 bellard
           "\n"
6409 7c9d8e07 bellard
#ifdef CONFIG_SLIRP
6410 0db1137d ths
           "-tftp dir       allow tftp access to files in dir [-net user]\n"
6411 47d5d01a ths
           "-bootp file     advertise file in BOOTP replies\n"
6412 7c9d8e07 bellard
#ifndef _WIN32
6413 7c9d8e07 bellard
           "-smb dir        allow SMB access to files in 'dir' [-net user]\n"
6414 c94c8d64 bellard
#endif
6415 9bf05444 bellard
           "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
6416 7c9d8e07 bellard
           "                redirect TCP or UDP connections from host to guest [-net user]\n"
6417 c20709aa bellard
#endif
6418 a20dd508 bellard
           "\n"
6419 c4b1fcc0 bellard
           "Linux boot specific:\n"
6420 a20dd508 bellard
           "-kernel bzImage use 'bzImage' as kernel image\n"
6421 a20dd508 bellard
           "-append cmdline use 'cmdline' as kernel command line\n"
6422 a20dd508 bellard
           "-initrd file    use 'file' as initial ram disk\n"
6423 fc01f7e7 bellard
           "\n"
6424 330d0414 bellard
           "Debug/Expert options:\n"
6425 82c643ff bellard
           "-monitor dev    redirect the monitor to char device 'dev'\n"
6426 82c643ff bellard
           "-serial dev     redirect the serial port to char device 'dev'\n"
6427 6508fe59 bellard
           "-parallel dev   redirect the parallel port to char device 'dev'\n"
6428 f7cce898 bellard
           "-pidfile file   Write PID to 'file'\n"
6429 cd6f1169 bellard
           "-S              freeze CPU at startup (use 'c' to start execution)\n"
6430 cfc3475a pbrook
           "-s              wait gdb connection to port\n"
6431 cfc3475a pbrook
           "-p port         set gdb connection port [default=%s]\n"
6432 f193c797 bellard
           "-d item1,...    output log to %s (use -d ? for a list of log items)\n"
6433 46d4767d bellard
           "-hdachs c,h,s[,t]  force hard disk 0 physical geometry and the optional BIOS\n"
6434 46d4767d bellard
           "                translation (t=none or lba) (usually qemu can guess them)\n"
6435 87b47350 bellard
           "-L path         set the directory for the BIOS, VGA BIOS and keymaps\n"
6436 d993e026 bellard
#ifdef USE_KQEMU
6437 6515b203 bellard
           "-kernel-kqemu   enable KQEMU full virtualization (default is user mode only)\n"
6438 d993e026 bellard
           "-no-kqemu       disable KQEMU kernel module usage\n"
6439 d993e026 bellard
#endif
6440 77fef8c1 bellard
#ifdef USE_CODE_COPY
6441 77fef8c1 bellard
           "-no-code-copy   disable code copy acceleration\n"
6442 77fef8c1 bellard
#endif
6443 bb0c6722 bellard
#ifdef TARGET_I386
6444 1bfe856e bellard
           "-std-vga        simulate a standard VGA card with VESA Bochs Extensions\n"
6445 1bfe856e bellard
           "                (default is CL-GD5446 PCI VGA)\n"
6446 6515b203 bellard
           "-no-acpi        disable ACPI\n"
6447 bb0c6722 bellard
#endif
6448 d1beab82 bellard
           "-no-reboot      exit instead of rebooting\n"
6449 d63d307f bellard
           "-loadvm file    start right away with a saved state (loadvm in monitor)\n"
6450 24236869 bellard
           "-vnc display    start a VNC server on display\n"
6451 71e3ceb8 ths
#ifndef _WIN32
6452 71e3ceb8 ths
           "-daemonize      daemonize QEMU after initializing\n"
6453 71e3ceb8 ths
#endif
6454 9ae02555 ths
           "-option-rom rom load a file, rom, into the option ROM space\n"
6455 0824d6fc bellard
           "\n"
6456 82c643ff bellard
           "During emulation, the following keys are useful:\n"
6457 032a8c9e bellard
           "ctrl-alt-f      toggle full screen\n"
6458 032a8c9e bellard
           "ctrl-alt-n      switch to virtual console 'n'\n"
6459 032a8c9e bellard
           "ctrl-alt        toggle mouse and keyboard grab\n"
6460 82c643ff bellard
           "\n"
6461 82c643ff bellard
           "When using -nographic, press 'ctrl-a h' to get some help.\n"
6462 82c643ff bellard
           ,
6463 0db63474 bellard
           "qemu",
6464 a00bad7e bellard
           DEFAULT_RAM_SIZE,
6465 7c9d8e07 bellard
#ifndef _WIN32
6466 a00bad7e bellard
           DEFAULT_NETWORK_SCRIPT,
6467 7c9d8e07 bellard
#endif
6468 6e44ba7f bellard
           DEFAULT_GDBSTUB_PORT,
6469 6e44ba7f bellard
           "/tmp/qemu.log");
6470 0824d6fc bellard
    exit(1);
6471 0824d6fc bellard
}
6472 0824d6fc bellard
6473 cd6f1169 bellard
#define HAS_ARG 0x0001
6474 cd6f1169 bellard
6475 cd6f1169 bellard
enum {
6476 cd6f1169 bellard
    QEMU_OPTION_h,
6477 cd6f1169 bellard
6478 cc1daa40 bellard
    QEMU_OPTION_M,
6479 94fc95cd j_mayer
    QEMU_OPTION_cpu,
6480 cd6f1169 bellard
    QEMU_OPTION_fda,
6481 cd6f1169 bellard
    QEMU_OPTION_fdb,
6482 cd6f1169 bellard
    QEMU_OPTION_hda,
6483 cd6f1169 bellard
    QEMU_OPTION_hdb,
6484 cd6f1169 bellard
    QEMU_OPTION_hdc,
6485 cd6f1169 bellard
    QEMU_OPTION_hdd,
6486 cd6f1169 bellard
    QEMU_OPTION_cdrom,
6487 a1bb27b1 pbrook
    QEMU_OPTION_sd,
6488 cd6f1169 bellard
    QEMU_OPTION_boot,
6489 cd6f1169 bellard
    QEMU_OPTION_snapshot,
6490 52ca8d6a bellard
#ifdef TARGET_I386
6491 52ca8d6a bellard
    QEMU_OPTION_no_fd_bootchk,
6492 52ca8d6a bellard
#endif
6493 cd6f1169 bellard
    QEMU_OPTION_m,
6494 cd6f1169 bellard
    QEMU_OPTION_nographic,
6495 1d14ffa9 bellard
#ifdef HAS_AUDIO
6496 1d14ffa9 bellard
    QEMU_OPTION_audio_help,
6497 1d14ffa9 bellard
    QEMU_OPTION_soundhw,
6498 1d14ffa9 bellard
#endif
6499 cd6f1169 bellard
6500 7c9d8e07 bellard
    QEMU_OPTION_net,
6501 c7f74643 bellard
    QEMU_OPTION_tftp,
6502 47d5d01a ths
    QEMU_OPTION_bootp,
6503 9d728e8c bellard
    QEMU_OPTION_smb,
6504 9bf05444 bellard
    QEMU_OPTION_redir,
6505 cd6f1169 bellard
6506 cd6f1169 bellard
    QEMU_OPTION_kernel,
6507 cd6f1169 bellard
    QEMU_OPTION_append,
6508 cd6f1169 bellard
    QEMU_OPTION_initrd,
6509 cd6f1169 bellard
6510 cd6f1169 bellard
    QEMU_OPTION_S,
6511 cd6f1169 bellard
    QEMU_OPTION_s,
6512 cd6f1169 bellard
    QEMU_OPTION_p,
6513 cd6f1169 bellard
    QEMU_OPTION_d,
6514 cd6f1169 bellard
    QEMU_OPTION_hdachs,
6515 cd6f1169 bellard
    QEMU_OPTION_L,
6516 cd6f1169 bellard
    QEMU_OPTION_no_code_copy,
6517 3d11d0eb bellard
    QEMU_OPTION_k,
6518 ee22c2f7 bellard
    QEMU_OPTION_localtime,
6519 1f04275e bellard
    QEMU_OPTION_cirrusvga,
6520 d34cab9f ths
    QEMU_OPTION_vmsvga,
6521 e9b137c2 bellard
    QEMU_OPTION_g,
6522 1bfe856e bellard
    QEMU_OPTION_std_vga,
6523 20d8a3ed ths
    QEMU_OPTION_echr,
6524 82c643ff bellard
    QEMU_OPTION_monitor,
6525 82c643ff bellard
    QEMU_OPTION_serial,
6526 6508fe59 bellard
    QEMU_OPTION_parallel,
6527 d63d307f bellard
    QEMU_OPTION_loadvm,
6528 d63d307f bellard
    QEMU_OPTION_full_screen,
6529 43523e93 ths
    QEMU_OPTION_no_frame,
6530 667accab ths
    QEMU_OPTION_no_quit,
6531 f7cce898 bellard
    QEMU_OPTION_pidfile,
6532 d993e026 bellard
    QEMU_OPTION_no_kqemu,
6533 89bfc105 bellard
    QEMU_OPTION_kernel_kqemu,
6534 a09db21f bellard
    QEMU_OPTION_win2k_hack,
6535 bb36d470 bellard
    QEMU_OPTION_usb,
6536 a594cfbf bellard
    QEMU_OPTION_usbdevice,
6537 6a00d601 bellard
    QEMU_OPTION_smp,
6538 24236869 bellard
    QEMU_OPTION_vnc,
6539 6515b203 bellard
    QEMU_OPTION_no_acpi,
6540 d1beab82 bellard
    QEMU_OPTION_no_reboot,
6541 71e3ceb8 ths
    QEMU_OPTION_daemonize,
6542 9ae02555 ths
    QEMU_OPTION_option_rom,
6543 c35734b2 ths
    QEMU_OPTION_semihosting,
6544 c35734b2 ths
    QEMU_OPTION_name,
6545 cd6f1169 bellard
};
6546 cd6f1169 bellard
6547 cd6f1169 bellard
typedef struct QEMUOption {
6548 cd6f1169 bellard
    const char *name;
6549 cd6f1169 bellard
    int flags;
6550 cd6f1169 bellard
    int index;
6551 cd6f1169 bellard
} QEMUOption;
6552 cd6f1169 bellard
6553 cd6f1169 bellard
const QEMUOption qemu_options[] = {
6554 cd6f1169 bellard
    { "h", 0, QEMU_OPTION_h },
6555 64423fb2 pbrook
    { "help", 0, QEMU_OPTION_h },
6556 cd6f1169 bellard
6557 cc1daa40 bellard
    { "M", HAS_ARG, QEMU_OPTION_M },
6558 94fc95cd j_mayer
    { "cpu", HAS_ARG, QEMU_OPTION_cpu },
6559 cd6f1169 bellard
    { "fda", HAS_ARG, QEMU_OPTION_fda },
6560 cd6f1169 bellard
    { "fdb", HAS_ARG, QEMU_OPTION_fdb },
6561 cd6f1169 bellard
    { "hda", HAS_ARG, QEMU_OPTION_hda },
6562 cd6f1169 bellard
    { "hdb", HAS_ARG, QEMU_OPTION_hdb },
6563 cd6f1169 bellard
    { "hdc", HAS_ARG, QEMU_OPTION_hdc },
6564 cd6f1169 bellard
    { "hdd", HAS_ARG, QEMU_OPTION_hdd },
6565 cd6f1169 bellard
    { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
6566 a1bb27b1 pbrook
    { "sd", HAS_ARG, QEMU_OPTION_sd },
6567 cd6f1169 bellard
    { "boot", HAS_ARG, QEMU_OPTION_boot },
6568 cd6f1169 bellard
    { "snapshot", 0, QEMU_OPTION_snapshot },
6569 52ca8d6a bellard
#ifdef TARGET_I386
6570 52ca8d6a bellard
    { "no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk },
6571 52ca8d6a bellard
#endif
6572 cd6f1169 bellard
    { "m", HAS_ARG, QEMU_OPTION_m },
6573 cd6f1169 bellard
    { "nographic", 0, QEMU_OPTION_nographic },
6574 3d11d0eb bellard
    { "k", HAS_ARG, QEMU_OPTION_k },
6575 1d14ffa9 bellard
#ifdef HAS_AUDIO
6576 1d14ffa9 bellard
    { "audio-help", 0, QEMU_OPTION_audio_help },
6577 1d14ffa9 bellard
    { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
6578 1d14ffa9 bellard
#endif
6579 cd6f1169 bellard
6580 7c9d8e07 bellard
    { "net", HAS_ARG, QEMU_OPTION_net},
6581 158156d1 bellard
#ifdef CONFIG_SLIRP
6582 c7f74643 bellard
    { "tftp", HAS_ARG, QEMU_OPTION_tftp },
6583 47d5d01a ths
    { "bootp", HAS_ARG, QEMU_OPTION_bootp },
6584 c94c8d64 bellard
#ifndef _WIN32
6585 9d728e8c bellard
    { "smb", HAS_ARG, QEMU_OPTION_smb },
6586 c94c8d64 bellard
#endif
6587 9bf05444 bellard
    { "redir", HAS_ARG, QEMU_OPTION_redir },
6588 158156d1 bellard
#endif
6589 cd6f1169 bellard
6590 cd6f1169 bellard
    { "kernel", HAS_ARG, QEMU_OPTION_kernel },
6591 cd6f1169 bellard
    { "append", HAS_ARG, QEMU_OPTION_append },
6592 cd6f1169 bellard
    { "initrd", HAS_ARG, QEMU_OPTION_initrd },
6593 cd6f1169 bellard
6594 cd6f1169 bellard
    { "S", 0, QEMU_OPTION_S },
6595 cd6f1169 bellard
    { "s", 0, QEMU_OPTION_s },
6596 cd6f1169 bellard
    { "p", HAS_ARG, QEMU_OPTION_p },
6597 cd6f1169 bellard
    { "d", HAS_ARG, QEMU_OPTION_d },
6598 cd6f1169 bellard
    { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
6599 cd6f1169 bellard
    { "L", HAS_ARG, QEMU_OPTION_L },
6600 cd6f1169 bellard
    { "no-code-copy", 0, QEMU_OPTION_no_code_copy },
6601 d993e026 bellard
#ifdef USE_KQEMU
6602 d993e026 bellard
    { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
6603 89bfc105 bellard
    { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
6604 d993e026 bellard
#endif
6605 6f7e9aec bellard
#if defined(TARGET_PPC) || defined(TARGET_SPARC)
6606 e9b137c2 bellard
    { "g", 1, QEMU_OPTION_g },
6607 77d4bc34 bellard
#endif
6608 ee22c2f7 bellard
    { "localtime", 0, QEMU_OPTION_localtime },
6609 1bfe856e bellard
    { "std-vga", 0, QEMU_OPTION_std_vga },
6610 20d8a3ed ths
    { "echr", 1, QEMU_OPTION_echr },
6611 82c643ff bellard
    { "monitor", 1, QEMU_OPTION_monitor },
6612 82c643ff bellard
    { "serial", 1, QEMU_OPTION_serial },
6613 6508fe59 bellard
    { "parallel", 1, QEMU_OPTION_parallel },
6614 d63d307f bellard
    { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
6615 d63d307f bellard
    { "full-screen", 0, QEMU_OPTION_full_screen },
6616 667accab ths
#ifdef CONFIG_SDL
6617 43523e93 ths
    { "no-frame", 0, QEMU_OPTION_no_frame },
6618 667accab ths
    { "no-quit", 0, QEMU_OPTION_no_quit },
6619 667accab ths
#endif
6620 f7cce898 bellard
    { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
6621 a09db21f bellard
    { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
6622 a594cfbf bellard
    { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
6623 6a00d601 bellard
    { "smp", HAS_ARG, QEMU_OPTION_smp },
6624 24236869 bellard
    { "vnc", HAS_ARG, QEMU_OPTION_vnc },
6625 96d30e48 ths
6626 1f04275e bellard
    /* temporary options */
6627 a594cfbf bellard
    { "usb", 0, QEMU_OPTION_usb },
6628 1f04275e bellard
    { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
6629 d34cab9f ths
    { "vmwarevga", 0, QEMU_OPTION_vmsvga },
6630 6515b203 bellard
    { "no-acpi", 0, QEMU_OPTION_no_acpi },
6631 d1beab82 bellard
    { "no-reboot", 0, QEMU_OPTION_no_reboot },
6632 71e3ceb8 ths
    { "daemonize", 0, QEMU_OPTION_daemonize },
6633 9ae02555 ths
    { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
6634 8e71621f pbrook
#if defined(TARGET_ARM)
6635 8e71621f pbrook
    { "semihosting", 0, QEMU_OPTION_semihosting },
6636 8e71621f pbrook
#endif
6637 c35734b2 ths
    { "name", HAS_ARG, QEMU_OPTION_name },
6638 cd6f1169 bellard
    { NULL },
6639 fc01f7e7 bellard
};
6640 fc01f7e7 bellard
6641 77fef8c1 bellard
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
6642 77fef8c1 bellard
6643 77fef8c1 bellard
/* this stack is only used during signal handling */
6644 77fef8c1 bellard
#define SIGNAL_STACK_SIZE 32768
6645 77fef8c1 bellard
6646 77fef8c1 bellard
static uint8_t *signal_stack;
6647 77fef8c1 bellard
6648 77fef8c1 bellard
#endif
6649 77fef8c1 bellard
6650 5905b2e5 bellard
/* password input */
6651 5905b2e5 bellard
6652 5905b2e5 bellard
static BlockDriverState *get_bdrv(int index)
6653 5905b2e5 bellard
{
6654 5905b2e5 bellard
    BlockDriverState *bs;
6655 5905b2e5 bellard
6656 5905b2e5 bellard
    if (index < 4) {
6657 5905b2e5 bellard
        bs = bs_table[index];
6658 5905b2e5 bellard
    } else if (index < 6) {
6659 5905b2e5 bellard
        bs = fd_table[index - 4];
6660 5905b2e5 bellard
    } else {
6661 5905b2e5 bellard
        bs = NULL;
6662 5905b2e5 bellard
    }
6663 5905b2e5 bellard
    return bs;
6664 5905b2e5 bellard
}
6665 5905b2e5 bellard
6666 5905b2e5 bellard
static void read_passwords(void)
6667 5905b2e5 bellard
{
6668 5905b2e5 bellard
    BlockDriverState *bs;
6669 5905b2e5 bellard
    int i, j;
6670 5905b2e5 bellard
    char password[256];
6671 5905b2e5 bellard
6672 5905b2e5 bellard
    for(i = 0; i < 6; i++) {
6673 5905b2e5 bellard
        bs = get_bdrv(i);
6674 5905b2e5 bellard
        if (bs && bdrv_is_encrypted(bs)) {
6675 5905b2e5 bellard
            term_printf("%s is encrypted.\n", bdrv_get_device_name(bs));
6676 5905b2e5 bellard
            for(j = 0; j < 3; j++) {
6677 5905b2e5 bellard
                monitor_readline("Password: ", 
6678 5905b2e5 bellard
                                 1, password, sizeof(password));
6679 5905b2e5 bellard
                if (bdrv_set_key(bs, password) == 0)
6680 5905b2e5 bellard
                    break;
6681 5905b2e5 bellard
                term_printf("invalid password\n");
6682 5905b2e5 bellard
            }
6683 5905b2e5 bellard
        }
6684 5905b2e5 bellard
    }
6685 5905b2e5 bellard
}
6686 5905b2e5 bellard
6687 cc1daa40 bellard
/* XXX: currently we cannot use simultaneously different CPUs */
6688 cc1daa40 bellard
void register_machines(void)
6689 cc1daa40 bellard
{
6690 cc1daa40 bellard
#if defined(TARGET_I386)
6691 cc1daa40 bellard
    qemu_register_machine(&pc_machine);
6692 3dbbdc25 bellard
    qemu_register_machine(&isapc_machine);
6693 cc1daa40 bellard
#elif defined(TARGET_PPC)
6694 cc1daa40 bellard
    qemu_register_machine(&heathrow_machine);
6695 cc1daa40 bellard
    qemu_register_machine(&core99_machine);
6696 cc1daa40 bellard
    qemu_register_machine(&prep_machine);
6697 6af0bf9c bellard
#elif defined(TARGET_MIPS)
6698 6af0bf9c bellard
    qemu_register_machine(&mips_machine);
6699 5856de80 ths
    qemu_register_machine(&mips_malta_machine);
6700 cc1daa40 bellard
#elif defined(TARGET_SPARC)
6701 3475187d bellard
#ifdef TARGET_SPARC64
6702 3475187d bellard
    qemu_register_machine(&sun4u_machine);
6703 3475187d bellard
#else
6704 36cd9210 blueswir1
    qemu_register_machine(&ss5_machine);
6705 e0353fe2 blueswir1
    qemu_register_machine(&ss10_machine);
6706 cc1daa40 bellard
#endif
6707 b5ff1b31 bellard
#elif defined(TARGET_ARM)
6708 3371d272 pbrook
    qemu_register_machine(&integratorcp_machine);
6709 cdbdb648 pbrook
    qemu_register_machine(&versatilepb_machine);
6710 16406950 pbrook
    qemu_register_machine(&versatileab_machine);
6711 e69954b9 pbrook
    qemu_register_machine(&realview_machine);
6712 27c7ca7e bellard
#elif defined(TARGET_SH4)
6713 27c7ca7e bellard
    qemu_register_machine(&shix_machine);
6714 eddf68a6 j_mayer
#elif defined(TARGET_ALPHA)
6715 eddf68a6 j_mayer
    /* XXX: TODO */
6716 b5ff1b31 bellard
#else
6717 b5ff1b31 bellard
#error unsupported CPU
6718 3475187d bellard
#endif
6719 cc1daa40 bellard
}
6720 cc1daa40 bellard
6721 1d14ffa9 bellard
#ifdef HAS_AUDIO
6722 6a36d84e bellard
struct soundhw soundhw[] = {
6723 fd06c375 bellard
#ifdef TARGET_I386
6724 fd06c375 bellard
    {
6725 fd06c375 bellard
        "pcspk",
6726 fd06c375 bellard
        "PC speaker",
6727 fd06c375 bellard
        0,
6728 fd06c375 bellard
        1,
6729 fd06c375 bellard
        { .init_isa = pcspk_audio_init }
6730 fd06c375 bellard
    },
6731 fd06c375 bellard
#endif
6732 6a36d84e bellard
    {
6733 6a36d84e bellard
        "sb16",
6734 6a36d84e bellard
        "Creative Sound Blaster 16",
6735 6a36d84e bellard
        0,
6736 6a36d84e bellard
        1,
6737 6a36d84e bellard
        { .init_isa = SB16_init }
6738 6a36d84e bellard
    },
6739 6a36d84e bellard
6740 1d14ffa9 bellard
#ifdef CONFIG_ADLIB
6741 6a36d84e bellard
    {
6742 6a36d84e bellard
        "adlib",
6743 1d14ffa9 bellard
#ifdef HAS_YMF262
6744 6a36d84e bellard
        "Yamaha YMF262 (OPL3)",
6745 1d14ffa9 bellard
#else
6746 6a36d84e bellard
        "Yamaha YM3812 (OPL2)",
6747 1d14ffa9 bellard
#endif
6748 6a36d84e bellard
        0,
6749 6a36d84e bellard
        1,
6750 6a36d84e bellard
        { .init_isa = Adlib_init }
6751 6a36d84e bellard
    },
6752 1d14ffa9 bellard
#endif
6753 6a36d84e bellard
6754 1d14ffa9 bellard
#ifdef CONFIG_GUS
6755 6a36d84e bellard
    {
6756 6a36d84e bellard
        "gus",
6757 6a36d84e bellard
        "Gravis Ultrasound GF1",
6758 6a36d84e bellard
        0,
6759 6a36d84e bellard
        1,
6760 6a36d84e bellard
        { .init_isa = GUS_init }
6761 6a36d84e bellard
    },
6762 1d14ffa9 bellard
#endif
6763 6a36d84e bellard
6764 6a36d84e bellard
    {
6765 6a36d84e bellard
        "es1370",
6766 6a36d84e bellard
        "ENSONIQ AudioPCI ES1370",
6767 6a36d84e bellard
        0,
6768 6a36d84e bellard
        0,
6769 6a36d84e bellard
        { .init_pci = es1370_init }
6770 6a36d84e bellard
    },
6771 6a36d84e bellard
6772 6a36d84e bellard
    { NULL, NULL, 0, 0, { NULL } }
6773 6a36d84e bellard
};
6774 6a36d84e bellard
6775 6a36d84e bellard
static void select_soundhw (const char *optarg)
6776 6a36d84e bellard
{
6777 6a36d84e bellard
    struct soundhw *c;
6778 6a36d84e bellard
6779 6a36d84e bellard
    if (*optarg == '?') {
6780 6a36d84e bellard
    show_valid_cards:
6781 6a36d84e bellard
6782 6a36d84e bellard
        printf ("Valid sound card names (comma separated):\n");
6783 6a36d84e bellard
        for (c = soundhw; c->name; ++c) {
6784 6a36d84e bellard
            printf ("%-11s %s\n", c->name, c->descr);
6785 6a36d84e bellard
        }
6786 6a36d84e bellard
        printf ("\n-soundhw all will enable all of the above\n");
6787 1d14ffa9 bellard
        exit (*optarg != '?');
6788 1d14ffa9 bellard
    }
6789 1d14ffa9 bellard
    else {
6790 6a36d84e bellard
        size_t l;
6791 1d14ffa9 bellard
        const char *p;
6792 1d14ffa9 bellard
        char *e;
6793 1d14ffa9 bellard
        int bad_card = 0;
6794 1d14ffa9 bellard
6795 6a36d84e bellard
        if (!strcmp (optarg, "all")) {
6796 6a36d84e bellard
            for (c = soundhw; c->name; ++c) {
6797 6a36d84e bellard
                c->enabled = 1;
6798 6a36d84e bellard
            }
6799 6a36d84e bellard
            return;
6800 6a36d84e bellard
        }
6801 1d14ffa9 bellard
6802 6a36d84e bellard
        p = optarg;
6803 1d14ffa9 bellard
        while (*p) {
6804 1d14ffa9 bellard
            e = strchr (p, ',');
6805 1d14ffa9 bellard
            l = !e ? strlen (p) : (size_t) (e - p);
6806 6a36d84e bellard
6807 6a36d84e bellard
            for (c = soundhw; c->name; ++c) {
6808 6a36d84e bellard
                if (!strncmp (c->name, p, l)) {
6809 6a36d84e bellard
                    c->enabled = 1;
6810 1d14ffa9 bellard
                    break;
6811 1d14ffa9 bellard
                }
6812 1d14ffa9 bellard
            }
6813 6a36d84e bellard
6814 6a36d84e bellard
            if (!c->name) {
6815 1d14ffa9 bellard
                if (l > 80) {
6816 1d14ffa9 bellard
                    fprintf (stderr,
6817 1d14ffa9 bellard
                             "Unknown sound card name (too big to show)\n");
6818 1d14ffa9 bellard
                }
6819 1d14ffa9 bellard
                else {
6820 1d14ffa9 bellard
                    fprintf (stderr, "Unknown sound card name `%.*s'\n",
6821 1d14ffa9 bellard
                             (int) l, p);
6822 1d14ffa9 bellard
                }
6823 1d14ffa9 bellard
                bad_card = 1;
6824 1d14ffa9 bellard
            }
6825 1d14ffa9 bellard
            p += l + (e != NULL);
6826 1d14ffa9 bellard
        }
6827 1d14ffa9 bellard
6828 1d14ffa9 bellard
        if (bad_card)
6829 1d14ffa9 bellard
            goto show_valid_cards;
6830 1d14ffa9 bellard
    }
6831 1d14ffa9 bellard
}
6832 1d14ffa9 bellard
#endif
6833 1d14ffa9 bellard
6834 3587d7e6 bellard
#ifdef _WIN32
6835 3587d7e6 bellard
static BOOL WINAPI qemu_ctrl_handler(DWORD type)
6836 3587d7e6 bellard
{
6837 3587d7e6 bellard
    exit(STATUS_CONTROL_C_EXIT);
6838 3587d7e6 bellard
    return TRUE;
6839 3587d7e6 bellard
}
6840 3587d7e6 bellard
#endif
6841 3587d7e6 bellard
6842 7c9d8e07 bellard
#define MAX_NET_CLIENTS 32
6843 c20709aa bellard
6844 0824d6fc bellard
int main(int argc, char **argv)
6845 0824d6fc bellard
{
6846 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
6847 cfc3475a pbrook
    int use_gdbstub;
6848 cfc3475a pbrook
    const char *gdbstub_port;
6849 67b915a5 bellard
#endif
6850 cc1daa40 bellard
    int i, cdrom_index;
6851 1ccde1cb bellard
    int snapshot, linux_boot;
6852 7f7f9873 bellard
    const char *initrd_filename;
6853 96d30e48 ths
    const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
6854 a1bb27b1 pbrook
    const char *sd_filename;
6855 a20dd508 bellard
    const char *kernel_filename, *kernel_cmdline;
6856 313aa567 bellard
    DisplayState *ds = &display_state;
6857 46d4767d bellard
    int cyls, heads, secs, translation;
6858 7c9d8e07 bellard
    char net_clients[MAX_NET_CLIENTS][256];
6859 7c9d8e07 bellard
    int nb_net_clients;
6860 cd6f1169 bellard
    int optind;
6861 cd6f1169 bellard
    const char *r, *optarg;
6862 82c643ff bellard
    CharDriverState *monitor_hd;
6863 82c643ff bellard
    char monitor_device[128];
6864 8d11df9e bellard
    char serial_devices[MAX_SERIAL_PORTS][128];
6865 8d11df9e bellard
    int serial_device_index;
6866 6508fe59 bellard
    char parallel_devices[MAX_PARALLEL_PORTS][128];
6867 6508fe59 bellard
    int parallel_device_index;
6868 d63d307f bellard
    const char *loadvm = NULL;
6869 cc1daa40 bellard
    QEMUMachine *machine;
6870 94fc95cd j_mayer
    const char *cpu_model;
6871 0d92ed30 pbrook
    char usb_devices[MAX_USB_CMDLINE][128];
6872 a594cfbf bellard
    int usb_devices_index;
6873 71e3ceb8 ths
    int fds[2];
6874 93815bc2 ths
    const char *pid_file = NULL;
6875 0bd48850 bellard
6876 0bd48850 bellard
    LIST_INIT (&vm_change_state_head);
6877 be995c27 bellard
#ifndef _WIN32
6878 be995c27 bellard
    {
6879 be995c27 bellard
        struct sigaction act;
6880 be995c27 bellard
        sigfillset(&act.sa_mask);
6881 be995c27 bellard
        act.sa_flags = 0;
6882 be995c27 bellard
        act.sa_handler = SIG_IGN;
6883 be995c27 bellard
        sigaction(SIGPIPE, &act, NULL);
6884 be995c27 bellard
    }
6885 3587d7e6 bellard
#else
6886 3587d7e6 bellard
    SetConsoleCtrlHandler(qemu_ctrl_handler, TRUE);
6887 a8e5ac33 bellard
    /* Note: cpu_interrupt() is currently not SMP safe, so we force
6888 a8e5ac33 bellard
       QEMU to run on a single CPU */
6889 a8e5ac33 bellard
    {
6890 a8e5ac33 bellard
        HANDLE h;
6891 a8e5ac33 bellard
        DWORD mask, smask;
6892 a8e5ac33 bellard
        int i;
6893 a8e5ac33 bellard
        h = GetCurrentProcess();
6894 a8e5ac33 bellard
        if (GetProcessAffinityMask(h, &mask, &smask)) {
6895 a8e5ac33 bellard
            for(i = 0; i < 32; i++) {
6896 a8e5ac33 bellard
                if (mask & (1 << i))
6897 a8e5ac33 bellard
                    break;
6898 a8e5ac33 bellard
            }
6899 a8e5ac33 bellard
            if (i != 32) {
6900 a8e5ac33 bellard
                mask = 1 << i;
6901 a8e5ac33 bellard
                SetProcessAffinityMask(h, mask);
6902 a8e5ac33 bellard
            }
6903 a8e5ac33 bellard
        }
6904 a8e5ac33 bellard
    }
6905 67b915a5 bellard
#endif
6906 be995c27 bellard
6907 cc1daa40 bellard
    register_machines();
6908 cc1daa40 bellard
    machine = first_machine;
6909 94fc95cd j_mayer
    cpu_model = NULL;
6910 fc01f7e7 bellard
    initrd_filename = NULL;
6911 c45886db bellard
    for(i = 0; i < MAX_FD; i++)
6912 c45886db bellard
        fd_filename[i] = NULL;
6913 96d30e48 ths
    for(i = 0; i < MAX_DISKS; i++)
6914 96d30e48 ths
        hd_filename[i] = NULL;
6915 a1bb27b1 pbrook
    sd_filename = NULL;
6916 a00bad7e bellard
    ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
6917 313aa567 bellard
    vga_ram_size = VGA_RAM_SIZE;
6918 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
6919 b4608c04 bellard
    use_gdbstub = 0;
6920 c636bb66 bellard
    gdbstub_port = DEFAULT_GDBSTUB_PORT;
6921 67b915a5 bellard
#endif
6922 33e3963e bellard
    snapshot = 0;
6923 a20dd508 bellard
    nographic = 0;
6924 a20dd508 bellard
    kernel_filename = NULL;
6925 a20dd508 bellard
    kernel_cmdline = "";
6926 cc1daa40 bellard
#ifdef TARGET_PPC
6927 cc1daa40 bellard
    cdrom_index = 1;
6928 cc1daa40 bellard
#else
6929 cc1daa40 bellard
    cdrom_index = 2;
6930 cc1daa40 bellard
#endif
6931 c4b1fcc0 bellard
    cyls = heads = secs = 0;
6932 46d4767d bellard
    translation = BIOS_ATA_TRANSLATION_AUTO;
6933 82c643ff bellard
    pstrcpy(monitor_device, sizeof(monitor_device), "vc");
6934 c4b1fcc0 bellard
6935 8d11df9e bellard
    pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
6936 8d11df9e bellard
    for(i = 1; i < MAX_SERIAL_PORTS; i++)
6937 8d11df9e bellard
        serial_devices[i][0] = '\0';
6938 8d11df9e bellard
    serial_device_index = 0;
6939 8d11df9e bellard
    
6940 6508fe59 bellard
    pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "vc");
6941 6508fe59 bellard
    for(i = 1; i < MAX_PARALLEL_PORTS; i++)
6942 6508fe59 bellard
        parallel_devices[i][0] = '\0';
6943 6508fe59 bellard
    parallel_device_index = 0;
6944 6508fe59 bellard
    
6945 a594cfbf bellard
    usb_devices_index = 0;
6946 a594cfbf bellard
    
6947 7c9d8e07 bellard
    nb_net_clients = 0;
6948 7c9d8e07 bellard
6949 7c9d8e07 bellard
    nb_nics = 0;
6950 702c651c bellard
    /* default mac address of the first network interface */
6951 82c643ff bellard
    
6952 cd6f1169 bellard
    optind = 1;
6953 0824d6fc bellard
    for(;;) {
6954 cd6f1169 bellard
        if (optind >= argc)
6955 0824d6fc bellard
            break;
6956 cd6f1169 bellard
        r = argv[optind];
6957 cd6f1169 bellard
        if (r[0] != '-') {
6958 96d30e48 ths
            hd_filename[0] = argv[optind++];
6959 cd6f1169 bellard
        } else {
6960 cd6f1169 bellard
            const QEMUOption *popt;
6961 cd6f1169 bellard
6962 cd6f1169 bellard
            optind++;
6963 dff5efc8 pbrook
            /* Treat --foo the same as -foo.  */
6964 dff5efc8 pbrook
            if (r[1] == '-')
6965 dff5efc8 pbrook
                r++;
6966 cd6f1169 bellard
            popt = qemu_options;
6967 cd6f1169 bellard
            for(;;) {
6968 cd6f1169 bellard
                if (!popt->name) {
6969 cd6f1169 bellard
                    fprintf(stderr, "%s: invalid option -- '%s'\n", 
6970 cd6f1169 bellard
                            argv[0], r);
6971 cd6f1169 bellard
                    exit(1);
6972 cd6f1169 bellard
                }
6973 cd6f1169 bellard
                if (!strcmp(popt->name, r + 1))
6974 cd6f1169 bellard
                    break;
6975 cd6f1169 bellard
                popt++;
6976 cd6f1169 bellard
            }
6977 cd6f1169 bellard
            if (popt->flags & HAS_ARG) {
6978 cd6f1169 bellard
                if (optind >= argc) {
6979 cd6f1169 bellard
                    fprintf(stderr, "%s: option '%s' requires an argument\n",
6980 cd6f1169 bellard
                            argv[0], r);
6981 cd6f1169 bellard
                    exit(1);
6982 cd6f1169 bellard
                }
6983 cd6f1169 bellard
                optarg = argv[optind++];
6984 cd6f1169 bellard
            } else {
6985 cd6f1169 bellard
                optarg = NULL;
6986 cd6f1169 bellard
            }
6987 cd6f1169 bellard
6988 cd6f1169 bellard
            switch(popt->index) {
6989 cc1daa40 bellard
            case QEMU_OPTION_M:
6990 cc1daa40 bellard
                machine = find_machine(optarg);
6991 cc1daa40 bellard
                if (!machine) {
6992 cc1daa40 bellard
                    QEMUMachine *m;
6993 cc1daa40 bellard
                    printf("Supported machines are:\n");
6994 cc1daa40 bellard
                    for(m = first_machine; m != NULL; m = m->next) {
6995 cc1daa40 bellard
                        printf("%-10s %s%s\n",
6996 cc1daa40 bellard
                               m->name, m->desc, 
6997 cc1daa40 bellard
                               m == first_machine ? " (default)" : "");
6998 cc1daa40 bellard
                    }
6999 cc1daa40 bellard
                    exit(1);
7000 cc1daa40 bellard
                }
7001 cc1daa40 bellard
                break;
7002 94fc95cd j_mayer
            case QEMU_OPTION_cpu:
7003 94fc95cd j_mayer
                /* hw initialization will check this */
7004 94fc95cd j_mayer
                if (optarg[0] == '?') {
7005 94fc95cd j_mayer
#if defined(TARGET_PPC)
7006 94fc95cd j_mayer
                    ppc_cpu_list(stdout, &fprintf);
7007 5adb4839 pbrook
#elif defined(TARGET_ARM)
7008 5adb4839 pbrook
                    arm_cpu_list();
7009 33d68b5f ths
#elif defined(TARGET_MIPS)
7010 33d68b5f ths
                    mips_cpu_list(stdout, &fprintf);
7011 62724a37 blueswir1
#elif defined(TARGET_SPARC)
7012 62724a37 blueswir1
                    sparc_cpu_list(stdout, &fprintf);
7013 94fc95cd j_mayer
#endif
7014 94fc95cd j_mayer
                    exit(1);
7015 94fc95cd j_mayer
                } else {
7016 94fc95cd j_mayer
                    cpu_model = optarg;
7017 94fc95cd j_mayer
                }
7018 94fc95cd j_mayer
                break;
7019 cd6f1169 bellard
            case QEMU_OPTION_initrd:
7020 fc01f7e7 bellard
                initrd_filename = optarg;
7021 fc01f7e7 bellard
                break;
7022 cd6f1169 bellard
            case QEMU_OPTION_hda:
7023 cd6f1169 bellard
            case QEMU_OPTION_hdb:
7024 cc1daa40 bellard
            case QEMU_OPTION_hdc:
7025 cc1daa40 bellard
            case QEMU_OPTION_hdd:
7026 cc1daa40 bellard
                {
7027 cc1daa40 bellard
                    int hd_index;
7028 cc1daa40 bellard
                    hd_index = popt->index - QEMU_OPTION_hda;
7029 96d30e48 ths
                    hd_filename[hd_index] = optarg;
7030 96d30e48 ths
                    if (hd_index == cdrom_index)
7031 96d30e48 ths
                        cdrom_index = -1;
7032 cc1daa40 bellard
                }
7033 fc01f7e7 bellard
                break;
7034 a1bb27b1 pbrook
            case QEMU_OPTION_sd:
7035 a1bb27b1 pbrook
                sd_filename = optarg;
7036 a1bb27b1 pbrook
                break;
7037 cd6f1169 bellard
            case QEMU_OPTION_snapshot:
7038 33e3963e bellard
                snapshot = 1;
7039 33e3963e bellard
                break;
7040 cd6f1169 bellard
            case QEMU_OPTION_hdachs:
7041 330d0414 bellard
                {
7042 330d0414 bellard
                    const char *p;
7043 330d0414 bellard
                    p = optarg;
7044 330d0414 bellard
                    cyls = strtol(p, (char **)&p, 0);
7045 46d4767d bellard
                    if (cyls < 1 || cyls > 16383)
7046 46d4767d bellard
                        goto chs_fail;
7047 330d0414 bellard
                    if (*p != ',')
7048 330d0414 bellard
                        goto chs_fail;
7049 330d0414 bellard
                    p++;
7050 330d0414 bellard
                    heads = strtol(p, (char **)&p, 0);
7051 46d4767d bellard
                    if (heads < 1 || heads > 16)
7052 46d4767d bellard
                        goto chs_fail;
7053 330d0414 bellard
                    if (*p != ',')
7054 330d0414 bellard
                        goto chs_fail;
7055 330d0414 bellard
                    p++;
7056 330d0414 bellard
                    secs = strtol(p, (char **)&p, 0);
7057 46d4767d bellard
                    if (secs < 1 || secs > 63)
7058 46d4767d bellard
                        goto chs_fail;
7059 46d4767d bellard
                    if (*p == ',') {
7060 46d4767d bellard
                        p++;
7061 46d4767d bellard
                        if (!strcmp(p, "none"))
7062 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_NONE;
7063 46d4767d bellard
                        else if (!strcmp(p, "lba"))
7064 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_LBA;
7065 46d4767d bellard
                        else if (!strcmp(p, "auto"))
7066 46d4767d bellard
                            translation = BIOS_ATA_TRANSLATION_AUTO;
7067 46d4767d bellard
                        else
7068 46d4767d bellard
                            goto chs_fail;
7069 46d4767d bellard
                    } else if (*p != '\0') {
7070 c4b1fcc0 bellard
                    chs_fail:
7071 46d4767d bellard
                        fprintf(stderr, "qemu: invalid physical CHS format\n");
7072 46d4767d bellard
                        exit(1);
7073 c4b1fcc0 bellard
                    }
7074 330d0414 bellard
                }
7075 330d0414 bellard
                break;
7076 cd6f1169 bellard
            case QEMU_OPTION_nographic:
7077 8d11df9e bellard
                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
7078 a39437aa ths
                pstrcpy(parallel_devices[0], sizeof(parallel_devices[0]), "null");
7079 20d8a3ed ths
                pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
7080 a20dd508 bellard
                nographic = 1;
7081 a20dd508 bellard
                break;
7082 cd6f1169 bellard
            case QEMU_OPTION_kernel:
7083 a20dd508 bellard
                kernel_filename = optarg;
7084 a20dd508 bellard
                break;
7085 cd6f1169 bellard
            case QEMU_OPTION_append:
7086 a20dd508 bellard
                kernel_cmdline = optarg;
7087 313aa567 bellard
                break;
7088 cd6f1169 bellard
            case QEMU_OPTION_cdrom:
7089 96d30e48 ths
                if (cdrom_index >= 0) {
7090 96d30e48 ths
                    hd_filename[cdrom_index] = optarg;
7091 fa1fb14c ths
                }
7092 36b486bb bellard
                break;
7093 cd6f1169 bellard
            case QEMU_OPTION_boot:
7094 36b486bb bellard
                boot_device = optarg[0];
7095 9e89a4be bellard
                if (boot_device != 'a' && 
7096 eec85c2a ths
#if defined(TARGET_SPARC) || defined(TARGET_I386)
7097 6f7e9aec bellard
                    // Network boot
7098 6f7e9aec bellard
                    boot_device != 'n' &&
7099 6f7e9aec bellard
#endif
7100 c45886db bellard
                    boot_device != 'c' && boot_device != 'd') {
7101 36b486bb bellard
                    fprintf(stderr, "qemu: invalid boot device '%c'\n", boot_device);
7102 36b486bb bellard
                    exit(1);
7103 36b486bb bellard
                }
7104 36b486bb bellard
                break;
7105 cd6f1169 bellard
            case QEMU_OPTION_fda:
7106 c45886db bellard
                fd_filename[0] = optarg;
7107 c45886db bellard
                break;
7108 cd6f1169 bellard
            case QEMU_OPTION_fdb:
7109 c45886db bellard
                fd_filename[1] = optarg;
7110 c45886db bellard
                break;
7111 52ca8d6a bellard
#ifdef TARGET_I386
7112 52ca8d6a bellard
            case QEMU_OPTION_no_fd_bootchk:
7113 52ca8d6a bellard
                fd_bootchk = 0;
7114 52ca8d6a bellard
                break;
7115 52ca8d6a bellard
#endif
7116 cd6f1169 bellard
            case QEMU_OPTION_no_code_copy:
7117 77fef8c1 bellard
                code_copy_enabled = 0;
7118 77fef8c1 bellard
                break;
7119 7c9d8e07 bellard
            case QEMU_OPTION_net:
7120 7c9d8e07 bellard
                if (nb_net_clients >= MAX_NET_CLIENTS) {
7121 7c9d8e07 bellard
                    fprintf(stderr, "qemu: too many network clients\n");
7122 c4b1fcc0 bellard
                    exit(1);
7123 c4b1fcc0 bellard
                }
7124 7c9d8e07 bellard
                pstrcpy(net_clients[nb_net_clients],
7125 7c9d8e07 bellard
                        sizeof(net_clients[0]),
7126 7c9d8e07 bellard
                        optarg);
7127 7c9d8e07 bellard
                nb_net_clients++;
7128 702c651c bellard
                break;
7129 c7f74643 bellard
#ifdef CONFIG_SLIRP
7130 c7f74643 bellard
            case QEMU_OPTION_tftp:
7131 c7f74643 bellard
                tftp_prefix = optarg;
7132 9bf05444 bellard
                break;
7133 47d5d01a ths
            case QEMU_OPTION_bootp:
7134 47d5d01a ths
                bootp_filename = optarg;
7135 47d5d01a ths
                break;
7136 c94c8d64 bellard
#ifndef _WIN32
7137 9d728e8c bellard
            case QEMU_OPTION_smb:
7138 9d728e8c bellard
                net_slirp_smb(optarg);
7139 9d728e8c bellard
                break;
7140 c94c8d64 bellard
#endif
7141 9bf05444 bellard
            case QEMU_OPTION_redir:
7142 9bf05444 bellard
                net_slirp_redir(optarg);                
7143 9bf05444 bellard
                break;
7144 c7f74643 bellard
#endif
7145 1d14ffa9 bellard
#ifdef HAS_AUDIO
7146 1d14ffa9 bellard
            case QEMU_OPTION_audio_help:
7147 1d14ffa9 bellard
                AUD_help ();
7148 1d14ffa9 bellard
                exit (0);
7149 1d14ffa9 bellard
                break;
7150 1d14ffa9 bellard
            case QEMU_OPTION_soundhw:
7151 1d14ffa9 bellard
                select_soundhw (optarg);
7152 1d14ffa9 bellard
                break;
7153 1d14ffa9 bellard
#endif
7154 cd6f1169 bellard
            case QEMU_OPTION_h:
7155 0824d6fc bellard
                help();
7156 cd6f1169 bellard
                break;
7157 cd6f1169 bellard
            case QEMU_OPTION_m:
7158 cd6f1169 bellard
                ram_size = atoi(optarg) * 1024 * 1024;
7159 cd6f1169 bellard
                if (ram_size <= 0)
7160 cd6f1169 bellard
                    help();
7161 cd6f1169 bellard
                if (ram_size > PHYS_RAM_MAX_SIZE) {
7162 cd6f1169 bellard
                    fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
7163 cd6f1169 bellard
                            PHYS_RAM_MAX_SIZE / (1024 * 1024));
7164 cd6f1169 bellard
                    exit(1);
7165 cd6f1169 bellard
                }
7166 cd6f1169 bellard
                break;
7167 cd6f1169 bellard
            case QEMU_OPTION_d:
7168 cd6f1169 bellard
                {
7169 cd6f1169 bellard
                    int mask;
7170 cd6f1169 bellard
                    CPULogItem *item;
7171 cd6f1169 bellard
                    
7172 cd6f1169 bellard
                    mask = cpu_str_to_log_mask(optarg);
7173 cd6f1169 bellard
                    if (!mask) {
7174 cd6f1169 bellard
                        printf("Log items (comma separated):\n");
7175 f193c797 bellard
                    for(item = cpu_log_items; item->mask != 0; item++) {
7176 f193c797 bellard
                        printf("%-10s %s\n", item->name, item->help);
7177 f193c797 bellard
                    }
7178 f193c797 bellard
                    exit(1);
7179 cd6f1169 bellard
                    }
7180 cd6f1169 bellard
                    cpu_set_log(mask);
7181 f193c797 bellard
                }
7182 cd6f1169 bellard
                break;
7183 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
7184 cd6f1169 bellard
            case QEMU_OPTION_s:
7185 cd6f1169 bellard
                use_gdbstub = 1;
7186 cd6f1169 bellard
                break;
7187 cd6f1169 bellard
            case QEMU_OPTION_p:
7188 cfc3475a pbrook
                gdbstub_port = optarg;
7189 cd6f1169 bellard
                break;
7190 67b915a5 bellard
#endif
7191 cd6f1169 bellard
            case QEMU_OPTION_L:
7192 cd6f1169 bellard
                bios_dir = optarg;
7193 cd6f1169 bellard
                break;
7194 cd6f1169 bellard
            case QEMU_OPTION_S:
7195 3c07f8e8 pbrook
                autostart = 0;
7196 cd6f1169 bellard
                break;
7197 3d11d0eb bellard
            case QEMU_OPTION_k:
7198 3d11d0eb bellard
                keyboard_layout = optarg;
7199 3d11d0eb bellard
                break;
7200 ee22c2f7 bellard
            case QEMU_OPTION_localtime:
7201 ee22c2f7 bellard
                rtc_utc = 0;
7202 ee22c2f7 bellard
                break;
7203 1f04275e bellard
            case QEMU_OPTION_cirrusvga:
7204 1f04275e bellard
                cirrus_vga_enabled = 1;
7205 d34cab9f ths
                vmsvga_enabled = 0;
7206 d34cab9f ths
                break;
7207 d34cab9f ths
            case QEMU_OPTION_vmsvga:
7208 d34cab9f ths
                cirrus_vga_enabled = 0;
7209 d34cab9f ths
                vmsvga_enabled = 1;
7210 1f04275e bellard
                break;
7211 1bfe856e bellard
            case QEMU_OPTION_std_vga:
7212 1bfe856e bellard
                cirrus_vga_enabled = 0;
7213 d34cab9f ths
                vmsvga_enabled = 0;
7214 1bfe856e bellard
                break;
7215 e9b137c2 bellard
            case QEMU_OPTION_g:
7216 e9b137c2 bellard
                {
7217 e9b137c2 bellard
                    const char *p;
7218 e9b137c2 bellard
                    int w, h, depth;
7219 e9b137c2 bellard
                    p = optarg;
7220 e9b137c2 bellard
                    w = strtol(p, (char **)&p, 10);
7221 e9b137c2 bellard
                    if (w <= 0) {
7222 e9b137c2 bellard
                    graphic_error:
7223 e9b137c2 bellard
                        fprintf(stderr, "qemu: invalid resolution or depth\n");
7224 e9b137c2 bellard
                        exit(1);
7225 e9b137c2 bellard
                    }
7226 e9b137c2 bellard
                    if (*p != 'x')
7227 e9b137c2 bellard
                        goto graphic_error;
7228 e9b137c2 bellard
                    p++;
7229 e9b137c2 bellard
                    h = strtol(p, (char **)&p, 10);
7230 e9b137c2 bellard
                    if (h <= 0)
7231 e9b137c2 bellard
                        goto graphic_error;
7232 e9b137c2 bellard
                    if (*p == 'x') {
7233 e9b137c2 bellard
                        p++;
7234 e9b137c2 bellard
                        depth = strtol(p, (char **)&p, 10);
7235 e9b137c2 bellard
                        if (depth != 8 && depth != 15 && depth != 16 && 
7236 e9b137c2 bellard
                            depth != 24 && depth != 32)
7237 e9b137c2 bellard
                            goto graphic_error;
7238 e9b137c2 bellard
                    } else if (*p == '\0') {
7239 e9b137c2 bellard
                        depth = graphic_depth;
7240 e9b137c2 bellard
                    } else {
7241 e9b137c2 bellard
                        goto graphic_error;
7242 e9b137c2 bellard
                    }
7243 e9b137c2 bellard
                    
7244 e9b137c2 bellard
                    graphic_width = w;
7245 e9b137c2 bellard
                    graphic_height = h;
7246 e9b137c2 bellard
                    graphic_depth = depth;
7247 e9b137c2 bellard
                }
7248 e9b137c2 bellard
                break;
7249 20d8a3ed ths
            case QEMU_OPTION_echr:
7250 20d8a3ed ths
                {
7251 20d8a3ed ths
                    char *r;
7252 20d8a3ed ths
                    term_escape_char = strtol(optarg, &r, 0);
7253 20d8a3ed ths
                    if (r == optarg)
7254 20d8a3ed ths
                        printf("Bad argument to echr\n");
7255 20d8a3ed ths
                    break;
7256 20d8a3ed ths
                }
7257 82c643ff bellard
            case QEMU_OPTION_monitor:
7258 82c643ff bellard
                pstrcpy(monitor_device, sizeof(monitor_device), optarg);
7259 82c643ff bellard
                break;
7260 82c643ff bellard
            case QEMU_OPTION_serial:
7261 8d11df9e bellard
                if (serial_device_index >= MAX_SERIAL_PORTS) {
7262 8d11df9e bellard
                    fprintf(stderr, "qemu: too many serial ports\n");
7263 8d11df9e bellard
                    exit(1);
7264 8d11df9e bellard
                }
7265 8d11df9e bellard
                pstrcpy(serial_devices[serial_device_index], 
7266 8d11df9e bellard
                        sizeof(serial_devices[0]), optarg);
7267 8d11df9e bellard
                serial_device_index++;
7268 82c643ff bellard
                break;
7269 6508fe59 bellard
            case QEMU_OPTION_parallel:
7270 6508fe59 bellard
                if (parallel_device_index >= MAX_PARALLEL_PORTS) {
7271 6508fe59 bellard
                    fprintf(stderr, "qemu: too many parallel ports\n");
7272 6508fe59 bellard
                    exit(1);
7273 6508fe59 bellard
                }
7274 6508fe59 bellard
                pstrcpy(parallel_devices[parallel_device_index], 
7275 6508fe59 bellard
                        sizeof(parallel_devices[0]), optarg);
7276 6508fe59 bellard
                parallel_device_index++;
7277 6508fe59 bellard
                break;
7278 d63d307f bellard
            case QEMU_OPTION_loadvm:
7279 d63d307f bellard
                loadvm = optarg;
7280 d63d307f bellard
                break;
7281 d63d307f bellard
            case QEMU_OPTION_full_screen:
7282 d63d307f bellard
                full_screen = 1;
7283 d63d307f bellard
                break;
7284 667accab ths
#ifdef CONFIG_SDL
7285 43523e93 ths
            case QEMU_OPTION_no_frame:
7286 43523e93 ths
                no_frame = 1;
7287 43523e93 ths
                break;
7288 667accab ths
            case QEMU_OPTION_no_quit:
7289 667accab ths
                no_quit = 1;
7290 667accab ths
                break;
7291 667accab ths
#endif
7292 f7cce898 bellard
            case QEMU_OPTION_pidfile:
7293 93815bc2 ths
                pid_file = optarg;
7294 f7cce898 bellard
                break;
7295 a09db21f bellard
#ifdef TARGET_I386
7296 a09db21f bellard
            case QEMU_OPTION_win2k_hack:
7297 a09db21f bellard
                win2k_install_hack = 1;
7298 a09db21f bellard
                break;
7299 a09db21f bellard
#endif
7300 d993e026 bellard
#ifdef USE_KQEMU
7301 d993e026 bellard
            case QEMU_OPTION_no_kqemu:
7302 d993e026 bellard
                kqemu_allowed = 0;
7303 d993e026 bellard
                break;
7304 89bfc105 bellard
            case QEMU_OPTION_kernel_kqemu:
7305 89bfc105 bellard
                kqemu_allowed = 2;
7306 89bfc105 bellard
                break;
7307 d993e026 bellard
#endif
7308 bb36d470 bellard
            case QEMU_OPTION_usb:
7309 bb36d470 bellard
                usb_enabled = 1;
7310 bb36d470 bellard
                break;
7311 a594cfbf bellard
            case QEMU_OPTION_usbdevice:
7312 a594cfbf bellard
                usb_enabled = 1;
7313 0d92ed30 pbrook
                if (usb_devices_index >= MAX_USB_CMDLINE) {
7314 a594cfbf bellard
                    fprintf(stderr, "Too many USB devices\n");
7315 a594cfbf bellard
                    exit(1);
7316 a594cfbf bellard
                }
7317 a594cfbf bellard
                pstrcpy(usb_devices[usb_devices_index],
7318 a594cfbf bellard
                        sizeof(usb_devices[usb_devices_index]),
7319 a594cfbf bellard
                        optarg);
7320 a594cfbf bellard
                usb_devices_index++;
7321 a594cfbf bellard
                break;
7322 6a00d601 bellard
            case QEMU_OPTION_smp:
7323 6a00d601 bellard
                smp_cpus = atoi(optarg);
7324 ba3c64fb bellard
                if (smp_cpus < 1 || smp_cpus > MAX_CPUS) {
7325 6a00d601 bellard
                    fprintf(stderr, "Invalid number of CPUs\n");
7326 6a00d601 bellard
                    exit(1);
7327 6a00d601 bellard
                }
7328 6a00d601 bellard
                break;
7329 24236869 bellard
            case QEMU_OPTION_vnc:
7330 73fc9742 ths
                vnc_display = optarg;
7331 24236869 bellard
                break;
7332 6515b203 bellard
            case QEMU_OPTION_no_acpi:
7333 6515b203 bellard
                acpi_enabled = 0;
7334 6515b203 bellard
                break;
7335 d1beab82 bellard
            case QEMU_OPTION_no_reboot:
7336 d1beab82 bellard
                no_reboot = 1;
7337 d1beab82 bellard
                break;
7338 71e3ceb8 ths
            case QEMU_OPTION_daemonize:
7339 71e3ceb8 ths
                daemonize = 1;
7340 71e3ceb8 ths
                break;
7341 9ae02555 ths
            case QEMU_OPTION_option_rom:
7342 9ae02555 ths
                if (nb_option_roms >= MAX_OPTION_ROMS) {
7343 9ae02555 ths
                    fprintf(stderr, "Too many option ROMs\n");
7344 9ae02555 ths
                    exit(1);
7345 9ae02555 ths
                }
7346 9ae02555 ths
                option_rom[nb_option_roms] = optarg;
7347 9ae02555 ths
                nb_option_roms++;
7348 9ae02555 ths
                break;
7349 8e71621f pbrook
            case QEMU_OPTION_semihosting:
7350 8e71621f pbrook
                semihosting_enabled = 1;
7351 8e71621f pbrook
                break;
7352 c35734b2 ths
            case QEMU_OPTION_name:
7353 c35734b2 ths
                qemu_name = optarg;
7354 c35734b2 ths
                break;
7355 cd6f1169 bellard
            }
7356 0824d6fc bellard
        }
7357 0824d6fc bellard
    }
7358 330d0414 bellard
7359 71e3ceb8 ths
#ifndef _WIN32
7360 71e3ceb8 ths
    if (daemonize && !nographic && vnc_display == NULL) {
7361 71e3ceb8 ths
        fprintf(stderr, "Can only daemonize if using -nographic or -vnc\n");
7362 71e3ceb8 ths
        daemonize = 0;
7363 71e3ceb8 ths
    }
7364 71e3ceb8 ths
7365 71e3ceb8 ths
    if (daemonize) {
7366 71e3ceb8 ths
        pid_t pid;
7367 71e3ceb8 ths
7368 71e3ceb8 ths
        if (pipe(fds) == -1)
7369 71e3ceb8 ths
            exit(1);
7370 71e3ceb8 ths
7371 71e3ceb8 ths
        pid = fork();
7372 71e3ceb8 ths
        if (pid > 0) {
7373 71e3ceb8 ths
            uint8_t status;
7374 71e3ceb8 ths
            ssize_t len;
7375 71e3ceb8 ths
7376 71e3ceb8 ths
            close(fds[1]);
7377 71e3ceb8 ths
7378 71e3ceb8 ths
        again:
7379 93815bc2 ths
            len = read(fds[0], &status, 1);
7380 93815bc2 ths
            if (len == -1 && (errno == EINTR))
7381 93815bc2 ths
                goto again;
7382 93815bc2 ths
7383 93815bc2 ths
            if (len != 1)
7384 93815bc2 ths
                exit(1);
7385 93815bc2 ths
            else if (status == 1) {
7386 93815bc2 ths
                fprintf(stderr, "Could not acquire pidfile\n");
7387 93815bc2 ths
                exit(1);
7388 93815bc2 ths
            } else
7389 93815bc2 ths
                exit(0);
7390 71e3ceb8 ths
        } else if (pid < 0)
7391 93815bc2 ths
            exit(1);
7392 71e3ceb8 ths
7393 71e3ceb8 ths
        setsid();
7394 71e3ceb8 ths
7395 71e3ceb8 ths
        pid = fork();
7396 71e3ceb8 ths
        if (pid > 0)
7397 71e3ceb8 ths
            exit(0);
7398 71e3ceb8 ths
        else if (pid < 0)
7399 71e3ceb8 ths
            exit(1);
7400 71e3ceb8 ths
7401 71e3ceb8 ths
        umask(027);
7402 71e3ceb8 ths
        chdir("/");
7403 71e3ceb8 ths
7404 71e3ceb8 ths
        signal(SIGTSTP, SIG_IGN);
7405 71e3ceb8 ths
        signal(SIGTTOU, SIG_IGN);
7406 71e3ceb8 ths
        signal(SIGTTIN, SIG_IGN);
7407 71e3ceb8 ths
    }
7408 71e3ceb8 ths
#endif
7409 71e3ceb8 ths
7410 aa26bb2d ths
    if (pid_file && qemu_create_pidfile(pid_file) != 0) {
7411 93815bc2 ths
        if (daemonize) {
7412 93815bc2 ths
            uint8_t status = 1;
7413 93815bc2 ths
            write(fds[1], &status, 1);
7414 93815bc2 ths
        } else
7415 93815bc2 ths
            fprintf(stderr, "Could not acquire pid file\n");
7416 93815bc2 ths
        exit(1);
7417 93815bc2 ths
    }
7418 93815bc2 ths
7419 ff3fbb30 bellard
#ifdef USE_KQEMU
7420 ff3fbb30 bellard
    if (smp_cpus > 1)
7421 ff3fbb30 bellard
        kqemu_allowed = 0;
7422 ff3fbb30 bellard
#endif
7423 a20dd508 bellard
    linux_boot = (kernel_filename != NULL);
7424 42550fde ths
7425 42550fde ths
    if (!linux_boot &&
7426 d84fe7ae ths
        boot_device != 'n' &&
7427 96d30e48 ths
        hd_filename[0] == '\0' && 
7428 96d30e48 ths
        (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
7429 c45886db bellard
        fd_filename[0] == '\0')
7430 0824d6fc bellard
        help();
7431 0824d6fc bellard
7432 96d30e48 ths
    /* boot to floppy or the default cd if no hard disk defined yet */
7433 96d30e48 ths
    if (hd_filename[0] == '\0' && boot_device == 'c') {
7434 96d30e48 ths
        if (fd_filename[0] != '\0')
7435 96d30e48 ths
            boot_device = 'a';
7436 96d30e48 ths
        else
7437 96d30e48 ths
            boot_device = 'd';
7438 96d30e48 ths
    }
7439 96d30e48 ths
7440 b118d61e bellard
    setvbuf(stdout, NULL, _IOLBF, 0);
7441 7c9d8e07 bellard
    
7442 634fce96 pbrook
    init_timers();
7443 634fce96 pbrook
    init_timer_alarm();
7444 83f64091 bellard
    qemu_aio_init();
7445 634fce96 pbrook
7446 fd1dff4b bellard
#ifdef _WIN32
7447 fd1dff4b bellard
    socket_init();
7448 fd1dff4b bellard
#endif
7449 fd1dff4b bellard
7450 7c9d8e07 bellard
    /* init network clients */
7451 7c9d8e07 bellard
    if (nb_net_clients == 0) {
7452 7c9d8e07 bellard
        /* if no clients, we use a default config */
7453 7c9d8e07 bellard
        pstrcpy(net_clients[0], sizeof(net_clients[0]),
7454 7c9d8e07 bellard
                "nic");
7455 7c9d8e07 bellard
        pstrcpy(net_clients[1], sizeof(net_clients[0]),
7456 7c9d8e07 bellard
                "user");
7457 7c9d8e07 bellard
        nb_net_clients = 2;
7458 c20709aa bellard
    }
7459 c20709aa bellard
7460 7c9d8e07 bellard
    for(i = 0;i < nb_net_clients; i++) {
7461 7c9d8e07 bellard
        if (net_client_init(net_clients[i]) < 0)
7462 7c9d8e07 bellard
            exit(1);
7463 702c651c bellard
    }
7464 f1510b2c bellard
7465 eec85c2a ths
#ifdef TARGET_I386
7466 eec85c2a ths
    if (boot_device == 'n') {
7467 eec85c2a ths
        for (i = 0; i < nb_nics; i++) {
7468 eec85c2a ths
            const char *model = nd_table[i].model;
7469 eec85c2a ths
            char buf[1024];
7470 eec85c2a ths
            if (model == NULL)
7471 eec85c2a ths
                model = "ne2k_pci";
7472 eec85c2a ths
            snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model);
7473 eec85c2a ths
            if (get_image_size(buf) > 0) {
7474 eec85c2a ths
                option_rom[nb_option_roms] = strdup(buf);
7475 eec85c2a ths
                nb_option_roms++;
7476 eec85c2a ths
                break;
7477 eec85c2a ths
            }
7478 eec85c2a ths
        }
7479 eec85c2a ths
        if (i == nb_nics) {
7480 eec85c2a ths
            fprintf(stderr, "No valid PXE rom found for network device\n");
7481 eec85c2a ths
            exit(1);
7482 eec85c2a ths
        }
7483 eec85c2a ths
        boot_device = 'c'; /* to prevent confusion by the BIOS */
7484 eec85c2a ths
    }
7485 eec85c2a ths
#endif
7486 eec85c2a ths
7487 0824d6fc bellard
    /* init the memory */
7488 970ac5a3 bellard
    phys_ram_size = ram_size + vga_ram_size + MAX_BIOS_SIZE;
7489 9ae02555 ths
7490 d993e026 bellard
    phys_ram_base = qemu_vmalloc(phys_ram_size);
7491 7f7f9873 bellard
    if (!phys_ram_base) {
7492 7f7f9873 bellard
        fprintf(stderr, "Could not allocate physical memory\n");
7493 0824d6fc bellard
        exit(1);
7494 0824d6fc bellard
    }
7495 0824d6fc bellard
7496 96d30e48 ths
    /* we always create the cdrom drive, even if no disk is there */
7497 5905b2e5 bellard
    bdrv_init();
7498 96d30e48 ths
    if (cdrom_index >= 0) {
7499 96d30e48 ths
        bs_table[cdrom_index] = bdrv_new("cdrom");
7500 96d30e48 ths
        bdrv_set_type_hint(bs_table[cdrom_index], BDRV_TYPE_CDROM);
7501 c4b1fcc0 bellard
    }
7502 c4b1fcc0 bellard
7503 96d30e48 ths
    /* open the virtual block devices */
7504 96d30e48 ths
    for(i = 0; i < MAX_DISKS; i++) {
7505 96d30e48 ths
        if (hd_filename[i]) {
7506 96d30e48 ths
            if (!bs_table[i]) {
7507 96d30e48 ths
                char buf[64];
7508 96d30e48 ths
                snprintf(buf, sizeof(buf), "hd%c", i + 'a');
7509 96d30e48 ths
                bs_table[i] = bdrv_new(buf);
7510 96d30e48 ths
            }
7511 96d30e48 ths
            if (bdrv_open(bs_table[i], hd_filename[i], snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
7512 96d30e48 ths
                fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
7513 96d30e48 ths
                        hd_filename[i]);
7514 96d30e48 ths
                exit(1);
7515 96d30e48 ths
            }
7516 96d30e48 ths
            if (i == 0 && cyls != 0) {
7517 96d30e48 ths
                bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
7518 96d30e48 ths
                bdrv_set_translation_hint(bs_table[i], translation);
7519 96d30e48 ths
            }
7520 96d30e48 ths
        }
7521 c4b1fcc0 bellard
    }
7522 c4b1fcc0 bellard
7523 c4b1fcc0 bellard
    /* we always create at least one floppy disk */
7524 c4b1fcc0 bellard
    fd_table[0] = bdrv_new("fda");
7525 c4b1fcc0 bellard
    bdrv_set_type_hint(fd_table[0], BDRV_TYPE_FLOPPY);
7526 c4b1fcc0 bellard
7527 c4b1fcc0 bellard
    for(i = 0; i < MAX_FD; i++) {
7528 c4b1fcc0 bellard
        if (fd_filename[i]) {
7529 c4b1fcc0 bellard
            if (!fd_table[i]) {
7530 c4b1fcc0 bellard
                char buf[64];
7531 c4b1fcc0 bellard
                snprintf(buf, sizeof(buf), "fd%c", i + 'a');
7532 c4b1fcc0 bellard
                fd_table[i] = bdrv_new(buf);
7533 c4b1fcc0 bellard
                bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY);
7534 c4b1fcc0 bellard
            }
7535 a1bb27b1 pbrook
            if (fd_filename[i][0] != '\0') {
7536 83f64091 bellard
                if (bdrv_open(fd_table[i], fd_filename[i],
7537 83f64091 bellard
                              snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
7538 c20709aa bellard
                    fprintf(stderr, "qemu: could not open floppy disk image '%s'\n",
7539 c4b1fcc0 bellard
                            fd_filename[i]);
7540 c4b1fcc0 bellard
                    exit(1);
7541 c4b1fcc0 bellard
                }
7542 c4b1fcc0 bellard
            }
7543 33e3963e bellard
        }
7544 33e3963e bellard
    }
7545 33e3963e bellard
7546 a1bb27b1 pbrook
    sd_bdrv = bdrv_new ("sd");
7547 a1bb27b1 pbrook
    /* FIXME: This isn't really a floppy, but it's a reasonable
7548 a1bb27b1 pbrook
       approximation.  */
7549 a1bb27b1 pbrook
    bdrv_set_type_hint(sd_bdrv, BDRV_TYPE_FLOPPY);
7550 a1bb27b1 pbrook
    if (sd_filename) {
7551 a1bb27b1 pbrook
        if (bdrv_open(sd_bdrv, sd_filename,
7552 a1bb27b1 pbrook
                      snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
7553 a1bb27b1 pbrook
            fprintf(stderr, "qemu: could not open SD card image %s\n",
7554 a1bb27b1 pbrook
                    sd_filename);
7555 a1bb27b1 pbrook
        }
7556 a1bb27b1 pbrook
    }
7557 a1bb27b1 pbrook
7558 c88676f8 bellard
    register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
7559 c88676f8 bellard
    register_savevm("ram", 0, 2, ram_save, ram_load, NULL);
7560 8a7ddc38 bellard
7561 330d0414 bellard
    init_ioports();
7562 0824d6fc bellard
7563 313aa567 bellard
    /* terminal init */
7564 a20dd508 bellard
    if (nographic) {
7565 313aa567 bellard
        dumb_display_init(ds);
7566 73fc9742 ths
    } else if (vnc_display != NULL) {
7567 24236869 bellard
        vnc_display_init(ds, vnc_display);
7568 313aa567 bellard
    } else {
7569 5b0753e0 bellard
#if defined(CONFIG_SDL)
7570 43523e93 ths
        sdl_display_init(ds, full_screen, no_frame);
7571 5b0753e0 bellard
#elif defined(CONFIG_COCOA)
7572 5b0753e0 bellard
        cocoa_display_init(ds, full_screen);
7573 313aa567 bellard
#else
7574 313aa567 bellard
        dumb_display_init(ds);
7575 313aa567 bellard
#endif
7576 313aa567 bellard
    }
7577 0824d6fc bellard
7578 20d8a3ed ths
    /* Maintain compatibility with multiple stdio monitors */
7579 20d8a3ed ths
    if (!strcmp(monitor_device,"stdio")) {
7580 20d8a3ed ths
        for (i = 0; i < MAX_SERIAL_PORTS; i++) {
7581 20d8a3ed ths
            if (!strcmp(serial_devices[i],"mon:stdio")) {
7582 20d8a3ed ths
                monitor_device[0] = '\0';
7583 20d8a3ed ths
                break;
7584 20d8a3ed ths
            } else if (!strcmp(serial_devices[i],"stdio")) {
7585 20d8a3ed ths
                monitor_device[0] = '\0';
7586 20d8a3ed ths
                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "mon:stdio");
7587 20d8a3ed ths
                break;
7588 20d8a3ed ths
            }
7589 20d8a3ed ths
        }
7590 20d8a3ed ths
    }
7591 20d8a3ed ths
    if (monitor_device[0] != '\0') {
7592 20d8a3ed ths
        monitor_hd = qemu_chr_open(monitor_device);
7593 20d8a3ed ths
        if (!monitor_hd) {
7594 20d8a3ed ths
            fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
7595 20d8a3ed ths
            exit(1);
7596 20d8a3ed ths
        }
7597 20d8a3ed ths
        monitor_init(monitor_hd, !nographic);
7598 82c643ff bellard
    }
7599 82c643ff bellard
7600 8d11df9e bellard
    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
7601 c03b0f0f bellard
        const char *devname = serial_devices[i];
7602 c03b0f0f bellard
        if (devname[0] != '\0' && strcmp(devname, "none")) {
7603 c03b0f0f bellard
            serial_hds[i] = qemu_chr_open(devname);
7604 8d11df9e bellard
            if (!serial_hds[i]) {
7605 8d11df9e bellard
                fprintf(stderr, "qemu: could not open serial device '%s'\n", 
7606 c03b0f0f bellard
                        devname);
7607 8d11df9e bellard
                exit(1);
7608 8d11df9e bellard
            }
7609 c03b0f0f bellard
            if (!strcmp(devname, "vc"))
7610 7ba1260a bellard
                qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
7611 8d11df9e bellard
        }
7612 82c643ff bellard
    }
7613 82c643ff bellard
7614 6508fe59 bellard
    for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
7615 c03b0f0f bellard
        const char *devname = parallel_devices[i];
7616 c03b0f0f bellard
        if (devname[0] != '\0' && strcmp(devname, "none")) {
7617 c03b0f0f bellard
            parallel_hds[i] = qemu_chr_open(devname);
7618 6508fe59 bellard
            if (!parallel_hds[i]) {
7619 6508fe59 bellard
                fprintf(stderr, "qemu: could not open parallel device '%s'\n", 
7620 c03b0f0f bellard
                        devname);
7621 6508fe59 bellard
                exit(1);
7622 6508fe59 bellard
            }
7623 c03b0f0f bellard
            if (!strcmp(devname, "vc"))
7624 7ba1260a bellard
                qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
7625 6508fe59 bellard
        }
7626 6508fe59 bellard
    }
7627 6508fe59 bellard
7628 cc1daa40 bellard
    machine->init(ram_size, vga_ram_size, boot_device,
7629 cc1daa40 bellard
                  ds, fd_filename, snapshot,
7630 94fc95cd j_mayer
                  kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
7631 73332e5c bellard
7632 0d92ed30 pbrook
    /* init USB devices */
7633 0d92ed30 pbrook
    if (usb_enabled) {
7634 0d92ed30 pbrook
        for(i = 0; i < usb_devices_index; i++) {
7635 0d92ed30 pbrook
            if (usb_device_add(usb_devices[i]) < 0) {
7636 0d92ed30 pbrook
                fprintf(stderr, "Warning: could not add USB device %s\n",
7637 0d92ed30 pbrook
                        usb_devices[i]);
7638 0d92ed30 pbrook
            }
7639 0d92ed30 pbrook
        }
7640 0d92ed30 pbrook
    }
7641 0d92ed30 pbrook
7642 8a7ddc38 bellard
    gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
7643 8a7ddc38 bellard
    qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
7644 7f7f9873 bellard
7645 67b915a5 bellard
#ifdef CONFIG_GDBSTUB
7646 b4608c04 bellard
    if (use_gdbstub) {
7647 c636bb66 bellard
        /* XXX: use standard host:port notation and modify options
7648 c636bb66 bellard
           accordingly. */
7649 cfc3475a pbrook
        if (gdbserver_start(gdbstub_port) < 0) {
7650 cfc3475a pbrook
            fprintf(stderr, "qemu: could not open gdbstub device on port '%s'\n",
7651 c636bb66 bellard
                    gdbstub_port);
7652 8a7ddc38 bellard
            exit(1);
7653 8a7ddc38 bellard
        }
7654 67b915a5 bellard
    } else 
7655 67b915a5 bellard
#endif
7656 d63d307f bellard
    if (loadvm)
7657 faea38e7 bellard
        do_loadvm(loadvm);
7658 d63d307f bellard
7659 67b915a5 bellard
    {
7660 5905b2e5 bellard
        /* XXX: simplify init */
7661 5905b2e5 bellard
        read_passwords();
7662 3c07f8e8 pbrook
        if (autostart) {
7663 5905b2e5 bellard
            vm_start();
7664 5905b2e5 bellard
        }
7665 0824d6fc bellard
    }
7666 ffd843bc ths
7667 71e3ceb8 ths
    if (daemonize) {
7668 71e3ceb8 ths
        uint8_t status = 0;
7669 71e3ceb8 ths
        ssize_t len;
7670 71e3ceb8 ths
        int fd;
7671 71e3ceb8 ths
7672 71e3ceb8 ths
    again1:
7673 71e3ceb8 ths
        len = write(fds[1], &status, 1);
7674 71e3ceb8 ths
        if (len == -1 && (errno == EINTR))
7675 71e3ceb8 ths
            goto again1;
7676 71e3ceb8 ths
7677 71e3ceb8 ths
        if (len != 1)
7678 71e3ceb8 ths
            exit(1);
7679 71e3ceb8 ths
7680 71e3ceb8 ths
        fd = open("/dev/null", O_RDWR);
7681 71e3ceb8 ths
        if (fd == -1)
7682 71e3ceb8 ths
            exit(1);
7683 71e3ceb8 ths
7684 71e3ceb8 ths
        dup2(fd, 0);
7685 71e3ceb8 ths
        dup2(fd, 1);
7686 71e3ceb8 ths
        dup2(fd, 2);
7687 71e3ceb8 ths
7688 71e3ceb8 ths
        close(fd);
7689 71e3ceb8 ths
    }
7690 71e3ceb8 ths
7691 8a7ddc38 bellard
    main_loop();
7692 40c3bac3 bellard
    quit_timers();
7693 0824d6fc bellard
    return 0;
7694 0824d6fc bellard
}