Permalink
Browse files

First attempt at converting rzh off off pdpzm. There's a big bug in e…

…cho to be fixed.
  • Loading branch information...
Scott Bronson
Scott Bronson committed Jun 13, 2005
1 parent 41efe92 commit d891589572bea5695f76ed218aa34f824c0fae13
Showing with 2,395 additions and 3,881 deletions.
  1. +4 −3 CHANGES
  2. +21 −20 Makefile
  3. +72 −43 bgio.c
  4. +12 −9 bgio.h
  5. +0 −145 crc32.h
  6. +0 −107 crcxm.h
  7. +159 −0 echo.c
  8. +1 −0 echo.h
  9. +0 −47 error.c
  10. +0 −63 error.h
  11. +0 −23 estdlib.h
  12. +56 −45 fifo.c
  13. +5 −5 fifo.h
  14. +94 −0 io/io.h
  15. +79 −0 io/io_epoll.c
  16. +149 −0 io/io_kqueue.c
  17. +31 −0 io/io_poll.c
  18. +185 −0 io/io_select.c
  19. +269 −0 io/io_socket.c
  20. +17 −0 io/io_socket.h
  21. +229 −0 io/iotest.c
  22. +119 −0 log.c
  23. +37 −0 log.h
  24. +0 −64 pdcomm.c
  25. +0 −32 pdcomm.h
  26. +56 −0 re2c/read-fd.c
  27. +14 −0 re2c/read-fd.h
  28. +93 −0 re2c/read-fp.c
  29. +17 −0 re2c/read-fp.h
  30. +52 −0 re2c/read-mem.c
  31. +10 −0 re2c/read-mem.h
  32. +41 −0 re2c/read.c
  33. +20 −0 re2c/read.h
  34. +69 −0 re2c/scan-dyn.c
  35. +11 −0 re2c/scan-dyn.h
  36. +56 −0 re2c/scan.c
  37. +260 −0 re2c/scan.h
  38. +52 −0 re2c/utils.c
  39. +14 −0 re2c/utils.h
  40. +24 −176 rzh.c
  41. +0 −148 scan.c
  42. +67 −0 scan.re
  43. +0 −1 trav.h
  44. +0 −6 unused.h
  45. +0 −457 zio.c
  46. +0 −48 zio.h
  47. +0 −1,798 zmcore.c
  48. +0 −66 zmcore.h
  49. +0 −28 zmext.h
  50. +0 −116 zmextm.c
  51. +0 −32 zmextm.h
  52. +0 −161 zmfr.c
  53. +0 −29 zmfr.h
  54. +0 −209 zmfrunix.c
