23#include <sys/socket.h>
33 for (
const char *p = str; *p; p++) {
45 clock_gettime(CLOCK_MONOTONIC, &ts);
46 return (
double) ts.tv_sec + (double) ts.tv_nsec * 1.0e-9;
53 struct sockaddr_un addr;
54 addr.sun_family = AF_UNIX;
57 if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
58 fprintf(stderr,
"socket() failed: %s\n", strerror(errno));
62 char *
path = addr.sun_path;
63 int len = (int)
sizeof(addr.sun_path);
64 if (snprintf(
path, len,
"%s/.dillo/ctl/%s",
dGethomedir(), pid) >= len) {
65 fprintf(stderr,
"pid path too long\n");
70 double maxtime = t0 + 10.0;
71 double warntime = t0 + 1.0;
73 struct timespec dur = { .tv_sec = 0, .tv_nsec = 50UL * 1000UL * 1000UL };
76 if (connect(fd, (
struct sockaddr *) &addr,
sizeof(addr)) == 0) {
79 }
else if (errno != ENOENT) {
80 fprintf(stderr,
"connect to %s failed: %s\n",
path, strerror(errno));
85 fprintf(stderr,
"connect to %s taking long\n",
path);
90 fprintf(stderr,
"timeout connecting to %s: %s\n",
91 path, strerror(errno));
96 nanosleep(&dur, NULL);
108 char ctlpath[PATH_MAX];
109 if (snprintf(ctlpath, PATH_MAX,
"%s/.dillo/ctl",
dGethomedir()) >= PATH_MAX) {
110 fprintf(stderr,
"path too long\n");
115 DIR *
dp = opendir(ctlpath);
117 fprintf(stderr,
"error: cannot open %s directory: %s\n",
118 ctlpath, strerror(errno));
119 fprintf(stderr,
"hint: is dillo running?\n");
124 struct sockaddr_un addr;
125 addr.sun_family = AF_UNIX;
127 while ((ep = readdir (
dp)) != NULL) {
128 const char *num = ep->d_name;
130 if (!strcmp(num,
".") || !strcmp(num,
".."))
137#define LEN ((int) sizeof(addr.sun_path))
138 if (snprintf(addr.sun_path,
LEN,
"%s/%s", ctlpath, num) >=
LEN) {
139 fprintf(stderr,
"pid path too long\n");
145 if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
146 fprintf(stderr,
"socket() failed: %s\n", strerror(errno));
152 ret = connect(fd, (
struct sockaddr *) &addr,
sizeof(addr));
153 }
while (ret == -1 && errno == EINTR);
156 if (++found_pid == 1) {
163 if (errno == ECONNREFUSED) {
165 remove(addr.sun_path);
167 fprintf(stderr,
"cannot connect to %s, skipping: %s\n",
168 addr.sun_path, strerror(errno));
172 if (fd != -1 &&
dClose(fd) != 0) {
173 fprintf(stderr,
"cannot close fd: %s", strerror(errno));
182 else if (found_pid == 0) {
183 fprintf(stderr,
"error: cannot find ctl socket, is dillo running?\n");
187 fprintf(stderr,
"multiple ctl sockets found, set DILLO_PID\n");
196 char *given_pid = getenv(
"DILLO_PID");
214int main(
int argc,
char *argv[])
217 fprintf(stderr,
"missing command, try 'dilloc help'\n");
226 if (argv[1] && (!strcmp(argv[1],
"load") || !strcmp(argv[1],
"rawload"))) {
231 for (
int i = 1; i < argc; i++) {
239 for (ssize_t w = 0; w < cmd->
len; ) {
240 w = write(fd, cmd->
str + w, cmd->
len - w);
253 ssize_t r = read(STDIN_FILENO, buf,
BUFSIZ);
264 ssize_t w = write(fd, p, r);
284 ssize_t r = read(fd, buf,
BUFSIZ);
297 fprintf(stderr,
"malformed reply: expected digit at first byte (got %c)\n", ch);
300 if (buf[1] !=
'\n') {
301 fprintf(stderr,
"malformed reply: expected newline at second byte\n");
311 size_t w = write(STDOUT_FILENO, p, r);
static double get_time_s(void)
static int find_working_socket(int *sock)
static int is_number(const char *str)
static int connect_to_dillo(int *sock)
static int connect_given_pid(int *sock, const char *pid)
void dStr_append(Dstr *ds, const char *s)
Append a C string to a Dstr.
void dStr_free(Dstr *ds, int all)
Free a dillo string.
int dClose(int fd)
Close a FD handling EINTR.
void dStr_append_c(Dstr *ds, int c)
Append one character.
Dstr * dStr_new(const char *s)
Create a new string.
char * dGethomedir(void)
Return the home directory in a static string (don't free)