xref: /illumos-gate/usr/src/lib/libc/port/gen/lfmt_log.c (revision 26fd7700)
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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 /* lfmt_log() - log info */
33 
34 #include "lint.h"
35 #include <mtlib.h>
36 #include <pfmt.h>
37 #include <stdio.h>
38 #include <sys/types.h>
39 #include <sys/types32.h>
40 #include <sys/stropts.h>
41 #include <sys/strlog.h>
42 #include <fcntl.h>
43 #include <errno.h>
44 #include <synch.h>
45 #include <thread.h>
46 #include "pfmt_data.h"
47 #include <time.h>
48 #include <stropts.h>
49 #include <unistd.h>
50 #include <strings.h>
51 #include <sys/uio.h>
52 
53 #define	MAXMSG	1024
54 #define	LOGNAME		"/dev/conslog"
55 #define	LOG_CONSOLE	"/dev/console"
56 
57 int
58 __lfmt_log(const char *text, const char *sev, va_list args, long flag, int ret)
59 {
60 	static int fd = -1;
61 	struct strbuf dat;
62 	int msg_offset;
63 	long len;
64 	union {
65 		long	flag;
66 		char	buf[MAXMSG];
67 	} msg;
68 	int err;
69 	int fdd;
70 
71 	len = ret + sizeof (long) + 3;
72 
73 	if (len > sizeof (msg)) {
74 		errno = ERANGE;
75 		return (-2);
76 	}
77 
78 	msg.flag = flag;
79 	msg_offset = (int)sizeof (long);
80 
81 	lrw_rdlock(&_rw_pfmt_label);
82 	if (*__pfmt_label)
83 		msg_offset += strlcpy(msg.buf + msg_offset, __pfmt_label,
84 		    sizeof (msg.buf) - msg_offset);
85 	lrw_unlock(&_rw_pfmt_label);
86 
87 	if (sev)
88 		msg_offset += sprintf(msg.buf + msg_offset, sev, flag & 0xff);
89 
90 	msg_offset += 1 + vsprintf(msg.buf + msg_offset, text, args);
91 	msg.buf[msg_offset++] = '\0';
92 
93 	if (fd == -1 &&
94 	    ((fd = open(LOGNAME, O_WRONLY)) == -1 ||
95 	    fcntl(fd, F_SETFD, 1) == -1))
96 		return (-2);
97 
98 	dat.maxlen = MAXMSG;
99 	dat.len = (int)msg_offset;
100 	dat.buf = msg.buf;
101 
102 	if (putmsg(fd, 0, &dat, 0) == -1) {
103 		(void) close(fd);
104 		return (-2);
105 	}
106 
107 	/*
108 	 *  Display it to a console
109 	 */
110 	if ((flag & MM_CONSOLE) != 0) {
111 		char *p;
112 		time_t t;
113 		char buf[128];
114 		err = errno;
115 		fdd = open(LOG_CONSOLE, O_WRONLY);
116 		if (fdd != -1) {
117 			/*
118 			 * Use C locale for time stamp.
119 			 */
120 			(void) time(&t);
121 			(void) ctime_r(&t, buf, sizeof (buf));
122 			p = (char *)strrchr(buf, '\n');
123 			if (p != NULL)
124 				*p = ':';
125 			(void) write(fdd, buf, strlen(buf));
126 			(void) write(fdd, msg.buf + sizeof (long),
127 			    msg_offset - sizeof (long));
128 			(void) write(fdd, "\n", 1);
129 		} else
130 			return (-2);
131 		(void) close(fdd);
132 		errno = err;
133 	}
134 	return (ret);
135 }
136