]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/journal/journal-send.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <sys/socket.h>
27 #include "sd-journal.h"
30 /* We open a single fd, and we'll share it with the current process,
31 * all its threads, and all its subprocesses. This means we need to
32 * initialize it atomically, and need to operate on it atomically
33 * never assuming we are the only user */
35 static int journal_fd(void) {
37 static int fd_plus_one
= 0;
41 return fd_plus_one
- 1;
43 fd
= socket(AF_UNIX
, SOCK_DGRAM
|SOCK_CLOEXEC
, 0);
47 if (!__sync_bool_compare_and_swap(&fd_plus_one
, 0, fd
+1)) {
48 close_nointr_nofail(fd
);
55 int sd_journal_print(const char *format
, ...) {
60 r
= sd_journal_printv(format
, ap
);
66 int sd_journal_printv(const char *format
, va_list ap
) {
67 char buffer
[8 + LINE_MAX
];
70 memcpy(buffer
, "MESSAGE=", 8);
71 vsnprintf(buffer
+8, sizeof(buffer
) - 8, format
, ap
);
76 IOVEC_SET_STRING(iov
, buffer
);
78 return sd_journal_sendv(&iov
, 1);
81 int sd_journal_send(const char *format
, ...) {
82 int r
, n
= 0, i
= 0, j
;
84 struct iovec
*iov
= NULL
;
93 c
= realloc(iov
, n
* sizeof(struct iovec
));
102 if (vasprintf(&buffer
, format
, ap
) < 0) {
107 IOVEC_SET_STRING(iov
[i
++], buffer
);
109 format
= va_arg(ap
, char *);
113 r
= sd_journal_sendv(iov
, i
);
116 for (j
= 0; j
< i
; j
++)
117 free(iov
[j
].iov_base
);
124 int sd_journal_sendv(const struct iovec
*iov
, int n
) {
130 struct sockaddr_un sa
;
135 w
= alloca(sizeof(struct iovec
) * n
* 5);
136 l
= alloca(sizeof(uint64_t) * n
);
138 for (i
= 0; i
< n
; i
++) {
141 c
= memchr(iov
[i
].iov_base
, '=', iov
[i
].iov_len
);
145 nl
= memchr(iov
[i
].iov_base
, '\n', iov
[i
].iov_len
);
150 /* Already includes a newline? Bummer, then
151 * let's write the variable name, then a
152 * newline, then the size (64bit LE), followed
153 * by the data and a final newline */
155 w
[j
].iov_base
= iov
[i
].iov_base
;
156 w
[j
].iov_len
= c
- (char*) iov
[i
].iov_base
;
159 IOVEC_SET_STRING(w
[j
++], "\n");
161 l
[i
] = htole64(iov
[i
].iov_len
- (c
- (char*) iov
[i
].iov_base
) - 1);
162 w
[j
].iov_base
= &l
[i
];
163 w
[j
].iov_len
= sizeof(uint64_t);
166 w
[j
].iov_base
= c
+ 1;
167 w
[j
].iov_len
= iov
[i
].iov_len
- (c
- (char*) iov
[i
].iov_base
) - 1;
171 /* Nothing special? Then just add the line and
172 * append a newline */
175 IOVEC_SET_STRING(w
[j
++], "\n");
183 sa
.sun_family
= AF_UNIX
;
184 strncpy(sa
.sun_path
,"/run/systemd/journal", sizeof(sa
.sun_path
));
188 mh
.msg_namelen
= offsetof(struct sockaddr_un
, sun_path
) + strlen(sa
.sun_path
);
192 if (sendmsg(fd
, &mh
, MSG_NOSIGNAL
) < 0)