-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexternal.c
126 lines (98 loc) · 2.05 KB
/
external.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <ncurses.h>
#include <termios.h>
#include <unistd.h>
#include "mem.h"
#include "ui.h"
#include "pos.h"
#include "region.h"
#include "list.h"
#include "external.h"
#ifdef FANCY_TERM
static int term_canon(int on)
{
struct termios this;
if(tcgetattr(0, &this))
return 0;
if(on)
this.c_lflag |= ICANON;
else
this.c_lflag &= ~ICANON;
return 0 == tcsetattr(0, 0, &this);
}
#endif
void shellout_wait_ret(void)
{
#ifdef FANCY_TERM
if(term_canon(0)){
int unget;
fprintf(stderr, "any key to continue...");
/* use getch() so we don't go behind ncurses' back */
while((unget = getch()) == -1);
term_canon(1);
fputc('\n', stderr);
ungetch(unget);
}else{
#endif
fprintf(stderr, "enter to continue...");
for(;;){
int c = getchar();
if(c == EOF || c == '\n')
break;
}
#ifdef FANCY_TERM
}
#endif
}
int shellout(const char *cmd)
{
const char *shcmd;
int r;
if(cmd){
shcmd = cmd;
}else{
const char *shell = getenv("SHELL");
if(!shell)
shell = "sh";
shcmd = shell;
}
ui_term();
r = system(shcmd);
shellout_wait_ret();
ui_init();
return r;
}
bool shellout_write(const char *cmd, list_t *seeked, int nlines)
{
ui_term();
FILE *subp = popen(cmd, "w");
if(!subp){
fprintf(stderr, "fork/exec: %s", strerror(errno));
return false;
}
int r = list_write_file(seeked, nlines, subp, /*eol*/true);
int errno_write = errno;
int waitret = pclose(subp);
int errno_wait = errno;
if(r){
fprintf(stderr, "write subprocess: %s", strerror(errno_write));
return false;
}
if(WIFEXITED(waitret)){
int ec = WEXITSTATUS(waitret);
if(ec)
fprintf(stderr, "command returned %d\n", ec);
}else if(WIFSIGNALED(waitret)){
fprintf(stderr, "command signalled with %d\n", WTERMSIG(waitret));
}else if(WIFSTOPPED(waitret)){
fprintf(stderr, "command stopped with %d\n", WSTOPSIG(waitret));
}else{
fprintf(stderr, "unknown state from wait()/pclose(): %d: %s",
waitret, strerror(errno_wait));
}
shellout_wait_ret();
return true;
}