-
Notifications
You must be signed in to change notification settings - Fork 0
/
ldpreload_fake_isatty0.c
152 lines (127 loc) · 3.4 KB
/
ldpreload_fake_isatty0.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#if 0 /*
archos=`uname -s -m | awk '{ print tolower($2) "-" tolower($1) }'`
libc_so=`ldd /usr/bin/env | awk '/libc.so/ { print $3 }'`
bn=`basename "$0" .c`; lbn=$bn-$archos
trap 'rm -f $bn.o' 0
WARN="-Wall -Wstrict-prototypes -pedantic -Wno-long-long"
WARN="$WARN -Wcast-align -Wpointer-arith " # -Wfloat-equal #-Werror
WARN="$WARN -W -Wwrite-strings -Wcast-qual -Wshadow" # -Wconversion
set -xeu
gcc -std=c99 -fPIC -rdynamic -g -c $WARN "$0" -o "$bn.o" \
-DARCHOS="\"$archos\"" -DLIBC_SO="\"$libc_so\""
gcc -shared -Wl,-soname,$lbn.so -o $lbn.so $bn.o -lc -ldl
exit
*/
#endif
/*
* $ ldpreload_fake_isatty0.c $
*
* Author: Tomi Ollila -- too ät iki piste fi
*
* Copyright (c) 2013 Tomi Ollila
* All rights reserved
*
* Created: Wed 27 Feb 2013 22:54:11 EET too
* Last modified: Mon 04 Mar 2013 21:38:13 EET too
*/
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <sys/uio.h>
#include <dlfcn.h>
#include <unistd.h>
#include <termios.h>
#ifndef NULL
#define NULL ((void*)0)
#endif
#if (__GNUC__ >= 4)
void die(int ev, ...) __attribute__((sentinel)) __attribute__((noreturn));
#endif
void die(int ev, ...)
{
struct iovec iov[10];
va_list ap;
va_start(ap, ev);
int i = 0;
for (char * s = va_arg(ap, char *); s; s = va_arg(ap, char *)) {
iov[i].iov_base = s;
iov[i].iov_len = strlen(s);
i++;
if (i == sizeof iov / sizeof iov[0])
break;
}
writev(2, iov, i);
exit(ev);
}
static void * dlhandle = NULL;
static void dlopen_libc(void)
{
if (dlhandle)
return;
dlhandle = dlopen(LIBC_SO, RTLD_LAZY);
if (!dlhandle)
die(1, "dlopening libc failed: ", dlerror(), NULL);
}
static void * dlsym_(const char * symbol)
{
void * sym = dlsym(dlhandle, symbol);
char * str = dlerror();
if (str != NULL)
die(1, "finding symbol '", symbol, "' failed: ", str, NULL);
return sym;
}
int isatty(int fd)
{
static int (*isatty_orig)(int) = NULL;
if (! isatty_orig)
{
dlopen_libc();
*(void **)(&isatty_orig) = dlsym_("isatty");
}
// fd 0 may be pipe/socket, fd2 should be the terminal (tx11ssh child ssh)
if (fd == 0)
fd = 2;
return isatty_orig(fd);
}
#if 0
int ioctl(int fd, int request, int anything)
{
static int (*ioctl_orig)(int, int, int) = NULL;
//printf("ioctl: %d %x %x\n", fd, request, anything);
if (! ioctl_orig)
{
dlopen_libc();
*(void **)(&ioctl_orig) = dlsym_("ioctl");
}
// fd 0 may be pipe/socket, fd2 should be the terminal (tx11ssh child ssh)
if (fd == 0)
fd = 2;
return ioctl_orig(fd, request, anything);
}
#endif
int tcgetattr(int fd, struct termios *termios_p)
{
static int (*tcgetattr_orig)(int, struct termios *) = NULL;
if (! tcgetattr_orig)
{
dlopen_libc();
*(void **)(&tcgetattr_orig) = dlsym_("tcgetattr");
}
// fd 0 may be pipe/socket, fd2 should be the terminal (tx11ssh child ssh)
if (fd == 0)
fd = 2;
return tcgetattr_orig(fd, termios_p);
}
int tcsetattr(int fd, int optional_actions, const struct termios *termios_p)
{
static int (*tcsetattr_orig)(int, int, const struct termios *) = NULL;
if (! tcsetattr_orig)
{
dlopen_libc();
*(void **)(&tcsetattr_orig) = dlsym_("tcsetattr");
}
// fd 0 may be pipe/socket, fd2 should be the terminal
if (fd == 0)
fd = 2;
return tcsetattr_orig(fd, optional_actions, termios_p);
}