Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Refactor: make bgio use globals again. Sine the user only interacts with

a single terminal, there's no reason to allow more than one simultaneous
bgio.  And it surely did add some noticeable complexity.
  • Loading branch information...
commit 4472db9371d95cc191424574cda66a7baff64d27 1 parent 4bc39ec
Scott Bronson authored
View
3  CHANGES
@@ -1,3 +1,6 @@
+- Get rid of master_pipe. Spread functionality into tasks, and the app
+ should just keep a global of the current task.
+
- We currently freeze when the transfer is cancelled. That's bad.
- rzh -q: tell current rzh to quit
View
12 Makefile
@@ -7,10 +7,16 @@
VERSION=0.8
-CSRC=bgio.c echo.c fifo.c log.c idle.c master.c pipe.c cmd.c \
- rztask.c task.c util.c zfin.c zrq.c
+CSRC=bgio.c cmd.c fifo.c idle.c log.c pipe.c task.c util.c zfin.c zrq.c
+CSRC+=consoletask.c echotask.c rztask.c
+CSRC+=io/io_socket.c
CHDR:=$(CSRC:.c=.h)
-CSRC+=rzh.c io/io_select.c io/io_socket.c
+
+CSRC+=io/io_select.c
+CHDR+=io/io.h
+
+CSRC+=rzh.c
+
COPTS+=-DVERSION=$(VERSION)
View
104 bgio.c
@@ -2,10 +2,6 @@
* Scott Bronson
*
* Starts up background I/O behind another process.
- *
- * NOTE: can currently only handle one ongoing bgio session because of
- * the single global used by the signal callbacks. Too bad C doesn't
- * have closures... Some dynamic alloc/dealloc would fix this if need be.
*/
#include <pty.h>
@@ -21,6 +17,7 @@
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <termios.h>
#include "bgio.h"
#include "log.h"
@@ -28,34 +25,49 @@
#include "util.h"
-command shellcmd;
+static int st_master_fd;
+static int st_slave_fd;
+int st_child_pid;
+static struct termios st_stdin_ios; // restore when finished
+static struct winsize st_window; // current winsize of terminal
-bgio_state *g_state; // this sucks. it's for the signals.
-int bgio_child_pid; // this also sucks. It's for the global sigchld handler.
static void window_resize(int dummy)
{
- bgio_state *state = g_state;
+ ioctl(0, TIOCGWINSZ, (char*)&st_window);
+ ioctl(st_slave_fd, TIOCSWINSZ, (char*)&st_window);
+ kill(st_child_pid, SIGWINCH);
+}
+
- ioctl(0, TIOCGWINSZ, (char*)&state->window);
- ioctl(state->slave, TIOCSWINSZ, (char*)&state->window);
- kill(state->child_pid, SIGWINCH);
+void bgio_stop()
+{
+ tcsetattr(0, TCSAFLUSH, &st_stdin_ios);
+ log_info("Closed FD %d (master)", st_master_fd);
+ close(st_master_fd);
+ log_info("Closed FD %d (slave)", st_slave_fd);
+ close(st_slave_fd);
}
-void bgio_stop(bgio_state *state)
+void bgio_close()
{
- tcsetattr(0, TCSAFLUSH, &state->stdin_termios);
- log_info("Closed FD %d (master)", state->master);
- close(state->master);
- log_info("Closed FD %d (slave)", state->slave);
- close(state->slave);
+ close(st_master_fd);
+ close(st_slave_fd);
}
-static void do_child(bgio_state *state)
+int bgio_get_window_width()
+{
+ // This routine may be called even if we're using socketio
+ // instead of bgio. Ensure we still return decent data.
+ return st_window.ws_col ? st_window.ws_col : 80;
+}
+
+
+static void do_child()
{
char *shell;
char *name;
@@ -77,28 +89,22 @@ static void do_child(bgio_state *state)
}
setsid();
- ioctl(state->slave, TIOCSCTTY, 0);
+ ioctl(st_slave_fd, TIOCSCTTY, 0);
- close(state->master);
- dup2(state->slave, 0);
- dup2(state->slave, 1);
- dup2(state->slave, 2);
- close(state->slave);
+ close(st_master_fd);
+ dup2(st_slave_fd, 0);
+ dup2(st_slave_fd, 1);
+ dup2(st_slave_fd, 2);
+ close(st_slave_fd);
log_close();
fdcheck();
- /*
- if(cmd) {
- execl(shell, name, "-c", cmd, NULL);
- fprintf(stderr, "Could not exec %s -c %s: %s\n",
- shell, cmd, strerror(errno));
- } else {
- */
- execl(shell, name, "-i", NULL);
- fprintf(stderr, "Could not exec %s -i: %s\n",
- shell, strerror(errno));
- // }
+ // There's probably no need for -i since input and output are
+ // to ttys anway. However, since all shells support it, why not?
+ execl(shell, name, "-i", NULL);
+ fprintf(stderr, "Could not exec %s -i: %s\n",
+ shell, strerror(errno));
exit(86);
}
@@ -118,44 +124,42 @@ static void do_child(bgio_state *state)
* it only exits if it couldn't allocate a pty. else it exits through bail).
*/
-void bgio_start(bgio_state *state)
+int bgio_start()
{
struct termios tt;
- // this is why we can only handle one session at once.
- g_state = state;
-
- tcgetattr(0, &state->stdin_termios);
- ioctl(0, TIOCGWINSZ, (char *)&state->window);
- if (openpty(&state->master, &state->slave, NULL,
- &state->stdin_termios, &state->window) < 0) {
+ tcgetattr(0, &st_stdin_ios);
+ ioctl(0, TIOCGWINSZ, (char *)&st_window);
+ if (openpty(&st_master_fd, &st_slave_fd, NULL,
+ &st_stdin_ios, &st_window) < 0) {
perror("calling openpty");
kill(0, SIGTERM);
exit(fork_error1);
}
- log_dbg("bgio: master=%d slave=%d", state->master, state->slave);
+ log_dbg("bgio: master=%d slave=%d", st_master_fd, st_slave_fd);
- tt = state->stdin_termios;
+ tt = st_stdin_ios;
cfmakeraw(&tt);
tt.c_lflag &= ~ECHO;
tcsetattr(0, TCSAFLUSH, &tt);
- state->child_pid = fork();
- if(state->child_pid < 0) {
+ st_child_pid = fork();
+ if(st_child_pid < 0) {
perror("forking child");
kill(0, SIGTERM);
bail(fork_error2);
}
- if(state->child_pid == 0) {
- do_child(state);
+ if(st_child_pid == 0) {
+ do_child();
perror("executing child");
kill(0, SIGTERM);
bail(fork_error3);
}
- bgio_child_pid = state->child_pid;
signal(SIGWINCH, window_resize);
+
+ return st_master_fd;
}
View
20 bgio.h
@@ -5,21 +5,15 @@
* This file is MIT licensed.
*/
-#include <termios.h>
-
-
-typedef struct {
- int master; // the fd of the master
- int slave; // the fd of the slave (needed for winch)
- int child_pid; // the pid of the subprocess
- struct termios stdin_termios; // original termios to restore when finished
- struct winsize window; // current winsize of terminal
-} bgio_state;
+extern int st_child_pid; // TODO: get rid of me!
// Opens a pty and forks the child process specified by bgio_subshell_command.
-void bgio_start(bgio_state *state);
-
+int bgio_start();
// Shuts down everything started by bgio_start, then exits.
-void bgio_stop(bgio_state *state);
+void bgio_stop();
+// closes the fds used by bgio but doesn't deallocate any memory
+void bgio_close();
+
+int bgio_get_window_width();
View
3  cmd.h
@@ -17,6 +17,5 @@ void cmd_parse(command *cmd, const char *str);
void cmd_print(const char *str, command *cmd);
void cmd_free(command *cmd);
-
-extern command rzcmd, shellcmd; // there must be a better place for this.
+extern command rzcmd;
View
75 master.c → consoletask.c
@@ -4,6 +4,7 @@
* Sets up the bgio master pipe and prepares it to accept tasks.
* Automatically installs the echo task as its first task.
*
+ * TODO: get rid of st_child_pid
* TODO: stdio is not reentrant. Can't call log_XX from a signal
* handler.
*/
@@ -24,8 +25,8 @@
#include "io/io.h"
#include "pipe.h"
#include "task.h"
-#include "master.h"
#include "util.h"
+#include "consoletask.h"
static int sigchild_received;
@@ -72,16 +73,14 @@ void master_check_sigchild(master_pipe *mp)
static void master_pipe_destructor(master_pipe *mp, int free_mem)
{
- bgio_state *bgio = mp->refcon;
-
master_pipe_default_destructor(mp, free_mem);
if(free_mem) {
- if(bgio) {
- bgio_stop(bgio);
- free(bgio);
- }
+ bgio_stop();
+ // TODO -- where do we stick this code? How does rzh.c
+ // discover that its console task has been destroyed?
+ //
// When we're done destroying the pipe, bail with no error.
if(!opt_quiet) {
fprintf(stderr, "rzh exited.\n");
@@ -90,35 +89,24 @@ static void master_pipe_destructor(master_pipe *mp, int free_mem)
// We only want to bail if we're exiting normally. If we're
// just cleaning up before forking, no need to bail!
bail(0);
- }
-
- // we're only forking so only close the files.
- if(bgio) {
- close(bgio->master);
- close(bgio->slave);
+ } else {
+ // we're only forking so close the files, don't free the mem.
+ bgio_close();
}
}
static void master_terminate(master_pipe *mp)
{
- bgio_state *bgio = mp->refcon;
- if(!bgio) {
- return;
+ if(st_child_pid > 0) {
+ kill(st_child_pid, SIGTERM);
}
-
- kill(bgio->child_pid, SIGTERM);
}
static void master_pipe_sigchild(master_pipe *mp, int pid)
{
- bgio_state *bgio = mp->refcon;
- if(!bgio) {
- return;
- }
-
- if(pid == bgio->child_pid) {
+ if(pid == st_child_pid) {
// our child shell has disappeared.
// Kill off all tasks. The removal of the last task will
// trigger the destructor which leaps directly home.
@@ -149,36 +137,19 @@ int master_idle(master_pipe *mp)
}
-static bgio_state* master_start_bgio()
-{
- bgio_state *bgio = malloc(sizeof(bgio_state));
- if(bgio == NULL) {
- perror("allocating bgio_state");
- bail(47);
- }
- bgio_start(bgio);
-
- log_dbg("FD Master: %d", bgio->master);
- log_dbg("FD Slave: %d", bgio->slave);
-
- return bgio;
-}
-
-
-master_pipe* master_setup(int sockfd)
+master_pipe* master_setup(int fd)
{
master_pipe *mp;
- bgio_state *bgio = NULL;
- if(sockfd < 0) {
+ if(fd < 0) {
// no socket, so open a tty
- bgio = master_start_bgio();
- mp = master_pipe_init(bgio->master);
- } else {
- // we were given a socket so use that
- mp = master_pipe_init(sockfd);
+ fd = bgio_start();
}
+ // TODO log_dbg("FD Master: %d", bgio->master);
+ // TODO log_dbg("FD Slave: %d", bgio->slave);
+ mp = master_pipe_init(fd);
+
if(mp == NULL) {
perror("allocating master pipe");
bail(49);
@@ -186,7 +157,6 @@ master_pipe* master_setup(int sockfd)
mp->destruct_proc = master_pipe_destructor;
mp->sigchild_proc = master_pipe_sigchild;
mp->terminate_proc = master_terminate;
- mp->refcon = bgio;
signal(SIGCHLD, sigchild);
signal(SIGPIPE, sigpipe);
@@ -194,10 +164,3 @@ master_pipe* master_setup(int sockfd)
return mp;
}
-
-int master_get_window_width(master_pipe *mp)
-{
- bgio_state *bgio = mp->refcon;
- return bgio ? bgio->window.ws_col : 80;
-}
-
View
1  master.h → consoletask.h
@@ -1,5 +1,4 @@
int master_idle();
master_pipe* master_setup(int sockfd);
void master_check_sigchild(master_pipe *mp);
-int master_get_window_width(master_pipe *mp);
View
0  echo.c → echotask.c
File renamed without changes
View
0  echo.h → echotask.h
File renamed without changes
View
13 idle.c
@@ -19,7 +19,6 @@
#include "task.h"
#include "idle.h"
#include "util.h"
-#include "master.h"
typedef struct {
@@ -152,9 +151,11 @@ static void idle_get_numbers(task_spec *spec, idle_numbers *out)
/** Pads the string out to the given number of characters with spaces
+ * @param buf The string to pad
+ * @param width How long the string should be, including blanks.
*/
-static void adjust_string_width(char *buf, int width)
+static void pad_with_blanks(char *buf, int width)
{
int i;
@@ -219,11 +220,11 @@ int idle_proc(task_spec *spec)
"%s %s: received %s at %s/s, sent %s at %s/s",
n->xfertime, idle->command, n->rnum, n->rbps, n->snum, n->sbps);
- len = master_get_window_width(spec->master);
+ len = get_window_width();
if(len > sizeof(buf) - 1) {
len = sizeof(buf) - 1;
}
- adjust_string_width(buf, len);
+ pad_with_blanks(buf, len);
buf[len-1] = '\r';
@@ -259,11 +260,11 @@ void idle_end(task_spec *spec)
"Received %s at %s/s Sent %s at %s/s.",
n->rnum, n->rbps, n->snum, n->sbps);
- len = master_get_window_width(spec->master);
+ len = get_window_width();
if(len > sizeof(buf) - 1) {
len = sizeof(buf) - 1;
}
- adjust_string_width(buf, len);
+ pad_with_blanks(buf, len);
buf[len-2] = '\r';
buf[len-1] = '\n';
View
14 rzh.c
@@ -28,8 +28,8 @@
#include "pipe.h"
#include "task.h"
#include "cmd.h"
-#include "echo.h"
-#include "master.h"
+#include "echotask.h"
+#include "consoletask.h"
#include "util.h"
@@ -280,7 +280,6 @@ static void process_args(int argc, char **argv)
{"version", 0, 0, 'V'},
{"rz", 1, 0, RZ_CMD}, // unfinished
- {"shell", 1, 0, SHELL_CMD}, // unfinished
#ifndef NDEBUG
{"connect", 1, 0, CONNECT_ADDR},
@@ -377,13 +376,6 @@ static void process_args(int argc, char **argv)
}
break;
- case SHELL_CMD:
- cmd_parse(&shellcmd, optarg);
- if(!opt_quiet) {
- cmd_print("Shell command", &shellcmd);
- }
- break;
-
case 'V':
printf("rzh version %s\n", stringify(VERSION));
exit(0);
@@ -432,7 +424,6 @@ int main(int argc, char **argv)
io_init();
cmd_init(&rzcmd);
- cmd_init(&shellcmd);
conn_addr.addr.s_addr = inet_addr("127.0.0.1");
conn_addr.port = 0;
@@ -479,7 +470,6 @@ int main(int argc, char **argv)
}
cmd_free(&rzcmd);
- cmd_free(&shellcmd);
if(val == 0) {
// We're not forking, we're qutting normally. The requirements are
View
31 task.c
@@ -1,14 +1,9 @@
/* task.c
* 14 June 2005
* Scott Bronson
- *
- * Tasks are inserted onto pipes to handle processing. For instance,
- * the default task is echo, just copying data unmodified over the
- * pipe. However, when the echo task notices a zmodem start sequence
- * it inserts the rztask onto the pipe. The rztask then handles all
- * data until it exits, when the echo task takes over again.
*/
+
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@@ -444,27 +439,3 @@ master_pipe* master_pipe_init(int masterfd)
return mp;
}
-
-/*
-void master_pipe_terminate(master_pipe *mp)
-{
- task_state *task = mp->task_head;
-
- while(task) {
- (*task->spec->terminate_proc)(mp, task->spec);
- task = task->next;
- }
-
- (*mp->terminate_proc)(mp);
-
- // TODO: Should probably wait around for kids to die...?
-
- while(mp->task_head) {
- task_remove(mp);
- }
-
- // now the pipe should be entirely destroyed.
-}
-*/
-
-
View
7 util.c
@@ -7,6 +7,7 @@
#include <unistd.h>
#include <errno.h>
+#include "bgio.h"
#include "util.h"
#include "log.h"
@@ -59,3 +60,9 @@ int chdir_to_dldir()
return succ;
}
+
+int get_window_width()
+{
+ return bgio_get_window_width();
+}
+
View
3  util.h
@@ -1,3 +1,5 @@
+// This is a file of random crap that doesn't easily fit anywhere else.
+
extern int g_highest_fd;
extern int opt_quiet;
@@ -5,6 +7,7 @@ extern const char *download_dir;
void fdcheck();
int find_highest_fd();
+int get_window_width();
// provided by rzh.
extern void bail(int val);
View
54 zfin.c
@@ -11,7 +11,7 @@
* Scans for the ZFIN packet and tries to assure an orderly shutdown.
*
* Terminating the connection without sending garbage onto the user's
- * terminal is made somewhat complex due to zmodem weirdness.
+ * terminal is made somewhat complex due to signfiicant zmodem weirdness.
* Here's how we do it now:
*
* 1) Sender sends ZFIN
@@ -83,6 +83,33 @@ void zfin_destroy(zfinscanstate *state)
}
+#if 0
+
+// This wrapper verifies that zfin_scan doesn't modify its data in any way.
+void zfin_scan(struct fifo *f, const char *buf, int size, int fd)
+{
+ log_warn("enter: size=%d refcon=%08lX", size, (long)f->refcon);
+ int ofe = f->end;
+ orig_zfin_scan(f, buf, size, fd);
+ int nfe = f->end;
+
+ if(nfe >= ofe) {
+ if(nfe - ofe != size) {
+ log_warn("sizes differ!");
+ } else if(memcmp(f->buf+ofe, buf, size) != 0) {
+ log_warn("contents differ!");
+ }
+ } else {
+ // skip this for now
+ log_warn("wrap!");
+ }
+}
+
+#define zfin_scan orig_zfin_scan
+
+#else
+
+
void zfin_scan(struct fifo *f, const char *buf, int size, int fd)
{
// technically this string should begin with "**". however there's
@@ -156,6 +183,8 @@ void zfin_scan(struct fifo *f, const char *buf, int size, int fd)
}
}
+#endif
+
/** No OO: drops an optional OO, then passes the rest to zfinsave */
// TODO: this doesn't appear to work 100%
@@ -230,26 +259,3 @@ void zfin_drop(struct fifo *f, const char *buf, int size, int fd)
log_info("IGNORE from %d: \"%s\"", fd, sanitize(buf, size));
}
-
-/*
- // This wrapper verifies that zfin_scan doesn't modify its data in any way.
-void zfin_scan(struct fifo *f, const char *buf, int size, int fd)
-{
- log_warn("enter: size=%d refcon=%08lX", size, (long)f->refcon);
- int ofe = f->end;
- azfin_scan(f, buf, size, fd);
- int nfe = f->end;
-
- if(nfe >= ofe) {
- if(nfe - ofe != size) {
- log_warn("sizes differ!");
- } else if(memcmp(f->buf+ofe, buf, size) != 0) {
- log_warn("contents differ!");
- }
- } else {
- // skip this for now
- log_warn("wrap!");
- }
-}
-*/
-
Please sign in to comment.
Something went wrong with that request. Please try again.