1 /*
2  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18 
19 FILE_LICENCE ( GPL2_OR_LATER );
20 
21 #include <string.h>
22 #include <stdio.h>
23 #include <errno.h>
24 #include <gpxe/process.h>
25 #include <console.h>
26 #include <gpxe/keys.h>
27 #include <gpxe/job.h>
28 #include <gpxe/monojob.h>
29 #include <gpxe/timer.h>
30 
31 /** @file
32  *
33  * Single foreground job
34  *
35  */
36 
37 static int monojob_rc;
38 
39 static void monojob_done ( struct job_interface *job __unused, int rc ) {
40 	monojob_rc = rc;
41 }
42 
43 /** Single foreground job operations */
44 static struct job_interface_operations monojob_operations = {
45 	.done		= monojob_done,
46 	.kill		= ignore_job_kill,
47 	.progress	= ignore_job_progress,
48 };
49 
50 /** Single foreground job */
51 struct job_interface monojob = {
52 	.intf = {
53 		.dest = &null_job.intf,
54 		.refcnt = NULL,
55 	},
56 	.op = &monojob_operations,
57 };
58 
59 /**
60  * Wait for single foreground job to complete
61  *
62  * @v string		Job description to display
63  * @ret rc		Job final status code
64  */
65 int monojob_wait ( const char *string ) {
66 	int key;
67 	int rc;
68 	unsigned long last_progress_dot;
69 	unsigned long elapsed;
70 
71 	printf ( "%s.", string );
72 	monojob_rc = -EINPROGRESS;
73 	last_progress_dot = currticks();
74 	while ( monojob_rc == -EINPROGRESS ) {
75 		step();
76 		if ( iskey() ) {
77 			key = getchar();
78 			switch ( key ) {
79 			case CTRL_C:
80 				job_kill ( &monojob );
81 				rc = -ECANCELED;
82 				goto done;
83 			default:
84 				break;
85 			}
86 		}
87 		elapsed = ( currticks() - last_progress_dot );
88 		if ( elapsed >= TICKS_PER_SEC ) {
89 			printf ( "." );
90 			last_progress_dot = currticks();
91 		}
92 	}
93 	rc = monojob_rc;
94 
95 done:
96 	job_done ( &monojob, rc );
97 	if ( rc ) {
98 		printf ( " %s\n", strerror ( rc ) );
99 	} else {
100 		printf ( " ok\n" );
101 	}
102 	return rc;
103 }
104