2 * ossp-util - OSS Proxy: Common utilities
4 * Copyright (C) 2008-2010 SUSE Linux Products GmbH
5 * Copyright (C) 2008-2010 Tejun Heo <tj@kernel.org>
7 * This file is released under the GPLv2.
20 #include "ossp-util.h"
22 #define BIT(nr) (1UL << (nr))
23 #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
24 #define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
25 #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
26 #define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
28 char ossp_log_name
[OSSP_LOG_NAME_LEN
];
29 int ossp_log_level
= OSSP_LOG_DFL
;
30 int ossp_log_timestamp
;
32 static const char *severity_strs
[] = {
33 [OSSP_LOG_CRIT
] = "CRIT",
34 [OSSP_LOG_ERR
] = " ERR",
35 [OSSP_LOG_WARN
] = "WARN",
36 [OSSP_LOG_INFO
] = NULL
,
37 [OSSP_LOG_DBG0
] = "DBG0",
38 [OSSP_LOG_DBG1
] = "DBG1",
41 static int severity_map
[] = {
42 [OSSP_LOG_CRIT
] = LOG_ERR
,
43 [OSSP_LOG_ERR
] = LOG_ERR
,
44 [OSSP_LOG_WARN
] = LOG_WARNING
,
45 [OSSP_LOG_INFO
] = LOG_INFO
,
46 [OSSP_LOG_DBG0
] = LOG_DEBUG
,
47 [OSSP_LOG_DBG1
] = LOG_DEBUG
,
50 void log_msg(int severity
, const char *fmt
, ...)
52 static int syslog_opened
= 0;
54 size_t len
= sizeof(buf
), off
= 0;
57 if (severity
> abs(ossp_log_level
))
60 if (ossp_log_level
< 0 && !syslog_opened
)
61 openlog(ossp_log_name
, 0, LOG_DAEMON
);
63 assert(severity
>= 0 && severity
< ARRAY_SIZE(severity_strs
));
65 if (ossp_log_timestamp
) {
66 static uint64_t start
;
69 gettimeofday(&tv
, NULL
);
70 now
= tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
74 off
+= snprintf(buf
+ off
, len
- off
, "<%08"PRIu64
"> ",
78 if (ossp_log_level
> 0) {
79 char sev_buf
[16] = "";
80 if (severity_strs
[severity
])
81 snprintf(sev_buf
, sizeof(sev_buf
), " %s",
82 severity_strs
[severity
]);
83 off
+= snprintf(buf
+ off
, len
- off
, "%s%s: ",
84 ossp_log_name
, sev_buf
);
85 } else if (severity_strs
[severity
])
86 off
+= snprintf(buf
+ off
, len
- off
, "%s ",
87 severity_strs
[severity
]);
90 off
+= vsnprintf(buf
+ off
, len
- off
, fmt
, ap
);
93 off
+= snprintf(buf
+ off
, len
- off
, "\n");
95 if (ossp_log_level
> 0)
98 syslog(severity_map
[severity
], "%s", buf
);
101 int read_fill(int fd
, void *buf
, size_t size
)
107 ret
= read(fd
, buf
, size
);
113 err_e(rc
, "failed to read_fill %zu bytes from fd %d",
123 int write_fill(int fd
, const void *buf
, size_t size
)
129 ret
= write(fd
, buf
, size
);
135 err_e(rc
, "failed to write_fill %zu bytes to fd %d",
145 void ring_fill(struct ring_buf
*ring
, const void *buf
, size_t size
)
149 assert(ring_space(ring
) >= size
);
151 tail
= (ring
->head
+ ring
->size
- ring
->bytes
) % ring
->size
;
153 if (ring
->head
>= tail
) {
154 size_t todo
= min(size
, ring
->size
- ring
->head
);
156 memcpy(ring
->buf
+ ring
->head
, buf
, todo
);
157 ring
->head
= (ring
->head
+ todo
) % ring
->size
;
163 assert(ring
->size
- ring
->head
>= size
);
164 memcpy(ring
->buf
+ ring
->head
, buf
, size
);
169 void *ring_data(struct ring_buf
*ring
, size_t *sizep
)
176 tail
= (ring
->head
+ ring
->size
- ring
->bytes
) % ring
->size
;
178 *sizep
= min(ring
->bytes
, ring
->size
- tail
);
179 return ring
->buf
+ tail
;
182 int ring_resize(struct ring_buf
*ring
, size_t new_size
)
184 struct ring_buf new_ring
= { .size
= new_size
};
188 if (ring_bytes(ring
) > new_size
)
191 new_ring
.buf
= calloc(1, new_size
);
192 if (new_size
&& !new_ring
.buf
)
195 while ((p
= ring_data(ring
, &size
))) {
196 ring_fill(&new_ring
, p
, size
);
197 ring_consume(ring
, size
);
205 int ensure_sbuf_size(struct sized_buf
*sbuf
, size_t size
)
209 if (sbuf
->size
>= size
)
212 new_buf
= realloc(sbuf
->buf
, size
);
213 if (size
&& !new_buf
)
221 static unsigned long __ffs(unsigned long word
)
225 if (BITS_PER_LONG
== 64) {
226 if ((word
& 0xffffffff) == 0) {
232 if ((word
& 0xffff) == 0) {
236 if ((word
& 0xff) == 0) {
240 if ((word
& 0xf) == 0) {
244 if ((word
& 0x3) == 0) {
248 if ((word
& 0x1) == 0)
253 #define ffz(x) __ffs(~(x))
255 unsigned long find_next_zero_bit(const unsigned long *addr
, unsigned long size
,
256 unsigned long offset
)
258 const unsigned long *p
= addr
+ BITOP_WORD(offset
);
259 unsigned long result
= offset
& ~(BITS_PER_LONG
-1);
265 offset
%= BITS_PER_LONG
;
268 tmp
|= ~0UL >> (BITS_PER_LONG
- offset
);
269 if (size
< BITS_PER_LONG
)
273 size
-= BITS_PER_LONG
;
274 result
+= BITS_PER_LONG
;
276 while (size
& ~(BITS_PER_LONG
-1)) {
279 result
+= BITS_PER_LONG
;
280 size
-= BITS_PER_LONG
;
288 if (tmp
== ~0UL) /* Are any bits zero? */
289 return result
+ size
; /* Nope. */
291 return result
+ ffz(tmp
);
294 void __set_bit(int nr
, volatile unsigned long *addr
)
296 unsigned long mask
= BIT_MASK(nr
);
297 unsigned long *p
= ((unsigned long *)addr
) + BIT_WORD(nr
);
302 void __clear_bit(int nr
, volatile unsigned long *addr
)
304 unsigned long mask
= BIT_MASK(nr
);
305 unsigned long *p
= ((unsigned long *)addr
) + BIT_WORD(nr
);
310 int get_proc_self_info(pid_t pid
, pid_t
*ppid_r
,
311 char *cmd_buf
, size_t cmd_buf_sz
)
314 char path
[64], buf
[4096];
316 char *cmd_start
, *cmd_end
, *ppid_start
, *end
;
321 snprintf(path
, sizeof(path
), "/proc/%ld/stat", (long)pid
);
322 fd
= open(path
, O_RDONLY
);
328 ret
= read(fd
, buf
, sizeof(buf
));
331 if (ret
== sizeof(buf
)) {
338 cmd_start
= strchr(buf
, '(');
339 cmd_end
= strrchr(buf
, ')');
340 if (!cmd_start
|| !cmd_end
)
344 ppid_start
= cmd_end
;
345 for (i
= 0; i
< 3; i
++) {
346 ppid_start
= strchr(ppid_start
, ' ');
352 ppid
= strtoul(ppid_start
, &end
, 10);
353 if (end
== ppid_start
|| *end
!= ' ')
359 size_t len
= min_t(size_t, cmd_end
- cmd_start
, cmd_buf_sz
- 1);
360 memcpy(cmd_buf
, cmd_start
, len
);