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