(Vwin32_downcase_file_names): New variable.
[bpt/emacs.git] / src / w32.c
1 /* Utility and Unix shadow routines for GNU Emacs on Windows NT.
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 <stdlib.h>
26 #include <stdio.h>
27 #include <io.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <ctype.h>
31 #include <signal.h>
32 #include <sys/time.h>
33
34 /* must include CRT headers *before* config.h */
35 #include "config.h"
36 #undef access
37 #undef chdir
38 #undef chmod
39 #undef creat
40 #undef ctime
41 #undef fopen
42 #undef link
43 #undef mkdir
44 #undef mktemp
45 #undef open
46 #undef rename
47 #undef rmdir
48 #undef unlink
49
50 #undef close
51 #undef dup
52 #undef dup2
53 #undef pipe
54 #undef read
55 #undef write
56
57 #define getwd _getwd
58 #include "lisp.h"
59 #undef getwd
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 #endif
77
78 #include "nt.h"
79 #include "ndir.h"
80 #include "ntheap.h"
81
82 /* Get the current working directory. */
83 char *
84 getwd (char *dir)
85 {
86 if (GetCurrentDirectory (MAXPATHLEN, dir) > 0)
87 return dir;
88 return NULL;
89 }
90
91 #ifndef HAVE_SOCKETS
92 /* Emulate gethostname. */
93 int
94 gethostname (char *buffer, int size)
95 {
96 /* NT only allows small host names, so the buffer is
97 certainly large enough. */
98 return !GetComputerName (buffer, &size);
99 }
100 #endif /* HAVE_SOCKETS */
101
102 /* Emulate getloadavg. */
103 int
104 getloadavg (double loadavg[], int nelem)
105 {
106 int i;
107
108 /* A faithful emulation is going to have to be saved for a rainy day. */
109 for (i = 0; i < nelem; i++)
110 {
111 loadavg[i] = 0.0;
112 }
113 return i;
114 }
115
116 /* Emulate the Unix directory procedures opendir, closedir,
117 and readdir. We can't use the procedures supplied in sysdep.c,
118 so we provide them here. */
119
120 struct direct dir_static; /* simulated directory contents */
121 static HANDLE dir_find_handle = INVALID_HANDLE_VALUE;
122 static int dir_is_fat;
123 static char dir_pathname[MAXPATHLEN+1];
124
125 DIR *
126 opendir (char *filename)
127 {
128 DIR *dirp;
129
130 /* Opening is done by FindFirstFile. However, a read is inherent to
131 this operation, so we defer the open until read time. */
132
133 if (!(dirp = (DIR *) malloc (sizeof (DIR))))
134 return NULL;
135 if (dir_find_handle != INVALID_HANDLE_VALUE)
136 return NULL;
137
138 dirp->dd_fd = 0;
139 dirp->dd_loc = 0;
140 dirp->dd_size = 0;
141
142 strncpy (dir_pathname, filename, MAXPATHLEN);
143 dir_pathname[MAXPATHLEN] = '\0';
144 dir_is_fat = is_fat_volume (filename, NULL);
145
146 return dirp;
147 }
148
149 void
150 closedir (DIR *dirp)
151 {
152 /* If we have a find-handle open, close it. */
153 if (dir_find_handle != INVALID_HANDLE_VALUE)
154 {
155 FindClose (dir_find_handle);
156 dir_find_handle = INVALID_HANDLE_VALUE;
157 }
158 xfree ((char *) dirp);
159 }
160
161 struct direct *
162 readdir (DIR *dirp)
163 {
164 WIN32_FIND_DATA find_data;
165
166 /* If we aren't dir_finding, do a find-first, otherwise do a find-next. */
167 if (dir_find_handle == INVALID_HANDLE_VALUE)
168 {
169 char filename[MAXNAMLEN + 3];
170 int ln;
171
172 strcpy (filename, dir_pathname);
173 ln = strlen (filename) - 1;
174 if (!IS_DIRECTORY_SEP (filename[ln]))
175 strcat (filename, "\\");
176 strcat (filename, "*");
177
178 dir_find_handle = FindFirstFile (filename, &find_data);
179
180 if (dir_find_handle == INVALID_HANDLE_VALUE)
181 return NULL;
182 }
183 else
184 {
185 if (!FindNextFile (dir_find_handle, &find_data))
186 return NULL;
187 }
188
189 /* Emacs never uses this value, so don't bother making it match
190 value returned by stat(). */
191 dir_static.d_ino = 1;
192
193 dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 +
194 dir_static.d_namlen - dir_static.d_namlen % 4;
195
196 dir_static.d_namlen = strlen (find_data.cFileName);
197 strcpy (dir_static.d_name, find_data.cFileName);
198 if (dir_is_fat)
199 _strlwr (dir_static.d_name);
200
201 return &dir_static;
202 }
203
204 /* Emulate getpwuid, getpwnam and others. */
205
206 #define PASSWD_FIELD_SIZE 256
207
208 static char the_passwd_name[PASSWD_FIELD_SIZE];
209 static char the_passwd_passwd[PASSWD_FIELD_SIZE];
210 static char the_passwd_gecos[PASSWD_FIELD_SIZE];
211 static char the_passwd_dir[PASSWD_FIELD_SIZE];
212 static char the_passwd_shell[PASSWD_FIELD_SIZE];
213
214 static struct passwd the_passwd =
215 {
216 the_passwd_name,
217 the_passwd_passwd,
218 0,
219 0,
220 0,
221 the_passwd_gecos,
222 the_passwd_dir,
223 the_passwd_shell,
224 };
225
226 int
227 getuid ()
228 {
229 return the_passwd.pw_uid;
230 }
231
232 int
233 geteuid ()
234 {
235 /* I could imagine arguing for checking to see whether the user is
236 in the Administrators group and returning a UID of 0 for that
237 case, but I don't know how wise that would be in the long run. */
238 return getuid ();
239 }
240
241 int
242 getgid ()
243 {
244 return the_passwd.pw_gid;
245 }
246
247 int
248 getegid ()
249 {
250 return getgid ();
251 }
252
253 struct passwd *
254 getpwuid (int uid)
255 {
256 if (uid == the_passwd.pw_uid)
257 return &the_passwd;
258 return NULL;
259 }
260
261 struct passwd *
262 getpwnam (char *name)
263 {
264 struct passwd *pw;
265
266 pw = getpwuid (getuid ());
267 if (!pw)
268 return pw;
269
270 if (stricmp (name, pw->pw_name))
271 return NULL;
272
273 return pw;
274 }
275
276 void
277 init_user_info ()
278 {
279 /* Find the user's real name by opening the process token and
280 looking up the name associated with the user-sid in that token.
281
282 Use the relative portion of the identifier authority value from
283 the user-sid as the user id value (same for group id using the
284 primary group sid from the process token). */
285
286 char user_sid[256], name[256], domain[256];
287 DWORD length = sizeof (name), dlength = sizeof (domain), trash;
288 HANDLE token = NULL;
289 SID_NAME_USE user_type;
290
291 if (OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &token)
292 && GetTokenInformation (token, TokenUser,
293 (PVOID) user_sid, sizeof (user_sid), &trash)
294 && LookupAccountSid (NULL, *((PSID *) user_sid), name, &length,
295 domain, &dlength, &user_type))
296 {
297 strcpy (the_passwd.pw_name, name);
298 /* Determine a reasonable uid value. */
299 if (stricmp ("administrator", name) == 0)
300 {
301 the_passwd.pw_uid = 0;
302 the_passwd.pw_gid = 0;
303 }
304 else
305 {
306 SID_IDENTIFIER_AUTHORITY * pSIA;
307
308 pSIA = GetSidIdentifierAuthority (*((PSID *) user_sid));
309 /* I believe the relative portion is the last 4 bytes (of 6)
310 with msb first. */
311 the_passwd.pw_uid = ((pSIA->Value[2] << 24) +
312 (pSIA->Value[3] << 16) +
313 (pSIA->Value[4] << 8) +
314 (pSIA->Value[5] << 0));
315 /* restrict to conventional uid range for normal users */
316 the_passwd.pw_uid = the_passwd.pw_uid % 60001;
317
318 /* Get group id */
319 if (GetTokenInformation (token, TokenPrimaryGroup,
320 (PVOID) user_sid, sizeof (user_sid), &trash))
321 {
322 SID_IDENTIFIER_AUTHORITY * pSIA;
323
324 pSIA = GetSidIdentifierAuthority (*((PSID *) user_sid));
325 the_passwd.pw_gid = ((pSIA->Value[2] << 24) +
326 (pSIA->Value[3] << 16) +
327 (pSIA->Value[4] << 8) +
328 (pSIA->Value[5] << 0));
329 /* I don't know if this is necessary, but for safety... */
330 the_passwd.pw_gid = the_passwd.pw_gid % 60001;
331 }
332 else
333 the_passwd.pw_gid = the_passwd.pw_uid;
334 }
335 }
336 /* If security calls are not supported (presumably because we
337 are running under Windows 95), fallback to this. */
338 else if (GetUserName (name, &length))
339 {
340 strcpy (the_passwd.pw_name, name);
341 if (stricmp ("administrator", name) == 0)
342 the_passwd.pw_uid = 0;
343 else
344 the_passwd.pw_uid = 123;
345 the_passwd.pw_gid = the_passwd.pw_uid;
346 }
347 else
348 {
349 strcpy (the_passwd.pw_name, "unknown");
350 the_passwd.pw_uid = 123;
351 the_passwd.pw_gid = 123;
352 }
353
354 /* Ensure HOME and SHELL are defined. */
355 if (getenv ("HOME") == NULL)
356 putenv ("HOME=c:/");
357 if (getenv ("SHELL") == NULL)
358 putenv ((GetVersion () & 0x80000000) ? "SHELL=command" : "SHELL=cmd");
359
360 /* Set dir and shell from environment variables. */
361 strcpy (the_passwd.pw_dir, getenv ("HOME"));
362 strcpy (the_passwd.pw_shell, getenv ("SHELL"));
363
364 if (token)
365 CloseHandle (token);
366 }
367
368 int
369 random ()
370 {
371 /* rand () on NT gives us 15 random bits...hack together 30 bits. */
372 return ((rand () << 15) | rand ());
373 }
374
375 void
376 srandom (int seed)
377 {
378 srand (seed);
379 }
380
381 /* Destructively turn backslashes into slashes. */
382 void
383 dostounix_filename (p)
384 register char *p;
385 {
386 while (*p)
387 {
388 if (*p == '\\')
389 *p = '/';
390 p++;
391 }
392 }
393
394 /* Destructively turn slashes into backslashes. */
395 void
396 unixtodos_filename (p)
397 register char *p;
398 {
399 while (*p)
400 {
401 if (*p == '/')
402 *p = '\\';
403 p++;
404 }
405 }
406
407 /* Remove all CR's that are followed by a LF.
408 (From msdos.c...probably should figure out a way to share it,
409 although this code isn't going to ever change.) */
410 int
411 crlf_to_lf (n, buf)
412 register int n;
413 register unsigned char *buf;
414 {
415 unsigned char *np = buf;
416 unsigned char *startp = buf;
417 unsigned char *endp = buf + n;
418
419 if (n == 0)
420 return n;
421 while (buf < endp - 1)
422 {
423 if (*buf == 0x0d)
424 {
425 if (*(++buf) != 0x0a)
426 *np++ = 0x0d;
427 }
428 else
429 *np++ = *buf++;
430 }
431 if (buf < endp)
432 *np++ = *buf++;
433 return np - startp;
434 }
435
436 /* Routines that are no-ops on NT but are defined to get Emacs to compile. */
437
438 int
439 sigsetmask (int signal_mask)
440 {
441 return 0;
442 }
443
444 int
445 sigblock (int sig)
446 {
447 return 0;
448 }
449
450 int
451 setpgrp (int pid, int gid)
452 {
453 return 0;
454 }
455
456 int
457 alarm (int seconds)
458 {
459 return 0;
460 }
461
462 int
463 unrequest_sigio (void)
464 {
465 return 0;
466 }
467
468 int
469 request_sigio (void)
470 {
471 return 0;
472 }
473
474 #define REG_ROOT "SOFTWARE\\GNU\\Emacs"
475
476 LPBYTE
477 nt_get_resource (key, lpdwtype)
478 char *key;
479 LPDWORD lpdwtype;
480 {
481 LPBYTE lpvalue;
482 HKEY hrootkey = NULL;
483 DWORD cbData;
484 BOOL ok = FALSE;
485
486 /* Check both the current user and the local machine to see if
487 we have any resources. */
488
489 if (RegOpenKeyEx (HKEY_CURRENT_USER, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
490 {
491 lpvalue = NULL;
492
493 if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS
494 && (lpvalue = (LPBYTE) xmalloc (cbData)) != NULL
495 && RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
496 {
497 return (lpvalue);
498 }
499
500 if (lpvalue) xfree (lpvalue);
501
502 RegCloseKey (hrootkey);
503 }
504
505 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
506 {
507 lpvalue = NULL;
508
509 if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS &&
510 (lpvalue = (LPBYTE) xmalloc (cbData)) != NULL &&
511 RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
512 {
513 return (lpvalue);
514 }
515
516 if (lpvalue) xfree (lpvalue);
517
518 RegCloseKey (hrootkey);
519 }
520
521 return (NULL);
522 }
523
524 void
525 init_environment ()
526 {
527 /* Check for environment variables and use registry if they don't exist */
528 {
529 int i;
530 LPBYTE lpval;
531 DWORD dwType;
532
533 static char * env_vars[] =
534 {
535 "HOME",
536 "emacs_dir",
537 "EMACSLOADPATH",
538 "SHELL",
539 "EMACSDATA",
540 "EMACSPATH",
541 "EMACSLOCKDIR",
542 "INFOPATH",
543 "EMACSDOC",
544 "TERM",
545 };
546
547 for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++)
548 {
549 if (!getenv (env_vars[i]) &&
550 (lpval = nt_get_resource (env_vars[i], &dwType)) != NULL)
551 {
552 if (dwType == REG_EXPAND_SZ)
553 {
554 char buf1[500], buf2[500];
555
556 ExpandEnvironmentStrings ((LPSTR) lpval, buf1, 500);
557 _snprintf (buf2, 499, "%s=%s", env_vars[i], buf1);
558 putenv (strdup (buf2));
559 }
560 else if (dwType == REG_SZ)
561 {
562 char buf[500];
563
564 _snprintf (buf, 499, "%s=%s", env_vars[i], lpval);
565 putenv (strdup (buf));
566 }
567
568 xfree (lpval);
569 }
570 }
571 }
572
573 init_user_info ();
574 }
575
576 /* We don't have scripts to automatically determine the system configuration
577 for Emacs before it's compiled, and we don't want to have to make the
578 user enter it, so we define EMACS_CONFIGURATION to invoke this runtime
579 routine. */
580
581 static char configuration_buffer[32];
582
583 char *
584 get_emacs_configuration (void)
585 {
586 char *arch, *oem, *os;
587
588 /* Determine the processor type. */
589 switch (get_processor_type ())
590 {
591
592 #ifdef PROCESSOR_INTEL_386
593 case PROCESSOR_INTEL_386:
594 case PROCESSOR_INTEL_486:
595 case PROCESSOR_INTEL_PENTIUM:
596 arch = "i386";
597 break;
598 #endif
599
600 #ifdef PROCESSOR_INTEL_860
601 case PROCESSOR_INTEL_860:
602 arch = "i860";
603 break;
604 #endif
605
606 #ifdef PROCESSOR_MIPS_R2000
607 case PROCESSOR_MIPS_R2000:
608 case PROCESSOR_MIPS_R3000:
609 case PROCESSOR_MIPS_R4000:
610 arch = "mips";
611 break;
612 #endif
613
614 #ifdef PROCESSOR_ALPHA_21064
615 case PROCESSOR_ALPHA_21064:
616 arch = "alpha";
617 break;
618 #endif
619
620 default:
621 arch = "unknown";
622 break;
623 }
624
625 /* Let oem be "*" until we figure out how to decode the OEM field. */
626 oem = "*";
627
628 os = (GetVersion () & 0x80000000) ? "win95" : "nt";
629
630 sprintf (configuration_buffer, "%s-%s-%s%d.%d", arch, oem, os,
631 get_nt_major_version (), get_nt_minor_version ());
632 return configuration_buffer;
633 }
634
635 #include <sys/timeb.h>
636
637 /* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */
638 void
639 gettimeofday (struct timeval *tv, struct timezone *tz)
640 {
641 struct _timeb tb;
642 _ftime (&tb);
643
644 tv->tv_sec = tb.time;
645 tv->tv_usec = tb.millitm * 1000L;
646 if (tz)
647 {
648 tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich */
649 tz->tz_dsttime = tb.dstflag; /* type of dst correction */
650 }
651 }
652
653 /* ------------------------------------------------------------------------- */
654 /* IO support and wrapper functions for Win32 API. */
655 /* ------------------------------------------------------------------------- */
656
657 /* Place a wrapper around the MSVC version of ctime. It returns NULL
658 on network directories, so we handle that case here.
659 (Ulrich Leodolter, 1/11/95). */
660 char *
661 sys_ctime (const time_t *t)
662 {
663 char *str = (char *) ctime (t);
664 return (str ? str : "Sun Jan 01 00:00:00 1970");
665 }
666
667 /* Emulate sleep...we could have done this with a define, but that
668 would necessitate including windows.h in the files that used it.
669 This is much easier. */
670 void
671 sys_sleep (int seconds)
672 {
673 Sleep (seconds * 1000);
674 }
675
676 /* Internal MSVC data and functions for low-level descriptor munging */
677 #if (_MSC_VER == 900)
678 extern char _osfile[];
679 #endif
680 extern int __cdecl _set_osfhnd (int fd, long h);
681 extern int __cdecl _free_osfhnd (int fd);
682
683 /* parallel array of private info on file handles */
684 filedesc fd_info [ MAXDESC ];
685
686 static struct {
687 DWORD serialnum;
688 DWORD maxcomp;
689 DWORD flags;
690 char name[32];
691 char type[32];
692 } volume_info;
693
694 /* Get information on the volume where name is held; set path pointer to
695 start of pathname in name (past UNC header\volume header if present). */
696 int
697 get_volume_info (const char * name, const char ** pPath)
698 {
699 char temp[MAX_PATH];
700 char *rootname = NULL; /* default to current volume */
701
702 if (name == NULL)
703 return FALSE;
704
705 /* find the root name of the volume if given */
706 if (isalpha (name[0]) && name[1] == ':')
707 {
708 rootname = temp;
709 temp[0] = *name++;
710 temp[1] = *name++;
711 temp[2] = '\\';
712 temp[3] = 0;
713 }
714 else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1]))
715 {
716 char *str = temp;
717 int slashes = 4;
718 rootname = temp;
719 do
720 {
721 if (IS_DIRECTORY_SEP (*name) && --slashes == 0)
722 break;
723 *str++ = *name++;
724 }
725 while ( *name );
726
727 *str++ = '\\';
728 *str = 0;
729 }
730
731 if (pPath)
732 *pPath = name;
733
734 if (GetVolumeInformation (rootname,
735 volume_info.name, 32,
736 &volume_info.serialnum,
737 &volume_info.maxcomp,
738 &volume_info.flags,
739 volume_info.type, 32))
740 {
741 return TRUE;
742 }
743 return FALSE;
744 }
745
746 /* Determine if volume is FAT format (ie. only supports short 8.3
747 names); also set path pointer to start of pathname in name. */
748 int
749 is_fat_volume (const char * name, const char ** pPath)
750 {
751 if (get_volume_info (name, pPath))
752 return (volume_info.maxcomp == 12);
753 return FALSE;
754 }
755
756 /* Map filename to a legal 8.3 name if necessary. */
757 const char *
758 map_win32_filename (const char * name, const char ** pPath)
759 {
760 static char shortname[MAX_PATH];
761 char * str = shortname;
762 char c;
763 char * path;
764
765 if (is_fat_volume (name, &path)) /* truncate to 8.3 */
766 {
767 register int left = 8; /* maximum number of chars in part */
768 register int extn = 0; /* extension added? */
769 register int dots = 2; /* maximum number of dots allowed */
770
771 while (name < path)
772 *str++ = *name++; /* skip past UNC header */
773
774 while ((c = *name++))
775 {
776 switch ( c )
777 {
778 case '\\':
779 case '/':
780 *str++ = '\\';
781 extn = 0; /* reset extension flags */
782 dots = 2; /* max 2 dots */
783 left = 8; /* max length 8 for main part */
784 break;
785 case ':':
786 *str++ = ':';
787 extn = 0; /* reset extension flags */
788 dots = 2; /* max 2 dots */
789 left = 8; /* max length 8 for main part */
790 break;
791 case '.':
792 if ( dots )
793 {
794 /* Convert path components of the form .xxx to _xxx,
795 but leave . and .. as they are. This allows .emacs
796 to be read as _emacs, for example. */
797
798 if (! *name ||
799 *name == '.' ||
800 IS_DIRECTORY_SEP (*name))
801 {
802 *str++ = '.';
803 dots--;
804 }
805 else
806 {
807 *str++ = '_';
808 left--;
809 dots = 0;
810 }
811 }
812 else if ( !extn )
813 {
814 *str++ = '.';
815 extn = 1; /* we've got an extension */
816 left = 3; /* 3 chars in extension */
817 }
818 else
819 {
820 /* any embedded dots after the first are converted to _ */
821 *str++ = '_';
822 }
823 break;
824 case '~':
825 case '#': /* don't lose these, they're important */
826 if ( ! left )
827 str[-1] = c; /* replace last character of part */
828 /* FALLTHRU */
829 default:
830 if ( left )
831 {
832 *str++ = tolower (c); /* map to lower case (looks nicer) */
833 left--;
834 dots = 0; /* started a path component */
835 }
836 break;
837 }
838 }
839 *str = '\0';
840 }
841 else
842 {
843 strcpy (shortname, name);
844 unixtodos_filename (shortname);
845 }
846
847 if (pPath)
848 *pPath = shortname + (path - name);
849
850 return shortname;
851 }
852
853
854 /* Shadow some MSVC runtime functions to map requests for long filenames
855 to reasonable short names if necessary. This was originally added to
856 permit running Emacs on NT 3.1 on a FAT partition, which doesn't support
857 long file names. */
858
859 int
860 sys_access (const char * path, int mode)
861 {
862 return _access (map_win32_filename (path, NULL), mode);
863 }
864
865 int
866 sys_chdir (const char * path)
867 {
868 return _chdir (map_win32_filename (path, NULL));
869 }
870
871 int
872 sys_chmod (const char * path, int mode)
873 {
874 return _chmod (map_win32_filename (path, NULL), mode);
875 }
876
877 int
878 sys_creat (const char * path, int mode)
879 {
880 return _creat (map_win32_filename (path, NULL), mode);
881 }
882
883 FILE *
884 sys_fopen(const char * path, const char * mode)
885 {
886 int fd;
887 int oflag;
888 const char * mode_save = mode;
889
890 /* Force all file handles to be non-inheritable. This is necessary to
891 ensure child processes don't unwittingly inherit handles that might
892 prevent future file access. */
893
894 if (mode[0] == 'r')
895 oflag = O_RDONLY;
896 else if (mode[0] == 'w' || mode[0] == 'a')
897 oflag = O_WRONLY | O_CREAT | O_TRUNC;
898 else
899 return NULL;
900
901 /* Only do simplistic option parsing. */
902 while (*++mode)
903 if (mode[0] == '+')
904 {
905 oflag &= ~(O_RDONLY | O_WRONLY);
906 oflag |= O_RDWR;
907 }
908 else if (mode[0] == 'b')
909 {
910 oflag &= ~O_TEXT;
911 oflag |= O_BINARY;
912 }
913 else if (mode[0] == 't')
914 {
915 oflag &= ~O_BINARY;
916 oflag |= O_TEXT;
917 }
918 else break;
919
920 fd = _open (map_win32_filename (path, NULL), oflag | _O_NOINHERIT, 0644);
921 if (fd < 0)
922 return NULL;
923
924 return fdopen (fd, mode_save);
925 }
926
927 int
928 sys_link (const char * path1, const char * path2)
929 {
930 errno = EINVAL;
931 return -1;
932 }
933
934 int
935 sys_mkdir (const char * path)
936 {
937 return _mkdir (map_win32_filename (path, NULL));
938 }
939
940 char *
941 sys_mktemp (char * template)
942 {
943 return (char *) map_win32_filename ((const char *) _mktemp (template), NULL);
944 }
945
946 int
947 sys_open (const char * path, int oflag, int mode)
948 {
949 /* Force all file handles to be non-inheritable. */
950 return _open (map_win32_filename (path, NULL), oflag | _O_NOINHERIT, mode);
951 }
952
953 int
954 sys_rename (const char * oldname, const char * newname)
955 {
956 char temp[MAX_PATH];
957
958 /* MoveFile on Win95 doesn't correctly change the short file name
959 alias when oldname has a three char extension and newname has the
960 same first three chars in its extension. To avoid problems, on
961 Win95 we rename to a temporary name first. */
962
963 strcpy (temp, map_win32_filename (oldname, NULL));
964
965 if (GetVersion () & 0x80000000)
966 {
967 char * p;
968
969 unixtodos_filename (temp);
970 if (p = strrchr (temp, '\\'))
971 p++;
972 else
973 p = temp;
974 strcpy (p, "__XXXXXX");
975 _mktemp (temp);
976 if (rename (map_win32_filename (oldname, NULL), temp) < 0)
977 return -1;
978 }
979
980 /* Emulate Unix behaviour - newname is deleted if it already exists
981 (at least if it is a file; don't do this for directories). */
982 newname = map_win32_filename (newname, NULL);
983 if (GetFileAttributes (newname) != -1)
984 {
985 _chmod (newname, 0666);
986 _unlink (newname);
987 }
988
989 return rename (temp, newname);
990 }
991
992 int
993 sys_rmdir (const char * path)
994 {
995 return _rmdir (map_win32_filename (path, NULL));
996 }
997
998 int
999 sys_unlink (const char * path)
1000 {
1001 return _unlink (map_win32_filename (path, NULL));
1002 }
1003
1004 static FILETIME utc_base_ft;
1005 static long double utc_base;
1006 static int init = 0;
1007
1008 static time_t
1009 convert_time (FILETIME ft)
1010 {
1011 long double ret;
1012
1013 if (!init)
1014 {
1015 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1016 SYSTEMTIME st;
1017
1018 st.wYear = 1970;
1019 st.wMonth = 1;
1020 st.wDay = 1;
1021 st.wHour = 0;
1022 st.wMinute = 0;
1023 st.wSecond = 0;
1024 st.wMilliseconds = 0;
1025
1026 SystemTimeToFileTime (&st, &utc_base_ft);
1027 utc_base = (long double) utc_base_ft.dwHighDateTime
1028 * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime;
1029 init = 1;
1030 }
1031
1032 if (CompareFileTime (&ft, &utc_base_ft) < 0)
1033 return 0;
1034
1035 ret = (long double) ft.dwHighDateTime * 4096 * 1024 * 1024 + ft.dwLowDateTime;
1036 ret -= utc_base;
1037 return (time_t) (ret * 1e-7);
1038 }
1039
1040 #if 0
1041 /* in case we ever have need of this */
1042 void
1043 convert_from_time_t (time_t time, FILETIME * pft)
1044 {
1045 long double tmp;
1046
1047 if (!init)
1048 {
1049 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1050 SYSTEMTIME st;
1051
1052 st.wYear = 1970;
1053 st.wMonth = 1;
1054 st.wDay = 1;
1055 st.wHour = 0;
1056 st.wMinute = 0;
1057 st.wSecond = 0;
1058 st.wMilliseconds = 0;
1059
1060 SystemTimeToFileTime (&st, &utc_base_ft);
1061 utc_base = (long double) utc_base_ft.dwHighDateTime
1062 * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime;
1063 init = 1;
1064 }
1065
1066 /* time in 100ns units since 1-Jan-1601 */
1067 tmp = (long double) time * 1e7 + utc_base;
1068 pft->dwHighDateTime = (DWORD) (tmp / (4096.0 * 1024 * 1024));
1069 pft->dwLowDateTime = (DWORD) (tmp - pft->dwHighDateTime);
1070 }
1071 #endif
1072
1073 /* "PJW" algorithm (see the "Dragon" compiler book). */
1074 static unsigned
1075 hashval (const char * str)
1076 {
1077 unsigned h = 0;
1078 unsigned g;
1079 while (*str)
1080 {
1081 h = (h << 4) + *str++;
1082 if ((g = h & 0xf0000000) != 0)
1083 h = (h ^ (g >> 24)) & 0x0fffffff;
1084 }
1085 return h;
1086 }
1087
1088 /* Return the hash value of the canonical pathname, excluding the
1089 drive/UNC header, to get a hopefully unique inode number. */
1090 static _ino_t
1091 generate_inode_val (const char * name)
1092 {
1093 char fullname[ MAX_PATH ];
1094 char * p;
1095 unsigned hash;
1096
1097 GetFullPathName (name, sizeof (fullname), fullname, &p);
1098 get_volume_info (fullname, &p);
1099 /* Normal Win32 filesystems are still case insensitive. */
1100 _strlwr (p);
1101 hash = hashval (p);
1102 return (_ino_t) (hash ^ (hash >> 16));
1103 }
1104
1105 /* MSVC stat function can't cope with UNC names and has other bugs, so
1106 replace it with our own. This also allows us to calculate consistent
1107 inode values without hacks in the main Emacs code. */
1108 int
1109 stat (const char * path, struct stat * buf)
1110 {
1111 char * name;
1112 WIN32_FIND_DATA wfd;
1113 HANDLE fh;
1114 int permission;
1115 int len;
1116 int rootdir = FALSE;
1117
1118 if (path == NULL || buf == NULL)
1119 {
1120 errno = EFAULT;
1121 return -1;
1122 }
1123
1124 name = (char *) map_win32_filename (path, &path);
1125 /* must be valid filename, no wild cards */
1126 if (strchr (name, '*') || strchr (name, '?'))
1127 {
1128 errno = ENOENT;
1129 return -1;
1130 }
1131
1132 /* Remove trailing directory separator, unless name is the root
1133 directory of a drive or UNC volume in which case ensure there
1134 is a trailing separator. */
1135 len = strlen (name);
1136 rootdir = (path >= name + len - 1
1137 && (IS_DIRECTORY_SEP (*path) || *path == 0));
1138 name = strcpy (alloca (len + 2), name);
1139
1140 if (rootdir)
1141 {
1142 if (!IS_DIRECTORY_SEP (name[len-1]))
1143 strcat (name, "\\");
1144 if (GetDriveType (name) < 2)
1145 {
1146 errno = ENOENT;
1147 return -1;
1148 }
1149 memset (&wfd, 0, sizeof (wfd));
1150 wfd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
1151 wfd.ftCreationTime = utc_base_ft;
1152 wfd.ftLastAccessTime = utc_base_ft;
1153 wfd.ftLastWriteTime = utc_base_ft;
1154 strcpy (wfd.cFileName, name);
1155 }
1156 else
1157 {
1158 if (IS_DIRECTORY_SEP (name[len-1]))
1159 name[len - 1] = 0;
1160 fh = FindFirstFile (name, &wfd);
1161 if (fh == INVALID_HANDLE_VALUE)
1162 {
1163 errno = ENOENT;
1164 return -1;
1165 }
1166 FindClose (fh);
1167 }
1168
1169 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1170 {
1171 buf->st_mode = _S_IFDIR;
1172 buf->st_nlink = 2; /* doesn't really matter */
1173 }
1174 else
1175 {
1176 #if 0
1177 /* This is more accurate in terms of gettting the correct number
1178 of links, but is quite slow (it is noticable when Emacs is
1179 making a list of file name completions). */
1180 BY_HANDLE_FILE_INFORMATION info;
1181
1182 fh = CreateFile (name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1183 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1184
1185 if (GetFileInformationByHandle (fh, &info))
1186 {
1187 switch (GetFileType (fh))
1188 {
1189 case FILE_TYPE_DISK:
1190 buf->st_mode = _S_IFREG;
1191 break;
1192 case FILE_TYPE_PIPE:
1193 buf->st_mode = _S_IFIFO;
1194 break;
1195 case FILE_TYPE_CHAR:
1196 case FILE_TYPE_UNKNOWN:
1197 default:
1198 buf->st_mode = _S_IFCHR;
1199 }
1200 buf->st_nlink = info.nNumberOfLinks;
1201 /* Could use file index, but this is not guaranteed to be
1202 unique unless we keep a handle open all the time. */
1203 /* buf->st_ino = info.nFileIndexLow ^ info.nFileIndexHigh; */
1204 CloseHandle (fh);
1205 }
1206 else
1207 {
1208 errno = EACCES;
1209 return -1;
1210 }
1211 #else
1212 buf->st_mode = _S_IFREG;
1213 buf->st_nlink = 1;
1214 #endif
1215 }
1216
1217 /* consider files to belong to current user */
1218 buf->st_uid = the_passwd.pw_uid;
1219 buf->st_gid = the_passwd.pw_gid;
1220
1221 /* volume_info is set indirectly by map_win32_filename */
1222 buf->st_dev = volume_info.serialnum;
1223 buf->st_rdev = volume_info.serialnum;
1224
1225 buf->st_ino = generate_inode_val (name);
1226
1227 buf->st_size = wfd.nFileSizeLow;
1228
1229 /* Convert timestamps to Unix format. */
1230 buf->st_mtime = convert_time (wfd.ftLastWriteTime);
1231 buf->st_atime = convert_time (wfd.ftLastAccessTime);
1232 if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
1233 buf->st_ctime = convert_time (wfd.ftCreationTime);
1234 if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
1235
1236 /* determine rwx permissions */
1237 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
1238 permission = _S_IREAD;
1239 else
1240 permission = _S_IREAD | _S_IWRITE;
1241
1242 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1243 permission |= _S_IEXEC;
1244 else
1245 {
1246 char * p = strrchr (name, '.');
1247 if (p != NULL &&
1248 (stricmp (p, ".exe") == 0 ||
1249 stricmp (p, ".com") == 0 ||
1250 stricmp (p, ".bat") == 0 ||
1251 stricmp (p, ".cmd") == 0))
1252 permission |= _S_IEXEC;
1253 }
1254
1255 buf->st_mode |= permission | (permission >> 3) | (permission >> 6);
1256
1257 return 0;
1258 }
1259
1260 #ifdef HAVE_SOCKETS
1261
1262 /* Wrappers for winsock functions to map between our file descriptors
1263 and winsock's handles; also set h_errno for convenience.
1264
1265 To allow Emacs to run on systems which don't have winsock support
1266 installed, we dynamically link to winsock on startup if present, and
1267 otherwise provide the minimum necessary functionality
1268 (eg. gethostname). */
1269
1270 /* function pointers for relevant socket functions */
1271 int (PASCAL *pfn_WSAStartup) (WORD wVersionRequired, LPWSADATA lpWSAData);
1272 void (PASCAL *pfn_WSASetLastError) (int iError);
1273 int (PASCAL *pfn_WSAGetLastError) (void);
1274 int (PASCAL *pfn_socket) (int af, int type, int protocol);
1275 int (PASCAL *pfn_bind) (SOCKET s, const struct sockaddr *addr, int namelen);
1276 int (PASCAL *pfn_connect) (SOCKET s, const struct sockaddr *addr, int namelen);
1277 int (PASCAL *pfn_ioctlsocket) (SOCKET s, long cmd, u_long *argp);
1278 int (PASCAL *pfn_recv) (SOCKET s, char * buf, int len, int flags);
1279 int (PASCAL *pfn_send) (SOCKET s, const char * buf, int len, int flags);
1280 int (PASCAL *pfn_closesocket) (SOCKET s);
1281 int (PASCAL *pfn_shutdown) (SOCKET s, int how);
1282 int (PASCAL *pfn_WSACleanup) (void);
1283
1284 u_short (PASCAL *pfn_htons) (u_short hostshort);
1285 u_short (PASCAL *pfn_ntohs) (u_short netshort);
1286 unsigned long (PASCAL *pfn_inet_addr) (const char * cp);
1287 int (PASCAL *pfn_gethostname) (char * name, int namelen);
1288 struct hostent * (PASCAL *pfn_gethostbyname) (const char * name);
1289 struct servent * (PASCAL *pfn_getservbyname) (const char * name, const char * proto);
1290
1291 static int have_winsock;
1292 static HANDLE winsock_lib;
1293
1294 static void
1295 term_winsock (void)
1296 {
1297 if (have_winsock)
1298 {
1299 pfn_WSACleanup ();
1300 FreeLibrary (winsock_lib);
1301 }
1302 }
1303
1304 static void
1305 init_winsock ()
1306 {
1307 WSADATA winsockData;
1308
1309 winsock_lib = LoadLibrary ("wsock32.dll");
1310
1311 if (winsock_lib != NULL)
1312 {
1313 /* dynamically link to socket functions */
1314
1315 #define LOAD_PROC(fn) \
1316 if ((pfn_##fn = (void *) GetProcAddress (winsock_lib, #fn)) == NULL) \
1317 goto fail;
1318
1319 LOAD_PROC( WSAStartup );
1320 LOAD_PROC( WSASetLastError );
1321 LOAD_PROC( WSAGetLastError );
1322 LOAD_PROC( socket );
1323 LOAD_PROC( bind );
1324 LOAD_PROC( connect );
1325 LOAD_PROC( ioctlsocket );
1326 LOAD_PROC( recv );
1327 LOAD_PROC( send );
1328 LOAD_PROC( closesocket );
1329 LOAD_PROC( shutdown );
1330 LOAD_PROC( htons );
1331 LOAD_PROC( ntohs );
1332 LOAD_PROC( inet_addr );
1333 LOAD_PROC( gethostname );
1334 LOAD_PROC( gethostbyname );
1335 LOAD_PROC( getservbyname );
1336 LOAD_PROC( WSACleanup );
1337
1338 /* specify version 1.1 of winsock */
1339 if (pfn_WSAStartup (0x101, &winsockData) == 0)
1340 {
1341 have_winsock = TRUE;
1342 return;
1343 }
1344
1345 fail:
1346 FreeLibrary (winsock_lib);
1347 }
1348 have_winsock = FALSE;
1349 }
1350
1351
1352 int h_errno = 0;
1353
1354 /* function to set h_errno for compatability; map winsock error codes to
1355 normal system codes where they overlap (non-overlapping definitions
1356 are already in <sys/socket.h> */
1357 static void set_errno ()
1358 {
1359 if (!have_winsock)
1360 h_errno = EINVAL;
1361 else
1362 h_errno = pfn_WSAGetLastError ();
1363
1364 switch (h_errno)
1365 {
1366 case WSAEACCES: h_errno = EACCES; break;
1367 case WSAEBADF: h_errno = EBADF; break;
1368 case WSAEFAULT: h_errno = EFAULT; break;
1369 case WSAEINTR: h_errno = EINTR; break;
1370 case WSAEINVAL: h_errno = EINVAL; break;
1371 case WSAEMFILE: h_errno = EMFILE; break;
1372 case WSAENAMETOOLONG: h_errno = ENAMETOOLONG; break;
1373 case WSAENOTEMPTY: h_errno = ENOTEMPTY; break;
1374 }
1375 errno = h_errno;
1376 }
1377
1378 static void check_errno ()
1379 {
1380 if (h_errno == 0 && have_winsock)
1381 pfn_WSASetLastError (0);
1382 }
1383
1384 /* [andrewi 3-May-96] I've had conflicting results using both methods,
1385 but I believe the method of keeping the socket handle separate (and
1386 insuring it is not inheritable) is the correct one. */
1387
1388 //#define SOCK_REPLACE_HANDLE
1389
1390 #ifdef SOCK_REPLACE_HANDLE
1391 #define SOCK_HANDLE(fd) ((SOCKET) _get_osfhandle (fd))
1392 #else
1393 #define SOCK_HANDLE(fd) ((SOCKET) fd_info[fd].hnd)
1394 #endif
1395
1396 int
1397 sys_socket(int af, int type, int protocol)
1398 {
1399 int fd;
1400 long s;
1401 child_process * cp;
1402
1403 if (!have_winsock)
1404 {
1405 h_errno = ENETDOWN;
1406 return INVALID_SOCKET;
1407 }
1408
1409 check_errno ();
1410
1411 /* call the real socket function */
1412 s = (long) pfn_socket (af, type, protocol);
1413
1414 if (s != INVALID_SOCKET)
1415 {
1416 /* Although under NT 3.5 _open_osfhandle will accept a socket
1417 handle, if opened with SO_OPENTYPE == SO_SYNCHRONOUS_NONALERT,
1418 that does not work under NT 3.1. However, we can get the same
1419 effect by using a backdoor function to replace an existing
1420 descriptor handle with the one we want. */
1421
1422 /* allocate a file descriptor (with appropriate flags) */
1423 fd = _open ("NUL:", _O_RDWR);
1424 if (fd >= 0)
1425 {
1426 #ifdef SOCK_REPLACE_HANDLE
1427 /* now replace handle to NUL with our socket handle */
1428 CloseHandle ((HANDLE) _get_osfhandle (fd));
1429 _free_osfhnd (fd);
1430 _set_osfhnd (fd, s);
1431 /* setmode (fd, _O_BINARY); */
1432 #else
1433 /* Make a non-inheritable copy of the socket handle. */
1434 {
1435 HANDLE parent;
1436 HANDLE new_s = INVALID_HANDLE_VALUE;
1437
1438 parent = GetCurrentProcess ();
1439
1440 DuplicateHandle (parent,
1441 (HANDLE) s,
1442 parent,
1443 &new_s,
1444 0,
1445 FALSE,
1446 DUPLICATE_SAME_ACCESS);
1447 pfn_closesocket (s);
1448 fd_info[fd].hnd = new_s;
1449 s = (SOCKET) new_s;
1450 }
1451 #endif
1452
1453 /* set our own internal flags */
1454 fd_info[fd].flags = FILE_SOCKET | FILE_BINARY | FILE_READ | FILE_WRITE;
1455
1456 cp = new_child ();
1457 if (cp)
1458 {
1459 cp->fd = fd;
1460 cp->status = STATUS_READ_ACKNOWLEDGED;
1461
1462 /* attach child_process to fd_info */
1463 if (fd_info[ fd ].cp != NULL)
1464 {
1465 DebPrint (("sys_socket: fd_info[%d] apparently in use!\n", fd));
1466 abort ();
1467 }
1468
1469 fd_info[ fd ].cp = cp;
1470
1471 /* success! */
1472 return fd;
1473 }
1474
1475 /* clean up */
1476 _close (fd);
1477 }
1478 pfn_closesocket (s);
1479 h_errno = EMFILE;
1480 }
1481 set_errno ();
1482
1483 return -1;
1484 }
1485
1486
1487 int
1488 sys_bind (int s, const struct sockaddr * addr, int namelen)
1489 {
1490 if (!have_winsock)
1491 {
1492 h_errno = ENOTSOCK;
1493 return SOCKET_ERROR;
1494 }
1495
1496 check_errno ();
1497 if (fd_info[s].flags & FILE_SOCKET)
1498 {
1499 int rc = pfn_bind (SOCK_HANDLE (s), addr, namelen);
1500 if (rc == SOCKET_ERROR)
1501 set_errno ();
1502 return rc;
1503 }
1504 h_errno = ENOTSOCK;
1505 return SOCKET_ERROR;
1506 }
1507
1508
1509 int
1510 sys_connect (int s, const struct sockaddr * name, int namelen)
1511 {
1512 if (!have_winsock)
1513 {
1514 h_errno = ENOTSOCK;
1515 return SOCKET_ERROR;
1516 }
1517
1518 check_errno ();
1519 if (fd_info[s].flags & FILE_SOCKET)
1520 {
1521 int rc = pfn_connect (SOCK_HANDLE (s), name, namelen);
1522 if (rc == SOCKET_ERROR)
1523 set_errno ();
1524 return rc;
1525 }
1526 h_errno = ENOTSOCK;
1527 return SOCKET_ERROR;
1528 }
1529
1530 u_short
1531 sys_htons (u_short hostshort)
1532 {
1533 return (have_winsock) ?
1534 pfn_htons (hostshort) : hostshort;
1535 }
1536
1537 u_short
1538 sys_ntohs (u_short netshort)
1539 {
1540 return (have_winsock) ?
1541 pfn_ntohs (netshort) : netshort;
1542 }
1543
1544 unsigned long
1545 sys_inet_addr (const char * cp)
1546 {
1547 return (have_winsock) ?
1548 pfn_inet_addr (cp) : INADDR_NONE;
1549 }
1550
1551 int
1552 sys_gethostname (char * name, int namelen)
1553 {
1554 if (have_winsock)
1555 return pfn_gethostname (name, namelen);
1556
1557 if (namelen > MAX_COMPUTERNAME_LENGTH)
1558 return !GetComputerName (name, &namelen);
1559
1560 h_errno = EFAULT;
1561 return SOCKET_ERROR;
1562 }
1563
1564 struct hostent *
1565 sys_gethostbyname(const char * name)
1566 {
1567 struct hostent * host;
1568
1569 if (!have_winsock)
1570 {
1571 h_errno = ENETDOWN;
1572 return NULL;
1573 }
1574
1575 check_errno ();
1576 host = pfn_gethostbyname (name);
1577 if (!host)
1578 set_errno ();
1579 return host;
1580 }
1581
1582 struct servent *
1583 sys_getservbyname(const char * name, const char * proto)
1584 {
1585 struct servent * serv;
1586
1587 if (!have_winsock)
1588 {
1589 h_errno = ENETDOWN;
1590 return NULL;
1591 }
1592
1593 check_errno ();
1594 serv = pfn_getservbyname (name, proto);
1595 if (!serv)
1596 set_errno ();
1597 return serv;
1598 }
1599
1600 #endif /* HAVE_SOCKETS */
1601
1602
1603 /* Shadow main io functions: we need to handle pipes and sockets more
1604 intelligently, and implement non-blocking mode as well. */
1605
1606 int
1607 sys_close (int fd)
1608 {
1609 int rc;
1610
1611 if (fd < 0 || fd >= MAXDESC)
1612 {
1613 errno = EBADF;
1614 return -1;
1615 }
1616
1617 if (fd_info[fd].cp)
1618 {
1619 child_process * cp = fd_info[fd].cp;
1620
1621 fd_info[fd].cp = NULL;
1622
1623 if (CHILD_ACTIVE (cp))
1624 {
1625 /* if last descriptor to active child_process then cleanup */
1626 int i;
1627 for (i = 0; i < MAXDESC; i++)
1628 {
1629 if (i == fd)
1630 continue;
1631 if (fd_info[i].cp == cp)
1632 break;
1633 }
1634 if (i == MAXDESC)
1635 {
1636 #if defined (HAVE_SOCKETS) && !defined (SOCK_REPLACE_HANDLE)
1637 if (fd_info[fd].flags & FILE_SOCKET)
1638 {
1639 if (!have_winsock) abort ();
1640
1641 pfn_shutdown (SOCK_HANDLE (fd), 2);
1642 rc = pfn_closesocket (SOCK_HANDLE (fd));
1643 }
1644 #endif
1645 delete_child (cp);
1646 }
1647 }
1648 }
1649
1650 /* Note that sockets do not need special treatment here (at least on
1651 NT and Win95 using the standard tcp/ip stacks) - it appears that
1652 closesocket is equivalent to CloseHandle, which is to be expected
1653 because socket handles are fully fledged kernel handles. */
1654 rc = _close (fd);
1655
1656 if (rc == 0)
1657 fd_info[fd].flags = 0;
1658
1659 return rc;
1660 }
1661
1662 int
1663 sys_dup (int fd)
1664 {
1665 int new_fd;
1666
1667 new_fd = _dup (fd);
1668 if (new_fd >= 0)
1669 {
1670 /* duplicate our internal info as well */
1671 fd_info[new_fd] = fd_info[fd];
1672 }
1673 return new_fd;
1674 }
1675
1676
1677 int
1678 sys_dup2 (int src, int dst)
1679 {
1680 int rc;
1681
1682 if (dst < 0 || dst >= MAXDESC)
1683 {
1684 errno = EBADF;
1685 return -1;
1686 }
1687
1688 /* make sure we close the destination first if it's a pipe or socket */
1689 if (src != dst && fd_info[dst].flags != 0)
1690 sys_close (dst);
1691
1692 rc = _dup2 (src, dst);
1693 if (rc == 0)
1694 {
1695 /* duplicate our internal info as well */
1696 fd_info[dst] = fd_info[src];
1697 }
1698 return rc;
1699 }
1700
1701 /* From callproc.c */
1702 extern Lisp_Object Vbinary_process_input;
1703 extern Lisp_Object Vbinary_process_output;
1704
1705 /* Unix pipe() has only one arg */
1706 int
1707 sys_pipe (int * phandles)
1708 {
1709 int rc;
1710 unsigned flags;
1711 child_process * cp;
1712
1713 /* make pipe handles non-inheritable; when we spawn a child,
1714 we replace the relevant handle with an inheritable one. */
1715 rc = _pipe (phandles, 0, _O_NOINHERIT);
1716
1717 if (rc == 0)
1718 {
1719 /* set internal flags, and put read and write handles into binary
1720 mode as necessary; if not in binary mode, set the MSVC internal
1721 FDEV (0x40) flag to prevent _read from treating ^Z as eof (this
1722 could otherwise allow Emacs to hang because it then waits
1723 indefinitely for the child process to exit, when it might not be
1724 finished). */
1725 flags = FILE_PIPE | FILE_READ;
1726 if (!NILP (Vbinary_process_output))
1727 {
1728 flags |= FILE_BINARY;
1729 setmode (phandles[0], _O_BINARY);
1730 }
1731 #if (_MSC_VER == 900)
1732 else
1733 _osfile[phandles[0]] |= 0x40;
1734 #endif
1735
1736 fd_info[phandles[0]].flags = flags;
1737
1738 flags = FILE_PIPE | FILE_WRITE;
1739 if (!NILP (Vbinary_process_input))
1740 {
1741 flags |= FILE_BINARY;
1742 setmode (phandles[1], _O_BINARY);
1743 }
1744 #if (_MSC_VER == 900)
1745 else
1746 _osfile[phandles[1]] |= 0x40;
1747 #endif
1748
1749 fd_info[phandles[1]].flags = flags;
1750 }
1751
1752 return rc;
1753 }
1754
1755 /* From ntproc.c */
1756 extern Lisp_Object Vwin32_pipe_read_delay;
1757
1758 /* Function to do blocking read of one byte, needed to implement
1759 select. It is only allowed on sockets and pipes. */
1760 int
1761 _sys_read_ahead (int fd)
1762 {
1763 child_process * cp;
1764 int rc;
1765
1766 if (fd < 0 || fd >= MAXDESC)
1767 return STATUS_READ_ERROR;
1768
1769 cp = fd_info[fd].cp;
1770
1771 if (cp == NULL || cp->fd != fd || cp->status != STATUS_READ_READY)
1772 return STATUS_READ_ERROR;
1773
1774 if ((fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET)) == 0
1775 || (fd_info[fd].flags & FILE_READ) == 0)
1776 {
1777 DebPrint (("_sys_read_ahead: internal error: fd %d is not a pipe or socket!\n", fd));
1778 abort ();
1779 }
1780
1781 cp->status = STATUS_READ_IN_PROGRESS;
1782
1783 if (fd_info[fd].flags & FILE_PIPE)
1784 {
1785 /* Use read to get CRLF translation */
1786 rc = _read (fd, &cp->chr, sizeof (char));
1787
1788 /* Give subprocess time to buffer some more output for us before
1789 reporting that input is available; we need this because Win95
1790 connects DOS programs to pipes by making the pipe appear to be
1791 the normal console stdout - as a result most DOS programs will
1792 write to stdout without buffering, ie. one character at a
1793 time. Even some Win32 programs do this - "dir" in a command
1794 shell on NT is very slow if we don't do this. */
1795 if (rc > 0)
1796 {
1797 int wait = XINT (Vwin32_pipe_read_delay);
1798
1799 if (wait > 0)
1800 Sleep (wait);
1801 else if (wait < 0)
1802 while (++wait <= 0)
1803 /* Yield remainder of our time slice, effectively giving a
1804 temporary priority boost to the child process. */
1805 Sleep (0);
1806 }
1807 }
1808 #ifdef HAVE_SOCKETS
1809 else if (fd_info[fd].flags & FILE_SOCKET)
1810 rc = pfn_recv (SOCK_HANDLE (fd), &cp->chr, sizeof (char), 0);
1811 #endif
1812
1813 if (rc == sizeof (char))
1814 cp->status = STATUS_READ_SUCCEEDED;
1815 else
1816 cp->status = STATUS_READ_FAILED;
1817
1818 return cp->status;
1819 }
1820
1821 int
1822 sys_read (int fd, char * buffer, unsigned int count)
1823 {
1824 int nchars;
1825 int extra = 0;
1826 int to_read;
1827 DWORD waiting;
1828
1829 if (fd < 0 || fd >= MAXDESC)
1830 {
1831 errno = EBADF;
1832 return -1;
1833 }
1834
1835 if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
1836 {
1837 child_process *cp = fd_info[fd].cp;
1838
1839 if ((fd_info[fd].flags & FILE_READ) == 0)
1840 {
1841 errno = EBADF;
1842 return -1;
1843 }
1844
1845 /* presence of a child_process structure means we are operating in
1846 non-blocking mode - otherwise we just call _read directly.
1847 Note that the child_process structure might be missing because
1848 reap_subprocess has been called; in this case the pipe is
1849 already broken, so calling _read on it is okay. */
1850 if (cp)
1851 {
1852 int current_status = cp->status;
1853
1854 switch (current_status)
1855 {
1856 case STATUS_READ_FAILED:
1857 case STATUS_READ_ERROR:
1858 /* report normal EOF */
1859 return 0;
1860
1861 case STATUS_READ_READY:
1862 case STATUS_READ_IN_PROGRESS:
1863 DebPrint (("sys_read called when read is in progress\n"));
1864 errno = EWOULDBLOCK;
1865 return -1;
1866
1867 case STATUS_READ_SUCCEEDED:
1868 /* consume read-ahead char */
1869 *buffer++ = cp->chr;
1870 count--;
1871 extra = 1;
1872 cp->status = STATUS_READ_ACKNOWLEDGED;
1873 ResetEvent (cp->char_avail);
1874
1875 case STATUS_READ_ACKNOWLEDGED:
1876 break;
1877
1878 default:
1879 DebPrint (("sys_read: bad status %d\n", current_status));
1880 errno = EBADF;
1881 return -1;
1882 }
1883
1884 if (fd_info[fd].flags & FILE_PIPE)
1885 {
1886 PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, &waiting, NULL);
1887 to_read = min (waiting, (DWORD) count);
1888
1889 /* Use read to get CRLF translation */
1890 nchars = _read (fd, buffer, to_read);
1891 }
1892 #ifdef HAVE_SOCKETS
1893 else /* FILE_SOCKET */
1894 {
1895 if (!have_winsock) abort ();
1896
1897 /* do the equivalent of a non-blocking read */
1898 pfn_ioctlsocket (SOCK_HANDLE (fd), FIONREAD, &waiting);
1899 if (waiting == 0 && extra == 0)
1900 {
1901 h_errno = errno = EWOULDBLOCK;
1902 return -1;
1903 }
1904
1905 nchars = 0;
1906 if (waiting)
1907 {
1908 /* always use binary mode for sockets */
1909 nchars = pfn_recv (SOCK_HANDLE (fd), buffer, count, 0);
1910 if (nchars == SOCKET_ERROR)
1911 {
1912 DebPrint(("sys_read.recv failed with error %d on socket %ld\n",
1913 pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
1914 if (extra == 0)
1915 {
1916 set_errno ();
1917 return -1;
1918 }
1919 nchars = 0;
1920 }
1921 }
1922 }
1923 #endif
1924 }
1925 else
1926 nchars = _read (fd, buffer, count);
1927 }
1928 else
1929 nchars = _read (fd, buffer, count);
1930
1931 return nchars + extra;
1932 }
1933
1934 /* For now, don't bother with a non-blocking mode */
1935 int
1936 sys_write (int fd, const void * buffer, unsigned int count)
1937 {
1938 int nchars;
1939
1940 if (fd < 0 || fd >= MAXDESC)
1941 {
1942 errno = EBADF;
1943 return -1;
1944 }
1945
1946 if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
1947 if ((fd_info[fd].flags & FILE_WRITE) == 0)
1948 {
1949 errno = EBADF;
1950 return -1;
1951 }
1952 #ifdef HAVE_SOCKETS
1953 if (fd_info[fd].flags & FILE_SOCKET)
1954 {
1955 if (!have_winsock) abort ();
1956 nchars = pfn_send (SOCK_HANDLE (fd), buffer, count, 0);
1957 if (nchars == SOCKET_ERROR)
1958 {
1959 DebPrint(("sys_read.send failed with error %d on socket %ld\n",
1960 pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
1961 set_errno ();
1962 }
1963 }
1964 else
1965 #endif
1966 nchars = _write (fd, buffer, count);
1967
1968 return nchars;
1969 }
1970
1971
1972 void
1973 term_ntproc ()
1974 {
1975 #ifdef HAVE_SOCKETS
1976 /* shutdown the socket interface if necessary */
1977 term_winsock ();
1978 #endif
1979 }
1980
1981 extern BOOL can_run_dos_process;
1982 extern BOOL dos_process_running;
1983
1984 void
1985 init_ntproc ()
1986 {
1987 #ifdef HAVE_SOCKETS
1988 /* initialise the socket interface if available */
1989 init_winsock ();
1990 #endif
1991
1992 /* Initial preparation for subprocess support: replace our standard
1993 handles with non-inheritable versions. */
1994 {
1995 HANDLE parent;
1996 HANDLE stdin_save = INVALID_HANDLE_VALUE;
1997 HANDLE stdout_save = INVALID_HANDLE_VALUE;
1998 HANDLE stderr_save = INVALID_HANDLE_VALUE;
1999
2000 parent = GetCurrentProcess ();
2001
2002 /* ignore errors when duplicating and closing; typically the
2003 handles will be invalid when running as a gui program. */
2004 DuplicateHandle (parent,
2005 GetStdHandle (STD_INPUT_HANDLE),
2006 parent,
2007 &stdin_save,
2008 0,
2009 FALSE,
2010 DUPLICATE_SAME_ACCESS);
2011
2012 DuplicateHandle (parent,
2013 GetStdHandle (STD_OUTPUT_HANDLE),
2014 parent,
2015 &stdout_save,
2016 0,
2017 FALSE,
2018 DUPLICATE_SAME_ACCESS);
2019
2020 DuplicateHandle (parent,
2021 GetStdHandle (STD_ERROR_HANDLE),
2022 parent,
2023 &stderr_save,
2024 0,
2025 FALSE,
2026 DUPLICATE_SAME_ACCESS);
2027
2028 fclose (stdin);
2029 fclose (stdout);
2030 fclose (stderr);
2031
2032 if (stdin_save != INVALID_HANDLE_VALUE)
2033 _open_osfhandle ((long) stdin_save, O_TEXT);
2034 else
2035 open ("nul", O_TEXT | O_NOINHERIT | O_RDONLY);
2036 fdopen (0, "r");
2037
2038 if (stdout_save != INVALID_HANDLE_VALUE)
2039 _open_osfhandle ((long) stdout_save, O_TEXT);
2040 else
2041 open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
2042 fdopen (1, "w");
2043
2044 if (stderr_save != INVALID_HANDLE_VALUE)
2045 _open_osfhandle ((long) stderr_save, O_TEXT);
2046 else
2047 open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
2048 fdopen (2, "w");
2049 }
2050
2051 /* Only allow Emacs to run DOS programs on Win95. */
2052 can_run_dos_process = (GetVersion () & 0x80000000);
2053 dos_process_running = FALSE;
2054
2055 /* unfortunately, atexit depends on implementation of malloc */
2056 /* atexit (term_ntproc); */
2057 signal (SIGABRT, term_ntproc);
2058 }
2059
2060 /* end of nt.c */