История изменений
Исправление firkax, (текущая версия) :
Блин, ты меня заставил код написать. С локами получилось бы сложнее, на самом деле, потому что дедлок тут поймать будет весьма легко.
Какой ещё дедлок?
static FILE *log_fp;
static t_lock lock;
static volatile int newlog;
static int usr1_handle(int sig) { newlog = 1; }
extern void init_usr1_handle(void) {
struct sigaction sa;
sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); sa.sa_handler = usr1_handle;
sigaction(SIGUSR1, &sa, NULL);
}
extern void check_newlog(void) {
LOCK(&lock);
if(newlog) {
fd = open("/path/to/log", O_WRONLY|O_CREAT|O_APPEND, 0644);
if(fd<0) fprintf(log_fp, "can't reopen log!\n");
else {
if(dup2(fd, fileno(log_fp))<0) fprintf(log_fp, "can't reopen log!\n");
close(fd);
}
newlog = 0;
}
UNLOCK(&lock);
}
extern void write_log(char const *fmt, ...) {
va_list arg;
int fd;
check_newlog(); /* но лучше её делать явно в рабочем цикле */
va_start(arg, fmt);
LOCK(&lock);
vfprintf(log_fp, fmt, arg);
fputc('\n', log_fp);
fflush(logfp);
UNLOCK(&lock);
va_end(arg);
}
Вместо t_lock подставить мютекс или что-то подобное.
А ещё signalfd в BSD нет, это Linux-specific.
Исправление firkax, :
Блин, ты меня заставил код написать. С локами получилось бы сложнее, на самом деле, потому что дедлок тут поймать будет весьма легко.
Какой ещё дедлок?
static FILE *log_fp;
static t_lock lock;
static volatile int newlog;
static int usr1_handle(int sig) { newlog = 1; }
extern void init_usr1_handle(void) {
struct sigaction sa;
sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); sa.sa_handler = usr1_handle;
sigaction(SIGUSR1, &sa, NULL);
}
extern void check_newlog(void) {
LOCK(&lock);
if(newlog) {
fd = open("/path/to/log", O_WRONLY|O_CREAT|O_APPEND, 0644);
if(fd<0) fprintf(log_fp, "can't reopen log!\n");
else { dup2(fd, fileno(log_fp); close(fd); }
newlog = 0;
}
UNLOCK(&lock);
}
extern void write_log(char const *fmt, ...) {
va_list arg;
int fd;
check_newlog(); /* но лучше её делать явно в рабочем цикле */
va_start(arg, fmt);
LOCK(&lock);
vfprintf(log_fp, fmt, arg);
fputc('\n', log_fp);
fflush(logfp);
UNLOCK(&lock);
va_end(arg);
}
Вместо t_lock подставить мютекс или что-то подобное.
А ещё signalfd в BSD нет, это Linux-specific.
Исходная версия firkax, :
Блин, ты меня заставил код написать. С локами получилось бы сложнее, на самом деле, потому что дедлок тут поймать будет весьма легко.
Какой ещё дедлок?
static FILE *log_fp;
static t_lock lock;
static volatile int newlog;
static int usr1_handle(int sig) { newlog = 1; }
extern void init_usr1_handle(void) {
struct sigaction sa;
sa.sa_flags = SA_RESTART; sigemptyset(&sa.sa_mask); sa.sa_handler = usr1_handle;
sigaction(SIGUSR1, &sa, NULL);
}
extern void check_newlog(void) {
LOCK(&lock);
if(newlog) {
fd = open("/path/to/log", O_WRONLY|O_CREAT|O_APPEND, 0644);
if(fd<0) fprintf(log_fp, "can't reopen log!\n");
else { dup2(fd, fileno(log_fp); close(fd); }
newlog = 0;
}
UNLOCK(&lock);
}
extern void write_log(char const *fmt, ...) {
va_list arg;
int fd;
check_newlog(); /* но лучше её делать явно в рабочем цикле */
va_start(arg, fmt);
LOCK(&lock);
vfprintf(log_fp, fmt, arg);
fputc('\n', log_fp);
fflush(logfp);
UNLOCK(&lock);
}
Вместо t_lock подставить мютекс или что-то подобное.