Add timeout support to sysinstall's general media handling,

allow SIGINT to stand for "time out now!" in certain cases.
This commit is contained in:
Jordan K. Hubbard 1997-01-17 15:58:58 +00:00
parent 171b420b11
commit 135c95a582
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=21806
11 changed files with 218 additions and 16 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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)