]> code.delx.au - gnu-emacs/blob - src/w32.c
(code_convert_string_norecord): New function.
[gnu-emacs] / src / w32.c
1 /* Utility and Unix shadow routines for GNU Emacs on the Microsoft W32 API.
2 Copyright (C) 1994, 1995 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20
21 Geoff Voelker (voelker@cs.washington.edu) 7-29-94
22 */
23
24
25 #include <stddef.h> /* for offsetof */
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <io.h>
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <ctype.h>
32 #include <signal.h>
33 #include <sys/time.h>
34 #include <sys/utime.h>
35
36 /* must include CRT headers *before* config.h */
37 #include "config.h"
38 #undef access
39 #undef chdir
40 #undef chmod
41 #undef creat
42 #undef ctime
43 #undef fopen
44 #undef link
45 #undef mkdir
46 #undef mktemp
47 #undef open
48 #undef rename
49 #undef rmdir
50 #undef unlink
51
52 #undef close
53 #undef dup
54 #undef dup2
55 #undef pipe
56 #undef read
57 #undef write
58
59 #include "lisp.h"
60
61 #include <pwd.h>
62
63 #include <windows.h>
64
65 #ifdef HAVE_SOCKETS /* TCP connection support, if kernel can do it */
66 #include <sys/socket.h>
67 #undef socket
68 #undef bind
69 #undef connect
70 #undef htons
71 #undef ntohs
72 #undef inet_addr
73 #undef gethostname
74 #undef gethostbyname
75 #undef getservbyname
76 #undef shutdown
77 #endif
78
79 #include "w32.h"
80 #include "ndir.h"
81 #include "w32heap.h"
82
83 #undef min
84 #undef max
85 #define min(x, y) (((x) < (y)) ? (x) : (y))
86 #define max(x, y) (((x) > (y)) ? (x) : (y))
87
88 extern Lisp_Object Vw32_downcase_file_names;
89 extern Lisp_Object Vw32_generate_fake_inodes;
90 extern Lisp_Object Vw32_get_true_file_attributes;
91
92 static char startup_dir[MAXPATHLEN];
93
94 /* Get the current working directory. */
95 char *
96 getwd (char *dir)
97 {
98 #if 0
99 if (GetCurrentDirectory (MAXPATHLEN, dir) > 0)
100 return dir;
101 return NULL;
102 #else
103 /* Emacs doesn't actually change directory itself, and we want to
104 force our real wd to be where emacs.exe is to avoid unnecessary
105 conflicts when trying to rename or delete directories. */
106 strcpy (dir, startup_dir);
107 return dir;
108 #endif
109 }
110
111 #ifndef HAVE_SOCKETS
112 /* Emulate gethostname. */
113 int
114 gethostname (char *buffer, int size)
115 {
116 /* NT only allows small host names, so the buffer is
117 certainly large enough. */
118 return !GetComputerName (buffer, &size);
119 }
120 #endif /* HAVE_SOCKETS */
121
122 /* Emulate getloadavg. */
123 int
124 getloadavg (double loadavg[], int nelem)
125 {
126 int i;
127
128 /* A faithful emulation is going to have to be saved for a rainy day. */
129 for (i = 0; i < nelem; i++)
130 {
131 loadavg[i] = 0.0;
132 }
133 return i;
134 }
135
136 /* Emulate getpwuid, getpwnam and others. */
137
138 #define PASSWD_FIELD_SIZE 256
139
140 static char the_passwd_name[PASSWD_FIELD_SIZE];
141 static char the_passwd_passwd[PASSWD_FIELD_SIZE];
142 static char the_passwd_gecos[PASSWD_FIELD_SIZE];
143 static char the_passwd_dir[PASSWD_FIELD_SIZE];
144 static char the_passwd_shell[PASSWD_FIELD_SIZE];
145
146 static struct passwd the_passwd =
147 {
148 the_passwd_name,
149 the_passwd_passwd,
150 0,
151 0,
152 0,
153 the_passwd_gecos,
154 the_passwd_dir,
155 the_passwd_shell,
156 };
157
158 int
159 getuid ()
160 {
161 return the_passwd.pw_uid;
162 }
163
164 int
165 geteuid ()
166 {
167 /* I could imagine arguing for checking to see whether the user is
168 in the Administrators group and returning a UID of 0 for that
169 case, but I don't know how wise that would be in the long run. */
170 return getuid ();
171 }
172
173 int
174 getgid ()
175 {
176 return the_passwd.pw_gid;
177 }
178
179 int
180 getegid ()
181 {
182 return getgid ();
183 }
184
185 struct passwd *
186 getpwuid (int uid)
187 {
188 if (uid == the_passwd.pw_uid)
189 return &the_passwd;
190 return NULL;
191 }
192
193 struct passwd *
194 getpwnam (char *name)
195 {
196 struct passwd *pw;
197
198 pw = getpwuid (getuid ());
199 if (!pw)
200 return pw;
201
202 if (stricmp (name, pw->pw_name))
203 return NULL;
204
205 return pw;
206 }
207
208 void
209 init_user_info ()
210 {
211 /* Find the user's real name by opening the process token and
212 looking up the name associated with the user-sid in that token.
213
214 Use the relative portion of the identifier authority value from
215 the user-sid as the user id value (same for group id using the
216 primary group sid from the process token). */
217
218 char user_sid[256], name[256], domain[256];
219 DWORD length = sizeof (name), dlength = sizeof (domain), trash;
220 HANDLE token = NULL;
221 SID_NAME_USE user_type;
222
223 if (OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &token)
224 && GetTokenInformation (token, TokenUser,
225 (PVOID) user_sid, sizeof (user_sid), &trash)
226 && LookupAccountSid (NULL, *((PSID *) user_sid), name, &length,
227 domain, &dlength, &user_type))
228 {
229 strcpy (the_passwd.pw_name, name);
230 /* Determine a reasonable uid value. */
231 if (stricmp ("administrator", name) == 0)
232 {
233 the_passwd.pw_uid = 0;
234 the_passwd.pw_gid = 0;
235 }
236 else
237 {
238 SID_IDENTIFIER_AUTHORITY * pSIA;
239
240 pSIA = GetSidIdentifierAuthority (*((PSID *) user_sid));
241 /* I believe the relative portion is the last 4 bytes (of 6)
242 with msb first. */
243 the_passwd.pw_uid = ((pSIA->Value[2] << 24) +
244 (pSIA->Value[3] << 16) +
245 (pSIA->Value[4] << 8) +
246 (pSIA->Value[5] << 0));
247 /* restrict to conventional uid range for normal users */
248 the_passwd.pw_uid = the_passwd.pw_uid % 60001;
249
250 /* Get group id */
251 if (GetTokenInformation (token, TokenPrimaryGroup,
252 (PVOID) user_sid, sizeof (user_sid), &trash))
253 {
254 SID_IDENTIFIER_AUTHORITY * pSIA;
255
256 pSIA = GetSidIdentifierAuthority (*((PSID *) user_sid));
257 the_passwd.pw_gid = ((pSIA->Value[2] << 24) +
258 (pSIA->Value[3] << 16) +
259 (pSIA->Value[4] << 8) +
260 (pSIA->Value[5] << 0));
261 /* I don't know if this is necessary, but for safety... */
262 the_passwd.pw_gid = the_passwd.pw_gid % 60001;
263 }
264 else
265 the_passwd.pw_gid = the_passwd.pw_uid;
266 }
267 }
268 /* If security calls are not supported (presumably because we
269 are running under Windows 95), fallback to this. */
270 else if (GetUserName (name, &length))
271 {
272 strcpy (the_passwd.pw_name, name);
273 if (stricmp ("administrator", name) == 0)
274 the_passwd.pw_uid = 0;
275 else
276 the_passwd.pw_uid = 123;
277 the_passwd.pw_gid = the_passwd.pw_uid;
278 }
279 else
280 {
281 strcpy (the_passwd.pw_name, "unknown");
282 the_passwd.pw_uid = 123;
283 the_passwd.pw_gid = 123;
284 }
285
286 /* Ensure HOME and SHELL are defined. */
287 if (getenv ("HOME") == NULL)
288 putenv ("HOME=c:/");
289 if (getenv ("SHELL") == NULL)
290 putenv (os_subtype == OS_WIN95 ? "SHELL=command" : "SHELL=cmd");
291
292 /* Set dir and shell from environment variables. */
293 strcpy (the_passwd.pw_dir, getenv ("HOME"));
294 strcpy (the_passwd.pw_shell, getenv ("SHELL"));
295
296 if (token)
297 CloseHandle (token);
298 }
299
300 int
301 random ()
302 {
303 /* rand () on NT gives us 15 random bits...hack together 30 bits. */
304 return ((rand () << 15) | rand ());
305 }
306
307 void
308 srandom (int seed)
309 {
310 srand (seed);
311 }
312
313
314 /* Normalize filename by converting all path separators to
315 the specified separator. Also conditionally convert upper
316 case path name components to lower case. */
317
318 static void
319 normalize_filename (fp, path_sep)
320 register char *fp;
321 char path_sep;
322 {
323 char sep;
324 char *elem;
325
326 /* Always lower-case drive letters a-z, even if the filesystem
327 preserves case in filenames.
328 This is so filenames can be compared by string comparison
329 functions that are case-sensitive. Even case-preserving filesystems
330 do not distinguish case in drive letters. */
331 if (fp[1] == ':' && *fp >= 'A' && *fp <= 'Z')
332 {
333 *fp += 'a' - 'A';
334 fp += 2;
335 }
336
337 if (NILP (Vw32_downcase_file_names))
338 {
339 while (*fp)
340 {
341 if (*fp == '/' || *fp == '\\')
342 *fp = path_sep;
343 fp++;
344 }
345 return;
346 }
347
348 sep = path_sep; /* convert to this path separator */
349 elem = fp; /* start of current path element */
350
351 do {
352 if (*fp >= 'a' && *fp <= 'z')
353 elem = 0; /* don't convert this element */
354
355 if (*fp == 0 || *fp == ':')
356 {
357 sep = *fp; /* restore current separator (or 0) */
358 *fp = '/'; /* after conversion of this element */
359 }
360
361 if (*fp == '/' || *fp == '\\')
362 {
363 if (elem && elem != fp)
364 {
365 *fp = 0; /* temporary end of string */
366 _strlwr (elem); /* while we convert to lower case */
367 }
368 *fp = sep; /* convert (or restore) path separator */
369 elem = fp + 1; /* next element starts after separator */
370 sep = path_sep;
371 }
372 } while (*fp++);
373 }
374
375 /* Destructively turn backslashes into slashes. */
376 void
377 dostounix_filename (p)
378 register char *p;
379 {
380 normalize_filename (p, '/');
381 }
382
383 /* Destructively turn slashes into backslashes. */
384 void
385 unixtodos_filename (p)
386 register char *p;
387 {
388 normalize_filename (p, '\\');
389 }
390
391 /* Remove all CR's that are followed by a LF.
392 (From msdos.c...probably should figure out a way to share it,
393 although this code isn't going to ever change.) */
394 int
395 crlf_to_lf (n, buf)
396 register int n;
397 register unsigned char *buf;
398 {
399 unsigned char *np = buf;
400 unsigned char *startp = buf;
401 unsigned char *endp = buf + n;
402
403 if (n == 0)
404 return n;
405 while (buf < endp - 1)
406 {
407 if (*buf == 0x0d)
408 {
409 if (*(++buf) != 0x0a)
410 *np++ = 0x0d;
411 }
412 else
413 *np++ = *buf++;
414 }
415 if (buf < endp)
416 *np++ = *buf++;
417 return np - startp;
418 }
419
420 /* Parse the root part of file name, if present. Return length and
421 optionally store pointer to char after root. */
422 static int
423 parse_root (char * name, char ** pPath)
424 {
425 char * start = name;
426
427 if (name == NULL)
428 return 0;
429
430 /* find the root name of the volume if given */
431 if (isalpha (name[0]) && name[1] == ':')
432 {
433 /* skip past drive specifier */
434 name += 2;
435 if (IS_DIRECTORY_SEP (name[0]))
436 name++;
437 }
438 else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1]))
439 {
440 int slashes = 2;
441 name += 2;
442 do
443 {
444 if (IS_DIRECTORY_SEP (*name) && --slashes == 0)
445 break;
446 name++;
447 }
448 while ( *name );
449 if (IS_DIRECTORY_SEP (name[0]))
450 name++;
451 }
452
453 if (pPath)
454 *pPath = name;
455
456 return name - start;
457 }
458
459 /* Get long base name for name; name is assumed to be absolute. */
460 static int
461 get_long_basename (char * name, char * buf, int size)
462 {
463 WIN32_FIND_DATA find_data;
464 HANDLE dir_handle;
465 int len = 0;
466
467 /* must be valid filename, no wild cards or other illegal characters */
468 if (strpbrk (name, "*?|<>\""))
469 return 0;
470
471 dir_handle = FindFirstFile (name, &find_data);
472 if (dir_handle != INVALID_HANDLE_VALUE)
473 {
474 if ((len = strlen (find_data.cFileName)) < size)
475 memcpy (buf, find_data.cFileName, len + 1);
476 else
477 len = 0;
478 FindClose (dir_handle);
479 }
480 return len;
481 }
482
483 /* Get long name for file, if possible (assumed to be absolute). */
484 BOOL
485 w32_get_long_filename (char * name, char * buf, int size)
486 {
487 char * o = buf;
488 char * p;
489 char * q;
490 char full[ MAX_PATH ];
491 int len;
492
493 len = strlen (name);
494 if (len >= MAX_PATH)
495 return FALSE;
496
497 /* Use local copy for destructive modification. */
498 memcpy (full, name, len+1);
499 unixtodos_filename (full);
500
501 /* Copy root part verbatim. */
502 len = parse_root (full, &p);
503 memcpy (o, full, len);
504 o += len;
505 size -= len;
506
507 do
508 {
509 q = p;
510 p = strchr (q, '\\');
511 if (p) *p = '\0';
512 len = get_long_basename (full, o, size);
513 if (len > 0)
514 {
515 o += len;
516 size -= len;
517 if (p != NULL)
518 {
519 *p++ = '\\';
520 if (size < 2)
521 return FALSE;
522 *o++ = '\\';
523 size--;
524 *o = '\0';
525 }
526 }
527 else
528 return FALSE;
529 }
530 while (p != NULL && *p);
531
532 return TRUE;
533 }
534
535
536 /* Routines that are no-ops on NT but are defined to get Emacs to compile. */
537
538 int
539 sigsetmask (int signal_mask)
540 {
541 return 0;
542 }
543
544 int
545 sigblock (int sig)
546 {
547 return 0;
548 }
549
550 int
551 setpgrp (int pid, int gid)
552 {
553 return 0;
554 }
555
556 int
557 alarm (int seconds)
558 {
559 return 0;
560 }
561
562 void
563 unrequest_sigio (void)
564 {
565 return;
566 }
567
568 void
569 request_sigio (void)
570 {
571 return;
572 }
573
574 #define REG_ROOT "SOFTWARE\\GNU\\Emacs"
575
576 LPBYTE
577 w32_get_resource (key, lpdwtype)
578 char *key;
579 LPDWORD lpdwtype;
580 {
581 LPBYTE lpvalue;
582 HKEY hrootkey = NULL;
583 DWORD cbData;
584 BOOL ok = FALSE;
585
586 /* Check both the current user and the local machine to see if
587 we have any resources. */
588
589 if (RegOpenKeyEx (HKEY_CURRENT_USER, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
590 {
591 lpvalue = NULL;
592
593 if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS
594 && (lpvalue = (LPBYTE) xmalloc (cbData)) != NULL
595 && RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
596 {
597 return (lpvalue);
598 }
599
600 if (lpvalue) xfree (lpvalue);
601
602 RegCloseKey (hrootkey);
603 }
604
605 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
606 {
607 lpvalue = NULL;
608
609 if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS
610 && (lpvalue = (LPBYTE) xmalloc (cbData)) != NULL
611 && RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
612 {
613 return (lpvalue);
614 }
615
616 if (lpvalue) xfree (lpvalue);
617
618 RegCloseKey (hrootkey);
619 }
620
621 return (NULL);
622 }
623
624 char *get_emacs_configuration (void);
625 extern Lisp_Object Vsystem_configuration;
626
627 void
628 init_environment ()
629 {
630 /* Check for environment variables and use registry if they don't exist */
631 {
632 int i;
633 LPBYTE lpval;
634 DWORD dwType;
635
636 static char * env_vars[] =
637 {
638 "HOME",
639 "PRELOAD_WINSOCK",
640 "emacs_dir",
641 "EMACSLOADPATH",
642 "SHELL",
643 "CMDPROXY",
644 "EMACSDATA",
645 "EMACSPATH",
646 "EMACSLOCKDIR",
647 /* We no longer set INFOPATH because Info-default-directory-list
648 is then ignored. We use a hook in winnt.el instead. */
649 /* "INFOPATH", */
650 "EMACSDOC",
651 "TERM",
652 };
653
654 for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++)
655 {
656 if (!getenv (env_vars[i])
657 && (lpval = w32_get_resource (env_vars[i], &dwType)) != NULL)
658 {
659 if (dwType == REG_EXPAND_SZ)
660 {
661 char buf1[500], buf2[500];
662
663 ExpandEnvironmentStrings ((LPSTR) lpval, buf1, 500);
664 _snprintf (buf2, 499, "%s=%s", env_vars[i], buf1);
665 putenv (strdup (buf2));
666 }
667 else if (dwType == REG_SZ)
668 {
669 char buf[500];
670
671 _snprintf (buf, 499, "%s=%s", env_vars[i], lpval);
672 putenv (strdup (buf));
673 }
674
675 xfree (lpval);
676 }
677 }
678 }
679
680 /* Rebuild system configuration to reflect invoking system. */
681 Vsystem_configuration = build_string (EMACS_CONFIGURATION);
682
683 /* Another special case: on NT, the PATH variable is actually named
684 "Path" although cmd.exe (perhaps NT itself) arranges for
685 environment variable lookup and setting to be case insensitive.
686 However, Emacs assumes a fully case sensitive environment, so we
687 need to change "Path" to "PATH" to match the expectations of
688 various elisp packages. We do this by the sneaky method of
689 modifying the string in the C runtime environ entry.
690
691 The same applies to COMSPEC. */
692 {
693 char ** envp;
694
695 for (envp = environ; *envp; envp++)
696 if (_strnicmp (*envp, "PATH=", 5) == 0)
697 memcpy (*envp, "PATH=", 5);
698 else if (_strnicmp (*envp, "COMSPEC=", 8) == 0)
699 memcpy (*envp, "COMSPEC=", 8);
700 }
701
702 /* Remember the initial working directory for getwd, then make the
703 real wd be the location of emacs.exe to avoid conflicts when
704 renaming or deleting directories. (We also don't call chdir when
705 running subprocesses for the same reason.) */
706 if (!GetCurrentDirectory (MAXPATHLEN, startup_dir))
707 abort ();
708
709 {
710 char *p;
711 char modname[MAX_PATH];
712
713 if (!GetModuleFileName (NULL, modname, MAX_PATH))
714 abort ();
715 if ((p = strrchr (modname, '\\')) == NULL)
716 abort ();
717 *p = 0;
718
719 SetCurrentDirectory (modname);
720 }
721
722 init_user_info ();
723 }
724
725 /* We don't have scripts to automatically determine the system configuration
726 for Emacs before it's compiled, and we don't want to have to make the
727 user enter it, so we define EMACS_CONFIGURATION to invoke this runtime
728 routine. */
729
730 static char configuration_buffer[32];
731
732 char *
733 get_emacs_configuration (void)
734 {
735 char *arch, *oem, *os;
736
737 /* Determine the processor type. */
738 switch (get_processor_type ())
739 {
740
741 #ifdef PROCESSOR_INTEL_386
742 case PROCESSOR_INTEL_386:
743 case PROCESSOR_INTEL_486:
744 case PROCESSOR_INTEL_PENTIUM:
745 arch = "i386";
746 break;
747 #endif
748
749 #ifdef PROCESSOR_INTEL_860
750 case PROCESSOR_INTEL_860:
751 arch = "i860";
752 break;
753 #endif
754
755 #ifdef PROCESSOR_MIPS_R2000
756 case PROCESSOR_MIPS_R2000:
757 case PROCESSOR_MIPS_R3000:
758 case PROCESSOR_MIPS_R4000:
759 arch = "mips";
760 break;
761 #endif
762
763 #ifdef PROCESSOR_ALPHA_21064
764 case PROCESSOR_ALPHA_21064:
765 arch = "alpha";
766 break;
767 #endif
768
769 default:
770 arch = "unknown";
771 break;
772 }
773
774 /* Let oem be "*" until we figure out how to decode the OEM field. */
775 oem = "*";
776
777 os = (GetVersion () & OS_WIN95) ? "windows95" : "nt";
778
779 sprintf (configuration_buffer, "%s-%s-%s%d.%d", arch, oem, os,
780 get_w32_major_version (), get_w32_minor_version ());
781 return configuration_buffer;
782 }
783
784 #include <sys/timeb.h>
785
786 /* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */
787 void
788 gettimeofday (struct timeval *tv, struct timezone *tz)
789 {
790 struct _timeb tb;
791 _ftime (&tb);
792
793 tv->tv_sec = tb.time;
794 tv->tv_usec = tb.millitm * 1000L;
795 if (tz)
796 {
797 tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich */
798 tz->tz_dsttime = tb.dstflag; /* type of dst correction */
799 }
800 }
801
802 /* ------------------------------------------------------------------------- */
803 /* IO support and wrapper functions for W32 API. */
804 /* ------------------------------------------------------------------------- */
805
806 /* Place a wrapper around the MSVC version of ctime. It returns NULL
807 on network directories, so we handle that case here.
808 (Ulrich Leodolter, 1/11/95). */
809 char *
810 sys_ctime (const time_t *t)
811 {
812 char *str = (char *) ctime (t);
813 return (str ? str : "Sun Jan 01 00:00:00 1970");
814 }
815
816 /* Emulate sleep...we could have done this with a define, but that
817 would necessitate including windows.h in the files that used it.
818 This is much easier. */
819 void
820 sys_sleep (int seconds)
821 {
822 Sleep (seconds * 1000);
823 }
824
825 /* Internal MSVC functions for low-level descriptor munging */
826 extern int __cdecl _set_osfhnd (int fd, long h);
827 extern int __cdecl _free_osfhnd (int fd);
828
829 /* parallel array of private info on file handles */
830 filedesc fd_info [ MAXDESC ];
831
832 typedef struct volume_info_data {
833 struct volume_info_data * next;
834
835 /* time when info was obtained */
836 DWORD timestamp;
837
838 /* actual volume info */
839 char * root_dir;
840 DWORD serialnum;
841 DWORD maxcomp;
842 DWORD flags;
843 char * name;
844 char * type;
845 } volume_info_data;
846
847 /* Global referenced by various functions. */
848 static volume_info_data volume_info;
849
850 /* Vector to indicate which drives are local and fixed (for which cached
851 data never expires). */
852 static BOOL fixed_drives[26];
853
854 /* Consider cached volume information to be stale if older than 10s,
855 at least for non-local drives. Info for fixed drives is never stale. */
856 #define DRIVE_INDEX( c ) ( (c) <= 'Z' ? (c) - 'A' : (c) - 'a' )
857 #define VOLINFO_STILL_VALID( root_dir, info ) \
858 ( ( isalpha (root_dir[0]) && \
859 fixed_drives[ DRIVE_INDEX (root_dir[0]) ] ) \
860 || GetTickCount () - info->timestamp < 10000 )
861
862 /* Cache support functions. */
863
864 /* Simple linked list with linear search is sufficient. */
865 static volume_info_data *volume_cache = NULL;
866
867 static volume_info_data *
868 lookup_volume_info (char * root_dir)
869 {
870 volume_info_data * info;
871
872 for (info = volume_cache; info; info = info->next)
873 if (stricmp (info->root_dir, root_dir) == 0)
874 break;
875 return info;
876 }
877
878 static void
879 add_volume_info (char * root_dir, volume_info_data * info)
880 {
881 info->root_dir = strdup (root_dir);
882 info->next = volume_cache;
883 volume_cache = info;
884 }
885
886
887 /* Wrapper for GetVolumeInformation, which uses caching to avoid
888 performance penalty (~2ms on 486 for local drives, 7.5ms for local
889 cdrom drive, ~5-10ms or more for remote drives on LAN). */
890 volume_info_data *
891 GetCachedVolumeInformation (char * root_dir)
892 {
893 volume_info_data * info;
894 char default_root[ MAX_PATH ];
895
896 /* NULL for root_dir means use root from current directory. */
897 if (root_dir == NULL)
898 {
899 if (GetCurrentDirectory (MAX_PATH, default_root) == 0)
900 return NULL;
901 parse_root (default_root, &root_dir);
902 *root_dir = 0;
903 root_dir = default_root;
904 }
905
906 /* Local fixed drives can be cached permanently. Removable drives
907 cannot be cached permanently, since the volume name and serial
908 number (if nothing else) can change. Remote drives should be
909 treated as if they are removable, since there is no sure way to
910 tell whether they are or not. Also, the UNC association of drive
911 letters mapped to remote volumes can be changed at any time (even
912 by other processes) without notice.
913
914 As a compromise, so we can benefit from caching info for remote
915 volumes, we use a simple expiry mechanism to invalidate cache
916 entries that are more than ten seconds old. */
917
918 #if 0
919 /* No point doing this, because WNetGetConnection is even slower than
920 GetVolumeInformation, consistently taking ~50ms on a 486 (FWIW,
921 GetDriveType is about the only call of this type which does not
922 involve network access, and so is extremely quick). */
923
924 /* Map drive letter to UNC if remote. */
925 if ( isalpha( root_dir[0] ) && !fixed[ DRIVE_INDEX( root_dir[0] ) ] )
926 {
927 char remote_name[ 256 ];
928 char drive[3] = { root_dir[0], ':' };
929
930 if (WNetGetConnection (drive, remote_name, sizeof (remote_name))
931 == NO_ERROR)
932 /* do something */ ;
933 }
934 #endif
935
936 info = lookup_volume_info (root_dir);
937
938 if (info == NULL || ! VOLINFO_STILL_VALID (root_dir, info))
939 {
940 char name[ 256 ];
941 DWORD serialnum;
942 DWORD maxcomp;
943 DWORD flags;
944 char type[ 256 ];
945
946 /* Info is not cached, or is stale. */
947 if (!GetVolumeInformation (root_dir,
948 name, sizeof (name),
949 &serialnum,
950 &maxcomp,
951 &flags,
952 type, sizeof (type)))
953 return NULL;
954
955 /* Cache the volume information for future use, overwriting existing
956 entry if present. */
957 if (info == NULL)
958 {
959 info = (volume_info_data *) xmalloc (sizeof (volume_info_data));
960 add_volume_info (root_dir, info);
961 }
962 else
963 {
964 free (info->name);
965 free (info->type);
966 }
967
968 info->name = strdup (name);
969 info->serialnum = serialnum;
970 info->maxcomp = maxcomp;
971 info->flags = flags;
972 info->type = strdup (type);
973 info->timestamp = GetTickCount ();
974 }
975
976 return info;
977 }
978
979 /* Get information on the volume where name is held; set path pointer to
980 start of pathname in name (past UNC header\volume header if present). */
981 int
982 get_volume_info (const char * name, const char ** pPath)
983 {
984 char temp[MAX_PATH];
985 char *rootname = NULL; /* default to current volume */
986 volume_info_data * info;
987
988 if (name == NULL)
989 return FALSE;
990
991 /* find the root name of the volume if given */
992 if (isalpha (name[0]) && name[1] == ':')
993 {
994 rootname = temp;
995 temp[0] = *name++;
996 temp[1] = *name++;
997 temp[2] = '\\';
998 temp[3] = 0;
999 }
1000 else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1]))
1001 {
1002 char *str = temp;
1003 int slashes = 4;
1004 rootname = temp;
1005 do
1006 {
1007 if (IS_DIRECTORY_SEP (*name) && --slashes == 0)
1008 break;
1009 *str++ = *name++;
1010 }
1011 while ( *name );
1012
1013 *str++ = '\\';
1014 *str = 0;
1015 }
1016
1017 if (pPath)
1018 *pPath = name;
1019
1020 info = GetCachedVolumeInformation (rootname);
1021 if (info != NULL)
1022 {
1023 /* Set global referenced by other functions. */
1024 volume_info = *info;
1025 return TRUE;
1026 }
1027 return FALSE;
1028 }
1029
1030 /* Determine if volume is FAT format (ie. only supports short 8.3
1031 names); also set path pointer to start of pathname in name. */
1032 int
1033 is_fat_volume (const char * name, const char ** pPath)
1034 {
1035 if (get_volume_info (name, pPath))
1036 return (volume_info.maxcomp == 12);
1037 return FALSE;
1038 }
1039
1040 /* Map filename to a legal 8.3 name if necessary. */
1041 const char *
1042 map_w32_filename (const char * name, const char ** pPath)
1043 {
1044 static char shortname[MAX_PATH];
1045 char * str = shortname;
1046 char c;
1047 char * path;
1048 const char * save_name = name;
1049
1050 if (is_fat_volume (name, &path)) /* truncate to 8.3 */
1051 {
1052 register int left = 8; /* maximum number of chars in part */
1053 register int extn = 0; /* extension added? */
1054 register int dots = 2; /* maximum number of dots allowed */
1055
1056 while (name < path)
1057 *str++ = *name++; /* skip past UNC header */
1058
1059 while ((c = *name++))
1060 {
1061 switch ( c )
1062 {
1063 case '\\':
1064 case '/':
1065 *str++ = '\\';
1066 extn = 0; /* reset extension flags */
1067 dots = 2; /* max 2 dots */
1068 left = 8; /* max length 8 for main part */
1069 break;
1070 case ':':
1071 *str++ = ':';
1072 extn = 0; /* reset extension flags */
1073 dots = 2; /* max 2 dots */
1074 left = 8; /* max length 8 for main part */
1075 break;
1076 case '.':
1077 if ( dots )
1078 {
1079 /* Convert path components of the form .xxx to _xxx,
1080 but leave . and .. as they are. This allows .emacs
1081 to be read as _emacs, for example. */
1082
1083 if (! *name ||
1084 *name == '.' ||
1085 IS_DIRECTORY_SEP (*name))
1086 {
1087 *str++ = '.';
1088 dots--;
1089 }
1090 else
1091 {
1092 *str++ = '_';
1093 left--;
1094 dots = 0;
1095 }
1096 }
1097 else if ( !extn )
1098 {
1099 *str++ = '.';
1100 extn = 1; /* we've got an extension */
1101 left = 3; /* 3 chars in extension */
1102 }
1103 else
1104 {
1105 /* any embedded dots after the first are converted to _ */
1106 *str++ = '_';
1107 }
1108 break;
1109 case '~':
1110 case '#': /* don't lose these, they're important */
1111 if ( ! left )
1112 str[-1] = c; /* replace last character of part */
1113 /* FALLTHRU */
1114 default:
1115 if ( left )
1116 {
1117 *str++ = tolower (c); /* map to lower case (looks nicer) */
1118 left--;
1119 dots = 0; /* started a path component */
1120 }
1121 break;
1122 }
1123 }
1124 *str = '\0';
1125 }
1126 else
1127 {
1128 strcpy (shortname, name);
1129 unixtodos_filename (shortname);
1130 }
1131
1132 if (pPath)
1133 *pPath = shortname + (path - save_name);
1134
1135 return shortname;
1136 }
1137
1138 /* Emulate the Unix directory procedures opendir, closedir,
1139 and readdir. We can't use the procedures supplied in sysdep.c,
1140 so we provide them here. */
1141
1142 struct direct dir_static; /* simulated directory contents */
1143 static HANDLE dir_find_handle = INVALID_HANDLE_VALUE;
1144 static int dir_is_fat;
1145 static char dir_pathname[MAXPATHLEN+1];
1146 static WIN32_FIND_DATA dir_find_data;
1147
1148 DIR *
1149 opendir (char *filename)
1150 {
1151 DIR *dirp;
1152
1153 /* Opening is done by FindFirstFile. However, a read is inherent to
1154 this operation, so we defer the open until read time. */
1155
1156 if (!(dirp = (DIR *) malloc (sizeof (DIR))))
1157 return NULL;
1158 if (dir_find_handle != INVALID_HANDLE_VALUE)
1159 return NULL;
1160
1161 dirp->dd_fd = 0;
1162 dirp->dd_loc = 0;
1163 dirp->dd_size = 0;
1164
1165 strncpy (dir_pathname, map_w32_filename (filename, NULL), MAXPATHLEN);
1166 dir_pathname[MAXPATHLEN] = '\0';
1167 dir_is_fat = is_fat_volume (filename, NULL);
1168
1169 return dirp;
1170 }
1171
1172 void
1173 closedir (DIR *dirp)
1174 {
1175 /* If we have a find-handle open, close it. */
1176 if (dir_find_handle != INVALID_HANDLE_VALUE)
1177 {
1178 FindClose (dir_find_handle);
1179 dir_find_handle = INVALID_HANDLE_VALUE;
1180 }
1181 xfree ((char *) dirp);
1182 }
1183
1184 struct direct *
1185 readdir (DIR *dirp)
1186 {
1187 /* If we aren't dir_finding, do a find-first, otherwise do a find-next. */
1188 if (dir_find_handle == INVALID_HANDLE_VALUE)
1189 {
1190 char filename[MAXNAMLEN + 3];
1191 int ln;
1192
1193 strcpy (filename, dir_pathname);
1194 ln = strlen (filename) - 1;
1195 if (!IS_DIRECTORY_SEP (filename[ln]))
1196 strcat (filename, "\\");
1197 strcat (filename, "*");
1198
1199 dir_find_handle = FindFirstFile (filename, &dir_find_data);
1200
1201 if (dir_find_handle == INVALID_HANDLE_VALUE)
1202 return NULL;
1203 }
1204 else
1205 {
1206 if (!FindNextFile (dir_find_handle, &dir_find_data))
1207 return NULL;
1208 }
1209
1210 /* Emacs never uses this value, so don't bother making it match
1211 value returned by stat(). */
1212 dir_static.d_ino = 1;
1213
1214 dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 +
1215 dir_static.d_namlen - dir_static.d_namlen % 4;
1216
1217 dir_static.d_namlen = strlen (dir_find_data.cFileName);
1218 strcpy (dir_static.d_name, dir_find_data.cFileName);
1219 if (dir_is_fat)
1220 _strlwr (dir_static.d_name);
1221 else if (!NILP (Vw32_downcase_file_names))
1222 {
1223 register char *p;
1224 for (p = dir_static.d_name; *p; p++)
1225 if (*p >= 'a' && *p <= 'z')
1226 break;
1227 if (!*p)
1228 _strlwr (dir_static.d_name);
1229 }
1230
1231 return &dir_static;
1232 }
1233
1234
1235 /* Shadow some MSVC runtime functions to map requests for long filenames
1236 to reasonable short names if necessary. This was originally added to
1237 permit running Emacs on NT 3.1 on a FAT partition, which doesn't support
1238 long file names. */
1239
1240 int
1241 sys_access (const char * path, int mode)
1242 {
1243 return _access (map_w32_filename (path, NULL), mode);
1244 }
1245
1246 int
1247 sys_chdir (const char * path)
1248 {
1249 return _chdir (map_w32_filename (path, NULL));
1250 }
1251
1252 int
1253 sys_chmod (const char * path, int mode)
1254 {
1255 return _chmod (map_w32_filename (path, NULL), mode);
1256 }
1257
1258 int
1259 sys_creat (const char * path, int mode)
1260 {
1261 return _creat (map_w32_filename (path, NULL), mode);
1262 }
1263
1264 FILE *
1265 sys_fopen(const char * path, const char * mode)
1266 {
1267 int fd;
1268 int oflag;
1269 const char * mode_save = mode;
1270
1271 /* Force all file handles to be non-inheritable. This is necessary to
1272 ensure child processes don't unwittingly inherit handles that might
1273 prevent future file access. */
1274
1275 if (mode[0] == 'r')
1276 oflag = O_RDONLY;
1277 else if (mode[0] == 'w' || mode[0] == 'a')
1278 oflag = O_WRONLY | O_CREAT | O_TRUNC;
1279 else
1280 return NULL;
1281
1282 /* Only do simplistic option parsing. */
1283 while (*++mode)
1284 if (mode[0] == '+')
1285 {
1286 oflag &= ~(O_RDONLY | O_WRONLY);
1287 oflag |= O_RDWR;
1288 }
1289 else if (mode[0] == 'b')
1290 {
1291 oflag &= ~O_TEXT;
1292 oflag |= O_BINARY;
1293 }
1294 else if (mode[0] == 't')
1295 {
1296 oflag &= ~O_BINARY;
1297 oflag |= O_TEXT;
1298 }
1299 else break;
1300
1301 fd = _open (map_w32_filename (path, NULL), oflag | _O_NOINHERIT, 0644);
1302 if (fd < 0)
1303 return NULL;
1304
1305 return _fdopen (fd, mode_save);
1306 }
1307
1308 /* This only works on NTFS volumes, but is useful to have. */
1309 int
1310 sys_link (const char * old, const char * new)
1311 {
1312 HANDLE fileh;
1313 int result = -1;
1314 char oldname[MAX_PATH], newname[MAX_PATH];
1315
1316 if (old == NULL || new == NULL)
1317 {
1318 errno = ENOENT;
1319 return -1;
1320 }
1321
1322 strcpy (oldname, map_w32_filename (old, NULL));
1323 strcpy (newname, map_w32_filename (new, NULL));
1324
1325 fileh = CreateFile (oldname, 0, 0, NULL, OPEN_EXISTING,
1326 FILE_FLAG_BACKUP_SEMANTICS, NULL);
1327 if (fileh != INVALID_HANDLE_VALUE)
1328 {
1329 int wlen;
1330
1331 /* Confusingly, the "alternate" stream name field does not apply
1332 when restoring a hard link, and instead contains the actual
1333 stream data for the link (ie. the name of the link to create).
1334 The WIN32_STREAM_ID structure before the cStreamName field is
1335 the stream header, which is then immediately followed by the
1336 stream data. */
1337
1338 struct {
1339 WIN32_STREAM_ID wid;
1340 WCHAR wbuffer[MAX_PATH]; /* extra space for link name */
1341 } data;
1342
1343 wlen = MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, newname, -1,
1344 data.wid.cStreamName, MAX_PATH);
1345 if (wlen > 0)
1346 {
1347 LPVOID context = NULL;
1348 DWORD wbytes = 0;
1349
1350 data.wid.dwStreamId = BACKUP_LINK;
1351 data.wid.dwStreamAttributes = 0;
1352 data.wid.Size.LowPart = wlen * sizeof(WCHAR);
1353 data.wid.Size.HighPart = 0;
1354 data.wid.dwStreamNameSize = 0;
1355
1356 if (BackupWrite (fileh, (LPBYTE)&data,
1357 offsetof (WIN32_STREAM_ID, cStreamName)
1358 + data.wid.Size.LowPart,
1359 &wbytes, FALSE, FALSE, &context)
1360 && BackupWrite (fileh, NULL, 0, &wbytes, TRUE, FALSE, &context))
1361 {
1362 /* succeeded */
1363 result = 0;
1364 }
1365 else
1366 {
1367 /* Should try mapping GetLastError to errno; for now just
1368 indicate a general error (eg. links not supported). */
1369 errno = EINVAL; // perhaps EMLINK?
1370 }
1371 }
1372
1373 CloseHandle (fileh);
1374 }
1375 else
1376 errno = ENOENT;
1377
1378 return result;
1379 }
1380
1381 int
1382 sys_mkdir (const char * path)
1383 {
1384 return _mkdir (map_w32_filename (path, NULL));
1385 }
1386
1387 /* Because of long name mapping issues, we need to implement this
1388 ourselves. Also, MSVC's _mktemp returns NULL when it can't generate
1389 a unique name, instead of setting the input template to an empty
1390 string.
1391
1392 Standard algorithm seems to be use pid or tid with a letter on the
1393 front (in place of the 6 X's) and cycle through the letters to find a
1394 unique name. We extend that to allow any reasonable character as the
1395 first of the 6 X's. */
1396 char *
1397 sys_mktemp (char * template)
1398 {
1399 char * p;
1400 int i;
1401 unsigned uid = GetCurrentThreadId ();
1402 static char first_char[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#";
1403
1404 if (template == NULL)
1405 return NULL;
1406 p = template + strlen (template);
1407 i = 5;
1408 /* replace up to the last 5 X's with uid in decimal */
1409 while (--p >= template && p[0] == 'X' && --i >= 0)
1410 {
1411 p[0] = '0' + uid % 10;
1412 uid /= 10;
1413 }
1414
1415 if (i < 0 && p[0] == 'X')
1416 {
1417 i = 0;
1418 do
1419 {
1420 int save_errno = errno;
1421 p[0] = first_char[i];
1422 if (sys_access (template, 0) < 0)
1423 {
1424 errno = save_errno;
1425 return template;
1426 }
1427 }
1428 while (++i < sizeof (first_char));
1429 }
1430
1431 /* Template is badly formed or else we can't generate a unique name,
1432 so return empty string */
1433 template[0] = 0;
1434 return template;
1435 }
1436
1437 int
1438 sys_open (const char * path, int oflag, int mode)
1439 {
1440 /* Force all file handles to be non-inheritable. */
1441 return _open (map_w32_filename (path, NULL), oflag | _O_NOINHERIT, mode);
1442 }
1443
1444 int
1445 sys_rename (const char * oldname, const char * newname)
1446 {
1447 char temp[MAX_PATH];
1448 DWORD attr;
1449 int result;
1450
1451 /* MoveFile on Windows 95 doesn't correctly change the short file name
1452 alias in a number of circumstances (it is not easy to predict when
1453 just by looking at oldname and newname, unfortunately). In these
1454 cases, renaming through a temporary name avoids the problem.
1455
1456 A second problem on Windows 95 is that renaming through a temp name when
1457 newname is uppercase fails (the final long name ends up in
1458 lowercase, although the short alias might be uppercase) UNLESS the
1459 long temp name is not 8.3.
1460
1461 So, on Windows 95 we always rename through a temp name, and we make sure
1462 the temp name has a long extension to ensure correct renaming. */
1463
1464 strcpy (temp, map_w32_filename (oldname, NULL));
1465
1466 if (os_subtype == OS_WIN95)
1467 {
1468 char * p;
1469
1470 if (p = strrchr (temp, '\\'))
1471 p++;
1472 else
1473 p = temp;
1474 /* Force temp name to require a manufactured 8.3 alias - this
1475 seems to make the second rename work properly. */
1476 strcpy (p, "_rename_temp.XXXXXX");
1477 sys_mktemp (temp);
1478 if (rename (map_w32_filename (oldname, NULL), temp) < 0)
1479 return -1;
1480 }
1481
1482 /* Emulate Unix behaviour - newname is deleted if it already exists
1483 (at least if it is a file; don't do this for directories).
1484 However, don't do this if we are just changing the case of the file
1485 name - we will end up deleting the file we are trying to rename! */
1486 newname = map_w32_filename (newname, NULL);
1487
1488 /* Suggested by Pekka Pirila <pekka.pirila@vtt.fi>: stricmp does not
1489 handle accented characters correctly, so comparing filenames will
1490 accidentally delete these files. Instead, do the rename first;
1491 newname will not be deleted if successful or if errno == EACCES.
1492 In this case, delete the file explicitly. */
1493 result = rename (temp, newname);
1494 if (result < 0 && errno == EACCES
1495 && (attr = GetFileAttributes (newname)) != -1
1496 && (attr & FILE_ATTRIBUTE_DIRECTORY) == 0)
1497 {
1498 _chmod (newname, 0666);
1499 _unlink (newname);
1500 }
1501
1502 return result;
1503 }
1504
1505 int
1506 sys_rmdir (const char * path)
1507 {
1508 return _rmdir (map_w32_filename (path, NULL));
1509 }
1510
1511 int
1512 sys_unlink (const char * path)
1513 {
1514 path = map_w32_filename (path, NULL);
1515
1516 /* On Unix, unlink works without write permission. */
1517 _chmod (path, 0666);
1518 return _unlink (path);
1519 }
1520
1521 static FILETIME utc_base_ft;
1522 static long double utc_base;
1523 static int init = 0;
1524
1525 static time_t
1526 convert_time (FILETIME ft)
1527 {
1528 long double ret;
1529
1530 if (!init)
1531 {
1532 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1533 SYSTEMTIME st;
1534
1535 st.wYear = 1970;
1536 st.wMonth = 1;
1537 st.wDay = 1;
1538 st.wHour = 0;
1539 st.wMinute = 0;
1540 st.wSecond = 0;
1541 st.wMilliseconds = 0;
1542
1543 SystemTimeToFileTime (&st, &utc_base_ft);
1544 utc_base = (long double) utc_base_ft.dwHighDateTime
1545 * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime;
1546 init = 1;
1547 }
1548
1549 if (CompareFileTime (&ft, &utc_base_ft) < 0)
1550 return 0;
1551
1552 ret = (long double) ft.dwHighDateTime * 4096 * 1024 * 1024 + ft.dwLowDateTime;
1553 ret -= utc_base;
1554 return (time_t) (ret * 1e-7);
1555 }
1556
1557 void
1558 convert_from_time_t (time_t time, FILETIME * pft)
1559 {
1560 long double tmp;
1561
1562 if (!init)
1563 {
1564 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1565 SYSTEMTIME st;
1566
1567 st.wYear = 1970;
1568 st.wMonth = 1;
1569 st.wDay = 1;
1570 st.wHour = 0;
1571 st.wMinute = 0;
1572 st.wSecond = 0;
1573 st.wMilliseconds = 0;
1574
1575 SystemTimeToFileTime (&st, &utc_base_ft);
1576 utc_base = (long double) utc_base_ft.dwHighDateTime
1577 * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime;
1578 init = 1;
1579 }
1580
1581 /* time in 100ns units since 1-Jan-1601 */
1582 tmp = (long double) time * 1e7 + utc_base;
1583 pft->dwHighDateTime = (DWORD) (tmp / (4096.0 * 1024 * 1024));
1584 pft->dwLowDateTime = (DWORD) (tmp - (4096.0 * 1024 * 1024) * pft->dwHighDateTime);
1585 }
1586
1587 #if 0
1588 /* No reason to keep this; faking inode values either by hashing or even
1589 using the file index from GetInformationByHandle, is not perfect and
1590 so by default Emacs doesn't use the inode values on Windows.
1591 Instead, we now determine file-truename correctly (except for
1592 possible drive aliasing etc). */
1593
1594 /* Modified version of "PJW" algorithm (see the "Dragon" compiler book). */
1595 static unsigned
1596 hashval (const unsigned char * str)
1597 {
1598 unsigned h = 0;
1599 while (*str)
1600 {
1601 h = (h << 4) + *str++;
1602 h ^= (h >> 28);
1603 }
1604 return h;
1605 }
1606
1607 /* Return the hash value of the canonical pathname, excluding the
1608 drive/UNC header, to get a hopefully unique inode number. */
1609 static DWORD
1610 generate_inode_val (const char * name)
1611 {
1612 char fullname[ MAX_PATH ];
1613 char * p;
1614 unsigned hash;
1615
1616 /* Get the truly canonical filename, if it exists. (Note: this
1617 doesn't resolve aliasing due to subst commands, or recognise hard
1618 links. */
1619 if (!w32_get_long_filename ((char *)name, fullname, MAX_PATH))
1620 abort ();
1621
1622 parse_root (fullname, &p);
1623 /* Normal W32 filesystems are still case insensitive. */
1624 _strlwr (p);
1625 return hashval (p);
1626 }
1627
1628 #endif
1629
1630 /* MSVC stat function can't cope with UNC names and has other bugs, so
1631 replace it with our own. This also allows us to calculate consistent
1632 inode values without hacks in the main Emacs code. */
1633 int
1634 stat (const char * path, struct stat * buf)
1635 {
1636 char *name, *r;
1637 WIN32_FIND_DATA wfd;
1638 HANDLE fh;
1639 DWORD fake_inode;
1640 int permission;
1641 int len;
1642 int rootdir = FALSE;
1643
1644 if (path == NULL || buf == NULL)
1645 {
1646 errno = EFAULT;
1647 return -1;
1648 }
1649
1650 name = (char *) map_w32_filename (path, &path);
1651 /* must be valid filename, no wild cards or other illegal characters */
1652 if (strpbrk (name, "*?|<>\""))
1653 {
1654 errno = ENOENT;
1655 return -1;
1656 }
1657
1658 /* If name is "c:/.." or "/.." then stat "c:/" or "/". */
1659 r = IS_DEVICE_SEP (name[1]) ? &name[2] : name;
1660 if (IS_DIRECTORY_SEP (r[0]) && r[1] == '.' && r[2] == '.' && r[3] == '\0')
1661 {
1662 r[1] = r[2] = '\0';
1663 }
1664
1665 /* Remove trailing directory separator, unless name is the root
1666 directory of a drive or UNC volume in which case ensure there
1667 is a trailing separator. */
1668 len = strlen (name);
1669 rootdir = (path >= name + len - 1
1670 && (IS_DIRECTORY_SEP (*path) || *path == 0));
1671 name = strcpy (alloca (len + 2), name);
1672
1673 if (rootdir)
1674 {
1675 if (!IS_DIRECTORY_SEP (name[len-1]))
1676 strcat (name, "\\");
1677 if (GetDriveType (name) < 2)
1678 {
1679 errno = ENOENT;
1680 return -1;
1681 }
1682 memset (&wfd, 0, sizeof (wfd));
1683 wfd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
1684 wfd.ftCreationTime = utc_base_ft;
1685 wfd.ftLastAccessTime = utc_base_ft;
1686 wfd.ftLastWriteTime = utc_base_ft;
1687 strcpy (wfd.cFileName, name);
1688 }
1689 else
1690 {
1691 if (IS_DIRECTORY_SEP (name[len-1]))
1692 name[len - 1] = 0;
1693
1694 /* (This is hacky, but helps when doing file completions on
1695 network drives.) Optimize by using information available from
1696 active readdir if possible. */
1697 if (dir_find_handle != INVALID_HANDLE_VALUE
1698 && (len = strlen (dir_pathname)),
1699 strnicmp (name, dir_pathname, len) == 0
1700 && IS_DIRECTORY_SEP (name[len])
1701 && stricmp (name + len + 1, dir_static.d_name) == 0)
1702 {
1703 /* This was the last entry returned by readdir. */
1704 wfd = dir_find_data;
1705 }
1706 else
1707 {
1708 fh = FindFirstFile (name, &wfd);
1709 if (fh == INVALID_HANDLE_VALUE)
1710 {
1711 errno = ENOENT;
1712 return -1;
1713 }
1714 FindClose (fh);
1715 }
1716 }
1717
1718 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1719 {
1720 buf->st_mode = _S_IFDIR;
1721 buf->st_nlink = 2; /* doesn't really matter */
1722 fake_inode = 0; /* this doesn't either I think */
1723 }
1724 else if (!NILP (Vw32_get_true_file_attributes))
1725 {
1726 /* This is more accurate in terms of gettting the correct number
1727 of links, but is quite slow (it is noticable when Emacs is
1728 making a list of file name completions). */
1729 BY_HANDLE_FILE_INFORMATION info;
1730
1731 /* No access rights required to get info. */
1732 fh = CreateFile (name, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
1733
1734 if (GetFileInformationByHandle (fh, &info))
1735 {
1736 switch (GetFileType (fh))
1737 {
1738 case FILE_TYPE_DISK:
1739 buf->st_mode = _S_IFREG;
1740 break;
1741 case FILE_TYPE_PIPE:
1742 buf->st_mode = _S_IFIFO;
1743 break;
1744 case FILE_TYPE_CHAR:
1745 case FILE_TYPE_UNKNOWN:
1746 default:
1747 buf->st_mode = _S_IFCHR;
1748 }
1749 buf->st_nlink = info.nNumberOfLinks;
1750 /* Might as well use file index to fake inode values, but this
1751 is not guaranteed to be unique unless we keep a handle open
1752 all the time (even then there are situations where it is
1753 not unique). Reputedly, there are at most 48 bits of info
1754 (on NTFS, presumably less on FAT). */
1755 fake_inode = info.nFileIndexLow ^ info.nFileIndexHigh;
1756 CloseHandle (fh);
1757 }
1758 else
1759 {
1760 errno = EACCES;
1761 return -1;
1762 }
1763 }
1764 else
1765 {
1766 /* Don't bother to make this information more accurate. */
1767 buf->st_mode = _S_IFREG;
1768 buf->st_nlink = 1;
1769 fake_inode = 0;
1770 }
1771
1772 #if 0
1773 /* Not sure if there is any point in this. */
1774 if (!NILP (Vw32_generate_fake_inodes))
1775 fake_inode = generate_inode_val (name);
1776 else if (fake_inode == 0)
1777 {
1778 /* For want of something better, try to make everything unique. */
1779 static DWORD gen_num = 0;
1780 fake_inode = ++gen_num;
1781 }
1782 #endif
1783
1784 /* MSVC defines _ino_t to be short; other libc's might not. */
1785 if (sizeof (buf->st_ino) == 2)
1786 buf->st_ino = fake_inode ^ (fake_inode >> 16);
1787 else
1788 buf->st_ino = fake_inode;
1789
1790 /* consider files to belong to current user */
1791 buf->st_uid = the_passwd.pw_uid;
1792 buf->st_gid = the_passwd.pw_gid;
1793
1794 /* volume_info is set indirectly by map_w32_filename */
1795 buf->st_dev = volume_info.serialnum;
1796 buf->st_rdev = volume_info.serialnum;
1797
1798
1799 buf->st_size = wfd.nFileSizeLow;
1800
1801 /* Convert timestamps to Unix format. */
1802 buf->st_mtime = convert_time (wfd.ftLastWriteTime);
1803 buf->st_atime = convert_time (wfd.ftLastAccessTime);
1804 if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
1805 buf->st_ctime = convert_time (wfd.ftCreationTime);
1806 if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
1807
1808 /* determine rwx permissions */
1809 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
1810 permission = _S_IREAD;
1811 else
1812 permission = _S_IREAD | _S_IWRITE;
1813
1814 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1815 permission |= _S_IEXEC;
1816 else
1817 {
1818 char * p = strrchr (name, '.');
1819 if (p != NULL
1820 && (stricmp (p, ".exe") == 0 ||
1821 stricmp (p, ".com") == 0 ||
1822 stricmp (p, ".bat") == 0 ||
1823 stricmp (p, ".cmd") == 0))
1824 permission |= _S_IEXEC;
1825 }
1826
1827 buf->st_mode |= permission | (permission >> 3) | (permission >> 6);
1828
1829 return 0;
1830 }
1831
1832 /* Provide fstat and utime as well as stat for consistent handling of
1833 file timestamps. */
1834 int
1835 fstat (int desc, struct stat * buf)
1836 {
1837 HANDLE fh = (HANDLE) _get_osfhandle (desc);
1838 BY_HANDLE_FILE_INFORMATION info;
1839 DWORD fake_inode;
1840 int permission;
1841
1842 switch (GetFileType (fh) & ~FILE_TYPE_REMOTE)
1843 {
1844 case FILE_TYPE_DISK:
1845 buf->st_mode = _S_IFREG;
1846 if (!GetFileInformationByHandle (fh, &info))
1847 {
1848 errno = EACCES;
1849 return -1;
1850 }
1851 break;
1852 case FILE_TYPE_PIPE:
1853 buf->st_mode = _S_IFIFO;
1854 goto non_disk;
1855 case FILE_TYPE_CHAR:
1856 case FILE_TYPE_UNKNOWN:
1857 default:
1858 buf->st_mode = _S_IFCHR;
1859 non_disk:
1860 memset (&info, 0, sizeof (info));
1861 info.dwFileAttributes = 0;
1862 info.ftCreationTime = utc_base_ft;
1863 info.ftLastAccessTime = utc_base_ft;
1864 info.ftLastWriteTime = utc_base_ft;
1865 }
1866
1867 if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1868 {
1869 buf->st_mode = _S_IFDIR;
1870 buf->st_nlink = 2; /* doesn't really matter */
1871 fake_inode = 0; /* this doesn't either I think */
1872 }
1873 else
1874 {
1875 buf->st_nlink = info.nNumberOfLinks;
1876 /* Might as well use file index to fake inode values, but this
1877 is not guaranteed to be unique unless we keep a handle open
1878 all the time (even then there are situations where it is
1879 not unique). Reputedly, there are at most 48 bits of info
1880 (on NTFS, presumably less on FAT). */
1881 fake_inode = info.nFileIndexLow ^ info.nFileIndexHigh;
1882 }
1883
1884 /* MSVC defines _ino_t to be short; other libc's might not. */
1885 if (sizeof (buf->st_ino) == 2)
1886 buf->st_ino = fake_inode ^ (fake_inode >> 16);
1887 else
1888 buf->st_ino = fake_inode;
1889
1890 /* consider files to belong to current user */
1891 buf->st_uid = 0;
1892 buf->st_gid = 0;
1893
1894 buf->st_dev = info.dwVolumeSerialNumber;
1895 buf->st_rdev = info.dwVolumeSerialNumber;
1896
1897 buf->st_size = info.nFileSizeLow;
1898
1899 /* Convert timestamps to Unix format. */
1900 buf->st_mtime = convert_time (info.ftLastWriteTime);
1901 buf->st_atime = convert_time (info.ftLastAccessTime);
1902 if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
1903 buf->st_ctime = convert_time (info.ftCreationTime);
1904 if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
1905
1906 /* determine rwx permissions */
1907 if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
1908 permission = _S_IREAD;
1909 else
1910 permission = _S_IREAD | _S_IWRITE;
1911
1912 if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1913 permission |= _S_IEXEC;
1914 else
1915 {
1916 #if 0 /* no way of knowing the filename */
1917 char * p = strrchr (name, '.');
1918 if (p != NULL &&
1919 (stricmp (p, ".exe") == 0 ||
1920 stricmp (p, ".com") == 0 ||
1921 stricmp (p, ".bat") == 0 ||
1922 stricmp (p, ".cmd") == 0))
1923 permission |= _S_IEXEC;
1924 #endif
1925 }
1926
1927 buf->st_mode |= permission | (permission >> 3) | (permission >> 6);
1928
1929 return 0;
1930 }
1931
1932 int
1933 utime (const char *name, struct utimbuf *times)
1934 {
1935 struct utimbuf deftime;
1936 HANDLE fh;
1937 FILETIME mtime;
1938 FILETIME atime;
1939
1940 if (times == NULL)
1941 {
1942 deftime.modtime = deftime.actime = time (NULL);
1943 times = &deftime;
1944 }
1945
1946 /* Need write access to set times. */
1947 fh = CreateFile (name, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
1948 0, OPEN_EXISTING, 0, NULL);
1949 if (fh)
1950 {
1951 convert_from_time_t (times->actime, &atime);
1952 convert_from_time_t (times->modtime, &mtime);
1953 if (!SetFileTime (fh, NULL, &atime, &mtime))
1954 {
1955 CloseHandle (fh);
1956 errno = EACCES;
1957 return -1;
1958 }
1959 CloseHandle (fh);
1960 }
1961 else
1962 {
1963 errno = EINVAL;
1964 return -1;
1965 }
1966 return 0;
1967 }
1968
1969 #ifdef HAVE_SOCKETS
1970
1971 /* Wrappers for winsock functions to map between our file descriptors
1972 and winsock's handles; also set h_errno for convenience.
1973
1974 To allow Emacs to run on systems which don't have winsock support
1975 installed, we dynamically link to winsock on startup if present, and
1976 otherwise provide the minimum necessary functionality
1977 (eg. gethostname). */
1978
1979 /* function pointers for relevant socket functions */
1980 int (PASCAL *pfn_WSAStartup) (WORD wVersionRequired, LPWSADATA lpWSAData);
1981 void (PASCAL *pfn_WSASetLastError) (int iError);
1982 int (PASCAL *pfn_WSAGetLastError) (void);
1983 int (PASCAL *pfn_socket) (int af, int type, int protocol);
1984 int (PASCAL *pfn_bind) (SOCKET s, const struct sockaddr *addr, int namelen);
1985 int (PASCAL *pfn_connect) (SOCKET s, const struct sockaddr *addr, int namelen);
1986 int (PASCAL *pfn_ioctlsocket) (SOCKET s, long cmd, u_long *argp);
1987 int (PASCAL *pfn_recv) (SOCKET s, char * buf, int len, int flags);
1988 int (PASCAL *pfn_send) (SOCKET s, const char * buf, int len, int flags);
1989 int (PASCAL *pfn_closesocket) (SOCKET s);
1990 int (PASCAL *pfn_shutdown) (SOCKET s, int how);
1991 int (PASCAL *pfn_WSACleanup) (void);
1992
1993 u_short (PASCAL *pfn_htons) (u_short hostshort);
1994 u_short (PASCAL *pfn_ntohs) (u_short netshort);
1995 unsigned long (PASCAL *pfn_inet_addr) (const char * cp);
1996 int (PASCAL *pfn_gethostname) (char * name, int namelen);
1997 struct hostent * (PASCAL *pfn_gethostbyname) (const char * name);
1998 struct servent * (PASCAL *pfn_getservbyname) (const char * name, const char * proto);
1999
2000 /* SetHandleInformation is only needed to make sockets non-inheritable. */
2001 BOOL (WINAPI *pfn_SetHandleInformation) (HANDLE object, DWORD mask, DWORD flags);
2002 #ifndef HANDLE_FLAG_INHERIT
2003 #define HANDLE_FLAG_INHERIT 1
2004 #endif
2005
2006 HANDLE winsock_lib;
2007 static int winsock_inuse;
2008
2009 BOOL
2010 term_winsock (void)
2011 {
2012 if (winsock_lib != NULL && winsock_inuse == 0)
2013 {
2014 /* Not sure what would cause WSAENETDOWN, or even if it can happen
2015 after WSAStartup returns successfully, but it seems reasonable
2016 to allow unloading winsock anyway in that case. */
2017 if (pfn_WSACleanup () == 0 ||
2018 pfn_WSAGetLastError () == WSAENETDOWN)
2019 {
2020 if (FreeLibrary (winsock_lib))
2021 winsock_lib = NULL;
2022 return TRUE;
2023 }
2024 }
2025 return FALSE;
2026 }
2027
2028 BOOL
2029 init_winsock (int load_now)
2030 {
2031 WSADATA winsockData;
2032
2033 if (winsock_lib != NULL)
2034 return TRUE;
2035
2036 pfn_SetHandleInformation = NULL;
2037 pfn_SetHandleInformation
2038 = (void *) GetProcAddress (GetModuleHandle ("kernel32.dll"),
2039 "SetHandleInformation");
2040
2041 winsock_lib = LoadLibrary ("wsock32.dll");
2042
2043 if (winsock_lib != NULL)
2044 {
2045 /* dynamically link to socket functions */
2046
2047 #define LOAD_PROC(fn) \
2048 if ((pfn_##fn = (void *) GetProcAddress (winsock_lib, #fn)) == NULL) \
2049 goto fail;
2050
2051 LOAD_PROC( WSAStartup );
2052 LOAD_PROC( WSASetLastError );
2053 LOAD_PROC( WSAGetLastError );
2054 LOAD_PROC( socket );
2055 LOAD_PROC( bind );
2056 LOAD_PROC( connect );
2057 LOAD_PROC( ioctlsocket );
2058 LOAD_PROC( recv );
2059 LOAD_PROC( send );
2060 LOAD_PROC( closesocket );
2061 LOAD_PROC( shutdown );
2062 LOAD_PROC( htons );
2063 LOAD_PROC( ntohs );
2064 LOAD_PROC( inet_addr );
2065 LOAD_PROC( gethostname );
2066 LOAD_PROC( gethostbyname );
2067 LOAD_PROC( getservbyname );
2068 LOAD_PROC( WSACleanup );
2069
2070 #undef LOAD_PROC
2071
2072 /* specify version 1.1 of winsock */
2073 if (pfn_WSAStartup (0x101, &winsockData) == 0)
2074 {
2075 if (winsockData.wVersion != 0x101)
2076 goto fail;
2077
2078 if (!load_now)
2079 {
2080 /* Report that winsock exists and is usable, but leave
2081 socket functions disabled. I am assuming that calling
2082 WSAStartup does not require any network interaction,
2083 and in particular does not cause or require a dial-up
2084 connection to be established. */
2085
2086 pfn_WSACleanup ();
2087 FreeLibrary (winsock_lib);
2088 winsock_lib = NULL;
2089 }
2090 winsock_inuse = 0;
2091 return TRUE;
2092 }
2093
2094 fail:
2095 FreeLibrary (winsock_lib);
2096 winsock_lib = NULL;
2097 }
2098
2099 return FALSE;
2100 }
2101
2102
2103 int h_errno = 0;
2104
2105 /* function to set h_errno for compatability; map winsock error codes to
2106 normal system codes where they overlap (non-overlapping definitions
2107 are already in <sys/socket.h> */
2108 static void set_errno ()
2109 {
2110 if (winsock_lib == NULL)
2111 h_errno = EINVAL;
2112 else
2113 h_errno = pfn_WSAGetLastError ();
2114
2115 switch (h_errno)
2116 {
2117 case WSAEACCES: h_errno = EACCES; break;
2118 case WSAEBADF: h_errno = EBADF; break;
2119 case WSAEFAULT: h_errno = EFAULT; break;
2120 case WSAEINTR: h_errno = EINTR; break;
2121 case WSAEINVAL: h_errno = EINVAL; break;
2122 case WSAEMFILE: h_errno = EMFILE; break;
2123 case WSAENAMETOOLONG: h_errno = ENAMETOOLONG; break;
2124 case WSAENOTEMPTY: h_errno = ENOTEMPTY; break;
2125 }
2126 errno = h_errno;
2127 }
2128
2129 static void check_errno ()
2130 {
2131 if (h_errno == 0 && winsock_lib != NULL)
2132 pfn_WSASetLastError (0);
2133 }
2134
2135 /* [andrewi 3-May-96] I've had conflicting results using both methods,
2136 but I believe the method of keeping the socket handle separate (and
2137 insuring it is not inheritable) is the correct one. */
2138
2139 //#define SOCK_REPLACE_HANDLE
2140
2141 #ifdef SOCK_REPLACE_HANDLE
2142 #define SOCK_HANDLE(fd) ((SOCKET) _get_osfhandle (fd))
2143 #else
2144 #define SOCK_HANDLE(fd) ((SOCKET) fd_info[fd].hnd)
2145 #endif
2146
2147 int
2148 sys_socket(int af, int type, int protocol)
2149 {
2150 int fd;
2151 long s;
2152 child_process * cp;
2153
2154 if (winsock_lib == NULL)
2155 {
2156 h_errno = ENETDOWN;
2157 return INVALID_SOCKET;
2158 }
2159
2160 check_errno ();
2161
2162 /* call the real socket function */
2163 s = (long) pfn_socket (af, type, protocol);
2164
2165 if (s != INVALID_SOCKET)
2166 {
2167 /* Although under NT 3.5 _open_osfhandle will accept a socket
2168 handle, if opened with SO_OPENTYPE == SO_SYNCHRONOUS_NONALERT,
2169 that does not work under NT 3.1. However, we can get the same
2170 effect by using a backdoor function to replace an existing
2171 descriptor handle with the one we want. */
2172
2173 /* allocate a file descriptor (with appropriate flags) */
2174 fd = _open ("NUL:", _O_RDWR);
2175 if (fd >= 0)
2176 {
2177 #ifdef SOCK_REPLACE_HANDLE
2178 /* now replace handle to NUL with our socket handle */
2179 CloseHandle ((HANDLE) _get_osfhandle (fd));
2180 _free_osfhnd (fd);
2181 _set_osfhnd (fd, s);
2182 /* setmode (fd, _O_BINARY); */
2183 #else
2184 /* Make a non-inheritable copy of the socket handle. */
2185 {
2186 HANDLE parent;
2187 HANDLE new_s = INVALID_HANDLE_VALUE;
2188
2189 parent = GetCurrentProcess ();
2190
2191 /* Apparently there is a bug in NT 3.51 with some service
2192 packs, which prevents using DuplicateHandle to make a
2193 socket handle non-inheritable (causes WSACleanup to
2194 hang). The work-around is to use SetHandleInformation
2195 instead if it is available and implemented. */
2196 if (!pfn_SetHandleInformation
2197 || !pfn_SetHandleInformation ((HANDLE) s,
2198 HANDLE_FLAG_INHERIT,
2199 0))
2200 {
2201 DuplicateHandle (parent,
2202 (HANDLE) s,
2203 parent,
2204 &new_s,
2205 0,
2206 FALSE,
2207 DUPLICATE_SAME_ACCESS);
2208 pfn_closesocket (s);
2209 s = (SOCKET) new_s;
2210 }
2211 fd_info[fd].hnd = (HANDLE) s;
2212 }
2213 #endif
2214
2215 /* set our own internal flags */
2216 fd_info[fd].flags = FILE_SOCKET | FILE_BINARY | FILE_READ | FILE_WRITE;
2217
2218 cp = new_child ();
2219 if (cp)
2220 {
2221 cp->fd = fd;
2222 cp->status = STATUS_READ_ACKNOWLEDGED;
2223
2224 /* attach child_process to fd_info */
2225 if (fd_info[ fd ].cp != NULL)
2226 {
2227 DebPrint (("sys_socket: fd_info[%d] apparently in use!\n", fd));
2228 abort ();
2229 }
2230
2231 fd_info[ fd ].cp = cp;
2232
2233 /* success! */
2234 winsock_inuse++; /* count open sockets */
2235 return fd;
2236 }
2237
2238 /* clean up */
2239 _close (fd);
2240 }
2241 pfn_closesocket (s);
2242 h_errno = EMFILE;
2243 }
2244 set_errno ();
2245
2246 return -1;
2247 }
2248
2249
2250 int
2251 sys_bind (int s, const struct sockaddr * addr, int namelen)
2252 {
2253 if (winsock_lib == NULL)
2254 {
2255 h_errno = ENOTSOCK;
2256 return SOCKET_ERROR;
2257 }
2258
2259 check_errno ();
2260 if (fd_info[s].flags & FILE_SOCKET)
2261 {
2262 int rc = pfn_bind (SOCK_HANDLE (s), addr, namelen);
2263 if (rc == SOCKET_ERROR)
2264 set_errno ();
2265 return rc;
2266 }
2267 h_errno = ENOTSOCK;
2268 return SOCKET_ERROR;
2269 }
2270
2271
2272 int
2273 sys_connect (int s, const struct sockaddr * name, int namelen)
2274 {
2275 if (winsock_lib == NULL)
2276 {
2277 h_errno = ENOTSOCK;
2278 return SOCKET_ERROR;
2279 }
2280
2281 check_errno ();
2282 if (fd_info[s].flags & FILE_SOCKET)
2283 {
2284 int rc = pfn_connect (SOCK_HANDLE (s), name, namelen);
2285 if (rc == SOCKET_ERROR)
2286 set_errno ();
2287 return rc;
2288 }
2289 h_errno = ENOTSOCK;
2290 return SOCKET_ERROR;
2291 }
2292
2293 u_short
2294 sys_htons (u_short hostshort)
2295 {
2296 return (winsock_lib != NULL) ?
2297 pfn_htons (hostshort) : hostshort;
2298 }
2299
2300 u_short
2301 sys_ntohs (u_short netshort)
2302 {
2303 return (winsock_lib != NULL) ?
2304 pfn_ntohs (netshort) : netshort;
2305 }
2306
2307 unsigned long
2308 sys_inet_addr (const char * cp)
2309 {
2310 return (winsock_lib != NULL) ?
2311 pfn_inet_addr (cp) : INADDR_NONE;
2312 }
2313
2314 int
2315 sys_gethostname (char * name, int namelen)
2316 {
2317 if (winsock_lib != NULL)
2318 return pfn_gethostname (name, namelen);
2319
2320 if (namelen > MAX_COMPUTERNAME_LENGTH)
2321 return !GetComputerName (name, &namelen);
2322
2323 h_errno = EFAULT;
2324 return SOCKET_ERROR;
2325 }
2326
2327 struct hostent *
2328 sys_gethostbyname(const char * name)
2329 {
2330 struct hostent * host;
2331
2332 if (winsock_lib == NULL)
2333 {
2334 h_errno = ENETDOWN;
2335 return NULL;
2336 }
2337
2338 check_errno ();
2339 host = pfn_gethostbyname (name);
2340 if (!host)
2341 set_errno ();
2342 return host;
2343 }
2344
2345 struct servent *
2346 sys_getservbyname(const char * name, const char * proto)
2347 {
2348 struct servent * serv;
2349
2350 if (winsock_lib == NULL)
2351 {
2352 h_errno = ENETDOWN;
2353 return NULL;
2354 }
2355
2356 check_errno ();
2357 serv = pfn_getservbyname (name, proto);
2358 if (!serv)
2359 set_errno ();
2360 return serv;
2361 }
2362
2363 int
2364 sys_shutdown (int s, int how)
2365 {
2366 int rc;
2367
2368 if (winsock_lib == NULL)
2369 {
2370 h_errno = ENETDOWN;
2371 return SOCKET_ERROR;
2372 }
2373
2374 check_errno ();
2375 if (fd_info[s].flags & FILE_SOCKET)
2376 {
2377 int rc = pfn_shutdown (SOCK_HANDLE (s), how);
2378 if (rc == SOCKET_ERROR)
2379 set_errno ();
2380 return rc;
2381 }
2382 h_errno = ENOTSOCK;
2383 return SOCKET_ERROR;
2384 }
2385
2386 #endif /* HAVE_SOCKETS */
2387
2388
2389 /* Shadow main io functions: we need to handle pipes and sockets more
2390 intelligently, and implement non-blocking mode as well. */
2391
2392 int
2393 sys_close (int fd)
2394 {
2395 int rc;
2396
2397 if (fd < 0 || fd >= MAXDESC)
2398 {
2399 errno = EBADF;
2400 return -1;
2401 }
2402
2403 if (fd_info[fd].cp)
2404 {
2405 child_process * cp = fd_info[fd].cp;
2406
2407 fd_info[fd].cp = NULL;
2408
2409 if (CHILD_ACTIVE (cp))
2410 {
2411 /* if last descriptor to active child_process then cleanup */
2412 int i;
2413 for (i = 0; i < MAXDESC; i++)
2414 {
2415 if (i == fd)
2416 continue;
2417 if (fd_info[i].cp == cp)
2418 break;
2419 }
2420 if (i == MAXDESC)
2421 {
2422 #ifdef HAVE_SOCKETS
2423 if (fd_info[fd].flags & FILE_SOCKET)
2424 {
2425 #ifndef SOCK_REPLACE_HANDLE
2426 if (winsock_lib == NULL) abort ();
2427
2428 pfn_shutdown (SOCK_HANDLE (fd), 2);
2429 rc = pfn_closesocket (SOCK_HANDLE (fd));
2430 #endif
2431 winsock_inuse--; /* count open sockets */
2432 }
2433 #endif
2434 delete_child (cp);
2435 }
2436 }
2437 }
2438
2439 /* Note that sockets do not need special treatment here (at least on
2440 NT and Windows 95 using the standard tcp/ip stacks) - it appears that
2441 closesocket is equivalent to CloseHandle, which is to be expected
2442 because socket handles are fully fledged kernel handles. */
2443 rc = _close (fd);
2444
2445 if (rc == 0)
2446 fd_info[fd].flags = 0;
2447
2448 return rc;
2449 }
2450
2451 int
2452 sys_dup (int fd)
2453 {
2454 int new_fd;
2455
2456 new_fd = _dup (fd);
2457 if (new_fd >= 0)
2458 {
2459 /* duplicate our internal info as well */
2460 fd_info[new_fd] = fd_info[fd];
2461 }
2462 return new_fd;
2463 }
2464
2465
2466 int
2467 sys_dup2 (int src, int dst)
2468 {
2469 int rc;
2470
2471 if (dst < 0 || dst >= MAXDESC)
2472 {
2473 errno = EBADF;
2474 return -1;
2475 }
2476
2477 /* make sure we close the destination first if it's a pipe or socket */
2478 if (src != dst && fd_info[dst].flags != 0)
2479 sys_close (dst);
2480
2481 rc = _dup2 (src, dst);
2482 if (rc == 0)
2483 {
2484 /* duplicate our internal info as well */
2485 fd_info[dst] = fd_info[src];
2486 }
2487 return rc;
2488 }
2489
2490 /* Unix pipe() has only one arg */
2491 int
2492 sys_pipe (int * phandles)
2493 {
2494 int rc;
2495 unsigned flags;
2496 child_process * cp;
2497
2498 /* make pipe handles non-inheritable; when we spawn a child, we
2499 replace the relevant handle with an inheritable one. Also put
2500 pipes into binary mode; we will do text mode translation ourselves
2501 if required. */
2502 rc = _pipe (phandles, 0, _O_NOINHERIT | _O_BINARY);
2503
2504 if (rc == 0)
2505 {
2506 flags = FILE_PIPE | FILE_READ | FILE_BINARY;
2507 fd_info[phandles[0]].flags = flags;
2508
2509 flags = FILE_PIPE | FILE_WRITE | FILE_BINARY;
2510 fd_info[phandles[1]].flags = flags;
2511 }
2512
2513 return rc;
2514 }
2515
2516 /* From ntproc.c */
2517 extern Lisp_Object Vw32_pipe_read_delay;
2518
2519 /* Function to do blocking read of one byte, needed to implement
2520 select. It is only allowed on sockets and pipes. */
2521 int
2522 _sys_read_ahead (int fd)
2523 {
2524 child_process * cp;
2525 int rc;
2526
2527 if (fd < 0 || fd >= MAXDESC)
2528 return STATUS_READ_ERROR;
2529
2530 cp = fd_info[fd].cp;
2531
2532 if (cp == NULL || cp->fd != fd || cp->status != STATUS_READ_READY)
2533 return STATUS_READ_ERROR;
2534
2535 if ((fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET)) == 0
2536 || (fd_info[fd].flags & FILE_READ) == 0)
2537 {
2538 DebPrint (("_sys_read_ahead: internal error: fd %d is not a pipe or socket!\n", fd));
2539 abort ();
2540 }
2541
2542 cp->status = STATUS_READ_IN_PROGRESS;
2543
2544 if (fd_info[fd].flags & FILE_PIPE)
2545 {
2546 rc = _read (fd, &cp->chr, sizeof (char));
2547
2548 /* Give subprocess time to buffer some more output for us before
2549 reporting that input is available; we need this because Windows 95
2550 connects DOS programs to pipes by making the pipe appear to be
2551 the normal console stdout - as a result most DOS programs will
2552 write to stdout without buffering, ie. one character at a
2553 time. Even some W32 programs do this - "dir" in a command
2554 shell on NT is very slow if we don't do this. */
2555 if (rc > 0)
2556 {
2557 int wait = XINT (Vw32_pipe_read_delay);
2558
2559 if (wait > 0)
2560 Sleep (wait);
2561 else if (wait < 0)
2562 while (++wait <= 0)
2563 /* Yield remainder of our time slice, effectively giving a
2564 temporary priority boost to the child process. */
2565 Sleep (0);
2566 }
2567 }
2568 #ifdef HAVE_SOCKETS
2569 else if (fd_info[fd].flags & FILE_SOCKET)
2570 rc = pfn_recv (SOCK_HANDLE (fd), &cp->chr, sizeof (char), 0);
2571 #endif
2572
2573 if (rc == sizeof (char))
2574 cp->status = STATUS_READ_SUCCEEDED;
2575 else
2576 cp->status = STATUS_READ_FAILED;
2577
2578 return cp->status;
2579 }
2580
2581 int
2582 sys_read (int fd, char * buffer, unsigned int count)
2583 {
2584 int nchars;
2585 int to_read;
2586 DWORD waiting;
2587 char * orig_buffer = buffer;
2588
2589 if (fd < 0 || fd >= MAXDESC)
2590 {
2591 errno = EBADF;
2592 return -1;
2593 }
2594
2595 if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
2596 {
2597 child_process *cp = fd_info[fd].cp;
2598
2599 if ((fd_info[fd].flags & FILE_READ) == 0)
2600 {
2601 errno = EBADF;
2602 return -1;
2603 }
2604
2605 nchars = 0;
2606
2607 /* re-read CR carried over from last read */
2608 if (fd_info[fd].flags & FILE_LAST_CR)
2609 {
2610 if (fd_info[fd].flags & FILE_BINARY) abort ();
2611 *buffer++ = 0x0d;
2612 count--;
2613 nchars++;
2614 fd_info[fd].flags &= ~FILE_LAST_CR;
2615 }
2616
2617 /* presence of a child_process structure means we are operating in
2618 non-blocking mode - otherwise we just call _read directly.
2619 Note that the child_process structure might be missing because
2620 reap_subprocess has been called; in this case the pipe is
2621 already broken, so calling _read on it is okay. */
2622 if (cp)
2623 {
2624 int current_status = cp->status;
2625
2626 switch (current_status)
2627 {
2628 case STATUS_READ_FAILED:
2629 case STATUS_READ_ERROR:
2630 /* report normal EOF if nothing in buffer */
2631 if (nchars <= 0)
2632 fd_info[fd].flags |= FILE_AT_EOF;
2633 return nchars;
2634
2635 case STATUS_READ_READY:
2636 case STATUS_READ_IN_PROGRESS:
2637 DebPrint (("sys_read called when read is in progress\n"));
2638 errno = EWOULDBLOCK;
2639 return -1;
2640
2641 case STATUS_READ_SUCCEEDED:
2642 /* consume read-ahead char */
2643 *buffer++ = cp->chr;
2644 count--;
2645 nchars++;
2646 cp->status = STATUS_READ_ACKNOWLEDGED;
2647 ResetEvent (cp->char_avail);
2648
2649 case STATUS_READ_ACKNOWLEDGED:
2650 break;
2651
2652 default:
2653 DebPrint (("sys_read: bad status %d\n", current_status));
2654 errno = EBADF;
2655 return -1;
2656 }
2657
2658 if (fd_info[fd].flags & FILE_PIPE)
2659 {
2660 PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, &waiting, NULL);
2661 to_read = min (waiting, (DWORD) count);
2662
2663 if (to_read > 0)
2664 nchars += _read (fd, buffer, to_read);
2665 }
2666 #ifdef HAVE_SOCKETS
2667 else /* FILE_SOCKET */
2668 {
2669 if (winsock_lib == NULL) abort ();
2670
2671 /* do the equivalent of a non-blocking read */
2672 pfn_ioctlsocket (SOCK_HANDLE (fd), FIONREAD, &waiting);
2673 if (waiting == 0 && nchars == 0)
2674 {
2675 h_errno = errno = EWOULDBLOCK;
2676 return -1;
2677 }
2678
2679 if (waiting)
2680 {
2681 /* always use binary mode for sockets */
2682 int res = pfn_recv (SOCK_HANDLE (fd), buffer, count, 0);
2683 if (res == SOCKET_ERROR)
2684 {
2685 DebPrint(("sys_read.recv failed with error %d on socket %ld\n",
2686 pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
2687 set_errno ();
2688 return -1;
2689 }
2690 nchars += res;
2691 }
2692 }
2693 #endif
2694 }
2695 else
2696 {
2697 int nread = _read (fd, buffer, count);
2698 if (nread >= 0)
2699 nchars += nread;
2700 else if (nchars == 0)
2701 nchars = nread;
2702 }
2703
2704 if (nchars <= 0)
2705 fd_info[fd].flags |= FILE_AT_EOF;
2706 /* Perform text mode translation if required. */
2707 else if ((fd_info[fd].flags & FILE_BINARY) == 0)
2708 {
2709 nchars = crlf_to_lf (nchars, orig_buffer);
2710 /* If buffer contains only CR, return that. To be absolutely
2711 sure we should attempt to read the next char, but in
2712 practice a CR to be followed by LF would not appear by
2713 itself in the buffer. */
2714 if (nchars > 1 && orig_buffer[nchars - 1] == 0x0d)
2715 {
2716 fd_info[fd].flags |= FILE_LAST_CR;
2717 nchars--;
2718 }
2719 }
2720 }
2721 else
2722 nchars = _read (fd, buffer, count);
2723
2724 return nchars;
2725 }
2726
2727 /* For now, don't bother with a non-blocking mode */
2728 int
2729 sys_write (int fd, const void * buffer, unsigned int count)
2730 {
2731 int nchars;
2732
2733 if (fd < 0 || fd >= MAXDESC)
2734 {
2735 errno = EBADF;
2736 return -1;
2737 }
2738
2739 if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
2740 {
2741 if ((fd_info[fd].flags & FILE_WRITE) == 0)
2742 {
2743 errno = EBADF;
2744 return -1;
2745 }
2746
2747 /* Perform text mode translation if required. */
2748 if ((fd_info[fd].flags & FILE_BINARY) == 0)
2749 {
2750 char * tmpbuf = alloca (count * 2);
2751 unsigned char * src = (void *)buffer;
2752 unsigned char * dst = tmpbuf;
2753 int nbytes = count;
2754
2755 while (1)
2756 {
2757 unsigned char *next;
2758 /* copy next line or remaining bytes */
2759 next = _memccpy (dst, src, '\n', nbytes);
2760 if (next)
2761 {
2762 /* copied one line ending with '\n' */
2763 int copied = next - dst;
2764 nbytes -= copied;
2765 src += copied;
2766 /* insert '\r' before '\n' */
2767 next[-1] = '\r';
2768 next[0] = '\n';
2769 dst = next + 1;
2770 count++;
2771 }
2772 else
2773 /* copied remaining partial line -> now finished */
2774 break;
2775 }
2776 buffer = tmpbuf;
2777 }
2778 }
2779
2780 #ifdef HAVE_SOCKETS
2781 if (fd_info[fd].flags & FILE_SOCKET)
2782 {
2783 if (winsock_lib == NULL) abort ();
2784 nchars = pfn_send (SOCK_HANDLE (fd), buffer, count, 0);
2785 if (nchars == SOCKET_ERROR)
2786 {
2787 DebPrint(("sys_read.send failed with error %d on socket %ld\n",
2788 pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
2789 set_errno ();
2790 }
2791 }
2792 else
2793 #endif
2794 nchars = _write (fd, buffer, count);
2795
2796 return nchars;
2797 }
2798
2799 static void
2800 check_windows_init_file ()
2801 {
2802 extern int noninteractive, inhibit_window_system;
2803
2804 /* A common indication that Emacs is not installed properly is when
2805 it cannot find the Windows installation file. If this file does
2806 not exist in the expected place, tell the user. */
2807
2808 if (!noninteractive && !inhibit_window_system) {
2809 extern Lisp_Object Vwindow_system, Vload_path;
2810 Lisp_Object init_file;
2811 int fd;
2812
2813 init_file = build_string ("term/w32-win");
2814 fd = openp (Vload_path, init_file, ".el:.elc", NULL, 0);
2815 if (fd < 0) {
2816 Lisp_Object load_path_print = Fprin1_to_string (Vload_path, Qnil);
2817 char *init_file_name = XSTRING (init_file)->data;
2818 char *load_path = XSTRING (load_path_print)->data;
2819 char *buffer = alloca (1024);
2820
2821 sprintf (buffer,
2822 "The Emacs Windows initialization file \"%s.el\" "
2823 "could not be found in your Emacs installation. "
2824 "Emacs checked the following directories for this file:\n"
2825 "\n%s\n\n"
2826 "When Emacs cannot find this file, it usually means that it "
2827 "was not installed properly, or its distribution file was "
2828 "not unpacked properly.\nSee the README.W32 file in the "
2829 "top-level Emacs directory for more information.",
2830 init_file_name, load_path);
2831 MessageBox (NULL,
2832 buffer,
2833 "Emacs Abort Dialog",
2834 MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL);
2835 close (fd);
2836
2837 /* Use the low-level Emacs abort. */
2838 #undef abort
2839 abort ();
2840 }
2841 }
2842 }
2843
2844 void
2845 term_ntproc ()
2846 {
2847 #ifdef HAVE_SOCKETS
2848 /* shutdown the socket interface if necessary */
2849 term_winsock ();
2850 #endif
2851
2852 /* Check whether we are shutting down because we cannot find the
2853 Windows initialization file. Do this during shutdown so that
2854 Emacs is initialized as possible, and so that it is out of the
2855 critical startup path. */
2856 check_windows_init_file ();
2857 }
2858
2859 void
2860 init_ntproc ()
2861 {
2862 #ifdef HAVE_SOCKETS
2863 /* Initialise the socket interface now if available and requested by
2864 the user by defining PRELOAD_WINSOCK; otherwise loading will be
2865 delayed until open-network-stream is called (w32-has-winsock can
2866 also be used to dynamically load or reload winsock).
2867
2868 Conveniently, init_environment is called before us, so
2869 PRELOAD_WINSOCK can be set in the registry. */
2870
2871 /* Always initialize this correctly. */
2872 winsock_lib = NULL;
2873
2874 if (getenv ("PRELOAD_WINSOCK") != NULL)
2875 init_winsock (TRUE);
2876 #endif
2877
2878 /* Initial preparation for subprocess support: replace our standard
2879 handles with non-inheritable versions. */
2880 {
2881 HANDLE parent;
2882 HANDLE stdin_save = INVALID_HANDLE_VALUE;
2883 HANDLE stdout_save = INVALID_HANDLE_VALUE;
2884 HANDLE stderr_save = INVALID_HANDLE_VALUE;
2885
2886 parent = GetCurrentProcess ();
2887
2888 /* ignore errors when duplicating and closing; typically the
2889 handles will be invalid when running as a gui program. */
2890 DuplicateHandle (parent,
2891 GetStdHandle (STD_INPUT_HANDLE),
2892 parent,
2893 &stdin_save,
2894 0,
2895 FALSE,
2896 DUPLICATE_SAME_ACCESS);
2897
2898 DuplicateHandle (parent,
2899 GetStdHandle (STD_OUTPUT_HANDLE),
2900 parent,
2901 &stdout_save,
2902 0,
2903 FALSE,
2904 DUPLICATE_SAME_ACCESS);
2905
2906 DuplicateHandle (parent,
2907 GetStdHandle (STD_ERROR_HANDLE),
2908 parent,
2909 &stderr_save,
2910 0,
2911 FALSE,
2912 DUPLICATE_SAME_ACCESS);
2913
2914 fclose (stdin);
2915 fclose (stdout);
2916 fclose (stderr);
2917
2918 if (stdin_save != INVALID_HANDLE_VALUE)
2919 _open_osfhandle ((long) stdin_save, O_TEXT);
2920 else
2921 _open ("nul", O_TEXT | O_NOINHERIT | O_RDONLY);
2922 _fdopen (0, "r");
2923
2924 if (stdout_save != INVALID_HANDLE_VALUE)
2925 _open_osfhandle ((long) stdout_save, O_TEXT);
2926 else
2927 _open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
2928 _fdopen (1, "w");
2929
2930 if (stderr_save != INVALID_HANDLE_VALUE)
2931 _open_osfhandle ((long) stderr_save, O_TEXT);
2932 else
2933 _open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
2934 _fdopen (2, "w");
2935 }
2936
2937 /* unfortunately, atexit depends on implementation of malloc */
2938 /* atexit (term_ntproc); */
2939 signal (SIGABRT, term_ntproc);
2940
2941 /* determine which drives are fixed, for GetCachedVolumeInformation */
2942 {
2943 /* GetDriveType must have trailing backslash. */
2944 char drive[] = "A:\\";
2945
2946 /* Loop over all possible drive letters */
2947 while (*drive <= 'Z')
2948 {
2949 /* Record if this drive letter refers to a fixed drive. */
2950 fixed_drives[DRIVE_INDEX (*drive)] =
2951 (GetDriveType (drive) == DRIVE_FIXED);
2952
2953 (*drive)++;
2954 }
2955 }
2956 }
2957
2958 /* end of nt.c */