b2aeed00964b2dca7f9a9eccab1695427ca6b14c
[mirror_edk2.git] / EdkUnixPkg / Sec / UnixThunk.c
1 /*++
2
3 Copyright (c) 2004 - 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 UnixThunk.c
15
16 Abstract:
17
18 Since the SEC is the only program in our emulation we
19 must use a Tiano mechanism to export APIs to other modules.
20 This is the role of the EFI_UNIX_THUNK_PROTOCOL.
21
22 The mUnixThunkTable exists so that a change to EFI_UNIX_THUNK_PROTOCOL
23 will cause an error in initializing the array if all the member functions
24 are not added. It looks like adding a element to end and not initializing
25 it may cause the table to be initaliized with the members at the end being
26 set to zero. This is bad as jumping to zero will crash.
27
28
29 gUnix is a a public exported global that contains the initialized
30 data.
31
32 --*/
33
34 #include "SecMain.h"
35 #include "Library/UnixLib.h"
36 #include <sys/time.h>
37 #include <time.h>
38 #include <signal.h>
39 #include <string.h>
40 #include <stdlib.h>
41 #include <termio.h>
42 #ifdef __INSIDE_CYGWIN__
43 extern ioctl (int fd, unsigned long int __request, ...);
44 #endif
45 static int settimer_initialized;
46 static struct timeval settimer_timeval;
47 static void (*settimer_callback)(UINT64 delta);
48
49 static void
50 settimer_handler (int sig)
51 {
52 struct timeval timeval;
53 UINT64 delta;
54
55 gettimeofday (&timeval, NULL);
56 delta = ((UINT64)timeval.tv_sec * 1000) + (timeval.tv_usec / 1000)
57 - ((UINT64)settimer_timeval.tv_sec * 1000)
58 - (settimer_timeval.tv_usec / 1000);
59 settimer_timeval = timeval;
60 if (settimer_callback)
61 (*settimer_callback)(delta);
62 }
63
64 static
65 VOID
66 SetTimer (UINT64 PeriodMs, VOID (*CallBack)(UINT64 DeltaMs))
67 {
68 struct itimerval timerval;
69
70 if (!settimer_initialized) {
71 struct sigaction act;
72
73 settimer_initialized = 1;
74 act.sa_handler = settimer_handler;
75 act.sa_flags = 0;
76 sigemptyset (&act.sa_mask);
77 if (sigaction (SIGALRM, &act, NULL) != 0) {
78 printf ("SetTimer: sigaction error %s\n", strerror (errno));
79 }
80 if (gettimeofday (&settimer_timeval, NULL) != 0) {
81 printf ("SetTimer: gettimeofday error %s\n", strerror (errno));
82 }
83 }
84 timerval.it_value.tv_sec = PeriodMs / 1000;
85 timerval.it_value.tv_usec = (PeriodMs % 1000) * 1000;
86 timerval.it_value.tv_sec = PeriodMs / 1000;
87 timerval.it_interval = timerval.it_value;
88
89 if (setitimer (ITIMER_REAL, &timerval, NULL) != 0) {
90 printf ("SetTimer: setitimer error %s\n", strerror (errno));
91 }
92 settimer_callback = CallBack;
93 }
94
95 void
96 msSleep (unsigned long Milliseconds)
97 {
98 struct timespec ts;
99
100 ts.tv_sec = Milliseconds / 1000;
101 ts.tv_nsec = (Milliseconds % 1000) * 1000000;
102
103 while (nanosleep (&ts, &ts) != 0 && errno == EINTR)
104 ;
105 }
106
107 void
108 GetLocalTime (EFI_TIME *Time)
109 {
110 struct tm *tm;
111 time_t t;
112
113 t = time (NULL);
114 tm = localtime (&t);
115
116 Time->Year = 1900 + tm->tm_year;
117 Time->Month = tm->tm_mon;
118 Time->Day = tm->tm_mday;
119 Time->Hour = tm->tm_hour;
120 Time->Minute = tm->tm_min;
121 Time->Second = tm->tm_sec;
122 Time->Nanosecond = 0;
123 Time->TimeZone = timezone;
124 Time->Daylight = (daylight ? EFI_TIME_ADJUST_DAYLIGHT : 0)
125 | (tm->tm_isdst > 0 ? EFI_TIME_IN_DAYLIGHT : 0);
126 }
127
128 static void
129 TzSet (void)
130 {
131 static int done = 0;
132 if (!done) {
133 tzset ();
134 done = 1;
135 }
136 }
137
138 long
139 GetTimeZone(void)
140 {
141 TzSet ();
142 return timezone;
143 }
144
145 int
146 GetDayLight(void)
147 {
148 TzSet ();
149 return daylight;
150 }
151
152 int
153 GetErrno(void)
154 {
155 return errno;
156 }
157
158 extern EFI_STATUS
159 UgaCreate(struct _EFI_UNIX_UGA_IO_PROTOCOL **UgaIo, CONST CHAR16 *Title);
160
161 EFI_UNIX_THUNK_PROTOCOL mUnixThunkTable = {
162 EFI_UNIX_THUNK_PROTOCOL_SIGNATURE,
163 msSleep, /* Sleep */
164 exit, /* Exit */
165 SetTimer,
166 GetLocalTime,
167 gmtime,
168 GetTimeZone,
169 GetDayLight,
170 (UnixPoll)poll,
171 (UnixRead)read,
172 (UnixWrite)write,
173 getenv,
174 (UnixOpen)open,
175 lseek,
176 ftruncate,
177 close,
178 mkdir,
179 rmdir,
180 unlink,
181 GetErrno,
182 opendir,
183 rewinddir,
184 readdir,
185 closedir,
186 stat,
187 statfs,
188 rename,
189 mktime,
190 fsync,
191 chmod,
192 utime,
193 tcflush,
194 UgaCreate,
195 perror,
196 ioctl,
197 fcntl,
198 cfsetispeed,
199 cfsetospeed,
200 tcgetattr,
201 tcsetattr
202 };
203
204
205 EFI_UNIX_THUNK_PROTOCOL *gUnix = &mUnixThunkTable;