summaryrefslogtreecommitdiffstats
path: root/release
diff options
context:
space:
mode:
authorjkh <jkh@FreeBSD.org>1997-01-17 15:58:58 +0000
committerjkh <jkh@FreeBSD.org>1997-01-17 15:58:58 +0000
commit36e3910a7d4d2443addb87b2ec5a93aa0a3c0a5a (patch)
treec617ad8c4cac1b6a32599d587298596325e5b0f1 /release
parentb293f5b41ca45894135a41fd164567da1f639444 (diff)
downloadFreeBSD-src-36e3910a7d4d2443addb87b2ec5a93aa0a3c0a5a.zip
FreeBSD-src-36e3910a7d4d2443addb87b2ec5a93aa0a3c0a5a.tar.gz
Add timeout support to sysinstall's general media handling,
allow SIGINT to stand for "time out now!" in certain cases.
Diffstat (limited to 'release')
-rw-r--r--release/sysinstall/attr.c9
-rw-r--r--release/sysinstall/dist.c38
-rw-r--r--release/sysinstall/media.c22
-rw-r--r--release/sysinstall/sysinstall.h6
-rw-r--r--release/sysinstall/system.c29
5 files changed, 92 insertions, 12 deletions
diff --git a/release/sysinstall/attr.c b/release/sysinstall/attr.c
index d98af51..3b00316 100644
--- a/release/sysinstall/attr.c
+++ b/release/sysinstall/attr.c
@@ -165,19 +165,12 @@ attr_match(Attribs *attr, char *name)
if (isDebug())
msgDebug("Trying to match attribute `%s'\n", name);
- for (n = 0; attr[n].name[0] && strcasecmp(attr[n].name, name) != 0; n++) {
- if (isDebug())
- msgDebug("Skipping attribute %u\n", n);
- }
-
- if (isDebug())
- msgDebug("Stopped on attribute %u\n", n);
+ for (n = 0; attr[n].name[0] && strcasecmp(attr[n].name, name); n++);
if (attr[n].name[0]) {
if (isDebug())
msgDebug("Returning `%s'\n", attr[n].value);
return(attr[n].value);
}
-
return NULL;
}
diff --git a/release/sysinstall/dist.c b/release/sysinstall/dist.c
index cf2b3c7..ea7a781 100644
--- a/release/sysinstall/dist.c
+++ b/release/sysinstall/dist.c
@@ -36,6 +36,7 @@
#include "sysinstall.h"
#include <sys/time.h>
+#include <signal.h>
unsigned int Dists;
unsigned int DESDists;
@@ -339,6 +340,13 @@ distSetXF86(dialogMenuItem *self)
return i | DITEM_RECREATE;
}
+/* timeout handler */
+static void
+media_timeout(int sig)
+{
+ AlarmWentOff = TRUE;
+}
+
static Boolean
distExtract(char *parent, Distribution *me)
{
@@ -350,6 +358,7 @@ distExtract(char *parent, Distribution *me)
Attribs *dist_attr;
WINDOW *w = savescr();
struct timeval start, stop;
+ struct sigaction old, new;
status = TRUE;
dialog_clear_norefresh();
@@ -388,15 +397,26 @@ distExtract(char *parent, Distribution *me)
snprintf(buf, sizeof buf, "%s/%s.inf", path, dist);
fp = mediaDevice->get(mediaDevice, buf, TRUE);
if (fp > 0) {
+ int status;
+
if (isDebug())
msgDebug("Parsing attributes file for distribution %s\n", dist);
dist_attr = alloca(sizeof(Attribs) * MAX_ATTRIBS);
- if (DITEM_STATUS(attr_parse(dist_attr, fp)) == DITEM_FAILURE)
+
+ /* Make ^C fake a sudden timeout */
+ new.sa_handler = media_timeout;
+ new.sa_flags = 0;
+ new.sa_mask = 0;
+ sigaction(SIGINT, &new, &old);
+
+ alarm_set(MEDIA_TIMEOUT, media_timeout);
+ status = attr_parse(dist_attr, fp);
+ alarm_clear();
+ sigaction(SIGINT, &old, NULL); /* Restore signal handler */
+ if (DITEM_STATUS(status) == DITEM_FAILURE)
msgConfirm("Cannot parse information file for the %s distribution!\n"
"Please verify that your media is valid and try again.", dist);
else {
- if (isDebug())
- msgDebug("Looking for attribute `pieces'\n");
tmp = attr_match(dist_attr, "pieces");
if (tmp)
numchunks = strtol(tmp, 0, 0);
@@ -464,11 +484,20 @@ distExtract(char *parent, Distribution *me)
}
snprintf(prompt, sizeof prompt, "Extracting %s into %s directory...", dist, root_bias(me[i].my_dir));
dialog_gauge("Progress", prompt, 8, 15, 6, 50, (int)((float)(chunk + 1) / numchunks * 100));
+
+ /* Make ^C fake a sudden timeout */
+ new.sa_handler = media_timeout;
+ new.sa_flags = 0;
+ new.sa_mask = 0;
+ sigaction(SIGINT, &new, &old);
+
while (1) {
int seconds;
+ alarm_set(MEDIA_TIMEOUT, media_timeout);
n = fread(buf, 1, BUFSIZ, fp);
- if (n <= 0)
+ alarm_clear();
+ if (n <= 0 || AlarmWentOff)
break;
total += n;
@@ -495,6 +524,7 @@ distExtract(char *parent, Distribution *me)
goto punt;
}
}
+ sigaction(SIGINT, &old, NULL); /* Restore signal handler */
fclose(fp);
}
close(fd2);
diff --git a/release/sysinstall/media.c b/release/sysinstall/media.c
index 8bade8a..cc8e2aa 100644
--- a/release/sysinstall/media.c
+++ b/release/sysinstall/media.c
@@ -35,6 +35,7 @@
*/
#include "sysinstall.h"
+#include <signal.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/param.h>
@@ -515,6 +516,11 @@ mediaExtractDistEnd(int zpid, int cpid)
return TRUE;
}
+static void
+media_timeout(int sig)
+{
+ AlarmWentOff = TRUE;
+}
Boolean
mediaExtractDist(char *dir, char *dist, FILE *fp)
@@ -522,6 +528,7 @@ mediaExtractDist(char *dir, char *dist, FILE *fp)
int i, j, total, seconds, zpid, cpid, pfd[2], qfd[2];
char buf[BUFSIZ];
struct timeval start, stop;
+ struct sigaction new, old;
if (!dir)
dir = "/";
@@ -582,7 +589,19 @@ mediaExtractDist(char *dir, char *dist, FILE *fp)
total = 0;
(void)gettimeofday(&start, (struct timezone *)0);
+ /* Make ^C fake a sudden timeout */
+ new.sa_handler = media_timeout;
+ new.sa_flags = 0;
+ new.sa_mask = 0;
+ sigaction(SIGINT, &new, &old);
+
+ alarm_set(MEDIA_TIMEOUT, media_timeout);
while ((i = fread(buf, 1, BUFSIZ, fp)) > 0) {
+ alarm_clear();
+ if (AlarmWentOff) {
+ msgDebug("Failure to read from media - timeout or user abort.\n");
+ break;
+ }
if (write(qfd[1], buf, i) != i) {
msgDebug("Write error on transfer to cpio process, try of %d bytes\n", i);
break;
@@ -600,7 +619,10 @@ mediaExtractDist(char *dir, char *dist, FILE *fp)
msgInfo("%10d bytes read from %s dist @ %.1f KB/sec.",
total, dist, (total / seconds) / 1024.0);
}
+ alarm_set(MEDIA_TIMEOUT, media_timeout);
}
+ alarm_clear();
+ sigaction(SIGINT, &old, NULL); /* restore sigint */
close(qfd[1]);
i = waitpid(zpid, &j, 0);
diff --git a/release/sysinstall/sysinstall.h b/release/sysinstall/sysinstall.h
index 0eea56f..69e400a 100644
--- a/release/sysinstall/sysinstall.h
+++ b/release/sysinstall/sysinstall.h
@@ -68,6 +68,9 @@
#define INTERFACE_MAX 50 /* Maximum number of network interfaces we'll deal with */
#define IO_ERROR -2 /* Status code for I/O error rather than normal EOF */
+/* Number of seconds to wait for data to come off even the slowest media */
+#define MEDIA_TIMEOUT 300
+
/*
* I make some pretty gross assumptions about having a max of 50 chunks
* total - 8 slices and 42 partitions. I can't easily display many more
@@ -301,6 +304,7 @@ typedef struct _devPriv {
/*** Externs ***/
+extern Boolean AlarmWentOff; /* Convenience variable for alarm_foo() stuff */
extern int DebugFD; /* Where diagnostic output goes */
extern Boolean Fake; /* Don't actually modify anything - testing */
extern Boolean SystemWasInstalled; /* Did we install it? */
@@ -627,6 +631,8 @@ extern int package_extract(Device *dev, char *name, Boolean depended);
extern Boolean package_exists(char *name);
/* system.c */
+extern void alarm_clear(void);
+extern void alarm_set(int delay, void (*handler)(int sig));
extern void systemInitialize(int argc, char **argv);
extern void systemShutdown(int status);
extern int execExecute(char *cmd, char *name);
diff --git a/release/sysinstall/system.c b/release/sysinstall/system.c
index 354f805..1fc4696 100644
--- a/release/sysinstall/system.c
+++ b/release/sysinstall/system.c
@@ -47,6 +47,35 @@ handle_intr(int sig)
restorescr(save);
}
+/* Public variable for ease of use - handler should set it if interested */
+Boolean AlarmWentOff;
+
+/* Simple alarm interface */
+void
+alarm_set(int delay, void (*handler)(int sig))
+{
+ struct sigaction act;
+
+ act.sa_handler = handler;
+ act.sa_flags = 0;
+ act.sa_mask = 0;
+ sigaction(SIGALRM, &act, NULL);
+ AlarmWentOff = FALSE;
+ alarm(delay);
+}
+
+void
+alarm_clear(void)
+{
+ struct sigaction act;
+
+ alarm(0);
+ act.sa_handler = SIG_DFL;
+ act.sa_flags = 0;
+ act.sa_mask = 0;
+ sigaction(SIGALRM, &act, NULL);
+}
+
/* Expand a file into a convenient location, nuking it each time */
static char *
expand(char *fname)
OpenPOWER on IntegriCloud