LINUX.ORG.RU

История изменений

Исправление 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 подставить мютекс или что-то подобное.