commit - 600a9440b627ae1bcb948c768d2517542699f9f7
commit + b60fb725c1f51b29e94172f5f7e12e73caa40502
blob - ed26cfbe42a2edae15431eafee0799f80e423dcf
blob + 04c623ad642c67d9bd68e517c8ff8ffcc55cf0a4
--- include/statbar.h
+++ include/statbar.h
/* Weather */
extern char weather_string[48];
-extern int weather_pipe[2];
-extern void get_weather(void);
+extern void get_weather(int fd);
+extern void read_weather(int fd);
extern char **get_weather_location_ptr(void);
extern void close_weather(void);
blob - 7085e1f03d83776821262c92c1c87feb2f4f7444
blob + 171da03417bae14675e68d9eafc3a2e819a03d9e
--- modules/weather.c
+++ modules/weather.c
#include <stdlib.h>
#include <string.h>
-#include <pthread.h>
#include <unistd.h>
-#include <curl/curl.h>
-
#include "statbar.h"
#define MAX_RETRY_ATTEMPTS 5
char weather_string[48] = "...";
-static pthread_t weather_pthread;
static char *weather_location;
char **
return &weather_location;
}
-size_t
-write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
+void
+get_weather(int fd)
{
- char *lbrk;
- size_t d_len;
+ pid_t pid = fork();
+ char *argv[] = { "weatherbar", weather_location, NULL };
- (void)size;
- (void)userdata;
-
- lbrk = strchr(ptr, '\n');
- if (lbrk) *lbrk = '\0';
-
- d_len = strlen(ptr);
- if (d_len >= 47)
+ if (pid != 0)
{
- (void)fprintf(stderr, "weather: too much data from server, got %lu, maximum is 47\n", d_len);
+ if (pid < 0) perror("fork");
- return 0;
+ return;
}
- (void)strcpy(weather_string, ptr);
- weather_string[d_len] = '\0';
-
- return nmemb;
+ (void)dup2(fd, STDOUT_FILENO);
+ if (execv("/usr/local/bin/weatherbar", argv) < 0)
+ perror("execv");
}
-void *
-weather_thread(void *arg)
-{
- CURL *curl;
- char *wttr_url;
- char err_buff[CURL_ERROR_SIZE];
- CURLcode curle;
- int request_count = 0;
-
- (void)arg;
- if (!weather_location) return NULL;
-
- if (asprintf(&wttr_url, "https://wttr.in/%s?format=1&u", weather_location) == -1)
- {
- perror("asprintf");
-
- return NULL;
- }
- if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK)
- {
- (void)fprintf(stderr, "Failed to init libcurl\n");
-
- return NULL;
- }
-
- curl = curl_easy_init();
- if (!curl)
- {
- (void)fputs("weather: failed to init libcurl\n", stderr);
- weather_string[0] = '\0';
-
- return NULL;
- }
- (void)curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, err_buff);
- (void)curl_easy_setopt(curl, CURLOPT_URL, wttr_url);
- (void)curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
- do
- {
- curle = curl_easy_perform(curl);
- if (curle != CURLE_OK)
- {
- (void)fprintf(stderr, "weather request failed: %s\n", err_buff);
- (void)sleep(1);
- }
- else
- {
- (void)write(weather_pipe[1], "1", 1);
- break;
- }
- } while (request_count++ < MAX_RETRY_ATTEMPTS - 1);
-
- curl_easy_cleanup(curl);
- curl_global_cleanup();
- free(wttr_url);
- (void)puts("Destroying weather thread");
-
- return NULL;
-}
-
void
-get_weather(void)
+read_weather(int fd)
{
- (void)puts("Creating weather thread");
- if (pthread_create(&weather_pthread, NULL, weather_thread, NULL) != 0)
- {
- perror("pthread_create");
+ ssize_t n = read(fd, weather_string, sizeof(weather_string));
+ char *lnbrk;
+ if (n < 0)
+ {
+ perror("read");
+
return;
}
+ lnbrk = strchr(weather_string, '\n');
+ if (lnbrk) *lnbrk = '\0';
}
void
blob - 661684782c4ca600416708e037aeb84991c04aba
blob + 71870f738fd5a6c106721b79c3acfde3104c70dc
--- src/main.c
+++ src/main.c
bool dirty = true;
struct pollfd *network_pfd = NULL;
struct pollfd *weather_pfd = NULL;
- char wpfd_buf;
bool apm_open = false;
bool hdl_open = false;
bool network_open = false;
{
weather_pfd = &pfd[nfds - 2];
weather_pfd->fd = weather_pipe[0];
- get_weather();
+ get_weather(weather_pipe[1]);
}
if (mail_path_valid) mail_path_valid = get_mail();
if (network_pfd->revents & POLLIN)
read_network_socket(network_pfd->fd);
if (weather_pfd && (weather_pfd->revents & POLLIN))
- (void)read(weather_pipe[0], &wpfd_buf, 1);
+ read_weather(weather_pfd->fd);
dirty = true;
}
/* Weather */
if (weather_loc_valid && weather_pfd && timespeccmp(&now, &clocks[WEATHER_CLOCK], >=))
{
- get_weather();
+ get_weather(weather_pipe[1]);
while (timespeccmp(&now, &clocks[WEATHER_CLOCK], >=))
timespecadd(&clocks[WEATHER_CLOCK], &weather_interval, &clocks[WEATHER_CLOCK]);
}