* Makefile.am: Add an empty check-DEJAGNU target, cause we only
[dejagnu.git] / config / dos.exp
blobf455acbf62625a9ae0562ea7866099bd2ea8786c
1 # Copyright (C) 1997 - 2001 Free Software Foundation, Inc.
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 # Please email any bugs, comments, and/or additions to this file to:
18 # bug-dejagnu@gnu.org
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 } {
26 global destbat_num
28 if ![info exists destbat_num] {
29 set destbat_num [pid];
31 if { [board_info $dest conninfo] == "" } {
32 global board_info;
33 set name [board_info $dest name];
35 set board_info($name,conninfo) "b${destbat_num}.bat";
36 incr destbat_num;
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 } {
50 return -1;
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" { }
57 default {
58 perror "failed connection to DOS on $dest."
59 return -1;
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" { }
70 default {
71 perror "failed connection to DOS on $dest."
72 return -1;
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" { }
84 default {
85 perror "failed connection to DOS on $dest."
86 return -1;
89 remote_send $dest "cd $dos_dir\n";
90 remote_expect $dest 10 {
91 -re "$shell_prompt" { }
92 default {
93 perror "failed connection to DOS on $dest."
94 return -1;
99 global target_alias
100 if [info exists target_alias] {
101 set talias $target_alias;
102 } else {
103 set talias "foo-bar"
106 global board_info;
107 if [board_info $dest exists name] {
108 set n [board_info $dest name];
109 } else {
110 set n $dest;
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."
119 return $shell_id;
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";
130 sleep 2;
132 return [remote_raw_close $dest];
136 proc dos_prep_command { dest cmdline } {
137 global board_info;
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];
145 verbose "opened"
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\x1a";
149 close $fileid;
150 set result [remote_download $dest $localbat $remotebat];
151 } else {
152 set result ""
154 remote_file build delete $localbat;
155 return $result;
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];
171 if { $inp != "" } {
172 set inp [remote_download $dest $inp inpfile];
173 if { $inp != "" } {
174 set inp " < $inp";
178 if { $outp != "" } {
179 set outpf " > tempout";
180 } else {
181 set outpf "";
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 } {
189 set exit_status -1;
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 } {
201 if { $outp != "" } {
202 remote_upload $dest tempout $outp;
203 remote_file $dest delete tempout;
205 return [list $exit_status $output];
207 if { $exit_status != -2 } {
208 remote_close $dest;
209 remote_reboot $dest;
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];
223 set prefix ""
224 set ok 0;
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 {
230 -re "\\(gdb\\)" {
231 set shell_prompt "\\(gdb\\)";
232 # gdb uses 'shell command'.
233 set prefix "shell ";
234 set ok 1;
236 -re "$shell_prompt" {
237 set ok 1;
239 default { }
242 if { ! $ok } {
243 remote_close $dest;
244 remote_reboot $dest;
247 if { ! $ok } {
248 return "unable to start command"
249 } else {
250 remote_send $dest "${prefix}${cmdline}\n";
251 remote_expect $dest 2 {
252 -re "${cmdline}\[\r\n\]\[\r\n\]?" { }
253 timeout { }
255 return "";
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.
267 set first 1
268 set string [string trimright $string "\r\n"]
269 foreach line [split $string "\r\n"] {
270 if {$first} {
271 set first 0
272 } else {
273 # small delay between lines, to keep from
274 # overwhelming the stupid telnet server.
275 sleep 1.0
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];
294 remote_close $dest;
295 remote_reboot $dest;
297 return -1;
300 proc dos_wait { dest timeout } {
301 set output "";
302 set shell_prompt [board_info $dest shell_prompt];
303 set status 1;
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);
311 exp_continue;
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" {
326 remote_close $dest;
327 remote_reboot $dest;
328 return [list -2 $output];
331 -re "\[\r\n\]+" {
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;
342 timeout {
343 warning "timeout in dos_wait";
344 if { [dos_interrupt_job $dest] == "" } {
345 return [list 1 $output];
349 eof {
350 warning "got EOF from dos host.";
354 remote_close $dest;
356 return [list -1 $output];
359 proc dos_load { dest prog args } {
360 global dos_dll_loaded;
361 set progargs "";
362 set inpfile "";
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] {
371 global target_alias;
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";
386 } else {
387 error "couldn't find cygwin.dll:$comp"
388 return "fail";
390 remote_download $dest $dll $dll_name
392 set dos_dll_loaded 1;
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 } {
400 set status $status2;
402 if { $status != 0 } {
403 set status "fail";
404 } else {
405 set status "pass";
407 return [list $status $output];
410 proc dos_file { dest op args } {
411 switch $op {
412 delete {
413 foreach x $args {
414 remote_exec $dest "del" "$x";
416 return;
419 default {
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";
436 exp_continue;
438 -re "$shell_prompt" {
439 return "";
441 -re ">" {
442 remote_send $host "\n";
443 exp_continue;
446 return "fail";
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";
455 return $remotefile;
457 } else {
458 return ""
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];
466 } else {
467 set result "";
469 if { $result != "" } {
470 remote_exec build "chmod" "a+rw $result";
471 return $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