PageRenderTime 27ms CodeModel.GetById 11ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/um/kernel/tty_log.c

https://bitbucket.org/evzijst/gittest
C | 230 lines | 178 code | 36 blank | 16 comment | 26 complexity | 27c143b8c92f2d0438b2dccc2e88ce44 MD5 | raw file
  1/* 
  2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and 
  3 * geoffrey hing <ghing@net.ohio-state.edu>
  4 * Licensed under the GPL
  5 */
  6
  7#include <errno.h>
  8#include <string.h>
  9#include <stdio.h>
 10#include <stdlib.h>
 11#include <unistd.h>
 12#include <sys/time.h>
 13#include "init.h"
 14#include "user.h"
 15#include "kern_util.h"
 16#include "os.h"
 17
 18#define TTY_LOG_DIR "./"
 19
 20/* Set early in boot and then unchanged */
 21static char *tty_log_dir = TTY_LOG_DIR;
 22static int tty_log_fd = -1;
 23
 24#define TTY_LOG_OPEN 1
 25#define TTY_LOG_CLOSE 2
 26#define TTY_LOG_WRITE 3
 27#define TTY_LOG_EXEC 4
 28
 29#define TTY_READ 1
 30#define TTY_WRITE 2
 31
 32struct tty_log_buf {
 33	int what;
 34	unsigned long tty;
 35	int len;
 36	int direction;
 37	unsigned long sec;
 38	unsigned long usec;
 39};
 40
 41int open_tty_log(void *tty, void *current_tty)
 42{
 43	struct timeval tv;
 44	struct tty_log_buf data;
 45	char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
 46	int fd;
 47
 48	gettimeofday(&tv, NULL);
 49	if(tty_log_fd != -1){
 50		data = ((struct tty_log_buf) { .what 	= TTY_LOG_OPEN,
 51					       .tty  = (unsigned long) tty,
 52					       .len  = sizeof(current_tty),
 53					       .direction = 0,
 54					       .sec = tv.tv_sec,
 55					       .usec = tv.tv_usec } );
 56		os_write_file(tty_log_fd, &data, sizeof(data));
 57		os_write_file(tty_log_fd, &current_tty, data.len);
 58		return(tty_log_fd);
 59	}
 60
 61	sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, 
 62 		(unsigned int) tv.tv_usec);
 63
 64	fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))),
 65			  0644);
 66	if(fd < 0){
 67		printk("open_tty_log : couldn't open '%s', errno = %d\n",
 68		       buf, -fd);
 69	}
 70	return(fd);
 71}
 72
 73void close_tty_log(int fd, void *tty)
 74{
 75	struct tty_log_buf data;
 76	struct timeval tv;
 77
 78	if(tty_log_fd != -1){
 79		gettimeofday(&tv, NULL);
 80		data = ((struct tty_log_buf) { .what 	= TTY_LOG_CLOSE,
 81					       .tty  = (unsigned long) tty,
 82					       .len  = 0,
 83					       .direction = 0,
 84					       .sec = tv.tv_sec,
 85					       .usec = tv.tv_usec } );
 86		os_write_file(tty_log_fd, &data, sizeof(data));
 87		return;
 88	}
 89	os_close_file(fd);
 90}
 91
 92static int log_chunk(int fd, const char *buf, int len)
 93{
 94	int total = 0, try, missed, n;
 95	char chunk[64];
 96
 97	while(len > 0){
 98		try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
 99		missed = copy_from_user_proc(chunk, (char *) buf, try);
100		try -= missed;
101		n = os_write_file(fd, chunk, try);
102		if(n != try) {
103			if(n < 0)
104				return(n);
105			return(-EIO);
106		}
107		if(missed != 0)
108			return(-EFAULT);
109
110		len -= try;
111		total += try;
112		buf += try;
113	}
114
115	return(total);
116}
117
118int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
119{
120	struct timeval tv;
121	struct tty_log_buf data;
122	int direction;
123
124	if(fd == tty_log_fd){
125		gettimeofday(&tv, NULL);
126		direction = is_read ? TTY_READ : TTY_WRITE;
127		data = ((struct tty_log_buf) { .what 	= TTY_LOG_WRITE,
128					       .tty  = (unsigned long) tty,
129					       .len  = len,
130					       .direction = direction,
131					       .sec = tv.tv_sec,
132					       .usec = tv.tv_usec } );
133		os_write_file(tty_log_fd, &data, sizeof(data));
134	}
135
136	return(log_chunk(fd, buf, len));
137}
138
139void log_exec(char **argv, void *tty)
140{
141	struct timeval tv;
142	struct tty_log_buf data;
143	char **ptr,*arg;
144	int len;
145
146	if(tty_log_fd == -1) return;
147
148	gettimeofday(&tv, NULL);
149
150	len = 0;
151	for(ptr = argv; ; ptr++){
152		if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
153			return;
154		if(arg == NULL) break;
155		len += strlen_user_proc(arg);
156	}
157
158	data = ((struct tty_log_buf) { .what 	= TTY_LOG_EXEC,
159				       .tty  = (unsigned long) tty,
160				       .len  = len,
161				       .direction = 0,
162				       .sec = tv.tv_sec,
163				       .usec = tv.tv_usec } );
164	os_write_file(tty_log_fd, &data, sizeof(data));
165
166	for(ptr = argv; ; ptr++){
167		if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
168			return;
169		if(arg == NULL) break;
170		log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
171	}
172}
173
174extern void register_tty_logger(int (*opener)(void *, void *),
175				int (*writer)(int, const char *, int,
176					      void *, int),
177				void (*closer)(int, void *));
178
179static int register_logger(void)
180{
181	register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
182	return(0);
183}
184
185__uml_initcall(register_logger);
186
187static int __init set_tty_log_dir(char *name, int *add)
188{
189	tty_log_dir = name;
190	return 0;
191}
192
193__uml_setup("tty_log_dir=", set_tty_log_dir,
194"tty_log_dir=<directory>\n"
195"    This is used to specify the directory where the logs of all pty\n"
196"    data from this UML machine will be written.\n\n"
197);
198
199static int __init set_tty_log_fd(char *name, int *add)
200{
201	char *end;
202
203	tty_log_fd = strtoul(name, &end, 0);
204	if((*end != '\0') || (end == name)){
205		printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
206		tty_log_fd = -1;
207	}
208
209	*add = 0;
210	return 0;
211}
212
213__uml_setup("tty_log_fd=", set_tty_log_fd,
214"tty_log_fd=<fd>\n"
215"    This is used to specify a preconfigured file descriptor to which all\n"
216"    tty data will be written.  Preconfigure the descriptor with something\n"
217"    like '10>tty_log tty_log_fd=10'.\n\n"
218);
219
220
221/*
222 * Overrides for Emacs so that we follow Linus's tabbing style.
223 * Emacs will notice this stuff at the end of the file and automatically
224 * adjust the settings for this buffer only.  This must remain at the end
225 * of the file.
226 * ---------------------------------------------------------------------------
227 * Local variables:
228 * c-file-style: "linux"
229 * End:
230 */