2 #include <sys/socket.h>
13 #include "fork_impl.h"
14 #include "locale_impl.h"
16 static volatile int lock
[1];
17 static char log_ident
[32];
19 static int log_facility
= LOG_USER
;
20 static int log_mask
= 0xff;
21 static int log_fd
= -1;
22 volatile int *const __syslog_lockptr
= lock
;
24 int setlogmask(int maskpri
)
28 if (maskpri
) log_mask
= maskpri
;
44 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, &cs
);
49 pthread_setcancelstate(cs
, 0);
52 static void __openlog()
54 log_fd
= socket(AF_UNIX
, SOCK_DGRAM
|SOCK_CLOEXEC
, 0);
55 if (log_fd
>= 0) connect(log_fd
, (void *)&log_addr
, sizeof log_addr
);
58 void openlog(const char *ident
, int opt
, int facility
)
61 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, &cs
);
65 size_t n
= strnlen(ident
, sizeof log_ident
- 1);
66 memcpy(log_ident
, ident
, n
);
72 log_facility
= facility
;
74 if ((opt
& LOG_NDELAY
) && log_fd
<0) __openlog();
77 pthread_setcancelstate(cs
, 0);
80 static int is_lost_conn(int e
)
82 return e
==ECONNREFUSED
|| e
==ECONNRESET
|| e
==ENOTCONN
|| e
==EPIPE
;
85 static void _vsyslog(int priority
, const char *message
, va_list ap
)
91 int errno_save
= errno
;
97 if (log_fd
< 0) __openlog();
99 if (!(priority
& LOG_FACMASK
)) priority
|= log_facility
;
103 strftime_l(timebuf
, sizeof timebuf
, "%b %e %T", &tm
, C_LOCALE
);
105 pid
= (log_opt
& LOG_PID
) ? getpid() : 0;
106 l
= snprintf(buf
, sizeof buf
, "<%d>%s %n%s%s%.0d%s: ",
107 priority
, timebuf
, &hlen
, log_ident
, "["+!pid
, pid
, "]"+!pid
);
109 l2
= vsnprintf(buf
+l
, sizeof buf
- l
, message
, ap
);
111 if (l2
>= sizeof buf
- l
) l
= sizeof buf
- 1;
113 if (buf
[l
-1] != '\n') buf
[l
++] = '\n';
114 if (send(log_fd
, buf
, l
, 0) < 0 && (!is_lost_conn(errno
)
115 || connect(log_fd
, (void *)&log_addr
, sizeof log_addr
) < 0
116 || send(log_fd
, buf
, l
, 0) < 0)
117 && (log_opt
& LOG_CONS
)) {
118 fd
= open("/dev/console", O_WRONLY
|O_NOCTTY
|O_CLOEXEC
);
120 dprintf(fd
, "%.*s", l
-hlen
, buf
+hlen
);
124 if (log_opt
& LOG_PERROR
) dprintf(2, "%.*s", l
-hlen
, buf
+hlen
);
128 static void __vsyslog(int priority
, const char *message
, va_list ap
)
131 if (!(log_mask
& LOG_MASK(priority
&7)) || (priority
&~0x3ff)) return;
132 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE
, &cs
);
134 _vsyslog(priority
, message
, ap
);
136 pthread_setcancelstate(cs
, 0);
139 void syslog(int priority
, const char *message
, ...)
142 va_start(ap
, message
);
143 __vsyslog(priority
, message
, ap
);
147 weak_alias(__vsyslog
, vsyslog
);