Changeset d5eac12 in rtems-libbsd
- Timestamp:
- 10/09/14 12:34:13 (8 years ago)
- Branches:
- 4.11, 5, 5-freebsd-12, 6-freebsd-12, freebsd-9.3, master
- Children:
- 43dc972
- Parents:
- 403d0b8
- git-author:
- Sebastian Huber <sebastian.huber@…> (10/09/14 12:34:13)
- git-committer:
- Sebastian Huber <sebastian.huber@…> (10/09/14 12:56:29)
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
rtemsbsd/rtems/syslog.c
r403d0b8 rd5eac12 1 /* 2 * RTEMS version of syslog and associated routines 1 /** 2 * @file 3 * 4 * @ingroup rtems_bsd_rtems 5 * 6 * @brief TODO. 3 7 */ 4 8 5 #ifdef HAVE_CONFIG_H 6 #include "config.h" 7 #endif 9 /* 10 * Copyright (c) 2014 embedded brains GmbH. All rights reserved. 11 * 12 * embedded brains GmbH 13 * Dornierstr. 4 14 * 82178 Puchheim 15 * Germany 16 * <rtems@embedded-brains.de> 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions 20 * are met: 21 * 1. Redistributions of source code must retain the above copyright 22 * notice, this list of conditions and the following disclaimer. 23 * 2. Redistributions in binary form must reproduce the above copyright 24 * notice, this list of conditions and the following disclaimer in the 25 * documentation and/or other materials provided with the distribution. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 */ 8 39 9 #include <rtems.h> 40 #include <machine/rtems-bsd-user-space.h> 41 #include <machine/rtems-bsd-program.h> 42 43 #include <syslog.h> 44 #include <errno.h> 10 45 #include <stdio.h> 11 #include <stdarg.h>12 #include <errno.h>13 #include <syslog.h>14 #include <rtems/bsd/sys/types.h>15 #include <sys/socket.h>16 #include <netinet/in.h>17 46 #include <string.h> 18 47 19 #include <unistd.h> 48 typedef struct { 49 int mask; 50 } rtems_bsd_syslog_context; 20 51 21 #include <machine/rtems-bsd-printf-to-iprintf.h> 52 /* FIXME: This should be thread specific */ 53 static rtems_bsd_syslog_context rtems_bsd_syslog_instance = { 54 .mask = LOG_UPTO(LOG_DEBUG) 55 }; 22 56 23 static int LogStatus = LOG_CONS; 24 static const char *LogTag = "syslog"; 25 static int LogFacility = LOG_USER; 26 static int LogMask = 0xff; 57 static const char * const rtems_bsd_syslog_priorities[] = { 58 [LOG_EMERG] = "emerg", 59 [LOG_ALERT] = "alert", 60 [LOG_CRIT] = "crit", 61 [LOG_ERR] = "err", 62 [LOG_WARNING] = "warning", 63 [LOG_NOTICE] = "notice", 64 [LOG_INFO] = "info", 65 [LOG_DEBUG] = "debug" 66 }; 27 67 28 static int LogFd = -1; 29 static rtems_id LogSemaphore; 30 extern struct in_addr rtems_bsdnet_log_host_address; 68 static rtems_bsd_syslog_context * 69 rtems_bsd_syslog_get_context(void) 70 { 71 return &rtems_bsd_syslog_instance; 72 } 31 73 32 #define SYSLOG_PORT 514 74 static void 75 rtems_bsd_syslog_format_buffer_overflow(void) 76 { 77 fputs("err: syslog: format buffer overflow\n", stderr); 78 } 33 79 34 80 void 35 syslog (int pri, const char *fmt, ...)81 syslog(int priority, const char *format, ...) 36 82 { 37 83 va_list ap; 38 84 39 va_start (ap, fmt); 40 vsyslog (pri, fmt, ap); 41 va_end (ap); 42 } 43 44 /* 45 * FIXME: Should cbuf be static? It could be if we put the mutex 46 * around the entire body of this routine. Then we wouldn't 47 * have to worry about blowing stacks with a local variable 48 * that large. Could make cbuf bigger, too. 49 */ 50 void 51 vsyslog (int pri, const char *fmt, va_list ap) 52 { 53 int cnt; 54 char *cp; 55 char *msgp, cbuf[200]; 56 int sent; 57 58 if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) { 59 syslog (LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID, 60 "syslog: unknown facility/priority: %#x", pri); 61 pri &= LOG_PRIMASK|LOG_FACMASK; 62 } 63 64 if (!(LOG_MASK(LOG_PRI(pri)) & LogMask)) 65 return; 66 67 if ((pri & LOG_FACMASK) == 0) 68 pri |= LogFacility; 69 70 cnt = sprintf (cbuf, "<%d>", pri); 71 cp = msgp = cbuf + cnt; 72 if (LogTag) { 73 const char *lp = LogTag; 74 while ((*cp = *lp++) != '\0') 75 cp++; 76 } 77 if (LogStatus & LOG_PID) { 78 rtems_id tid; 79 rtems_task_ident (RTEMS_SELF, 0, &tid); 80 cnt = sprintf (cp, "[%#lx]", (unsigned long)tid); 81 cp += cnt; 82 } 83 if (LogTag) { 84 *cp++ = ':'; 85 *cp++ = ' '; 86 } 87 cnt = vsprintf (cp, fmt, ap); 88 cnt += cp - cbuf; 89 if (cbuf[cnt-1] == '\n') 90 cbuf[--cnt] = '\0'; 91 92 if (LogStatus & LOG_PERROR) 93 printf ("%s\n", cbuf); 94 95 /* 96 * Grab the mutex 97 */ 98 sent = 0; 99 if ((rtems_bsdnet_log_host_address.s_addr != INADDR_ANY) 100 && (LogFd >= 0) 101 && (rtems_semaphore_obtain (LogSemaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT) == RTEMS_SUCCESSFUL)) { 102 /* 103 * Set the destination address/port 104 */ 105 struct sockaddr_in farAddress; 106 farAddress.sin_family = AF_INET; 107 farAddress.sin_port = htons (SYSLOG_PORT); 108 farAddress.sin_addr = rtems_bsdnet_log_host_address; 109 memset (farAddress.sin_zero, '\0', sizeof farAddress.sin_zero); 110 111 /* 112 * Send the message 113 */ 114 if (sendto (LogFd, cbuf, cnt, 0, (struct sockaddr *)&farAddress, sizeof farAddress) >= 0) 115 sent = 1; 116 rtems_semaphore_release (LogSemaphore); 117 } 118 if (!sent && (LogStatus & LOG_CONS) && !(LogStatus & LOG_PERROR)) 119 printf ("%s\n", msgp); 85 va_start(ap, format); 86 vsyslog(priority, format, ap); 87 va_end(ap); 120 88 } 121 89 122 90 void 123 openlog (const char *ident, int logstat, int logfac)91 vsyslog(int priority, const char *format, va_list ap) 124 92 { 125 rtems_status_code sc; 126 struct sockaddr_in myAddress; 93 rtems_bsd_syslog_context *ctx = rtems_bsd_syslog_get_context(); 94 int pri = LOG_PRI(priority); 95 char fmt[128]; 96 char buf[128]; 97 const char *src; 98 char *dst; 99 size_t rem; 100 char *m; 101 int n; 102 size_t len; 127 103 128 if (ident != NULL) 129 LogTag = ident; 130 LogStatus = logstat; 131 if (logfac != 0 && (logfac & ~LOG_FACMASK) == 0) 132 LogFacility = logfac; 133 134 /* 135 * Create the socket 136 */ 137 if ((LogFd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) { 138 printf ("Can't create syslog socket: %d\n", errno); 104 if ((LOG_MASK(pri) & ctx->mask) == 0) { 139 105 return; 140 106 } 141 107 142 /* 143 * Bind socket to name 144 */ 145 myAddress.sin_family = AF_INET; 146 myAddress.sin_addr.s_addr = INADDR_ANY; 147 myAddress.sin_port = 0; 148 memset (myAddress.sin_zero, '\0', sizeof myAddress.sin_zero); 149 if (bind (LogFd, (struct sockaddr *)&myAddress, sizeof (myAddress)) < 0) { 150 close (LogFd); 151 LogFd = -1; 152 printf ("Can't bind syslog socket: %d\n", errno); 108 /* Expand the %m in the format string and add a newline character */ 109 110 src = format; 111 dst = &fmt[0]; 112 rem = sizeof(fmt) - 2; 113 114 while ((m = strstr(src, "%m")) != NULL) { 115 size_t c = m - src; 116 117 if (c > rem) { 118 rtems_bsd_syslog_format_buffer_overflow(); 119 return; 120 } 121 122 memcpy(dst, src, c); 123 dst += c; 124 src += c + 2; 125 rem -= c; 126 127 n = sniprintf(dst, rem, "%s", strerror(errno)); 128 if (n > rem || n < 0) { 129 rtems_bsd_syslog_format_buffer_overflow(); 130 return; 131 } 132 133 dst += (size_t) n; 134 rem -= (size_t) n; 135 } 136 137 len = strlen(src); 138 if (len > rem) { 139 rtems_bsd_syslog_format_buffer_overflow(); 153 140 return; 154 141 } 155 142 156 /* 157 * Create the mutex 158 */ 159 sc = rtems_semaphore_create (rtems_build_name('s', 'L', 'o', 'g'), 160 1, 161 RTEMS_PRIORITY | 162 RTEMS_BINARY_SEMAPHORE | 163 RTEMS_INHERIT_PRIORITY | 164 RTEMS_NO_PRIORITY_CEILING | 165 RTEMS_LOCAL, 166 0, 167 &LogSemaphore); 168 if (sc != RTEMS_SUCCESSFUL) { 169 printf ("Can't create syslog semaphore: %d\n", sc); 170 close (LogFd); 171 LogFd = -1; 143 memcpy(dst, src, len); 144 dst += len; 145 dst[0] = '\n'; 146 dst[1] = '\0'; 147 148 /* Print into buffer */ 149 150 dst = &buf[0]; 151 rem = sizeof(buf) - 1; 152 153 n = sniprintf(dst, rem, "%s: ", rtems_bsd_syslog_priorities[pri]); 154 if (n <= rem) { 155 dst += (size_t) n; 156 rem -= (size_t) n; 172 157 } 158 159 n = sniprintf(dst, rem, "%s: ", rtems_bsd_program_get_name()); 160 if (n <= rem) { 161 dst += (size_t) n; 162 rem -= (size_t) n; 163 } 164 165 vsniprintf(dst, rem, &fmt[0], ap); 166 167 /* Write in one rush */ 168 169 fputs(&buf[0], stderr); 170 } 171 172 void 173 openlog(const char *ident, int option, int facility) 174 { 175 /* TODO */ 173 176 } 174 177 … … 176 179 closelog(void) 177 180 { 178 if (LogFd >= 0) { 179 close (LogFd); 180 LogFd = -1; 181 rtems_semaphore_delete (LogSemaphore); 182 } 181 /* TODO */ 183 182 } 184 183 185 184 int 186 setlogmask (int pmask)185 setlogmask(int mask) 187 186 { 188 int omask; 187 rtems_bsd_syslog_context *ctx = rtems_bsd_syslog_get_context(); 188 int cur = ctx->mask; 189 189 190 omask = LogMask; 191 if (pmask != 0) 192 LogMask = pmask; 193 return (omask); 190 ctx->mask = mask & LOG_UPTO(LOG_DEBUG); 191 192 return cur; 194 193 } -
testsuite/syscalls01/test_main.c
r403d0b8 rd5eac12 51 51 #include <string.h> 52 52 #include <unistd.h> 53 #include <syslog.h> 53 54 54 55 #define RTEMS_BSD_PROGRAM_NO_EXIT_WRAP … … 1693 1694 1694 1695 static void 1696 test_syslog(void) 1697 { 1698 puts("test syslog"); 1699 1700 errno = 0; 1701 syslog(LOG_ERR, "%m"); 1702 syslog(LOG_ERR, "b%m"); 1703 syslog(LOG_ERR, "%me"); 1704 errno = ENXIO; 1705 syslog(LOG_ERR, "<%m><%m><%m>"); 1706 syslog(LOG_INFO, "%m%m%m%m%m%m%m%m%m%m%m%m%m%m"); 1707 syslog(LOG_EMERG, "emerg"); 1708 syslog(LOG_ALERT, "alert"); 1709 syslog(LOG_CRIT, "crit"); 1710 syslog(LOG_ERR, "err"); 1711 syslog(LOG_WARNING, "warning"); 1712 syslog(LOG_NOTICE, "notice"); 1713 syslog(LOG_INFO, "info"); 1714 syslog(LOG_DEBUG, "debug"); 1715 } 1716 1717 static void 1695 1718 test_main(void) 1696 1719 { … … 1721 1744 test_warn(); 1722 1745 test_err(); 1746 test_syslog(); 1723 1747 1724 1748 exit(0);
Note: See TracChangeset
for help on using the changeset viewer.