1
2 #include "../processx.h"
3
4 #include <termios.h>
5 #include <sys/ioctl.h>
6
processx__tmp_string(SEXP str,int i)7 char *processx__tmp_string(SEXP str, int i) {
8 const char *ptr = CHAR(STRING_ELT(str, i));
9 char *cstr = R_alloc(1, (int) strlen(ptr) + 1);
10 strcpy(cstr, ptr);
11 return cstr;
12 }
13
processx__tmp_character(SEXP chr)14 char **processx__tmp_character(SEXP chr) {
15 size_t i, n = LENGTH(chr);
16 char **cchr = (void*) R_alloc(n + 1, sizeof(char*));
17 for (i = 0; i < n; i++) {
18 cchr[i] = processx__tmp_string(chr, (int) i);
19 }
20 cchr[n] = 0;
21 return cchr;
22 }
23
processx__nonblock_fcntl(int fd,int set)24 int processx__nonblock_fcntl(int fd, int set) {
25 int flags;
26 int r;
27
28 do { r = fcntl(fd, F_GETFL); } while (r == -1 && errno == EINTR);
29 if (r == -1) { return -errno; }
30
31 /* Bail out now if already set/clear. */
32 if (!!(r & O_NONBLOCK) == !!set) { return 0; }
33
34 if (set) { flags = r | O_NONBLOCK; } else { flags = r & ~O_NONBLOCK; }
35
36 do { r = fcntl(fd, F_SETFL, flags); } while (r == -1 && errno == EINTR);
37 if (r) { return -errno; }
38
39 return 0;
40 }
41
processx__cloexec_fcntl(int fd,int set)42 int processx__cloexec_fcntl(int fd, int set) {
43 int flags;
44 int r;
45
46 do { r = fcntl(fd, F_GETFD); } while (r == -1 && errno == EINTR);
47 if (r == -1) { return -errno; }
48
49 /* Bail out now if already set/clear. */
50 if (!!(r & FD_CLOEXEC) == !!set) { return 0; }
51
52 if (set) { flags = r | FD_CLOEXEC; } else { flags = r & ~FD_CLOEXEC; }
53
54 do { r = fcntl(fd, F_SETFD, flags); } while (r == -1 && errno == EINTR);
55 if (r) { return -errno; }
56
57 return 0;
58 }
59
processx_disable_crash_dialog()60 SEXP processx_disable_crash_dialog() {
61 struct sigaction action;
62 memset(&action, 0, sizeof(action));
63 action.sa_handler = SIG_DFL;
64 sigaction(SIGSEGV, &action, /* oldact= */ NULL);
65 sigaction(SIGILL, &action, /* oldact= */ NULL);
66 #ifdef SIGBUS
67 sigaction(SIGBUS, &action, /* oldact= */ NULL);
68 #endif
69 return R_NilValue;
70 }
71
processx__echo_on()72 SEXP processx__echo_on() {
73 struct termios tp;
74
75 if (tcgetattr(STDOUT_FILENO, &tp) == -1) {
76 R_THROW_ERROR("Cannot turn terminal echo on");
77 }
78
79 tp.c_lflag |= ECHO;
80
81 if (tcsetattr(STDOUT_FILENO, TCSAFLUSH, &tp) == -1) {
82 R_THROW_ERROR("Cannot turn terminal echo on");
83 }
84
85 return R_NilValue;
86 }
87
processx__echo_off()88 SEXP processx__echo_off() {
89 struct termios tp;
90
91 if (tcgetattr(STDOUT_FILENO, &tp) == -1) {
92 R_THROW_ERROR("Cannot turn terminal echo off");
93 }
94
95 tp.c_lflag &= ~ECHO;
96
97 if (tcsetattr(STDOUT_FILENO, TCSAFLUSH, &tp) == -1) {
98 R_THROW_ERROR("Cannot turn terminal echo off");
99 }
100
101 return R_NilValue;
102 }
103