forked from Minki/linux
edea138584
Tidy kern_util.h. It turns out that most of the function declarations aren't used, so they can go away. os.h no longer includes kern_util.h, so files which got it through os.h now need to include it directly. A number of other files never needed it, so these includes are deleted. The structure which was used to pass signal handlers from the kernel side to the userspace side is gone. Instead, the handlers are declared here, and used directly from libc code. This allows arch/um/os-Linux/trap.c to be deleted, with its remnants being moved to arch/um/os-Linux/skas/trap.c. arch/um/os-Linux/tty.c had its inclusions changed, and it needed some style attention, so it got tidied. Signed-off-by: Jeff Dike <jdike@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
218 lines
4.8 KiB
C
218 lines
4.8 KiB
C
/*
|
|
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and
|
|
* geoffrey hing <ghing@net.ohio-state.edu>
|
|
* Licensed under the GPL
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <sys/time.h>
|
|
#include "init.h"
|
|
#include "user.h"
|
|
#include "os.h"
|
|
|
|
#define TTY_LOG_DIR "./"
|
|
|
|
/* Set early in boot and then unchanged */
|
|
static char *tty_log_dir = TTY_LOG_DIR;
|
|
static int tty_log_fd = -1;
|
|
|
|
#define TTY_LOG_OPEN 1
|
|
#define TTY_LOG_CLOSE 2
|
|
#define TTY_LOG_WRITE 3
|
|
#define TTY_LOG_EXEC 4
|
|
|
|
#define TTY_READ 1
|
|
#define TTY_WRITE 2
|
|
|
|
struct tty_log_buf {
|
|
int what;
|
|
unsigned long tty;
|
|
int len;
|
|
int direction;
|
|
unsigned long sec;
|
|
unsigned long usec;
|
|
};
|
|
|
|
int open_tty_log(void *tty, void *current_tty)
|
|
{
|
|
struct timeval tv;
|
|
struct tty_log_buf data;
|
|
char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
|
|
int fd;
|
|
|
|
gettimeofday(&tv, NULL);
|
|
if(tty_log_fd != -1){
|
|
data = ((struct tty_log_buf) { .what = TTY_LOG_OPEN,
|
|
.tty = (unsigned long) tty,
|
|
.len = sizeof(current_tty),
|
|
.direction = 0,
|
|
.sec = tv.tv_sec,
|
|
.usec = tv.tv_usec } );
|
|
write(tty_log_fd, &data, sizeof(data));
|
|
write(tty_log_fd, ¤t_tty, data.len);
|
|
return tty_log_fd;
|
|
}
|
|
|
|
sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec,
|
|
(unsigned int) tv.tv_usec);
|
|
|
|
fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))),
|
|
0644);
|
|
if(fd < 0){
|
|
printk("open_tty_log : couldn't open '%s', errno = %d\n",
|
|
buf, -fd);
|
|
}
|
|
return fd;
|
|
}
|
|
|
|
void close_tty_log(int fd, void *tty)
|
|
{
|
|
struct tty_log_buf data;
|
|
struct timeval tv;
|
|
|
|
if(tty_log_fd != -1){
|
|
gettimeofday(&tv, NULL);
|
|
data = ((struct tty_log_buf) { .what = TTY_LOG_CLOSE,
|
|
.tty = (unsigned long) tty,
|
|
.len = 0,
|
|
.direction = 0,
|
|
.sec = tv.tv_sec,
|
|
.usec = tv.tv_usec } );
|
|
write(tty_log_fd, &data, sizeof(data));
|
|
return;
|
|
}
|
|
os_close_file(fd);
|
|
}
|
|
|
|
static int log_chunk(int fd, const char *buf, int len)
|
|
{
|
|
int total = 0, try, missed, n;
|
|
char chunk[64];
|
|
|
|
while(len > 0){
|
|
try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
|
|
missed = copy_from_user_proc(chunk, (char *) buf, try);
|
|
try -= missed;
|
|
n = write(fd, chunk, try);
|
|
if(n != try) {
|
|
if(n < 0)
|
|
return -errno;
|
|
return -EIO;
|
|
}
|
|
if(missed != 0)
|
|
return -EFAULT;
|
|
|
|
len -= try;
|
|
total += try;
|
|
buf += try;
|
|
}
|
|
|
|
return total;
|
|
}
|
|
|
|
int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
|
|
{
|
|
struct timeval tv;
|
|
struct tty_log_buf data;
|
|
int direction;
|
|
|
|
if(fd == tty_log_fd){
|
|
gettimeofday(&tv, NULL);
|
|
direction = is_read ? TTY_READ : TTY_WRITE;
|
|
data = ((struct tty_log_buf) { .what = TTY_LOG_WRITE,
|
|
.tty = (unsigned long) tty,
|
|
.len = len,
|
|
.direction = direction,
|
|
.sec = tv.tv_sec,
|
|
.usec = tv.tv_usec } );
|
|
write(tty_log_fd, &data, sizeof(data));
|
|
}
|
|
|
|
return log_chunk(fd, buf, len);
|
|
}
|
|
|
|
void log_exec(char **argv, void *tty)
|
|
{
|
|
struct timeval tv;
|
|
struct tty_log_buf data;
|
|
char **ptr,*arg;
|
|
int len;
|
|
|
|
if(tty_log_fd == -1) return;
|
|
|
|
gettimeofday(&tv, NULL);
|
|
|
|
len = 0;
|
|
for(ptr = argv; ; ptr++){
|
|
if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
|
|
return;
|
|
if(arg == NULL) break;
|
|
len += strlen_user_proc(arg);
|
|
}
|
|
|
|
data = ((struct tty_log_buf) { .what = TTY_LOG_EXEC,
|
|
.tty = (unsigned long) tty,
|
|
.len = len,
|
|
.direction = 0,
|
|
.sec = tv.tv_sec,
|
|
.usec = tv.tv_usec } );
|
|
write(tty_log_fd, &data, sizeof(data));
|
|
|
|
for(ptr = argv; ; ptr++){
|
|
if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
|
|
return;
|
|
if(arg == NULL) break;
|
|
log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
|
|
}
|
|
}
|
|
|
|
extern void register_tty_logger(int (*opener)(void *, void *),
|
|
int (*writer)(int, const char *, int,
|
|
void *, int),
|
|
void (*closer)(int, void *));
|
|
|
|
static int register_logger(void)
|
|
{
|
|
register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
|
|
return 0;
|
|
}
|
|
|
|
__uml_initcall(register_logger);
|
|
|
|
static int __init set_tty_log_dir(char *name, int *add)
|
|
{
|
|
tty_log_dir = name;
|
|
return 0;
|
|
}
|
|
|
|
__uml_setup("tty_log_dir=", set_tty_log_dir,
|
|
"tty_log_dir=<directory>\n"
|
|
" This is used to specify the directory where the logs of all pty\n"
|
|
" data from this UML machine will be written.\n\n"
|
|
);
|
|
|
|
static int __init set_tty_log_fd(char *name, int *add)
|
|
{
|
|
char *end;
|
|
|
|
tty_log_fd = strtoul(name, &end, 0);
|
|
if((*end != '\0') || (end == name)){
|
|
printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
|
|
tty_log_fd = -1;
|
|
}
|
|
|
|
*add = 0;
|
|
return 0;
|
|
}
|
|
|
|
__uml_setup("tty_log_fd=", set_tty_log_fd,
|
|
"tty_log_fd=<fd>\n"
|
|
" This is used to specify a preconfigured file descriptor to which all\n"
|
|
" tty data will be written. Preconfigure the descriptor with something\n"
|
|
" like '10>tty_log tty_log_fd=10'.\n\n"
|
|
);
|