diff options
-rw-r--r-- | st.c | 60 | ||||
-rw-r--r-- | st.h | 7 |
2 files changed, 41 insertions, 26 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* See LICENSE for licence details. */ | 1 | /* See LICENSE for licence details. */ |
2 | #include "st.h" | 2 | #include "st.h" |
3 | 3 | ||
4 | /* Globals */ | 4 | /* Globals */ |
@@ -7,6 +7,7 @@ XWindow xw; | |||
7 | Term term; | 7 | Term term; |
8 | Escseq escseq; | 8 | Escseq escseq; |
9 | int cmdfd; | 9 | int cmdfd; |
10 | pid_t pid; | ||
10 | int running; | 11 | int running; |
11 | 12 | ||
12 | void | 13 | void |
@@ -27,34 +28,45 @@ execsh(void) { | |||
27 | } | 28 | } |
28 | 29 | ||
29 | void | 30 | void |
30 | xbell(void) { /* visual bell */ | 31 | xbell(void) { /* visual bell */ |
31 | XRectangle r = { 0, 0, xw.w, xw.h }; | 32 | XRectangle r = { 0, 0, xw.w, xw.h }; |
32 | XSetForeground(xw.dis, dc.gc, dc.col[BellCol]); | 33 | XSetForeground(xw.dis, dc.gc, dc.col[BellCol]); |
33 | XFillRectangles(xw.dis, xw.win, dc.gc, &r, 1); | 34 | XFillRectangles(xw.dis, xw.win, dc.gc, &r, 1); |
34 | usleep(30000); | 35 | /* usleep(30000); */ |
35 | draw(SCredraw); | 36 | draw(SCredraw); |
36 | } | 37 | } |
37 | 38 | ||
39 | void | ||
40 | sigchld(int a) { | ||
41 | int stat = 0; | ||
42 | if(waitpid(pid, &stat, 0) < 0) | ||
43 | die("Waiting for pid %hd failed: %s\n", pid, SERRNO); | ||
44 | if(WIFEXITED(stat)) | ||
45 | exit(WEXITSTATUS(stat)); | ||
46 | else | ||
47 | exit(EXIT_FAILURE); | ||
48 | } | ||
49 | |||
50 | |||
38 | void | 51 | void |
39 | ttynew(void) { | 52 | ttynew(void) { |
40 | int m, s; | 53 | int m, s; |
41 | pid_t pid; | ||
42 | char *pts; | 54 | char *pts; |
43 | 55 | ||
44 | if((m = posix_openpt(O_RDWR | O_NOCTTY)) < 0) | 56 | if((m = posix_openpt(O_RDWR | O_NOCTTY)) < 0) |
45 | die("openpt"); | 57 | die("openpt failed: %s\n", SERRNO); |
46 | if(grantpt(m) == -1) | 58 | if(grantpt(m) < 0) |
47 | die("grandpt"); | 59 | die("grandpt failed: %s\n", SERRNO); |
48 | if(unlockpt(m) == -1) | 60 | if(unlockpt(m) < 0) |
49 | die("unlockpt"); | 61 | die("unlockpt failed: %s\n", SERRNO); |
50 | if((pts = ptsname(m)) == NULL) | 62 | if(!(pts = ptsname(m))) |
51 | die("ptsname"); | 63 | die("ptsname failed: %s\n", SERRNO); |
52 | if((s = open(pts, O_RDWR | O_NOCTTY)) < 0) | 64 | if((s = open(pts, O_RDWR | O_NOCTTY)) < 0) |
53 | die("slave open"); | 65 | die("Couldn't open slave: %s\n", SERRNO); |
54 | fcntl(s, F_SETFL, O_NDELAY); | 66 | fcntl(s, F_SETFL, O_NDELAY); |
55 | switch(pid = fork()) { | 67 | switch(pid = fork()) { |
56 | case -1: | 68 | case -1: |
57 | die("fork"); | 69 | die("fork failed\n"); |
58 | break; | 70 | break; |
59 | case 0: | 71 | case 0: |
60 | setsid(); /* create a new process group */ | 72 | setsid(); /* create a new process group */ |
@@ -62,12 +74,13 @@ ttynew(void) { | |||
62 | dup2(s, STDOUT_FILENO); | 74 | dup2(s, STDOUT_FILENO); |
63 | dup2(s, STDERR_FILENO); | 75 | dup2(s, STDERR_FILENO); |
64 | if(ioctl(s, TIOCSCTTY, NULL) < 0) | 76 | if(ioctl(s, TIOCSCTTY, NULL) < 0) |
65 | die("slave TTIOCSTTY"); | 77 | die("ioctl TTIOCSTTY failed: %s\n", SERRNO); |
66 | execsh(); | 78 | execsh(); |
67 | break; | 79 | break; |
68 | default: | 80 | default: |
69 | close(s); | 81 | close(s); |
70 | cmdfd = m; | 82 | cmdfd = m; |
83 | signal(SIGCHLD, sigchld); | ||
71 | } | 84 | } |
72 | } | 85 | } |
73 | 86 | ||
@@ -85,9 +98,8 @@ ttyread(void) { | |||
85 | int ret; | 98 | int ret; |
86 | 99 | ||
87 | switch(ret = read(cmdfd, buf, BUFSIZ)) { | 100 | switch(ret = read(cmdfd, buf, BUFSIZ)) { |
88 | case -1: /* error or exit */ | 101 | case -1: |
89 | /* XXX: be more precise */ | 102 | die("Couldn't read from shell: %s\n", SERRNO); |
90 | running = 0; | ||
91 | break; | 103 | break; |
92 | default: | 104 | default: |
93 | tputs(buf, ret); | 105 | tputs(buf, ret); |
@@ -97,7 +109,7 @@ ttyread(void) { | |||
97 | void | 109 | void |
98 | ttywrite(char *s, size_t n) { | 110 | ttywrite(char *s, size_t n) { |
99 | if(write(cmdfd, s, n) == -1) | 111 | if(write(cmdfd, s, n) == -1) |
100 | die("write error on tty."); | 112 | die("write error on tty: %s\n", SERRNO); |
101 | } | 113 | } |
102 | 114 | ||
103 | void | 115 | void |
@@ -108,7 +120,7 @@ ttyresize(int x, int y) { | |||
108 | w.ws_col = term.col; | 120 | w.ws_col = term.col; |
109 | w.ws_xpixel = w.ws_ypixel = 0; | 121 | w.ws_xpixel = w.ws_ypixel = 0; |
110 | if(ioctl(cmdfd, TIOCSWINSZ, &w) < 0) | 122 | if(ioctl(cmdfd, TIOCSWINSZ, &w) < 0) |
111 | fprintf(stderr, "Couldn't set window size: %m\n"); | 123 | fprintf(stderr, "Couldn't set window size: %s\n", SERRNO); |
112 | } | 124 | } |
113 | 125 | ||
114 | int | 126 | int |
@@ -889,7 +901,7 @@ run(void) { | |||
889 | 901 | ||
890 | running = 1; | 902 | running = 1; |
891 | XSelectInput(xw.dis, xw.win, ExposureMask | KeyPressMask | StructureNotifyMask); | 903 | XSelectInput(xw.dis, xw.win, ExposureMask | KeyPressMask | StructureNotifyMask); |
892 | XResizeWindow(xw.dis, xw.win, xw.w , xw.h); /* seems to fix the resize bug in wmii */ | 904 | XResizeWindow(xw.dis, xw.win, xw.w , xw.h); /* fix resize bug in wmii (?) */ |
893 | 905 | ||
894 | while(running) { | 906 | while(running) { |
895 | FD_ZERO(&rfd); | 907 | FD_ZERO(&rfd); |
@@ -898,11 +910,9 @@ run(void) { | |||
898 | XFlush(xw.dis); | 910 | XFlush(xw.dis); |
899 | ret = select(MAX(xfd, cmdfd)+1, &rfd, NULL, NULL, NULL); | 911 | ret = select(MAX(xfd, cmdfd)+1, &rfd, NULL, NULL, NULL); |
900 | 912 | ||
901 | if(ret < 0) { | 913 | if(ret < 0) |
902 | fprintf(stderr, "select: %m\n"); | 914 | die("select failed: %s\n", SERRNO); |
903 | running = 0; | 915 | |
904 | } | ||
905 | |||
906 | if(FD_ISSET(xfd, &rfd)) { | 916 | if(FD_ISSET(xfd, &rfd)) { |
907 | while(XPending(xw.dis)) { | 917 | while(XPending(xw.dis)) { |
908 | XNextEvent(xw.dis, &ev); | 918 | XNextEvent(xw.dis, &ev); |
@@ -1,16 +1,19 @@ | |||
1 | /* See LICENSE for licence details. */ | 1 | /* See LICENSE for licence details. */ |
2 | #define _XOPEN_SOURCE | 2 | #define _XOPEN_SOURCE |
3 | #include <ctype.h> | 3 | #include <ctype.h> |
4 | #include <errno.h> | ||
4 | #include <fcntl.h> | 5 | #include <fcntl.h> |
5 | #include <locale.h> | 6 | #include <locale.h> |
6 | #include <stdarg.h> | 7 | #include <stdarg.h> |
7 | #include <stdio.h> | 8 | #include <stdio.h> |
8 | #include <stdlib.h> | 9 | #include <stdlib.h> |
9 | #include <string.h> | 10 | #include <string.h> |
11 | #include <signal.h> | ||
10 | #include <sys/ioctl.h> | 12 | #include <sys/ioctl.h> |
11 | #include <sys/select.h> | 13 | #include <sys/select.h> |
12 | #include <sys/stat.h> | 14 | #include <sys/stat.h> |
13 | #include <sys/types.h> | 15 | #include <sys/types.h> |
16 | #include <sys/wait.h> | ||
14 | #include <unistd.h> | 17 | #include <unistd.h> |
15 | #include <X11/Xlib.h> | 18 | #include <X11/Xlib.h> |
16 | #include <X11/keysym.h> | 19 | #include <X11/keysym.h> |
@@ -52,6 +55,7 @@ static char* colorname[] = { | |||
52 | #define ESCSIZ 256 | 55 | #define ESCSIZ 256 |
53 | #define ESCARG 16 | 56 | #define ESCARG 16 |
54 | 57 | ||
58 | #define SERRNO strerror(errno) | ||
55 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) | 59 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) |
56 | #define MAX(a, b) ((a) < (b) ? (b) : (a)) | 60 | #define MAX(a, b) ((a) < (b) ? (b) : (a)) |
57 | #define LEN(a) (sizeof(a) / sizeof(a[0])) | 61 | #define LEN(a) (sizeof(a) / sizeof(a[0])) |
@@ -63,7 +67,7 @@ static char* colorname[] = { | |||
63 | enum { ATnone=0 , ATreverse=1 , ATunderline=2, ATbold=4 }; /* Attribute */ | 67 | enum { ATnone=0 , ATreverse=1 , ATunderline=2, ATbold=4 }; /* Attribute */ |
64 | enum { CSup, CSdown, CSright, CSleft, CShide, CSdraw, CSwrap, CSsave, CSload }; /* Cursor */ | 68 | enum { CSup, CSdown, CSright, CSleft, CShide, CSdraw, CSwrap, CSsave, CSload }; /* Cursor */ |
65 | enum { CRset=1 , CRupdate=2 }; /* Character state */ | 69 | enum { CRset=1 , CRupdate=2 }; /* Character state */ |
66 | enum { TMwrap=1 , TMinsert=2 }; /* Terminal mode */ | 70 | enum { TMwrap=1 , TMinsert=2, TMaltcharset }; /* Terminal mode */ |
67 | enum { SCupdate, SCredraw }; /* screen draw mode */ | 71 | enum { SCupdate, SCredraw }; /* screen draw mode */ |
68 | 72 | ||
69 | typedef int Color; | 73 | typedef int Color; |
@@ -130,6 +134,7 @@ typedef struct { | |||
130 | void die(const char *errstr, ...); | 134 | void die(const char *errstr, ...); |
131 | void draw(int); | 135 | void draw(int); |
132 | void execsh(void); | 136 | void execsh(void); |
137 | void sigchld(int); | ||
133 | void kpress(XKeyEvent *); | 138 | void kpress(XKeyEvent *); |
134 | void resize(XEvent *); | 139 | void resize(XEvent *); |
135 | void run(void); | 140 | void run(void); |