1 #include <test.h>
2 
3 #include <compiler.h>
4 #include <process_lib.h>
5 #include <process_unix_priv.h>
6 
7 /*
8  * procfs.h is not 64-bit off_t clean, but the only affected structure is
9  * priovec, which we don't use. Hence we may work around #error in sys/procfs.h
10  * by lying that we are not compiling with large file support (while we do).
11  */
12 #define _FILE_OFFSET_BITS 32
13 
14 #include <procfs.h>
15 
open(const char * filename,int flags,...)16 int open(const char *filename, int flags, ...)
17 {
18     if (!strcmp(filename, "/proc/1/psinfo"))
19     {
20         return 1;
21     }
22 
23     if (!strcmp(filename, "/proc/1/status"))
24     {
25         return 101;
26     }
27 
28     if (!strcmp(filename, "/proc/2/status"))
29     {
30         return 102;
31     }
32 
33     if (!strcmp(filename, "/proc/3/status"))
34     {
35         return 103;
36     }
37 
38     errno = ENOENT;
39     return -1;
40 }
41 
42 int fdpos[4];
43 
read(int fd,void * buf,size_t bufsize)44 ssize_t read(int fd, void *buf, size_t bufsize)
45 {
46     if (fd == 1)
47     {
48         if (fdpos[0] == 0)
49         {
50             psinfo_t psinfo;
51             psinfo.pr_start.tv_sec = 100;
52             memcpy(buf, &psinfo, sizeof(psinfo));
53             fdpos[0] = sizeof(psinfo);
54             return sizeof(psinfo);
55         }
56         else
57         {
58             return 0;
59         }
60     }
61 
62     if (fd == 101)
63     {
64         if (fdpos[1] == 0)
65         {
66             pstatus_t pstatus;
67             pstatus.pr_nlwp = 1;
68             pstatus.pr_lwp.pr_flags = PR_STOPPED;
69             pstatus.pr_lwp.pr_why = PR_SIGNALLED;
70             memcpy(buf, &pstatus, sizeof(pstatus));
71             fdpos[1] = sizeof(pstatus);
72             return sizeof(pstatus);
73         }
74         else
75         {
76             return 0;
77         }
78     }
79 
80     if (fd == 102)
81     {
82         if (fdpos[2] == 0)
83         {
84             pstatus_t pstatus;
85             pstatus.pr_nlwp = 1;
86             pstatus.pr_lwp.pr_flags = 0;
87             pstatus.pr_lwp.pr_why = 0;
88             memcpy(buf, &pstatus, sizeof(pstatus));
89             fdpos[2] = sizeof(pstatus);
90             return sizeof(pstatus);
91         }
92         else
93         {
94             return 0;
95         }
96     }
97 
98     if (fd == 103)
99     {
100         if (fdpos[3] == 0)
101         {
102             /* Currently this is unused, the test is switched off. */
103 
104             pstatus_t pstatus;
105             pstatus.pr_nlwp = 0;                                /* zombie */
106             memcpy(buf, &pstatus, sizeof(pstatus));
107             fdpos[3] = sizeof(pstatus);
108             return sizeof(pstatus);
109         }
110         else
111         {
112             return 0;
113         }
114     }
115 
116     errno = EIO;
117     return -1;
118 }
119 
close(int fd)120 int close(int fd)
121 {
122     return 0;
123 }
124 
test_get_start_time_process1(void)125 static void test_get_start_time_process1(void)
126 {
127     time_t t = GetProcessStartTime(1);
128     assert_int_equal(t, 100);
129 }
130 
test_get_start_time_process2(void)131 static void test_get_start_time_process2(void)
132 {
133     time_t t = GetProcessStartTime(2);
134     assert_int_equal(t, PROCESS_START_TIME_UNKNOWN);
135 }
136 
test_get_state_process1(void)137 static void test_get_state_process1(void)
138 {
139     ProcessState s = GetProcessState(1);
140     assert_int_equal(s, PROCESS_STATE_STOPPED);
141 }
142 
test_get_state_process2(void)143 static void test_get_state_process2(void)
144 {
145     ProcessState s = GetProcessState(2);
146     assert_int_equal(s, PROCESS_STATE_RUNNING);
147 }
148 
test_get_state_process3(void)149 static void test_get_state_process3(void)
150 {
151     ProcessState s = GetProcessState(3);
152     assert_int_equal(s, PROCESS_STATE_ZOMBIE);
153 }
154 
test_get_state_process4(void)155 static void test_get_state_process4(void)
156 {
157     ProcessState s = GetProcessState(4);
158     assert_int_equal(s, PROCESS_STATE_DOES_NOT_EXIST);
159 }
160 
main()161 int main()
162 {
163     PRINT_TEST_BANNER();
164 
165     const UnitTest tests[] =
166     {
167         unit_test(test_get_start_time_process1),
168         unit_test(test_get_start_time_process2),
169         unit_test(test_get_state_process1),
170         unit_test(test_get_state_process2),
171         /* TODO zombie process unit test for solaris is not currently working
172          * because of the huge amount of hacks needed to actually figure out
173          * if a process is zombie, see libpromises/process_solaris.c. */
174 //        unit_test(test_get_state_process3),
175     };
176 
177     return run_tests(tests);
178 }
179