1
# Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software
4
# This file is part of DejaGnu.
6
# DejaGnu is free software; you can redistribute it and/or modify it
7
# under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
11
# DejaGnu is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
# General Public License for more details.
16
# You should have received a copy of the GNU General Public License
17
# along with DejaGnu; if not, write to the Free Software Foundation,
18
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
# This file was written by Bob Manson (manson@cygnus.com)
23
# Open a connection to the remote DOS host.
25
proc dos_open { dest args } {
28
if ![info exists destbat_num] {
31
if { [board_info $dest conninfo] == "" } {
33
set name [board_info $dest name]
35
set board_info($name,conninfo) "b${destbat_num}.bat"
39
if [board_info $dest exists fileid] {
40
return [board_info $dest fileid]
43
verbose "doing a dos_open to $dest"
45
set shell_prompt [board_info $dest shell_prompt]
47
set shell_id [remote_raw_open $dest]
49
if { $shell_id == "" || $shell_id < 0 } {
53
if [board_info $dest exists init_command] {
54
remote_send $dest "[board_info $dest init_command]\n"
55
remote_expect $dest 10 {
56
-re "$shell_prompt" { }
58
perror "failed connection to DOS on $dest."
64
if [board_info $dest exists ftp_directory] {
65
set dir [board_info $dest ftp_directory]
66
regsub -all "/" "$dir" "\\" dir
67
remote_send $dest "cd $dir\n"
68
remote_expect $dest 10 {
69
-re "$shell_prompt" { }
71
perror "failed connection to DOS on $dest."
77
if [board_info $dest exists dos_dir] {
78
set dos_dir [board_info $dest dos_dir]
79
regsub -all "^(\[a-zA-Z]:).*$" "$dos_dir" "\\1" drive
80
regsub -all "^\[a-zA-Z]:" "$dos_dir" "" dos_dir
81
remote_send $dest "${drive}\n"
82
remote_expect $dest 10 {
83
-re "$shell_prompt" { }
85
perror "failed connection to DOS on $dest."
89
remote_send $dest "cd $dos_dir\n"
90
remote_expect $dest 10 {
91
-re "$shell_prompt" { }
93
perror "failed connection to DOS on $dest."
100
if [info exists target_alias] {
101
set talias $target_alias
107
if [board_info $dest exists name] {
108
set n [board_info $dest name]
112
set board_info($n,fileid) $shell_id
114
if [board_info $dest exists init_script] {
115
remote_exec $dest "[board_info $dest init_script] $talias"
118
verbose "Succeeded in connecting to DOS."
123
# Close the connection to the remote host. If we're telnetting there, we
124
# need to exit the connection first (ataman telnetd gets confused otherwise).
126
proc dos_close { dest args } {
127
if [board_info $dest exists fileid] {
128
if { [board_info $dest connect] == "telnet" } {
129
remote_send $dest "exit\n"
132
return [remote_raw_close $dest]
136
proc dos_prep_command { dest cmdline } {
139
set name [board_info $dest name]
140
set shell_id [remote_open "$dest"]
142
set localbat "/tmp/b[pid].bat"
143
set remotebat [board_info $dest conninfo]
146
if { $shell_id != "" && $shell_id >= 0 } {
147
set fileid [open "$localbat" "w"]
148
puts -nonewline $fileid "@echo off\r\n$cmdline\r\nif errorlevel 1 echo *** DOSEXIT code 1\r\nif not errorlevel 1 echo *** DOSEXIT code 0\r\n"
150
set result [remote_download $dest $localbat $remotebat]
154
remote_file build delete $localbat
159
# Run CMDLINE on DESTHOST. We handle two cases; one is where we're at
160
# a DOS prompt, and the other is where we're in GDB.
161
# We run CMDLINE by creating a batchfile, downloading it, and then
162
# executing it; this handles the case where the commandline is too
163
# long for command.com to deal with.
166
proc dos_exec { dest program pargs inp outp } {
167
set cmdline "$program $pargs"
169
set shell_prompt [board_info $dest shell_prompt]
172
set inp [remote_download $dest $inp inpfile]
179
set outpf " > tempout"
184
verbose "cmdline is $cmdline$inp." 2
186
# Make a DOS batch file; we use @echo off so we don't have to see
187
# the DOS command prompts and such.
188
for { set i 0 } { $i < 2 } { incr i } {
190
verbose "calling open"
191
set batfile [dos_prep_command $dest "$cmdline$inp$outpf"]
192
if { $batfile != "" } {
193
if { [dos_start_command $batfile $dest] == "" } {
194
# FIXME: The 300 below should be a parameter.
195
set result [remote_wait $dest 300]
196
set exit_status [lindex $result 0]
197
set output [lindex $result 1]
200
if { $exit_status >= 0 } {
202
remote_upload $dest tempout $outp
203
remote_file $dest delete tempout
205
return [list $exit_status $output]
207
if { $exit_status != -2 } {
212
return [list -1 "program execution failed"]
216
# Start CMDLINE executing on DEST.
217
# There are two cases that we handle, one where we're at a DOS prompt
218
# and the other is when the remote machine is running GDB.
221
proc dos_start_command { cmdline dest } {
222
set shell_prompt [board_info $dest shell_prompt]
225
for { set i 0 } {$i <= 2 && ! $ok} { incr i } {
226
set shell_id [remote_open $dest]
227
if { $shell_id != "" && $shell_id > 0 } {
228
remote_send $dest "echo k\r"
229
remote_expect $dest 20 {
231
set shell_prompt "\\(gdb\\)"
232
# gdb uses 'shell command'.
236
-re "$shell_prompt" {
248
return "unable to start command"
250
remote_send $dest "${prefix}${cmdline}\n"
251
remote_expect $dest 2 {
252
-re "${cmdline}\[\r\n\]\[\r\n\]?" { }
260
# Send STRING to DEST, translating all LFs to CRs first, and sending one
261
# line at a time because of strangeness with telnet in some circumstances.
264
proc dos_send { dest string } {
265
verbose "Sending '$string' to $dest" 2
266
# Convert LFs to CRs, 'cause that is what DOS wants to see.
268
set string [string trimright $string "\r\n"]
269
foreach line [split $string "\r\n"] {
273
# small delay between lines, to keep from
274
# overwhelming the stupid telnet server.
277
remote_raw_send $dest "$line\r"
282
# Spawn PROGRAM on DEST, and return the spawn_id associated with the
283
# connection; we can only spawn one command at a time.
286
proc dos_spawn { dest program args } {
287
verbose "running $program on $dest"
288
set remotebat [dos_prep_command $dest $program]
290
for { set x 0 } { $x < 3 } { incr x } {
291
if { [dos_start_command $remotebat $dest] == "" } {
292
return [board_info $dest fileid]
300
proc dos_wait { dest timeout } {
302
set shell_prompt [board_info $dest shell_prompt]
305
verbose "waiting in dos_wait"
306
remote_expect $dest $timeout {
307
-re "(.*)\[*\]\[*\]\[*\] DOSEXIT code (\[0-9\]+)\[\r\n\]\[\r\n\]?" {
308
verbose "got exit status"
309
append output $expect_out(1,string)
310
set status $expect_out(2,string)
314
-re "(.*)${shell_prompt}" {
315
append output $expect_out(1,string)
316
verbose "output from dos is:'$output'"
317
return [list $status $output]
320
-re "(.*)\\(gdb\\)" {
321
append output $expect_out(1,string)
322
return [list $status $output]
325
-re "In.*cygwin.*except" {
328
return [list -2 $output]
332
# This is a bit obscure. We only want to put whole
333
# lines into the output string, because otherwise we
334
# might miss a prompt because we only got 1/2 of it the
335
# first time 'round. The other tricky bit is that
336
# expect_out(buffer) will contain everything before and including
337
# the matched pattern.
338
append output $expect_out(buffer)
339
exp_continue -continue_timer
343
warning "timeout in dos_wait"
344
if { [dos_interrupt_job $dest] == "" } {
345
return [list 1 $output]
350
warning "got EOF from dos host."
356
return [list -1 $output]
359
proc dos_load { dest prog args } {
360
global dos_dll_loaded
363
if { [llength $args] > 0 } {
364
set progargs [lindex $args 1]
366
if { [llength $args] > 1 } {
367
set inpfile [lindex $args 1]
369
if ![info exists dos_dll_loaded] {
370
if ![is_remote host] {
373
set comp [get_multilibs]
374
if [file exists "${comp}/winsup/new-cygwin1.dll"] {
375
set dll "${comp}/winsup/new-cygwin1.dll"
376
set dll_name "cygwin1.dll"
377
} elseif [file exists "${comp}/winsup/new-cygwin.dll"] {
378
set dll "${comp}/winsup/new-cygwin.dll"
379
set dll_name "cygwin.dll"
380
} elseif [file exists ${comp}/lib/cygwin1.dll] {
381
set dll "${comp}/lib/cygwin1.dll"
382
set dll_name "cygwin1.dll"
383
} elseif [file exists ${comp}/lib/cygwin.dll] {
384
set dll "${comp}/lib/cygwin.dll"
385
set dll_name "cygwin.dll"
387
error "couldn't find cygwin.dll:$comp"
390
remote_download $dest $dll $dll_name
394
set remote_prog [remote_download $dest $prog "aout.exe"]
395
set result [remote_exec $dest $remote_prog $progargs $inpfile]
396
set status [lindex $result 0]
397
set output [lindex $result 1]
398
set status2 [check_for_board_status output]
399
if { $status2 >= 0 } {
402
if { $status != 0 } {
407
return [list $status $output]
410
proc dos_file { dest op args } {
414
remote_exec $dest "del" "$x"
420
return [eval standard_file \{$dest\} \{$op\} $args]
426
# Interrupt the current spawned command being run; the only tricky
427
# part is that we have to handle the "Terminate batch job" prompt.
429
proc dos_interrupt_job { host } {
430
set shell_prompt [board_info $host shell_prompt]
432
remote_send $host "\003"
433
remote_expect $host 10 {
434
-re "Terminate batch job.*Y/N\[)\]\[?\] *$" {
435
remote_send $host "n\n"
438
-re "$shell_prompt" {
442
remote_send $host "\n"
449
proc dos_copy_download { host localfile remotefile } {
450
remote_file build delete "[board_info $host local_dir]/$remotefile"
451
if [remote_file build exists $localfile] {
452
set result [remote_download build $localfile "[board_info $host local_dir]/$remotefile"]
453
if { $result != "" } {
454
remote_exec build "chmod" "a+rw $result"
462
proc dos_copy_upload { host remotefile localfile } {
463
remote_file build delete $localfile
464
if [file exists "[board_info $host local_dir]/$remotefile"] {
465
set result [remote_download build "[board_info $host local_dir]/$remotefile" $localfile]
469
if { $result != "" } {
470
remote_exec build "chmod" "a+rw $result"
475
proc dos_copy_file { dest op args } {
476
if { $op == "delete" } {
477
set file "[board_info $dest local_dir]/[lindex $args 0]"
478
remote_file build delete $file
482
set_board_info protocol "dos"
483
set_board_info shell_prompt "(^|\[\r\n\])\[a-zA-Z\]:\[^\r\n\]*>\[ \t\]*$"
484
set_board_info needs_status_wrapper 1