Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/warp/warp.sh
1808 views
1
########################################################################
2
# #
3
# This software is part of the ast package #
4
# Copyright (c) 1998-2011 AT&T Intellectual Property #
5
# and is licensed under the #
6
# Eclipse Public License, Version 1.0 #
7
# by AT&T Intellectual Property #
8
# #
9
# A copy of the License is available at #
10
# http://www.eclipse.org/org/documents/epl-v10.html #
11
# (with md5 checksum b35adb5213ca9657e911e9befb180842) #
12
# #
13
# Information and Software Systems Research #
14
# AT&T Research #
15
# Florham Park NJ #
16
# #
17
# Glenn Fowler <[email protected]> #
18
# #
19
########################################################################
20
: warp : execute a command in a different time frame
21
22
integer warp now base factor
23
typeset env show command opt prefix dll suffix ifs root path s
24
typeset base_str
25
typeset OPT ARGV0 USAGE
26
27
command=warp
28
case $(getopts '[-][123:xyz]' opt --xyz 2>/dev/null; echo 0$opt) in
29
0123) ARGV0="-a $command"
30
USAGE=$'
31
[-?
32
@(#)$Id: warp (AT&T Labs Research) 1999-11-19 $
33
]
34
'$USAGE_LICENSE$'
35
[+NAME?warp - execute a command in a different time frame]
36
[+DESCRIPTION?\bwarp\b executes a dynamically linked \acommand\a
37
in a different time frame by intercepting time related system calls
38
and modifying the times seen by \acommand\a using the formula:]{
39
[+time = time + warp + (time - base) * (factor - 1)?]
40
}
41
[+?where \awarp\a is \adate-now\a, \abase\a is \adate\a by default, and
42
\afactor\a is 1 by default. Command argument date specifications
43
support common conventions:]{
44
[+yesterday?]
45
[+next week?]
46
[+50 days?]
47
[+2000-02-28+00:00?]
48
[+feb 28 2000?]
49
[+#\aseconds\a?A \btime_t\b value in \aseconds\a since the epoch.]
50
}
51
[b:base?Set the base or starting date to \adate\a. Useful for repeating
52
a set of tests.]:[date:=date]
53
[f:factor?Set the warped clock to tick at \afactor\a seconds per real second.]:
54
[factor:=1]
55
[n!:exec?Execute \acommand\a. \b--noexec\b shows how \acommand\a would be
56
invoked but does not execute.]
57
[t:trace?Trace each intercepted system call on the standard error.]
58
[+DETAILS?\bwarp\b executes \acommand\a with optional \aargs\a, or \bsh\b(1) if
59
\acommand\a is omitted. All processes executed by \acommand\a are
60
warped in the same time frame. Time progresses for \acommand\a and its
61
children at the rate of \afactor\a times the system clock. Any files
62
created by \acommand\a or its children will appear newer than \adate\a
63
to \acommand\a and its children, but will actually be in the normal
64
time frame for non-warped commands.]
65
[+?Processes are warped by intercepting system calls with a dll that is
66
preloaded at process startup before \amain\a() is called. The
67
interception mechanism may involve the environment on some systems;
68
in those cases commands like \benv\b(1) that clear the enviroment
69
before execution may defeat the \bwarp\b intercepts. The intercepted
70
system calls are:]{
71
[+alarm?]
72
[+fstat?]
73
[+getitimer?]
74
[+gettimeofday?]
75
[+lstat?]
76
[+poll?]
77
[+select?]
78
[+setitimer?]
79
[+stat?]
80
[+time?]
81
[+times?]
82
[+utime?]
83
[+utimes?]
84
}
85
[+?Also intercepted are the \b_\b and \b_libc_\b name permutations of the
86
calls, as well as any 32-bit and 64-bit versions, and the abominable
87
System V \bx\b versions of the \bstat\b(2) family. \bwarp\b ignores
88
calls not present in a particular host system. In addition, \bwarp\b
89
only works on dynamically linked executables that have neither set-uid
90
set-uid nor set-gid permissions. It may not have the intended effect
91
on programs written in a language or linked with a language runtime
92
that hides or mangles system call library symbols, or that
93
directly emit system call instruction sequences rather than using
94
the corresponding library functions, or that dynamically link
95
libraries outside of the scope of the \bwarp\b intercepts.]
96
[+?Multi-process client-server applications may misbehave if the \bwarp\b
97
environment between the related processes is not kept in sync.]
98
99
date [ command [ arg ... ] ]
100
101
[+ENVIRONMENT?\bwarp\b is implemented by three components: the \bwarp\b script,
102
located on \b$PATH\b; the \bwarp\b dll (shared library), located either
103
on \b$PATH\b or in one of the \b../lib\b* directories on \b$PATH\b,
104
depending on local compilation system conventions; and the \bast\b
105
\bdate\b(1) command, located on \b$PATH\b, that supports conversion
106
to/from \btime_t\b values at the shell level. Systems like
107
\bsgi.mips3\b that support multiple a.out formats may have multiple
108
versions of the \bwarp\b dll. In all cases the \bwarp\b script handles
109
the dll search.]
110
[+EXAMPLES?]{
111
[+$ date -f %K?1998-03-11+13:41]
112
[+$ warp 2000-02-29+12::30::30 date -f %K?2000-02-29+12:30]
113
[+$ warp "2 years" date -f %K?2000-01-01+00:00]
114
[+$ PS1="(warp) " warp -f $((60*60*24)) 2000-02-29+12::30::30?#
115
interactive \bsh\b(1) where 1 warped day passes for each
116
real second.]
117
}
118
[+SEE ALSO?\b3d\b(1), \bdate\b(1), \benv\b(1), \bie\b(1), \bsh\b(1),
119
\btrace\b(1), \bstat\b(2)]
120
'
121
;;
122
*) ARGV0=""
123
USAGE='b:[base]f:[factor]nt date [ command [ arg ... ] ]'
124
;;
125
esac
126
127
: grab the options
128
129
while getopts $ARGV0 "$USAGE" OPT
130
do case $OPT in
131
b) base_str=$OPTARG ;;
132
f) factor=$OPTARG ;;
133
n) show=print ;;
134
t) opt="$opt-$OPT " ;;
135
*) exit 2 ;;
136
esac
137
done
138
shift $OPTIND-1
139
case $# in
140
0) set -- '-?'; getopts $ARGV0 "$USAGE" OPT; exit 2 ;;
141
esac
142
143
: find the warp dll root dir
144
145
ifs=${IFS-'
146
'}
147
IFS=:
148
set -A path $PATH
149
IFS=$ifs
150
for root in ${path[@]}
151
do root=${root%/*}
152
set -A lib $root/@(bin|lib)/@(lib|)warp*([0-9]).@(dll|dylib|s[ol]*([0-9.]))
153
dll=${lib[${#lib[@]}-1]}
154
if test -f $dll
155
then break
156
fi
157
done
158
prefix=${dll%.@(dll|dylib|s[ol]*([0-9.]))}
159
suffix=${dll##$prefix}
160
prefix=${prefix#$root/}
161
162
: determine the warp offset
163
164
(( now = $(LD_LIBRARY_PATH=$root/lib:$LD_LIBRARY_PATH $root/bin/date -f %s) ))
165
case $1 in
166
now) (( warp = now ))
167
;;
168
+([0-9]))
169
(( warp = $1 ))
170
;;
171
*) (( warp = $(LD_LIBRARY_PATH=$root/lib:$LD_LIBRARY_PATH $root/bin/date -f %s -s "$1") ))
172
;;
173
esac
174
shift
175
176
: determine the warp factor base
177
178
if (( factor ))
179
then case $base_str in
180
''|now) (( base = now ))
181
;;
182
+([0-9]))
183
(( base = $base_str ))
184
;;
185
*) (( base = $(LD_LIBRARY_PATH=$root/lib:$LD_LIBRARY_PATH $root/bin/date -f %s -s "$base_str") ))
186
;;
187
esac
188
opt="$opt-b$base -f$factor "
189
fi
190
191
: final adjustments
192
193
(( warp = warp - now ))
194
195
: if no command then start a warped shell
196
197
case $# in
198
0) command=${SHELL:-ksh} ;;
199
*) if test -x "$1"
200
then command=$1
201
else command=$(whence $1)
202
fi
203
shift
204
;;
205
esac
206
207
: hack the preload magic, and we mean hack
208
209
env="WARP='$opt$warp' LD_PRELOAD='$root/$prefix$suffix${LD_PRELOAD:+ $LD_PRELOAD}' DYLD_INSERT_LIBRARIES='$root/$prefix$suffix${DYLD_INSERT_LIBRARIES:+ $DYLD_INSERT_LIBRARIES}'"
210
case $root in
211
*-n32) env="$env _RLDN32_LIST=$root/$prefix$suffix"
212
case $_RLDN32_LIST in
213
"") env="$env:DEFAULT" ;;
214
*) env="$env:$_RLDN32_LIST" ;;
215
esac
216
;;
217
*) if test -f $root/$prefix-n32$suffix
218
then env="$env _RLD64_LIST=$dll"
219
case $_RLD64_LIST in
220
"") env="$env:DEFAULT" ;;
221
*) env="$env:$_RLD64_LIST" ;;
222
esac
223
env="$env _RLDN32_LIST=$root/$prefix-n32$suffix"
224
case $_RLDN32_LIST in
225
"") env="$env:DEFAULT" ;;
226
*) env="$env:$_RLDN32_LIST" ;;
227
esac
228
env="$env _RLD_LIST=$root/$prefix-o32$suffix"
229
case $_RLD_LIST in
230
"") env="$env:DEFAULT" ;;
231
*) env="$env:$_RLD_LIST" ;;
232
esac
233
elif test -f $root/$prefix-64$suffix -o -f $root/$prefix-o32$suffix
234
then env="$env _RLD64_LIST=$root/$prefix-64$suffix"
235
case $_RLD64_LIST in
236
"") env="$env:DEFAULT" ;;
237
*) env="$env:$_RLD64_LIST" ;;
238
esac
239
env="$env _RLDN32_LIST=$dll"
240
case $_RLDN32_LIST in
241
"") env="$env:DEFAULT" ;;
242
*) env="$env:$_RLDN32_LIST" ;;
243
esac
244
env="$env _RLD_LIST=$root/$prefix-o32$suffix"
245
case $_RLD_LIST in
246
"") env="$env:DEFAULT" ;;
247
*) env="$env:$_RLD_LIST" ;;
248
esac
249
else case $root in
250
*/sgi.mips[2-9]*)
251
root=${root%-*}
252
root=${root%?}
253
env="$env _RLD64_LIST=${root}4/$prefix$suffix"
254
case $_RLD64_LIST in
255
"") env="$env:DEFAULT" ;;
256
*) env="$env:$_RLD64_LIST" ;;
257
esac
258
env="$env _RLDN32_LIST=${root}3/$prefix$suffix"
259
case $_RLDN32_LIST in
260
"") env="$env:DEFAULT" ;;
261
*) env="$env:$_RLDN32_LIST" ;;
262
esac
263
env="$env _RLD_LIST=${root}2/$prefix$suffix"
264
case $_RLD_LIST in
265
"") env="$env:DEFAULT" ;;
266
*) env="$env:$_RLD_LIST" ;;
267
esac
268
;;
269
*) env="$env _RLD_LIST=${root}/$prefix$suffix"
270
case $_RLD_LIST in
271
"") env="$env:DEFAULT" ;;
272
*) env="$env:$_RLD_LIST" ;;
273
esac
274
esac
275
fi
276
;;
277
esac
278
279
: engage
280
281
case $show in
282
"") eval $env '$command "$@"' ;;
283
*) $show $env $command "$@" ;;
284
esac
285
286