9803
|
1 /* Utility and Unix shadow routines for GNU Emacs on Windows NT.
|
11384
|
2 Copyright (C) 1994, 1995 Free Software Foundation, Inc.
|
9803
|
3
|
|
4 This file is part of GNU Emacs.
|
|
5
|
|
6 GNU Emacs is free software; you can redistribute it and/or modify it
|
|
7 under the terms of the GNU General Public License as published by the
|
11384
|
8 Free Software Foundation; either version 2, or (at your option) any later
|
9803
|
9 version.
|
|
10
|
|
11 GNU Emacs is distributed in the hope that it will be useful, but WITHOUT
|
|
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
14 more details.
|
|
15
|
|
16 You should have received a copy of the GNU General Public License along
|
|
17 with GNU Emacs; see the file COPYING. If not, write to the Free Software
|
|
18 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
19
|
|
20 Geoff Voelker (voelker@cs.washington.edu) 7-29-94
|
|
21 */
|
|
22
|
11384
|
23 /* Define stat before including config.h. */
|
|
24 #include <string.h>
|
|
25 #include <sys/stat.h>
|
|
26 int
|
|
27 nt_stat (char *filename, struct stat *statbuf)
|
|
28 {
|
|
29 int r, l = strlen (filename);
|
|
30 char *str = NULL;
|
|
31 extern long *xmalloc ();
|
|
32 extern void xfree ();
|
|
33
|
|
34 /* stat has a bug when passed a name of a directory with a trailing
|
|
35 backslash (but a trailing forward slash works fine). */
|
|
36 if (filename[l - 1] == '\\')
|
|
37 {
|
|
38 str = (char *) xmalloc (l + 1);
|
|
39 strcpy (str, filename);
|
|
40 str[l - 1] = '/';
|
|
41 r = stat (str, statbuf);
|
|
42 xfree (str);
|
|
43 return r;
|
|
44 }
|
|
45 else
|
|
46 return stat (filename, statbuf);
|
|
47 }
|
|
48
|
|
49 /* Place a wrapper around the NT version of ctime. It returns NULL
|
|
50 on network directories, so we handle that case here.
|
|
51 Define it before including config.h. (Ulrich Leodolter, 1/11/95). */
|
|
52 char *
|
|
53 nt_ctime (const time_t *t)
|
|
54 {
|
|
55 char *str = (char *) ctime (t);
|
|
56 return (str ? str : "Sun Jan 01 00:00:00 1970");
|
|
57 }
|
|
58
|
9803
|
59 #include <windows.h>
|
|
60 #include <stdlib.h>
|
|
61 #include <stdio.h>
|
|
62 #include <io.h>
|
|
63 #include <fcntl.h>
|
|
64 #include <ctype.h>
|
|
65
|
|
66 #include "config.h"
|
|
67 #define getwd _getwd
|
|
68 #include "lisp.h"
|
|
69 #undef getwd
|
|
70
|
|
71 #include <pwd.h>
|
|
72
|
|
73 #include "ndir.h"
|
|
74 #include "ntheap.h"
|
|
75
|
|
76 extern int report_file_error (char *, Lisp_Object);
|
|
77
|
|
78 /* Get the current working directory. */
|
|
79 int
|
|
80 getwd (char *dir)
|
|
81 {
|
|
82 return GetCurrentDirectory (MAXPATHLEN, dir);
|
|
83 }
|
|
84
|
|
85 /* Emulate gethostname. */
|
|
86 int
|
|
87 gethostname (char *buffer, int size)
|
|
88 {
|
|
89 /* NT only allows small host names, so the buffer is
|
|
90 certainly large enough. */
|
|
91 return !GetComputerName (buffer, &size);
|
|
92 }
|
|
93
|
|
94 /* Emulate getloadavg. */
|
|
95 int
|
|
96 getloadavg (double loadavg[], int nelem)
|
|
97 {
|
|
98 int i;
|
|
99
|
|
100 /* A faithful emulation is going to have to be saved for a rainy day. */
|
|
101 for (i = 0; i < nelem; i++)
|
|
102 {
|
|
103 loadavg[i] = 0.0;
|
|
104 }
|
|
105 return i;
|
|
106 }
|
|
107
|
|
108 /* Emulate sleep...we could have done this with a define, but that
|
|
109 would necessitate including windows.h in the files that used it.
|
|
110 This is much easier. */
|
|
111 void
|
|
112 nt_sleep (int seconds)
|
|
113 {
|
|
114 Sleep (seconds * 1000);
|
|
115 }
|
|
116
|
|
117 /* Emulate the Unix directory procedures opendir, closedir,
|
|
118 and readdir. We can't use the procedures supplied in sysdep.c,
|
|
119 so we provide them here. */
|
|
120
|
|
121 struct direct dir_static; /* simulated directory contents */
|
|
122 static int dir_finding;
|
|
123 static HANDLE dir_find_handle;
|
|
124
|
|
125 DIR *
|
|
126 opendir (char *filename)
|
|
127 {
|
|
128 DIR *dirp;
|
|
129
|
|
130 /* Opening is done by FindFirstFile. However, a read is inherent to
|
|
131 this operation, so we have a flag to handle the open at read
|
|
132 time. This flag essentially means "there is a find-handle open and
|
|
133 it needs to be closed." */
|
|
134
|
|
135 if (!(dirp = (DIR *) malloc (sizeof (DIR))))
|
|
136 {
|
|
137 return 0;
|
|
138 }
|
|
139
|
|
140 dirp->dd_fd = 0;
|
|
141 dirp->dd_loc = 0;
|
|
142 dirp->dd_size = 0;
|
|
143
|
|
144 /* This is tacky, but we need the directory name for our
|
|
145 implementation of readdir. */
|
|
146 strncpy (dirp->dd_buf, filename, DIRBLKSIZ);
|
|
147 return dirp;
|
|
148 }
|
|
149
|
|
150 void
|
|
151 closedir (DIR *dirp)
|
|
152 {
|
|
153 /* If we have a find-handle open, close it. */
|
|
154 if (dir_finding)
|
|
155 {
|
|
156 FindClose (dir_find_handle);
|
|
157 dir_finding = 0;
|
|
158 }
|
|
159 xfree ((char *) dirp);
|
|
160 }
|
|
161
|
|
162 struct direct *
|
|
163 readdir (DIR *dirp)
|
|
164 {
|
|
165 WIN32_FIND_DATA find_data;
|
|
166
|
|
167 /* If we aren't dir_finding, do a find-first, otherwise do a find-next. */
|
|
168 if (!dir_finding)
|
|
169 {
|
|
170 char filename[MAXNAMLEN + 3];
|
|
171 int ln;
|
|
172
|
|
173 strncpy (filename, dirp->dd_buf, MAXNAMLEN);
|
|
174 ln = strlen (filename)-1;
|
|
175 if (filename[ln] != '\\' && filename[ln] != ':')
|
|
176 strcat (filename, "\\");
|
|
177 strcat (filename, "*.*");
|
|
178
|
|
179 dir_find_handle = FindFirstFile (filename, &find_data);
|
|
180
|
|
181 if (dir_find_handle == INVALID_HANDLE_VALUE)
|
|
182 return NULL;
|
|
183
|
|
184 dir_finding = 1;
|
|
185 }
|
|
186 else
|
|
187 {
|
|
188 if (!FindNextFile (dir_find_handle, &find_data))
|
|
189 return NULL;
|
|
190 }
|
|
191
|
|
192 /* NT's unique ID for a file is 64 bits, so we have to fake it here.
|
|
193 This should work as long as we never use 0. */
|
|
194 dir_static.d_ino = 1;
|
|
195
|
|
196 dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 +
|
|
197 dir_static.d_namlen - dir_static.d_namlen % 4;
|
|
198
|
|
199 dir_static.d_namlen = strlen (find_data.cFileName);
|
|
200 strncpy (dir_static.d_name, find_data.cFileName, MAXNAMLEN);
|
|
201
|
|
202 return &dir_static;
|
|
203 }
|
|
204
|
|
205 /* Emulate getpwuid and getpwnam. */
|
|
206
|
|
207 int getuid (); /* forward declaration */
|
|
208
|
|
209 static char the_passwd_name[256];
|
|
210 static char the_passwd_passwd[256];
|
|
211 static char the_passwd_gecos[256];
|
|
212 static char the_passwd_dir[256];
|
|
213 static char the_passwd_shell[256];
|
|
214
|
|
215 static struct passwd the_passwd =
|
|
216 {
|
|
217 the_passwd_name,
|
|
218 the_passwd_passwd,
|
|
219 0,
|
|
220 0,
|
|
221 0,
|
|
222 the_passwd_gecos,
|
|
223 the_passwd_dir,
|
|
224 the_passwd_shell,
|
|
225 };
|
|
226
|
|
227 struct passwd *
|
|
228 getpwuid (int uid)
|
|
229 {
|
|
230 int size = 256;
|
|
231
|
|
232 if (!GetUserName (the_passwd.pw_name, &size))
|
|
233 return NULL;
|
|
234
|
|
235 the_passwd.pw_passwd[0] = '\0';
|
|
236 the_passwd.pw_uid = 0;
|
|
237 the_passwd.pw_gid = 0;
|
|
238 strcpy (the_passwd.pw_gecos, the_passwd.pw_name);
|
|
239 the_passwd.pw_dir[0] = '\0';
|
|
240 the_passwd.pw_shell[0] = '\0';
|
|
241
|
|
242 return &the_passwd;
|
|
243 }
|
|
244
|
|
245 struct passwd *
|
|
246 getpwnam (char *name)
|
|
247 {
|
|
248 struct passwd *pw;
|
|
249
|
|
250 pw = getpwuid (getuid ());
|
|
251 if (!pw)
|
|
252 return pw;
|
|
253
|
|
254 if (strcmp (name, pw->pw_name))
|
|
255 return NULL;
|
|
256
|
|
257 return pw;
|
|
258 }
|
|
259
|
|
260
|
|
261 /* We don't have scripts to automatically determine the system configuration
|
|
262 for Emacs before it's compiled, and we don't want to have to make the
|
|
263 user enter it, so we define EMACS_CONFIGURATION to invoke this runtime
|
|
264 routine. */
|
|
265
|
|
266 static char configuration_buffer[16];
|
|
267
|
|
268 char *
|
|
269 get_emacs_configuration (void)
|
|
270 {
|
|
271 char *arch, *oem;
|
|
272
|
|
273 /* Determine the processor type. */
|
|
274 switch (get_processor_type ())
|
|
275 {
|
|
276 case PROCESSOR_INTEL_386:
|
|
277 case PROCESSOR_INTEL_486:
|
|
278 case PROCESSOR_INTEL_PENTIUM:
|
|
279 arch = "i386";
|
|
280 break;
|
|
281 case PROCESSOR_INTEL_860:
|
|
282 arch = "i860";
|
|
283 break;
|
|
284 case PROCESSOR_MIPS_R2000:
|
|
285 case PROCESSOR_MIPS_R3000:
|
|
286 case PROCESSOR_MIPS_R4000:
|
|
287 arch = "mips";
|
|
288 break;
|
|
289 case PROCESSOR_ALPHA_21064:
|
|
290 arch = "alpha";
|
|
291 break;
|
|
292 default:
|
|
293 arch = "unknown";
|
|
294 break;
|
|
295 }
|
|
296
|
|
297 /* Let oem be "*" until we figure out how to decode the OEM field. */
|
|
298 oem = "*";
|
|
299
|
|
300 sprintf (configuration_buffer, "%s-%s-nt%d.%d", arch, oem,
|
|
301 get_nt_major_version (), get_nt_minor_version ());
|
|
302 return configuration_buffer;
|
|
303 }
|
|
304
|
|
305 /* Conjure up inode and device numbers that will serve the purpose
|
|
306 of Emacs. Return 1 upon success, 0 upon failure. */
|
|
307 int
|
|
308 get_inode_and_device_vals (Lisp_Object filename, Lisp_Object *p_inode,
|
|
309 Lisp_Object *p_device)
|
|
310 {
|
|
311 /* File uids on NT are found using a handle to a file, which
|
|
312 implies that it has been opened. Since we want to be able
|
|
313 to stat an arbitrary file, we must open it, get the info,
|
|
314 and then close it.
|
|
315
|
|
316 Also, NT file uids are 64-bits. This is a problem. */
|
|
317
|
|
318 HANDLE handle;
|
|
319 BOOL result;
|
11384
|
320 DWORD attrs;
|
9803
|
321 BY_HANDLE_FILE_INFORMATION info;
|
|
322
|
11384
|
323 /* We have to stat files and directories differently, so check
|
|
324 to see what filename references. */
|
|
325 attrs = GetFileAttributes (XSTRING (filename)->data);
|
|
326 if (attrs == 0xFFFFFFFF) {
|
|
327 return 0;
|
|
328 }
|
|
329 if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
|
|
330 /* Conjure up bogus, but unique, values. */
|
|
331 attrs = GetTickCount ();
|
|
332 *p_inode = make_number (attrs);
|
|
333 *p_device = make_number (attrs);
|
|
334 return 1;
|
|
335 }
|
|
336
|
9803
|
337 /* FIXME: It shouldn't be opened without READ access, but NT on x86
|
|
338 doesn't allow GetFileInfo in that case (NT on mips does). */
|
|
339
|
|
340 handle = CreateFile (XSTRING (filename)->data,
|
|
341 GENERIC_READ,
|
|
342 FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
343 NULL,
|
|
344 OPEN_EXISTING,
|
|
345 FILE_ATTRIBUTE_NORMAL,
|
|
346 NULL);
|
|
347 if (handle == INVALID_HANDLE_VALUE)
|
|
348 return 0;
|
|
349
|
|
350 result = GetFileInformationByHandle (handle, &info);
|
|
351 CloseHandle (handle);
|
|
352 if (!result)
|
|
353 return 0;
|
|
354
|
|
355 *p_inode = make_number (info.nFileIndexLow); /* use the low value */
|
|
356 *p_device = make_number (info.dwVolumeSerialNumber);
|
|
357
|
|
358 return 1;
|
|
359 }
|
|
360
|
|
361 /* The following pipe routines are used to support our fork emulation.
|
|
362 Since NT's crt dup always creates inherited handles, we
|
|
363 must be careful in setting up pipes. First create
|
|
364 non-inherited pipe handles, then create an inherited handle
|
|
365 to the write end by dup-ing it, and then close the non-inherited
|
|
366 end that was just duped. This gives us one non-inherited handle
|
|
367 on the read end and one inherited handle to the write end. As
|
|
368 the parent, we close the inherited handle to the write end after
|
|
369 spawning the child. */
|
|
370
|
|
371 /* From callproc.c */
|
|
372 extern Lisp_Object Vbinary_process_input;
|
|
373 extern Lisp_Object Vbinary_process_output;
|
|
374
|
|
375 void
|
|
376 pipe_with_inherited_out (int fds[2])
|
|
377 {
|
|
378 int inherit_out;
|
|
379 unsigned int flags = _O_NOINHERIT;
|
|
380
|
|
381 if (!NILP (Vbinary_process_output))
|
|
382 flags |= _O_BINARY;
|
|
383
|
|
384 _pipe (fds, 0, flags);
|
|
385 inherit_out = dup (fds[1]);
|
|
386 close (fds[1]);
|
|
387 fds[1] = inherit_out;
|
|
388 }
|
|
389
|
|
390 void
|
|
391 pipe_with_inherited_in (int fds[2])
|
|
392 {
|
|
393 int inherit_in;
|
|
394 unsigned int flags = _O_NOINHERIT;
|
|
395
|
|
396 if (!NILP (Vbinary_process_input))
|
|
397 flags |= _O_BINARY;
|
|
398
|
|
399 _pipe (fds, 0, flags);
|
|
400 inherit_in = dup (fds[0]);
|
|
401 close (fds[0]);
|
|
402 fds[0] = inherit_in;
|
|
403 }
|
|
404
|
|
405 /* The following two routines are used to manipulate stdin, stdout, and
|
|
406 stderr of our child processes.
|
|
407
|
|
408 Assuming that in, out, and err are inherited, we make them stdin,
|
|
409 stdout, and stderr of the child as follows:
|
|
410
|
|
411 - Save the parent's current standard handles.
|
|
412 - Set the parent's standard handles to the handles being passed in.
|
|
413 (Note that _get_osfhandle is an io.h procedure that
|
|
414 maps crt file descriptors to NT file handles.)
|
|
415 - Spawn the child, which inherits in, out, and err as stdin,
|
|
416 stdout, and stderr. (see Spawnve)
|
|
417 - Reset the parent's standard handles to the saved handles.
|
|
418 (see reset_standard_handles)
|
|
419 We assume that the caller closes in, out, and err after calling us. */
|
|
420
|
|
421 void
|
|
422 prepare_standard_handles (int in, int out, int err, HANDLE handles[4])
|
|
423 {
|
|
424 HANDLE parent, stdin_save, stdout_save, stderr_save, err_handle;
|
|
425
|
|
426 parent = GetCurrentProcess ();
|
|
427 if (!DuplicateHandle (parent,
|
|
428 GetStdHandle (STD_INPUT_HANDLE),
|
|
429 parent,
|
|
430 &stdin_save,
|
|
431 0,
|
|
432 FALSE,
|
|
433 DUPLICATE_SAME_ACCESS))
|
|
434 report_file_error ("Duplicating parent's input handle", Qnil);
|
|
435
|
|
436 if (!DuplicateHandle (parent,
|
|
437 GetStdHandle (STD_OUTPUT_HANDLE),
|
|
438 parent,
|
|
439 &stdout_save,
|
|
440 0,
|
|
441 FALSE,
|
|
442 DUPLICATE_SAME_ACCESS))
|
|
443 report_file_error ("Duplicating parent's output handle", Qnil);
|
|
444
|
|
445 if (!DuplicateHandle (parent,
|
|
446 GetStdHandle (STD_ERROR_HANDLE),
|
|
447 parent,
|
|
448 &stderr_save,
|
|
449 0,
|
|
450 FALSE,
|
|
451 DUPLICATE_SAME_ACCESS))
|
|
452 report_file_error ("Duplicating parent's error handle", Qnil);
|
|
453
|
|
454 if (!SetStdHandle (STD_INPUT_HANDLE, (HANDLE) _get_osfhandle (in)))
|
|
455 report_file_error ("Changing stdin handle", Qnil);
|
|
456
|
|
457 if (!SetStdHandle (STD_OUTPUT_HANDLE, (HANDLE) _get_osfhandle (out)))
|
|
458 report_file_error ("Changing stdout handle", Qnil);
|
|
459
|
|
460 /* We lose data if we use the same handle to the pipe for stdout and
|
|
461 stderr, so make a duplicate. This took a while to find. */
|
|
462 if (out == err)
|
|
463 {
|
|
464 if (!DuplicateHandle (parent,
|
|
465 (HANDLE) _get_osfhandle (err),
|
|
466 parent,
|
|
467 &err_handle,
|
|
468 0,
|
|
469 TRUE,
|
|
470 DUPLICATE_SAME_ACCESS))
|
|
471 report_file_error ("Duplicating out handle to make err handle.",
|
|
472 Qnil);
|
|
473 }
|
|
474 else
|
|
475 {
|
|
476 err_handle = (HANDLE) _get_osfhandle (err);
|
|
477 }
|
|
478
|
|
479 if (!SetStdHandle (STD_ERROR_HANDLE, err_handle))
|
|
480 report_file_error ("Changing stderr handle", Qnil);
|
|
481
|
|
482 handles[0] = stdin_save;
|
|
483 handles[1] = stdout_save;
|
|
484 handles[2] = stderr_save;
|
|
485 handles[3] = err_handle;
|
|
486 }
|
|
487
|
|
488 void
|
|
489 reset_standard_handles (int in, int out, int err, HANDLE handles[4])
|
|
490 {
|
|
491 HANDLE stdin_save = handles[0];
|
|
492 HANDLE stdout_save = handles[1];
|
|
493 HANDLE stderr_save = handles[2];
|
|
494 HANDLE err_handle = handles[3];
|
|
495
|
|
496 if (!SetStdHandle (STD_INPUT_HANDLE, stdin_save))
|
|
497 report_file_error ("Resetting input handle", Qnil);
|
|
498
|
|
499 if (!SetStdHandle (STD_OUTPUT_HANDLE, stdout_save))
|
|
500 report_file_error ("Resetting output handle", Qnil);
|
|
501
|
|
502 if (!SetStdHandle (STD_ERROR_HANDLE, stderr_save))
|
|
503 report_file_error ("Resetting error handle", Qnil);
|
|
504
|
|
505 if (out == err)
|
|
506 {
|
|
507 /* If out and err are the same handle, then we duplicated out
|
|
508 and stuck it in err_handle. Close the duplicate to clean up. */
|
|
509 if (!CloseHandle (err_handle))
|
|
510 report_file_error ("Closing error handle duplicated from out.",
|
|
511 Qnil);
|
|
512 }
|
|
513 }
|
|
514
|
11384
|
515 int
|
|
516 random ()
|
|
517 {
|
|
518 /* rand () on NT gives us 15 random bits...hack together 30 bits. */
|
|
519 return ((rand () << 15) | rand ());
|
|
520 }
|
|
521
|
|
522 void
|
|
523 srandom (int seed)
|
|
524 {
|
|
525 srand (seed);
|
|
526 }
|
|
527
|
9803
|
528 /* Destructively turn backslashes into slashes. */
|
|
529 void
|
|
530 dostounix_filename (p)
|
|
531 register char *p;
|
|
532 {
|
|
533 while (*p)
|
|
534 {
|
|
535 if (*p == '\\')
|
|
536 *p = '/';
|
|
537 p++;
|
|
538 }
|
|
539 }
|
|
540
|
|
541 /* Routines that are no-ops on NT but are defined to get Emacs to compile. */
|
|
542
|
|
543
|
|
544 int
|
|
545 sigsetmask (int signal_mask)
|
|
546 {
|
|
547 return 0;
|
|
548 }
|
|
549
|
|
550 int
|
|
551 sigblock (int sig)
|
|
552 {
|
|
553 return 0;
|
|
554 }
|
|
555
|
|
556 int
|
|
557 kill (int pid, int signal)
|
|
558 {
|
|
559 return 0;
|
|
560 }
|
|
561
|
|
562 int
|
|
563 setpgrp (int pid, int gid)
|
|
564 {
|
|
565 return 0;
|
|
566 }
|
|
567
|
|
568 int
|
|
569 alarm (int seconds)
|
|
570 {
|
|
571 return 0;
|
|
572 }
|
|
573
|
|
574 int
|
|
575 unrequest_sigio (void)
|
|
576 {
|
|
577 return 0;
|
|
578 }
|
|
579
|
|
580 int
|
|
581 request_sigio (void)
|
|
582 {
|
|
583 return 0;
|
|
584 }
|
|
585
|
|
586 int
|
|
587 getuid ()
|
|
588 {
|
|
589 return 0;
|
|
590 }
|
|
591
|
|
592 int
|
|
593 geteuid ()
|
|
594 {
|
|
595 return 0;
|
|
596 }
|
|
597
|
|
598 /* Remove all CR's that are followed by a LF.
|
|
599 (From msdos.c...probably should figure out a way to share it,
|
|
600 although this code isn't going to ever change.) */
|
|
601 int
|
|
602 crlf_to_lf (n, buf)
|
|
603 register int n;
|
|
604 register unsigned char *buf;
|
|
605 {
|
|
606 unsigned char *np = buf;
|
|
607 unsigned char *startp = buf;
|
|
608 unsigned char *endp = buf + n;
|
|
609
|
|
610 if (n == 0)
|
|
611 return n;
|
|
612 while (buf < endp - 1)
|
|
613 {
|
|
614 if (*buf == 0x0d)
|
|
615 {
|
|
616 if (*(++buf) != 0x0a)
|
|
617 *np++ = 0x0d;
|
|
618 }
|
|
619 else
|
|
620 *np++ = *buf++;
|
|
621 }
|
|
622 if (buf < endp)
|
|
623 *np++ = *buf++;
|
|
624 return np - startp;
|
|
625 }
|
|
626
|
11384
|
627 #ifdef HAVE_TIMEVAL
|
|
628 #include <sys/timeb.h>
|
|
629
|
|
630 /* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */
|
|
631 void
|
|
632 gettimeofday (struct timeval *tv, struct timezone *tz)
|
|
633 {
|
|
634 struct _timeb tb;
|
|
635 _ftime (&tb);
|
|
636
|
|
637 tv->tv_sec = tb.time;
|
|
638 tv->tv_usec = tb.millitm * 1000L;
|
|
639 if (tz)
|
|
640 {
|
|
641 tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich */
|
|
642 tz->tz_dsttime = tb.dstflag; /* type of dst correction */
|
|
643 }
|
|
644 }
|
|
645 #endif /* HAVE_TIMEVAL */
|
|
646
|
9803
|
647
|
|
648 #ifdef PIGSFLY
|
|
649 Keep this around...we might need it later.
|
|
650 #ifdef WINDOWSNT
|
|
651 {
|
|
652 /*
|
|
653 * Find the user's real name by opening the process token and looking
|
|
654 * up the name associated with the user-sid in that token.
|
|
655 */
|
|
656
|
|
657 char b[256], Name[256], RefD[256];
|
|
658 DWORD length = 256, rlength = 256, trash;
|
|
659 HANDLE Token;
|
|
660 SID_NAME_USE User;
|
|
661
|
|
662 if (1)
|
|
663 Vuser_real_name = build_string ("foo");
|
|
664 else if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &Token))
|
|
665 {
|
|
666 Vuser_real_name = build_string ("unknown");
|
|
667 }
|
|
668 else if (!GetTokenInformation (Token, TokenUser, (PVOID)b, 256,
|
|
669 &trash))
|
|
670 {
|
|
671 CloseHandle (Token);
|
|
672 Vuser_real_name = build_string ("unknown");
|
|
673 }
|
|
674 else if (!LookupAccountSid ((void *)0, (PSID)b, Name, &length, RefD,
|
|
675 &rlength, &User))
|
|
676 {
|
|
677 CloseHandle (Token);
|
|
678 Vuser_real_name = build_string ("unknown");
|
|
679 }
|
|
680 else
|
|
681 Vuser_real_name = build_string (Name);
|
|
682 }
|
|
683 #else /* not WINDOWSNT */
|
|
684 #endif /* not WINDOWSNT */
|
|
685 #endif /* PIGSFLY */
|