xref: /illumos-gate/usr/src/lib/libc/port/gen/lfmt_log.c (revision 7a6d80f1660abd4755c68cbd094d4a914681d26e)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1988 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 /* lfmt_log() - log info */
31 
32 #include "lint.h"
33 #include <mtlib.h>
34 #include <pfmt.h>
35 #include <stdio.h>
36 #include <sys/types.h>
37 #include <sys/types32.h>
38 #include <sys/stropts.h>
39 #include <sys/strlog.h>
40 #include <fcntl.h>
41 #include <errno.h>
42 #include <synch.h>
43 #include <thread.h>
44 #include "pfmt_data.h"
45 #include <time.h>
46 #include <stropts.h>
47 #include <unistd.h>
48 #include <strings.h>
49 #include <sys/uio.h>
50 
51 #define	MAXMSG	1024
52 #define	LOGNAME		"/dev/conslog"
53 #define	LOG_CONSOLE	"/dev/console"
54 
55 int
56 __lfmt_log(const char *text, const char *sev, va_list args, long flag, int ret)
57 {
58 	static int fd = -1;
59 	struct strbuf dat;
60 	int msg_offset;
61 	long len;
62 	union {
63 		long	flag;
64 		char	buf[MAXMSG];
65 	} msg;
66 	int err;
67 	int fdd;
68 
69 	len = ret + sizeof (long) + 3;
70 
71 	if (len > sizeof (msg)) {
72 		errno = ERANGE;
73 		return (-2);
74 	}
75 
76 	msg.flag = flag;
77 	msg_offset = (int)sizeof (long);
78 
79 	lrw_rdlock(&_rw_pfmt_label);
80 	if (*__pfmt_label)
81 		msg_offset += strlcpy(msg.buf + msg_offset, __pfmt_label,
82 		    sizeof (msg.buf) - msg_offset);
83 	lrw_unlock(&_rw_pfmt_label);
84 
85 	if (sev)
86 		msg_offset += sprintf(msg.buf + msg_offset, sev, flag & 0xff);
87 
88 	msg_offset += 1 + vsprintf(msg.buf + msg_offset, text, args);
89 	msg.buf[msg_offset++] = '\0';
90 
91 	if (fd == -1 &&
92 	    ((fd = open(LOGNAME, O_WRONLY)) == -1 ||
93 	    fcntl(fd, F_SETFD, 1) == -1))
94 		return (-2);
95 
96 	dat.maxlen = MAXMSG;
97 	dat.len = (int)msg_offset;
98 	dat.buf = msg.buf;
99 
100 	if (putmsg(fd, 0, &dat, 0) == -1) {
101 		(void) close(fd);
102 		return (-2);
103 	}
104 
105 	/*
106 	 *  Display it to a console
107 	 */
108 	if ((flag & MM_CONSOLE) != 0) {
109 		char *p;
110 		time_t t;
111 		char buf[128];
112 		err = errno;
113 		fdd = open(LOG_CONSOLE, O_WRONLY);
114 		if (fdd != -1) {
115 			/*
116 			 * Use C locale for time stamp.
117 			 */
118 			(void) time(&t);
119 			(void) ctime_r(&t, buf, sizeof (buf));
120 			p = (char *)strrchr(buf, '\n');
121 			if (p != NULL)
122 				*p = ':';
123 			(void) write(fdd, buf, strlen(buf));
124 			(void) write(fdd, msg.buf + sizeof (long),
125 			    msg_offset - sizeof (long));
126 			(void) write(fdd, "\n", 1);
127 		} else
128 			return (-2);
129 		(void) close(fdd);
130 		errno = err;
131 	}
132 	return (ret);
133 }
134