View
@@ -1,15 +1,16 @@
13 Jun 2005:
- * pdpzm is excruciatingly slow. Now forking lrzsz to handle the transfer.
+ * pdpzm works but it is excruciatingly slow. So, the third attempt:
+ fork a new rz process to handle the zmodem transfer.
13 Nov 2004: tagged version 0.2 (r27)
* Made zmfr.c modular, sent in patches.
* Added send functionality but it appears very broken.
5 Nov 2004: tagged version 0.1 (r21)
* First version that works. Switched to the pdpzm library because the
- lrzsz code is supremely scary.
+ lrzsz code is amazingly brittle.
-13 Jan 2004:
+15 Jan 2004:
* First version. Uses the code from lrzsz.
View
@@ -2,37 +2,38 @@
# Scott Bronson
# This file is MIT licensed (public domain, but removes author liability).
-VERSION=0.2
-
-# pdpzm files
-CSRC=zmcore.c zmfrunix.c zmextm.c error.c pdcomm.c fifo.c bgio.c scan.c zio.c rzh.c
+VERSION=0.5
+CSRC=bgio.c echo.c fifo.c io/io_select.c log.c rzh.c
+# -lrt
# ------------------------ #
-OBJ=$(CSRC:.c=.o)
+# OBJ=$(CSRC:.c=.o)
-COPTS+=-isystem .
+COPTS+=-DVERSION=$(VERSION)
COPTS+=-Wall -Werror
COPTS+=-g
-COPTS+=-DVERSION=$(VERSION)
all: rzh doc
- @(cd test; $(MAKE))
-rzh: $(OBJ)
- $(CC) $(OBJ) -lrt -lutil -o rzh
+rzh: $(CSRC)
+ $(CC) $(COPTS) $(CSRC) -lutil -o rzh
+
+#%.o: %.c
+# $(CC) $(COPTS) -c $<
-%.o: %.c
- $(CC) $(COPTS) -c $<
+%.c: %.re
+ re2c $(REOPTS) $< > $@
+ perl -pi -e 's/^\#line.*$$//' $@
# autogenerate deps
# See http://www.gnu.org/software/make/manual/html_chapter/make_4.html#SEC51
-%.dep: %.c
- @set -e; rm -f $@; \
- $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \
- sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
- rm -f $@.$$$$
+#%.dep: %.c
+# @set -e; rm -f $@; \
+# $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \
+# sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+# rm -f $@.$$$$
-include $(CSRC:.c=.dep)
@@ -43,9 +44,9 @@ doc: rzh.1
clean:
rm -f rzh rzh.1
- rm -f $(CSRC:.c=.o)
- rm -f $(CSRC:.c=.dep)
- rm -f $(CSRC:.c=.dep.*)
+# rm -f $(CSRC:.c=.o)
+# rm -f $(CSRC:.c=.dep)
+# rm -f $(CSRC:.c=.dep.*)
@(cd test; $(MAKE) clean)
dist-clean: clean
View
115 bgio.c
@@ -1,16 +1,19 @@
/* bgio.c
* Scott Bronson
*
- * Starts up background I/O. This file was derived from ancient BSD code.
- * It should probably fall under some sort of BSD license.
+ * 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>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
+#include <errno.h>
#include <string.h>
-#include <termios.h>
#include <unistd.h>
#include <utmp.h>
#include <sys/ioctl.h>
@@ -20,57 +23,53 @@
#include <sys/wait.h>
#include "bgio.h"
+#include "log.h"
-char *bgio_subshell_command=NULL;
-int bgio_master;
-int bgio_slave;
-
-static int child_pid;
-static struct termios stdin_termios;
-
+bgio_state *g_state; // this sucks.
static void window_resize(int dummy)
{
- struct winsize win;
+ bgio_state *state = g_state;
+ struct winsize win;
ioctl(0, TIOCGWINSZ, (char*)&win);
- ioctl(bgio_slave, TIOCSWINSZ, (char*)&win);
-
- kill(child_pid, SIGWINCH);
+ ioctl(state->slave, TIOCSWINSZ, (char*)&win);
+ kill(state->child_pid, SIGWINCH);
}
-void bgio_stop(int code)
+void bgio_stop(bgio_state *state, int code)
{
- tcsetattr(0, TCSAFLUSH, &stdin_termios);
- close(bgio_master);
+ tcsetattr(0, TCSAFLUSH, &state->stdin_termios);
+ close(state->master);
fprintf(stderr, "\r\nrzh exited.\r\n");
exit(code);
}
static void sigchild(int dummy)
{
+ bgio_state *state = g_state;
int pid;
while ((pid = wait3(&dummy, 0, 0)) > 0) {
- if (pid == child_pid) {
- bgio_stop(0);
+ if (pid == state->child_pid) {
+ bgio_stop(state, 0);
}
}
}
-static void do_child()
+static void do_child(bgio_state *state, const char *cmd)
{
char *shell;
char *name;
shell = getenv("SHELL");
if(!shell) {
- shell = _PATH_BSHELL;
+ shell = _PATH_BSHELL; // should be defined by stdlib.
}
name = strrchr(shell, '/');
@@ -80,55 +79,85 @@ static void do_child()
name = shell;
}
- setsid();
- ioctl(bgio_slave, TIOCSCTTY, 0);
-
- close(bgio_master);
- dup2(bgio_slave, 0);
- dup2(bgio_slave, 1);
- dup2(bgio_slave, 2);
- close(bgio_slave);
+ log_dbg("Hello from the child. shell=\"%s\"", shell);
- if(bgio_subshell_command) {
- execl(shell, name, "-c", bgio_subshell_command, 0);
+ setsid();
+ ioctl(state->slave, TIOCSCTTY, 0);
+
+ close(state->master);
+ dup2(state->slave, 0);
+ dup2(state->slave, 1);
+ dup2(state->slave, 2);
+ close(state->slave);
+
+ if(cmd) {
+ execl(shell, name, "-c", cmd, 0);
+ fprintf(stderr, "Could not exec %s -c %s: %s\n",
+ shell, cmd, strerror(errno));
} else {
execl(shell, name, "-i", 0);
+ fprintf(stderr, "Could not exec %s -i: %s\n",
+ shell, strerror(errno));
}
+
+ log_dbg("child got fuxored.");
+
+ exit(86);
}
+/**
+ * http://www.dusek.ch/manual/glibc/libc_17.html:
+ * Data written to the master side is received by the slave side as
+ * if it was the result of a user typing at an ordinary terminal,
+ * and data written to the slave side is sent to the master side as
+ * if it was written on an ordinary terminal.
+ *
+ * @param state: uninitialized memory to store the state for this conn.
+ * @param cmd: Command to run in child. If NULL, starts the default shell.
+ *
+ * @returns: Nothing! It prints a message to stdout and exits on failure.
+ * This should really be changed one day.
+ */
-void bgio_start()
+void bgio_start(bgio_state *state, const char *cmd)
{
- struct winsize win;
+ struct winsize win;
struct termios tt;
- tcgetattr(0, &stdin_termios);
+ // this is why we can only handle one session at once.
+ g_state = state;
+
+ tcgetattr(0, &state->stdin_termios);
ioctl(0, TIOCGWINSZ, (char *)&win);
- if (openpty(&bgio_master, &bgio_slave, NULL, &stdin_termios, &win) < 0) {
+ if (openpty(&state->master, &state->slave, NULL,
+ &state->stdin_termios, &win) < 0) {
perror("calling openpty");
kill(0, SIGTERM);
- bgio_stop(fork_error1);
+ fprintf(stderr, "\r\nrzh exited.\r\n");
+ exit(fork_error1);
}
- tt = stdin_termios;
+ log_dbg("bgio: master=%d slave=%d", state->master, state->slave);
+
+ tt = state->stdin_termios;
cfmakeraw(&tt);
tt.c_lflag &= ~ECHO;
tcsetattr(0, TCSAFLUSH, &tt);
signal(SIGCHLD, sigchild);
- child_pid = fork();
- if(child_pid < 0) {
+ state->child_pid = fork();
+ if(state->child_pid < 0) {
perror("forking child");
kill(0, SIGTERM);
- bgio_stop(fork_error2);
+ bgio_stop(state, fork_error2);
}
- if(child_pid == 0) {
- do_child();
+ if(state->child_pid == 0) {
+ do_child(state, cmd);
perror("executing child");
kill(0, SIGTERM);
- bgio_stop(fork_error3);
+ bgio_stop(state, fork_error3);
}
signal(SIGWINCH, window_resize);
View
21 bgio.h
@@ -5,23 +5,26 @@
* This file is MIT licensed.
*/
-// Command to run in child. If NULL, starts the default shell.
-extern char *bgio_subshell_command;
+#include <termios.h>
+
+
+typedef struct {
+ int master; // the fd of the master
+ int slave; // the fd of the slave
+ int child_pid; // the pid of the subprocess
+ struct termios stdin_termios; // original termios to restore when finished
+} bgio_state;
-// Need to call start_bgio before these are valid.
-extern int bgio_master;
-extern int bgio_slave;
// Opens a pty and forks the child process specified by bgio_subshell_command.
-void bgio_start();
+void bgio_start(bgio_state *state, const char *cmd);
// Shuts down everything started by bgio_start, then exits.
-void bgio_stop(int code);
+void bgio_stop(bgio_state *state, int code);
// result codes returned by exit().
-// actually, htese are mostly used by main, not bgio
-// but bgio needs to access the fork_errors.
+// actually, these are mostly used by main, not bgio
enum {
argument_error=1,
Oops, something went wrong.

0 comments on commit d891589

Please sign in to comment.