mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-30 04:22:44 +00:00
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:
parent
171b420b11
commit
135c95a582
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=21806
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user