This source file includes following definitions.
- sleep
- getwd
- getppid
- getlogin
- getuid
- geteuid
- getgid
- getegid
- setuid
- setregid
- getpwuid
- getpass
- fchown
- sys_fopen
- sys_chdir
- sys_mkdir
- convert_time
- is_exec
- stat
- lstat
- fstat
- sys_rename
- sys_open
- nl_langinfo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #define DEFER_MS_W32_H
24 #include <config.h>
25
26 #include <windows.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <time.h>
30 #include <direct.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <errno.h>
34 #include <ctype.h>
35 #include <sys/timeb.h>
36 #include <mbstring.h>
37 #include <locale.h>
38
39 #include <nl_types.h>
40 #include <langinfo.h>
41
42 #include "ntlib.h"
43
44 char *sys_ctime (const time_t *);
45 FILE *sys_fopen (const char *, const char *);
46 int sys_mkdir (const char *, mode_t);
47 int sys_chdir (const char *);
48 int mkostemp (char *, int);
49 int sys_rename (const char *, const char *);
50 int sys_open (const char *, int, int);
51
52
53
54 #ifndef _TIMEZONE_DEFINED
55 struct timezone
56 {
57 int tz_minuteswest;
58 int tz_dsttime;
59 };
60 #endif
61
62 #define MAXPATHLEN _MAX_PATH
63
64
65
66
67 unsigned
68 sleep (unsigned seconds)
69 {
70 Sleep (seconds * 1000);
71 return 0;
72 }
73
74
75 char *
76 getwd (char *dir)
77 {
78 if (GetCurrentDirectory (MAXPATHLEN, dir) > 0)
79 return dir;
80 return NULL;
81 }
82
83 static HANDLE getppid_parent;
84 static int getppid_ppid;
85
86 int
87 getppid (void)
88 {
89 char *ppid;
90 DWORD result;
91
92 ppid = getenv ("EM_PARENT_PROCESS_ID");
93 if (!ppid)
94 {
95 printf ("no pid.\n");
96 return 0;
97 }
98 else
99 {
100 getppid_ppid = atoi (ppid);
101 }
102
103 if (!getppid_parent)
104 {
105 getppid_parent = OpenProcess (SYNCHRONIZE, FALSE, atoi (ppid));
106 if (!getppid_parent)
107 {
108 printf ("Failed to open handle to parent process: %lu\n",
109 GetLastError ());
110 exit (1);
111 }
112 }
113
114 result = WaitForSingleObject (getppid_parent, 0);
115 switch (result)
116 {
117 case WAIT_TIMEOUT:
118
119 return getppid_ppid;
120 case WAIT_OBJECT_0:
121
122 return 1;
123 case WAIT_FAILED:
124 default:
125 printf ("Checking parent status failed: %lu\n", GetLastError ());
126 exit (1);
127 }
128 }
129
130 char *
131 getlogin (void)
132 {
133 static char user_name[256];
134 DWORD length = sizeof (user_name);
135
136 if (GetUserName (user_name, &length))
137 return user_name;
138 return NULL;
139 }
140
141 unsigned
142 getuid (void)
143 {
144 return 0;
145 }
146
147 unsigned
148 geteuid (void)
149 {
150 return getuid ();
151 }
152
153 unsigned
154 getgid (void)
155 {
156 return 0;
157 }
158
159 unsigned
160 getegid (void)
161 {
162 return 0;
163 }
164
165 int
166 setuid (unsigned uid)
167 {
168 return 0;
169 }
170
171 int
172 setregid (unsigned rgid, unsigned gid)
173 {
174 return 0;
175 }
176
177 struct passwd *
178 getpwuid (unsigned uid)
179 {
180 return NULL;
181 }
182
183 char *
184 getpass (const char * prompt)
185 {
186 static char input[256];
187 HANDLE in;
188 HANDLE err;
189 DWORD count;
190
191 in = GetStdHandle (STD_INPUT_HANDLE);
192 err = GetStdHandle (STD_ERROR_HANDLE);
193
194 if (in == INVALID_HANDLE_VALUE || err == INVALID_HANDLE_VALUE)
195 return NULL;
196
197 if (WriteFile (err, prompt, strlen (prompt), &count, NULL))
198 {
199 int istty = (GetFileType (in) == FILE_TYPE_CHAR);
200 DWORD old_flags;
201 int rc;
202
203 if (istty)
204 {
205 if (GetConsoleMode (in, &old_flags))
206 SetConsoleMode (in, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
207 else
208 istty = 0;
209 }
210 rc = ReadFile (in, input, sizeof (input), &count, NULL);
211 if (count >= 2 && input[count - 2] == '\r')
212 input[count - 2] = '\0';
213 else
214 {
215 char buf[256];
216 while (ReadFile (in, buf, sizeof (buf), &count, NULL) > 0)
217 if (count >= 2 && buf[count - 2] == '\r')
218 break;
219 }
220 WriteFile (err, "\r\n", 2, &count, NULL);
221 if (istty)
222 SetConsoleMode (in, old_flags);
223 if (rc)
224 return input;
225 }
226
227 return NULL;
228 }
229
230 int
231 fchown (int fd, unsigned uid, unsigned gid)
232 {
233 return 0;
234 }
235
236 FILE *
237 sys_fopen (const char * path, const char * mode)
238 {
239 return fopen (path, mode);
240 }
241
242 int
243 sys_chdir (const char * path)
244 {
245 return _chdir (path);
246 }
247
248 int
249 sys_mkdir (const char * path, mode_t mode)
250 {
251 return _mkdir (path);
252 }
253
254 static FILETIME utc_base_ft;
255 static long double utc_base;
256 static int init = 0;
257
258 static time_t
259 convert_time (FILETIME ft)
260 {
261 long double ret;
262
263 if (CompareFileTime (&ft, &utc_base_ft) < 0)
264 return 0;
265
266 ret = (long double) ft.dwHighDateTime
267 * 4096.0L * 1024.0L * 1024.0L + ft.dwLowDateTime;
268 ret -= utc_base;
269 return (time_t) (ret * 1e-7L);
270 }
271
272 static int
273 is_exec (const char * name)
274 {
275 char * p = strrchr (name, '.');
276 return
277 (p != NULL
278 && (stricmp (p, ".exe") == 0 ||
279 stricmp (p, ".com") == 0 ||
280 stricmp (p, ".bat") == 0 ||
281 stricmp (p, ".cmd") == 0));
282 }
283
284
285
286 int
287 stat (const char * path, struct stat * buf)
288 {
289 WIN32_FIND_DATA wfd;
290 HANDLE fh;
291 int permission;
292 int len;
293 int rootdir = FALSE;
294 char *name = alloca (FILENAME_MAX);
295
296 if (!init)
297 {
298
299 SYSTEMTIME st;
300
301 st.wYear = 1970;
302 st.wMonth = 1;
303 st.wDay = 1;
304 st.wHour = 0;
305 st.wMinute = 0;
306 st.wSecond = 0;
307 st.wMilliseconds = 0;
308
309 SystemTimeToFileTime (&st, &utc_base_ft);
310 utc_base = (long double) utc_base_ft.dwHighDateTime
311 * 4096.0L * 1024.0L * 1024.0L + utc_base_ft.dwLowDateTime;
312 init = 1;
313 }
314
315 if (path == NULL || buf == NULL || *path == '\0')
316 {
317 errno = EFAULT;
318 return -1;
319 }
320 if (_mbspbrk (path, "*?|<>\""))
321 {
322 errno = ENOENT;
323 return -1;
324 }
325
326 strcpy (name, path);
327
328
329
330 len = strlen (name);
331 rootdir = IS_DIRECTORY_SEP (name[0])
332 || (len == 3 && name[1] == ':' && IS_DIRECTORY_SEP (name[2]));
333 if (rootdir)
334 {
335 if (GetDriveType (name) < 2)
336 {
337 errno = ENOENT;
338 return -1;
339 }
340 memset (&wfd, 0, sizeof (wfd));
341 wfd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
342 wfd.ftCreationTime = utc_base_ft;
343 wfd.ftLastAccessTime = utc_base_ft;
344 wfd.ftLastWriteTime = utc_base_ft;
345 strcpy (wfd.cFileName, name);
346 }
347 else
348 {
349 if (IS_DIRECTORY_SEP (name[len-1]))
350 name[len - 1] = 0;
351
352 fh = FindFirstFile (name, &wfd);
353 if (fh == INVALID_HANDLE_VALUE)
354 {
355 errno = ENOENT;
356 return -1;
357 }
358 FindClose (fh);
359 }
360 buf->st_mode = (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ?
361 S_IFDIR : S_IFREG;
362 buf->st_nlink = 1;
363 buf->st_ino = 0;
364
365 if (name[0] && name[1] == ':')
366 buf->st_dev = tolower (name[0]) - 'a' + 1;
367 else
368 buf->st_dev = _getdrive ();
369 buf->st_rdev = buf->st_dev;
370
371 buf->st_size = wfd.nFileSizeHigh;
372 buf->st_size <<= 32;
373 buf->st_size += wfd.nFileSizeLow;
374
375
376 buf->st_mtime = convert_time (wfd.ftLastWriteTime);
377 buf->st_atime = convert_time (wfd.ftLastAccessTime);
378 if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
379 buf->st_ctime = convert_time (wfd.ftCreationTime);
380 if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
381
382
383 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
384 permission = S_IREAD;
385 else
386 permission = S_IREAD | S_IWRITE;
387
388 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
389 permission |= S_IEXEC;
390 else if (is_exec (name))
391 permission |= S_IEXEC;
392
393 buf->st_mode |= permission | (permission >> 3) | (permission >> 6);
394
395 return 0;
396 }
397
398 int
399 lstat (const char * path, struct stat * buf)
400 {
401 return stat (path, buf);
402 }
403
404 int
405 fstat (int desc, struct stat * buf)
406 {
407 HANDLE fh = (HANDLE) _get_osfhandle (desc);
408 BY_HANDLE_FILE_INFORMATION info;
409 unsigned __int64 fake_inode;
410 int permission;
411
412 if (!init)
413 {
414
415 SYSTEMTIME st;
416
417 st.wYear = 1970;
418 st.wMonth = 1;
419 st.wDay = 1;
420 st.wHour = 0;
421 st.wMinute = 0;
422 st.wSecond = 0;
423 st.wMilliseconds = 0;
424
425 SystemTimeToFileTime (&st, &utc_base_ft);
426 utc_base = (long double) utc_base_ft.dwHighDateTime
427 * 4096.0L * 1024.0L * 1024.0L + utc_base_ft.dwLowDateTime;
428 init = 1;
429 }
430
431 switch (GetFileType (fh) & ~FILE_TYPE_REMOTE)
432 {
433 case FILE_TYPE_DISK:
434 buf->st_mode = S_IFREG;
435 if (!GetFileInformationByHandle (fh, &info))
436 {
437 errno = EACCES;
438 return -1;
439 }
440 break;
441 case FILE_TYPE_PIPE:
442 buf->st_mode = S_IFIFO;
443 goto non_disk;
444 case FILE_TYPE_CHAR:
445 case FILE_TYPE_UNKNOWN:
446 default:
447 buf->st_mode = S_IFCHR;
448 non_disk:
449 memset (&info, 0, sizeof (info));
450 info.dwFileAttributes = 0;
451 info.ftCreationTime = utc_base_ft;
452 info.ftLastAccessTime = utc_base_ft;
453 info.ftLastWriteTime = utc_base_ft;
454 }
455
456 if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
457 buf->st_mode = S_IFDIR;
458
459 buf->st_nlink = info.nNumberOfLinks;
460
461
462
463 fake_inode = info.nFileIndexHigh;
464 fake_inode <<= 32;
465 fake_inode += info.nFileIndexLow;
466 buf->st_ino = fake_inode;
467
468 buf->st_dev = info.dwVolumeSerialNumber;
469 buf->st_rdev = info.dwVolumeSerialNumber;
470
471 buf->st_size = info.nFileSizeHigh;
472 buf->st_size <<= 32;
473 buf->st_size += info.nFileSizeLow;
474
475
476 buf->st_mtime = convert_time (info.ftLastWriteTime);
477 buf->st_atime = convert_time (info.ftLastAccessTime);
478 if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
479 buf->st_ctime = convert_time (info.ftCreationTime);
480 if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
481
482
483 if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
484 permission = S_IREAD;
485 else
486 permission = S_IREAD | S_IWRITE;
487
488 if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
489 permission |= S_IEXEC;
490
491 buf->st_mode |= permission | (permission >> 3) | (permission >> 6);
492
493 return 0;
494 }
495
496
497 int
498 sys_rename (const char *from, const char *to)
499 {
500 int retval = rename (from, to);
501
502 if (retval < 0 && errno == EEXIST)
503 {
504 if (unlink (to) == 0)
505 retval = rename (from, to);
506 }
507 return retval;
508 }
509
510 int
511 sys_open (const char * path, int oflag, int mode)
512 {
513 return _open (path, oflag, mode);
514 }
515
516
517
518 char *
519 nl_langinfo (nl_item item)
520 {
521 switch (item)
522 {
523 case CODESET:
524 {
525
526
527 static char buf[2 + 10 + 1];
528 char const *locale = setlocale (LC_CTYPE, NULL);
529 char *codeset = buf;
530 size_t codesetlen;
531 codeset[0] = '\0';
532
533 if (locale && locale[0])
534 {
535
536
537 char *dot = strchr (locale, '.');
538
539 if (dot)
540 {
541
542
543 char *codeset_start = dot + 1;
544 char const *modifier = strchr (codeset_start, '@');
545
546 if (! modifier)
547 codeset = codeset_start;
548 else
549 {
550 codesetlen = modifier - codeset_start;
551 if (codesetlen < sizeof buf)
552 {
553 codeset = memcpy (buf, codeset_start, codesetlen);
554 codeset[codesetlen] = '\0';
555 }
556 }
557 }
558 }
559
560
561
562
563
564
565 codesetlen = strlen (codeset);
566 if (0 < codesetlen && codesetlen < sizeof buf - 2)
567 memmove (buf + 2, codeset, codesetlen + 1);
568 else
569 sprintf (buf + 2, "%u", GetACP ());
570 codeset = memcpy (buf, "CP", 2);
571
572 return codeset;
573 }
574 default:
575 return (char *) "";
576 }
577 }