f60e319464913caae57219ec3a494b0cf211d1f0
[platform/upstream/ltrace.git] / testsuite / ltrace.main / system_calls.exp
1 # This file is part of ltrace.
2 # Copyright (C) 2014 Petr Machata, Red Hat Inc.
3 # Copyright (C) 2006 Yao Qi <qiyao@cn.ibm.com>, IBM Corporation
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License as
7 # published by the Free Software Foundation; either version 2 of the
8 # License, or (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 # 02110-1301 USA
19
20 # Objectives: Verify that Ltrace can trace all the system calls in
21 # execution.  Note that this test is necessarily noisy.  Dynamic
22 # linker adds a bunch of system calls of its own.
23
24 set empty [ltraceCompile {} [ltraceSource c {
25     int main (void) { return 0; }
26 }]]
27
28 set bin [ltraceCompile {} [ltraceSource c {
29     #include <stdio.h>
30     #include <unistd.h>
31     #include <sys/syscall.h>
32     #include <sys/stat.h>
33     #include <errno.h>
34     #include <stdlib.h>
35
36     int
37     main ()
38     {
39       FILE* fp;
40       char s[]="system_calls";
41       char buffer[1024];
42       struct stat state;
43
44       fp = fopen ("system_calls.tmp", "w");
45       if (fp == NULL)
46         {
47           printf("Can not create system_calls.tmp\n");
48           exit (0);
49         }
50       fwrite(s, sizeof(s), 1, fp);
51       fseek (fp, 0, SEEK_CUR);
52       fread(buffer, sizeof(s), 1, fp);
53       fclose(fp);
54
55       getcwd (buffer, sizeof buffer);
56       chdir (".");
57       symlink ("system_calls.tmp", "system_calls.link");
58       remove("system_calls.link");
59       rename ("system_calls.tmp", "system_calls.tmp1");
60       stat ("system_calls.tmp", &state);
61       access ("system_calls.tmp", R_OK);
62       remove("system_calls.tmp1");
63
64       mkdir ("system_call_mkdir", 0777);
65       rmdir ("system_call_mkdir");
66
67       return 0;
68     }
69 }]]
70
71 proc Calls {logfile} {
72     set fp [open $logfile]
73     set ret {}
74
75     while {[gets $fp line] >= 0} {
76         if [regexp -- {^[a-zA-Z0-9]*@SYS} $line] {
77             set call [lindex [split $line @] 0]
78             dict incr ret $call
79         }
80     }
81
82     close $fp
83     return $ret
84 }
85
86 proc GetDefault {d key def} {
87     if {[dict exists $d $key]} {
88         return [dict get $d $key]
89     } else {
90         return $def
91     }
92 }
93
94 proc Diff {d1 d2} {
95     set keys [lsort -unique [concat [dict keys $d1] [dict keys $d2]]]
96     set ret {}
97     foreach key $keys {
98         set n1 [GetDefault $d1 $key 0]
99         set n2 [GetDefault $d2 $key 0]
100         set sum [expr $n1 - $n2]
101         if {[expr $sum != 0]} {
102                 dict set ret $key $sum
103         }
104     }
105     return $ret
106 }
107
108 proc Match {d patterns} {
109     foreach line $patterns {
110         set pattern [lindex $line 0]
111         set op [lindex $line 1]
112         set expect [lindex $line 2]
113
114         set count 0
115         foreach key [dict keys $d] {
116             if [regexp -- $pattern $key] {
117                 incr count [dict get $d $key]
118             }
119         }
120
121         set msgMain "$pattern was recorded $count times"
122
123         if {[eval expr $count $op $expect]} {
124             pass $msgMain
125         } else {
126             fail "$msgMain, expected $op $expect"
127         }
128     }
129 }
130
131 Match [Diff [Calls [ltraceRun -L -S -- $bin]] \
132            [Calls [ltraceRun -L -S -- $empty]]] {
133     { {^write$} == 1 }
134     { {^unlink(at)?$} >= 2 }
135     { {^open(at)?$} == 1 }
136     { {^(new|f)?stat(64)?$} == 1 }
137     { {^close$} == 1 }
138     { {^getcwd$} == 1 }
139     { {^chdir$} == 1 }
140     { {^symlink(at)?$} == 1 }
141     { {^f?access(at)?$} == 1 }
142     { {^rename(at)?$} == 1 }
143     { {^mkdir(at)?$} == 1 }
144 }
145
146 ltraceDone