11
#endif /* HAVE_UNISTD_H */
14
#endif /* HAVE_FCNTL_H */
17
#endif /* HAVE_SIGNAL_H */
19
#ifdef HAVE_SYS_TYPES_H
20
# include <sys/types.h>
21
#endif /* HAVE_SYS_TYPES_H */
22
#ifdef HAVE_SYS_SOCKET_H
23
# include <sys/socket.h>
24
#endif /* HAVE_SYS_SOCKET_H */
25
#ifdef HAVE_SYS_STAT_H
26
# include <sys/stat.h>
27
#endif /* HAVE_SYS_STAT_H */
30
#endif /* HAVE_SYS_UN_H */
31
#ifdef HAVE_SYS_TIME_H
32
# include <sys/time.h>
33
#endif /* HAVE_SYS_TIME_H */
34
#ifdef HAVE_SYS_SELECT_H
35
# include <sys/select.h>
36
#endif /* HAVE_SYS_SELECT_H */
37
#ifdef HAVE_SYS_WAIT_H
38
# include <sys/wait.h>
39
#endif /* HAVE_SYS_WAIT_H */
41
#include "rccexternal.h"
44
#define RCC_EXT_PROG_NAME "rccexternal"
46
static pid_t pid = (pid_t)-1;
47
static char *addr = NULL;
49
int rccExternalInit() {
52
#endif /* HAVE_SIGNAL_H */
54
if (pid != (pid_t)-1) return 0;
57
addr = (char*)malloc(strlen(rcc_home_dir)+32);
63
if (pid == (pid_t)-1) return -1;
64
sprintf(addr,"%s/.rcc/comm/%lu.sock", rcc_home_dir, (unsigned long)pid);
67
act.sa_handler = SIG_IGN;
68
sigemptyset(&act.sa_mask);
70
sigaction(SIGPIPE,&act,NULL);
71
#endif /* HAVE_SIGNAL_H */
76
execl(LIBRCC_DATA_DIR "/" RCC_EXT_PROG_NAME, RCC_EXT_PROG_NAME, NULL);
80
void rccExternalFree() {
81
if (pid == (pid_t)-1) return;
83
rccExternalConnect(0);
86
waitpid(pid, NULL, 0);
90
static int rccExternalSetDeadline(struct timeval *tv, unsigned long timeout) {
91
gettimeofday(tv, NULL);
92
tv->tv_sec += (tv->tv_usec + timeout + RCC_EXTERNAL_TIMEOUT) / 1000000;
93
tv->tv_usec = (tv->tv_usec + timeout + RCC_EXTERNAL_TIMEOUT) % 1000000;
97
size_t rccExternalWrite(int s, const char *buffer, ssize_t size, unsigned long timeout) {
99
unsigned char connected = 1;
100
ssize_t writed, res = 0;
104
if (s == -1) return -1;
106
for (writed = 0; (writed < size)&&(connected); writed += connected?res:0) {
109
rccExternalSetDeadline(&tv, timeout);
110
err = select(s+1,NULL,&fdcon,NULL,&tv);
111
if (err<=0) connected = 0;
113
res = write(s, buffer + writed, size - writed);
114
if (res<=0) connected = 0;
118
return size - writed;
121
size_t rccExternalRead(int s, char *buffer, ssize_t size, unsigned long timeout) {
123
unsigned char connected = 1;
124
ssize_t readed, res = 0;
128
if (s == -1) return -1;
130
for (readed = 0; (readed < size)&&(connected); readed += connected?res:0) {
133
rccExternalSetDeadline(&tv, timeout);
134
err = select(s+1,&fdcon,NULL,NULL,&tv);
135
if (err<=0) connected = 0;
137
res = read(s, buffer + readed, size - readed);
138
if (res<=0) connected = 0;
142
return size - readed;
145
int rccExternalConnect(unsigned char module) {
150
struct sockaddr_un mysock;
155
if (pid == (pid_t)-1) return -1;
157
sock = socket(PF_UNIX, SOCK_STREAM, 0);
158
if (sock<=0) return -1;
160
flags = fcntl(sock,F_GETFL,0);
161
if (flags<0) flags = 0;
162
if (fcntl(sock,F_SETFL,flags|O_NONBLOCK)<0) {
167
memset(&mysock, 0, sizeof(mysock));
168
mysock.sun_family=AF_UNIX;
169
strncpy(mysock.sun_path,addr,sizeof(mysock.sun_path));
170
mysock.sun_path[sizeof(mysock.sun_path)-1]=0;
173
if (connect(sock,(struct sockaddr*)&mysock,sizeof(mysock))<0) {
174
if (errno == EINPROGRESS) {
176
FD_SET(sock, &fdcon);
178
rccExternalSetDeadline(&tv, 0);
179
err = select(sock+1,&fdcon,NULL,NULL,&tv);
184
} else if ((errno == ENOENT)&&(retries)) {
185
ts.tv_sec = (RCC_EXTERNAL_TIMEOUT/10) / 1000000;
186
ts.tv_nsec = ((RCC_EXTERNAL_TIMEOUT/10) % 1000000)*1000;
187
nanosleep(&ts, NULL);
196
if (rccExternalWrite(sock, &module, 1, 0)) {
204
void rccExternalClose(int s) {
205
unsigned char cmd = 0;