(_sys_read_ahead): Handle sleep here.
[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 if (slashes > 1)
728 return FALSE;
729
730 *str++ = '\\';
731 *str = 0;
732 }
733
734 if (pPath)
735 *pPath = name;
736
737 if (GetVolumeInformation (rootname,
738 volume_info.name, 32,
739 &volume_info.serialnum,
740 &volume_info.maxcomp,
741 &volume_info.flags,
742 volume_info.type, 32))
743 {
744 return TRUE;
745 }
746 return FALSE;
747 }
748
749 /* Determine if volume is FAT format (ie. only supports short 8.3
750 names); also set path pointer to start of pathname in name. */
751 int
752 is_fat_volume (const char * name, const char ** pPath)
753 {
754 if (get_volume_info (name, pPath))
755 return (volume_info.maxcomp == 12);
756 return FALSE;
757 }
758
759 /* Map filename to a legal 8.3 name if necessary. */
760 const char *
761 map_win32_filename (const char * name, const char ** pPath)
762 {
763 static char shortname[MAX_PATH];
764 char * str = shortname;
765 char c;
766 char * path;
767
768 if (is_fat_volume (name, &path)) /* truncate to 8.3 */
769 {
770 register int left = 8; /* maximum number of chars in part */
771 register int extn = 0; /* extension added? */
772 register int dots = 2; /* maximum number of dots allowed */
773
774 while (name < path)
775 *str++ = *name++; /* skip past UNC header */
776
777 while ((c = *name++))
778 {
779 switch ( c )
780 {
781 case '\\':
782 case '/':
783 *str++ = '\\';
784 extn = 0; /* reset extension flags */
785 dots = 2; /* max 2 dots */
786 left = 8; /* max length 8 for main part */
787 break;
788 case ':':
789 *str++ = ':';
790 extn = 0; /* reset extension flags */
791 dots = 2; /* max 2 dots */
792 left = 8; /* max length 8 for main part */
793 break;
794 case '.':
795 if ( dots )
796 {
797 /* Convert path components of the form .xxx to _xxx,
798 but leave . and .. as they are. This allows .emacs
799 to be read as _emacs, for example. */
800
801 if (! *name ||
802 *name == '.' ||
803 IS_DIRECTORY_SEP (*name))
804 {
805 *str++ = '.';
806 dots--;
807 }
808 else
809 {
810 *str++ = '_';
811 left--;
812 dots = 0;
813 }
814 }
815 else if ( !extn )
816 {
817 *str++ = '.';
818 extn = 1; /* we've got an extension */
819 left = 3; /* 3 chars in extension */
820 }
821 else
822 {
823 /* any embedded dots after the first are converted to _ */
824 *str++ = '_';
825 }
826 break;
827 case '~':
828 case '#': /* don't lose these, they're important */
829 if ( ! left )
830 str[-1] = c; /* replace last character of part */
831 /* FALLTHRU */
832 default:
833 if ( left )
834 {
835 *str++ = tolower (c); /* map to lower case (looks nicer) */
836 left--;
837 dots = 0; /* started a path component */
838 }
839 break;
840 }
841 }
842 *str = '\0';
843 }
844 else
845 {
846 strcpy (shortname, name);
847 unixtodos_filename (shortname);
848 }
849
850 if (pPath)
851 *pPath = shortname + (path - name);
852
853 return shortname;
854 }
855
856
857 /* Shadow some MSVC runtime functions to map requests for long filenames
858 to reasonable short names if necessary. This was originally added to
859 permit running Emacs on NT 3.1 on a FAT partition, which doesn't support
860 long file names. */
861
862 int
863 sys_access (const char * path, int mode)
864 {
865 return _access (map_win32_filename (path, NULL), mode);
866 }
867
868 int
869 sys_chdir (const char * path)
870 {
871 return _chdir (map_win32_filename (path, NULL));
872 }
873
874 int
875 sys_chmod (const char * path, int mode)
876 {
877 return _chmod (map_win32_filename (path, NULL), mode);
878 }
879
880 int
881 sys_creat (const char * path, int mode)
882 {
883 return _creat (map_win32_filename (path, NULL), mode);
884 }
885
886 FILE *
887 sys_fopen(const char * path, const char * mode)
888 {
889 int fd;
890 int oflag;
891 const char * mode_save = mode;
892
893 /* Force all file handles to be non-inheritable. This is necessary to
894 ensure child processes don't unwittingly inherit handles that might
895 prevent future file access. */
896
897 if (mode[0] == 'r')
898 oflag = O_RDONLY;
899 else if (mode[0] == 'w' || mode[0] == 'a')
900 oflag = O_WRONLY | O_CREAT | O_TRUNC;
901 else
902 return NULL;
903
904 /* Only do simplistic option parsing. */
905 while (*++mode)
906 if (mode[0] == '+')
907 {
908 oflag &= ~(O_RDONLY | O_WRONLY);
909 oflag |= O_RDWR;
910 }
911 else if (mode[0] == 'b')
912 {
913 oflag &= ~O_TEXT;
914 oflag |= O_BINARY;
915 }
916 else if (mode[0] == 't')
917 {
918 oflag &= ~O_BINARY;
919 oflag |= O_TEXT;
920 }
921 else break;
922
923 fd = _open (map_win32_filename (path, NULL), oflag | _O_NOINHERIT, 0644);
924 if (fd < 0)
925 return NULL;
926
927 return fdopen (fd, mode_save);
928 }
929
930 int
931 sys_link (const char * path1, const char * path2)
932 {
933 errno = EINVAL;
934 return -1;
935 }
936
937 int
938 sys_mkdir (const char * path)
939 {
940 return _mkdir (map_win32_filename (path, NULL));
941 }
942
943 char *
944 sys_mktemp (char * template)
945 {
946 return (char *) map_win32_filename ((const char *) _mktemp (template), NULL);
947 }
948
949 int
950 sys_open (const char * path, int oflag, int mode)
951 {
952 /* Force all file handles to be non-inheritable. */
953 return _open (map_win32_filename (path, NULL), oflag | _O_NOINHERIT, mode);
954 }
955
956 int
957 sys_rename (const char * oldname, const char * newname)
958 {
959 char temp[MAX_PATH];
960
961 /* MoveFile on Win95 doesn't correctly change the short file name
962 alias when oldname has a three char extension and newname has the
963 same first three chars in its extension. To avoid problems, on
964 Win95 we rename to a temporary name first. */
965
966 strcpy (temp, map_win32_filename (oldname, NULL));
967
968 if (GetVersion () & 0x80000000)
969 {
970 char * p;
971
972 unixtodos_filename (temp);
973 if (p = strrchr (temp, '\\'))
974 p++;
975 else
976 p = temp;
977 strcpy (p, "__XXXXXX");
978 _mktemp (temp);
979 if (rename (map_win32_filename (oldname, NULL), temp) < 0)
980 return -1;
981 }
982
983 /* Emulate Unix behaviour - newname is deleted if it already exists
984 (at least if it is a file; don't do this for directories). */
985 newname = map_win32_filename (newname, NULL);
986 if (GetFileAttributes (newname) != -1)
987 {
988 _chmod (newname, 0666);
989 _unlink (newname);
990 }
991
992 return rename (temp, newname);
993 }
994
995 int
996 sys_rmdir (const char * path)
997 {
998 return _rmdir (map_win32_filename (path, NULL));
999 }
1000
1001 int
1002 sys_unlink (const char * path)
1003 {
1004 return _unlink (map_win32_filename (path, NULL));
1005 }
1006
1007 static FILETIME utc_base_ft;
1008 static long double utc_base;
1009 static int init = 0;
1010
1011 static time_t
1012 convert_time (FILETIME ft)
1013 {
1014 long double ret;
1015
1016 if (!init)
1017 {
1018 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1019 SYSTEMTIME st;
1020
1021 st.wYear = 1970;
1022 st.wMonth = 1;
1023 st.wDay = 1;
1024 st.wHour = 0;
1025 st.wMinute = 0;
1026 st.wSecond = 0;
1027 st.wMilliseconds = 0;
1028
1029 SystemTimeToFileTime (&st, &utc_base_ft);
1030 utc_base = (long double) utc_base_ft.dwHighDateTime
1031 * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime;
1032 init = 1;
1033 }
1034
1035 if (CompareFileTime (&ft, &utc_base_ft) < 0)
1036 return 0;
1037
1038 ret = (long double) ft.dwHighDateTime * 4096 * 1024 * 1024 + ft.dwLowDateTime;
1039 ret -= utc_base;
1040 return (time_t) (ret * 1e-7);
1041 }
1042
1043 #if 0
1044 /* in case we ever have need of this */
1045 void
1046 convert_from_time_t (time_t time, FILETIME * pft)
1047 {
1048 long double tmp;
1049
1050 if (!init)
1051 {
1052 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1053 SYSTEMTIME st;
1054
1055 st.wYear = 1970;
1056 st.wMonth = 1;
1057 st.wDay = 1;
1058 st.wHour = 0;
1059 st.wMinute = 0;
1060 st.wSecond = 0;
1061 st.wMilliseconds = 0;
1062
1063 SystemTimeToFileTime (&st, &utc_base_ft);
1064 utc_base = (long double) utc_base_ft.dwHighDateTime
1065 * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime;
1066 init = 1;
1067 }
1068
1069 /* time in 100ns units since 1-Jan-1601 */
1070 tmp = (long double) time * 1e7 + utc_base;
1071 pft->dwHighDateTime = (DWORD) (tmp / (4096.0 * 1024 * 1024));
1072 pft->dwLowDateTime = (DWORD) (tmp - pft->dwHighDateTime);
1073 }
1074 #endif
1075
1076 /* "PJW" algorithm (see the "Dragon" compiler book). */
1077 static unsigned
1078 hashval (const char * str)
1079 {
1080 unsigned h = 0;
1081 unsigned g;
1082 while (*str)
1083 {
1084 h = (h << 4) + *str++;
1085 if ((g = h & 0xf0000000) != 0)
1086 h = (h ^ (g >> 24)) & 0x0fffffff;
1087 }
1088 return h;
1089 }
1090
1091 /* Return the hash value of the canonical pathname, excluding the
1092 drive/UNC header, to get a hopefully unique inode number. */
1093 static _ino_t
1094 generate_inode_val (const char * name)
1095 {
1096 char fullname[ MAX_PATH ];
1097 char * p;
1098 unsigned hash;
1099
1100 GetFullPathName (name, sizeof (fullname), fullname, &p);
1101 get_volume_info (fullname, &p);
1102 /* Normal Win32 filesystems are still case insensitive. */
1103 _strlwr (p);
1104 hash = hashval (p);
1105 return (_ino_t) (hash ^ (hash >> 16));
1106 }
1107
1108 /* MSVC stat function can't cope with UNC names and has other bugs, so
1109 replace it with our own. This also allows us to calculate consistent
1110 inode values without hacks in the main Emacs code. */
1111 int
1112 stat (const char * path, struct stat * buf)
1113 {
1114 char * name;
1115 WIN32_FIND_DATA wfd;
1116 HANDLE fh;
1117 int permission;
1118 int len;
1119 int rootdir = FALSE;
1120
1121 if (path == NULL || buf == NULL)
1122 {
1123 errno = EFAULT;
1124 return -1;
1125 }
1126
1127 name = (char *) map_win32_filename (path, &path);
1128 /* must be valid filename, no wild cards */
1129 if (strchr (name, '*') || strchr (name, '?'))
1130 {
1131 errno = ENOENT;
1132 return -1;
1133 }
1134
1135 /* Remove trailing directory separator, unless name is the root
1136 directory of a drive or UNC volume in which case ensure there
1137 is a trailing separator. */
1138 len = strlen (name);
1139 rootdir = (path >= name + len - 1
1140 && (IS_DIRECTORY_SEP (*path) || *path == 0));
1141 name = strcpy (alloca (len + 2), name);
1142
1143 if (rootdir)
1144 {
1145 if (!IS_DIRECTORY_SEP (name[len-1]))
1146 strcat (name, "\\");
1147 if (GetDriveType (name) < 2)
1148 {
1149 errno = ENOENT;
1150 return -1;
1151 }
1152 memset (&wfd, 0, sizeof (wfd));
1153 wfd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
1154 wfd.ftCreationTime = utc_base_ft;
1155 wfd.ftLastAccessTime = utc_base_ft;
1156 wfd.ftLastWriteTime = utc_base_ft;
1157 strcpy (wfd.cFileName, name);
1158 }
1159 else
1160 {
1161 if (IS_DIRECTORY_SEP (name[len-1]))
1162 name[len - 1] = 0;
1163 fh = FindFirstFile (name, &wfd);
1164 if (fh == INVALID_HANDLE_VALUE)
1165 {
1166 errno = ENOENT;
1167 return -1;
1168 }
1169 FindClose (fh);
1170 }
1171
1172 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1173 {
1174 buf->st_mode = _S_IFDIR;
1175 buf->st_nlink = 2; /* doesn't really matter */
1176 }
1177 else
1178 {
1179 #if 0
1180 /* This is more accurate in terms of gettting the correct number
1181 of links, but is quite slow (it is noticable when Emacs is
1182 making a list of file name completions). */
1183 BY_HANDLE_FILE_INFORMATION info;
1184
1185 fh = CreateFile (name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1186 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1187
1188 if (GetFileInformationByHandle (fh, &info))
1189 {
1190 switch (GetFileType (fh))
1191 {
1192 case FILE_TYPE_DISK:
1193 buf->st_mode = _S_IFREG;
1194 break;
1195 case FILE_TYPE_PIPE:
1196 buf->st_mode = _S_IFIFO;
1197 break;
1198 case FILE_TYPE_CHAR:
1199 case FILE_TYPE_UNKNOWN:
1200 default:
1201 buf->st_mode = _S_IFCHR;
1202 }
1203 buf->st_nlink = info.nNumberOfLinks;
1204 /* Could use file index, but this is not guaranteed to be
1205 unique unless we keep a handle open all the time. */
1206 /* buf->st_ino = info.nFileIndexLow ^ info.nFileIndexHigh; */
1207 CloseHandle (fh);
1208 }
1209 else
1210 {
1211 errno = EACCES;
1212 return -1;
1213 }
1214 #else
1215 buf->st_mode = _S_IFREG;
1216 buf->st_nlink = 1;
1217 #endif
1218 }
1219
1220 /* consider files to belong to current user */
1221 buf->st_uid = the_passwd.pw_uid;
1222 buf->st_gid = the_passwd.pw_gid;
1223
1224 /* volume_info is set indirectly by map_win32_filename */
1225 buf->st_dev = volume_info.serialnum;
1226 buf->st_rdev = volume_info.serialnum;
1227
1228 buf->st_ino = generate_inode_val (name);
1229
1230 buf->st_size = wfd.nFileSizeLow;
1231
1232 /* Convert timestamps to Unix format. */
1233 buf->st_mtime = convert_time (wfd.ftLastWriteTime);
1234 buf->st_atime = convert_time (wfd.ftLastAccessTime);
1235 if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
1236 buf->st_ctime = convert_time (wfd.ftCreationTime);
1237 if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
1238
1239 /* determine rwx permissions */
1240 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
1241 permission = _S_IREAD;
1242 else
1243 permission = _S_IREAD | _S_IWRITE;
1244
1245 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1246 permission |= _S_IEXEC;
1247 else
1248 {
1249 char * p = strrchr (name, '.');
1250 if (p != NULL &&
1251 (stricmp (p, ".exe") == 0 ||
1252 stricmp (p, ".com") == 0 ||
1253 stricmp (p, ".bat") == 0 ||
1254 stricmp (p, ".cmd") == 0))
1255 permission |= _S_IEXEC;
1256 }
1257
1258 buf->st_mode |= permission | (permission >> 3) | (permission >> 6);
1259
1260 return 0;
1261 }
1262
1263 #ifdef HAVE_SOCKETS
1264
1265 /* Wrappers for winsock functions to map between our file descriptors
1266 and winsock's handles; also set h_errno for convenience.
1267
1268 To allow Emacs to run on systems which don't have winsock support
1269 installed, we dynamically link to winsock on startup if present, and
1270 otherwise provide the minimum necessary functionality
1271 (eg. gethostname). */
1272
1273 /* function pointers for relevant socket functions */
1274 int (PASCAL *pfn_WSAStartup) (WORD wVersionRequired, LPWSADATA lpWSAData);
1275 void (PASCAL *pfn_WSASetLastError) (int iError);
1276 int (PASCAL *pfn_WSAGetLastError) (void);
1277 int (PASCAL *pfn_socket) (int af, int type, int protocol);
1278 int (PASCAL *pfn_bind) (SOCKET s, const struct sockaddr *addr, int namelen);
1279 int (PASCAL *pfn_connect) (SOCKET s, const struct sockaddr *addr, int namelen);
1280 int (PASCAL *pfn_ioctlsocket) (SOCKET s, long cmd, u_long *argp);
1281 int (PASCAL *pfn_recv) (SOCKET s, char * buf, int len, int flags);
1282 int (PASCAL *pfn_send) (SOCKET s, const char * buf, int len, int flags);
1283 int (PASCAL *pfn_closesocket) (SOCKET s);
1284 int (PASCAL *pfn_shutdown) (SOCKET s, int how);
1285 int (PASCAL *pfn_WSACleanup) (void);
1286
1287 u_short (PASCAL *pfn_htons) (u_short hostshort);
1288 u_short (PASCAL *pfn_ntohs) (u_short netshort);
1289 unsigned long (PASCAL *pfn_inet_addr) (const char * cp);
1290 int (PASCAL *pfn_gethostname) (char * name, int namelen);
1291 struct hostent * (PASCAL *pfn_gethostbyname) (const char * name);
1292 struct servent * (PASCAL *pfn_getservbyname) (const char * name, const char * proto);
1293
1294 static int have_winsock;
1295 static HANDLE winsock_lib;
1296
1297 static void
1298 term_winsock (void)
1299 {
1300 if (have_winsock)
1301 {
1302 pfn_WSACleanup ();
1303 FreeLibrary (winsock_lib);
1304 }
1305 }
1306
1307 static void
1308 init_winsock ()
1309 {
1310 WSADATA winsockData;
1311
1312 winsock_lib = LoadLibrary ("wsock32.dll");
1313
1314 if (winsock_lib != NULL)
1315 {
1316 /* dynamically link to socket functions */
1317
1318 #define LOAD_PROC(fn) \
1319 if ((pfn_##fn = (void *) GetProcAddress (winsock_lib, #fn)) == NULL) \
1320 goto fail;
1321
1322 LOAD_PROC( WSAStartup );
1323 LOAD_PROC( WSASetLastError );
1324 LOAD_PROC( WSAGetLastError );
1325 LOAD_PROC( socket );
1326 LOAD_PROC( bind );
1327 LOAD_PROC( connect );
1328 LOAD_PROC( ioctlsocket );
1329 LOAD_PROC( recv );
1330 LOAD_PROC( send );
1331 LOAD_PROC( closesocket );
1332 LOAD_PROC( shutdown );
1333 LOAD_PROC( htons );
1334 LOAD_PROC( ntohs );
1335 LOAD_PROC( inet_addr );
1336 LOAD_PROC( gethostname );
1337 LOAD_PROC( gethostbyname );
1338 LOAD_PROC( getservbyname );
1339 LOAD_PROC( WSACleanup );
1340
1341 /* specify version 1.1 of winsock */
1342 if (pfn_WSAStartup (0x101, &winsockData) == 0)
1343 {
1344 have_winsock = TRUE;
1345 return;
1346 }
1347
1348 fail:
1349 FreeLibrary (winsock_lib);
1350 }
1351 have_winsock = FALSE;
1352 }
1353
1354
1355 int h_errno = 0;
1356
1357 /* function to set h_errno for compatability; map winsock error codes to
1358 normal system codes where they overlap (non-overlapping definitions
1359 are already in <sys/socket.h> */
1360 static void set_errno ()
1361 {
1362 if (!have_winsock)
1363 h_errno = EINVAL;
1364 else
1365 h_errno = pfn_WSAGetLastError ();
1366
1367 switch (h_errno)
1368 {
1369 case WSAEACCES: h_errno = EACCES; break;
1370 case WSAEBADF: h_errno = EBADF; break;
1371 case WSAEFAULT: h_errno = EFAULT; break;
1372 case WSAEINTR: h_errno = EINTR; break;
1373 case WSAEINVAL: h_errno = EINVAL; break;
1374 case WSAEMFILE: h_errno = EMFILE; break;
1375 case WSAENAMETOOLONG: h_errno = ENAMETOOLONG; break;
1376 case WSAENOTEMPTY: h_errno = ENOTEMPTY; break;
1377 }
1378 errno = h_errno;
1379 }
1380
1381 static void check_errno ()
1382 {
1383 if (h_errno == 0 && have_winsock)
1384 pfn_WSASetLastError (0);
1385 }
1386
1387 /* [andrewi 3-May-96] I've had conflicting results using both methods,
1388 but I believe the method of keeping the socket handle separate (and
1389 insuring it is not inheritable) is the correct one. */
1390
1391 //#define SOCK_REPLACE_HANDLE
1392
1393 #ifdef SOCK_REPLACE_HANDLE
1394 #define SOCK_HANDLE(fd) ((SOCKET) _get_osfhandle (fd))
1395 #else
1396 #define SOCK_HANDLE(fd) ((SOCKET) fd_info[fd].hnd)
1397 #endif
1398
1399 int
1400 sys_socket(int af, int type, int protocol)
1401 {
1402 int fd;
1403 long s;
1404 child_process * cp;
1405
1406 if (!have_winsock)
1407 {
1408 h_errno = ENETDOWN;
1409 return INVALID_SOCKET;
1410 }
1411
1412 check_errno ();
1413
1414 /* call the real socket function */
1415 s = (long) pfn_socket (af, type, protocol);
1416
1417 if (s != INVALID_SOCKET)
1418 {
1419 /* Although under NT 3.5 _open_osfhandle will accept a socket
1420 handle, if opened with SO_OPENTYPE == SO_SYNCHRONOUS_NONALERT,
1421 that does not work under NT 3.1. However, we can get the same
1422 effect by using a backdoor function to replace an existing
1423 descriptor handle with the one we want. */
1424
1425 /* allocate a file descriptor (with appropriate flags) */
1426 fd = _open ("NUL:", _O_RDWR);
1427 if (fd >= 0)
1428 {
1429 #ifdef SOCK_REPLACE_HANDLE
1430 /* now replace handle to NUL with our socket handle */
1431 CloseHandle ((HANDLE) _get_osfhandle (fd));
1432 _free_osfhnd (fd);
1433 _set_osfhnd (fd, s);
1434 /* setmode (fd, _O_BINARY); */
1435 #else
1436 /* Make a non-inheritable copy of the socket handle. */
1437 {
1438 HANDLE parent;
1439 HANDLE new_s = INVALID_HANDLE_VALUE;
1440
1441 parent = GetCurrentProcess ();
1442
1443 DuplicateHandle (parent,
1444 (HANDLE) s,
1445 parent,
1446 &new_s,
1447 0,
1448 FALSE,
1449 DUPLICATE_SAME_ACCESS);
1450 pfn_closesocket (s);
1451 fd_info[fd].hnd = new_s;
1452 s = (SOCKET) new_s;
1453 }
1454 #endif
1455
1456 /* set our own internal flags */
1457 fd_info[fd].flags = FILE_SOCKET | FILE_BINARY | FILE_READ | FILE_WRITE;
1458
1459 cp = new_child ();
1460 if (cp)
1461 {
1462 cp->fd = fd;
1463 cp->status = STATUS_READ_ACKNOWLEDGED;
1464
1465 /* attach child_process to fd_info */
1466 if (fd_info[ fd ].cp != NULL)
1467 {
1468 DebPrint (("sys_socket: fd_info[%d] apparently in use!\n", fd));
1469 abort ();
1470 }
1471
1472 fd_info[ fd ].cp = cp;
1473
1474 /* success! */
1475 return fd;
1476 }
1477
1478 /* clean up */
1479 _close (fd);
1480 }
1481 pfn_closesocket (s);
1482 h_errno = EMFILE;
1483 }
1484 set_errno ();
1485
1486 return -1;
1487 }
1488
1489
1490 int
1491 sys_bind (int s, const struct sockaddr * addr, int namelen)
1492 {
1493 if (!have_winsock)
1494 {
1495 h_errno = ENOTSOCK;
1496 return SOCKET_ERROR;
1497 }
1498
1499 check_errno ();
1500 if (fd_info[s].flags & FILE_SOCKET)
1501 {
1502 int rc = pfn_bind (SOCK_HANDLE (s), addr, namelen);
1503 if (rc == SOCKET_ERROR)
1504 set_errno ();
1505 return rc;
1506 }
1507 h_errno = ENOTSOCK;
1508 return SOCKET_ERROR;
1509 }
1510
1511
1512 int
1513 sys_connect (int s, const struct sockaddr * name, int namelen)
1514 {
1515 if (!have_winsock)
1516 {
1517 h_errno = ENOTSOCK;
1518 return SOCKET_ERROR;
1519 }
1520
1521 check_errno ();
1522 if (fd_info[s].flags & FILE_SOCKET)
1523 {
1524 int rc = pfn_connect (SOCK_HANDLE (s), name, namelen);
1525 if (rc == SOCKET_ERROR)
1526 set_errno ();
1527 return rc;
1528 }
1529 h_errno = ENOTSOCK;
1530 return SOCKET_ERROR;
1531 }
1532
1533 u_short
1534 sys_htons (u_short hostshort)
1535 {
1536 return (have_winsock) ?
1537 pfn_htons (hostshort) : hostshort;
1538 }
1539
1540 u_short
1541 sys_ntohs (u_short netshort)
1542 {
1543 return (have_winsock) ?
1544 pfn_ntohs (netshort) : netshort;
1545 }
1546
1547 unsigned long
1548 sys_inet_addr (const char * cp)
1549 {
1550 return (have_winsock) ?
1551 pfn_inet_addr (cp) : INADDR_NONE;
1552 }
1553
1554 int
1555 sys_gethostname (char * name, int namelen)
1556 {
1557 if (have_winsock)
1558 return pfn_gethostname (name, namelen);
1559
1560 if (namelen > MAX_COMPUTERNAME_LENGTH)
1561 return !GetComputerName (name, &namelen);
1562
1563 h_errno = EFAULT;
1564 return SOCKET_ERROR;
1565 }
1566
1567 struct hostent *
1568 sys_gethostbyname(const char * name)
1569 {
1570 struct hostent * host;
1571
1572 if (!have_winsock)
1573 {
1574 h_errno = ENETDOWN;
1575 return NULL;
1576 }
1577
1578 check_errno ();
1579 host = pfn_gethostbyname (name);
1580 if (!host)
1581 set_errno ();
1582 return host;
1583 }
1584
1585 struct servent *
1586 sys_getservbyname(const char * name, const char * proto)
1587 {
1588 struct servent * serv;
1589
1590 if (!have_winsock)
1591 {
1592 h_errno = ENETDOWN;
1593 return NULL;
1594 }
1595
1596 check_errno ();
1597 serv = pfn_getservbyname (name, proto);
1598 if (!serv)
1599 set_errno ();
1600 return serv;
1601 }
1602
1603 #endif /* HAVE_SOCKETS */
1604
1605
1606 /* Shadow main io functions: we need to handle pipes and sockets more
1607 intelligently, and implement non-blocking mode as well. */
1608
1609 int
1610 sys_close (int fd)
1611 {
1612 int rc;
1613
1614 if (fd < 0 || fd >= MAXDESC)
1615 {
1616 errno = EBADF;
1617 return -1;
1618 }
1619
1620 if (fd_info[fd].cp)
1621 {
1622 child_process * cp = fd_info[fd].cp;
1623
1624 fd_info[fd].cp = NULL;
1625
1626 if (CHILD_ACTIVE (cp))
1627 {
1628 /* if last descriptor to active child_process then cleanup */
1629 int i;
1630 for (i = 0; i < MAXDESC; i++)
1631 {
1632 if (i == fd)
1633 continue;
1634 if (fd_info[i].cp == cp)
1635 break;
1636 }
1637 if (i == MAXDESC)
1638 {
1639 #if defined (HAVE_SOCKETS) && !defined (SOCK_REPLACE_HANDLE)
1640 if (fd_info[fd].flags & FILE_SOCKET)
1641 {
1642 if (!have_winsock) abort ();
1643
1644 pfn_shutdown (SOCK_HANDLE (fd), 2);
1645 rc = pfn_closesocket (SOCK_HANDLE (fd));
1646 }
1647 #endif
1648 delete_child (cp);
1649 }
1650 }
1651 }
1652
1653 /* Note that sockets do not need special treatment here (at least on
1654 NT and Win95 using the standard tcp/ip stacks) - it appears that
1655 closesocket is equivalent to CloseHandle, which is to be expected
1656 because socket handles are fully fledged kernel handles. */
1657 rc = _close (fd);
1658
1659 if (rc == 0)
1660 fd_info[fd].flags = 0;
1661
1662 return rc;
1663 }
1664
1665 int
1666 sys_dup (int fd)
1667 {
1668 int new_fd;
1669
1670 new_fd = _dup (fd);
1671 if (new_fd >= 0)
1672 {
1673 /* duplicate our internal info as well */
1674 fd_info[new_fd] = fd_info[fd];
1675 }
1676 return new_fd;
1677 }
1678
1679
1680 int
1681 sys_dup2 (int src, int dst)
1682 {
1683 int rc;
1684
1685 if (dst < 0 || dst >= MAXDESC)
1686 {
1687 errno = EBADF;
1688 return -1;
1689 }
1690
1691 /* make sure we close the destination first if it's a pipe or socket */
1692 if (src != dst && fd_info[dst].flags != 0)
1693 sys_close (dst);
1694
1695 rc = _dup2 (src, dst);
1696 if (rc == 0)
1697 {
1698 /* duplicate our internal info as well */
1699 fd_info[dst] = fd_info[src];
1700 }
1701 return rc;
1702 }
1703
1704 /* From callproc.c */
1705 extern Lisp_Object Vbinary_process_input;
1706 extern Lisp_Object Vbinary_process_output;
1707
1708 /* Unix pipe() has only one arg */
1709 int
1710 sys_pipe (int * phandles)
1711 {
1712 int rc;
1713 unsigned flags;
1714 child_process * cp;
1715
1716 /* make pipe handles non-inheritable; when we spawn a child,
1717 we replace the relevant handle with an inheritable one. */
1718 rc = _pipe (phandles, 0, _O_NOINHERIT);
1719
1720 if (rc == 0)
1721 {
1722 /* set internal flags, and put read and write handles into binary
1723 mode as necessary; if not in binary mode, set the MSVC internal
1724 FDEV (0x40) flag to prevent _read from treating ^Z as eof (this
1725 could otherwise allow Emacs to hang because it then waits
1726 indefinitely for the child process to exit, when it might not be
1727 finished). */
1728 flags = FILE_PIPE | FILE_READ;
1729 if (!NILP (Vbinary_process_output))
1730 {
1731 flags |= FILE_BINARY;
1732 setmode (phandles[0], _O_BINARY);
1733 }
1734 #if (_MSC_VER == 900)
1735 else
1736 _osfile[phandles[0]] |= 0x40;
1737 #endif
1738
1739 fd_info[phandles[0]].flags = flags;
1740
1741 flags = FILE_PIPE | FILE_WRITE;
1742 if (!NILP (Vbinary_process_input))
1743 {
1744 flags |= FILE_BINARY;
1745 setmode (phandles[1], _O_BINARY);
1746 }
1747 #if (_MSC_VER == 900)
1748 else
1749 _osfile[phandles[1]] |= 0x40;
1750 #endif
1751
1752 fd_info[phandles[1]].flags = flags;
1753 }
1754
1755 return rc;
1756 }
1757
1758 /* From ntproc.c */
1759 extern Lisp_Object Vwin32_pipe_read_delay;
1760
1761 /* Function to do blocking read of one byte, needed to implement
1762 select. It is only allowed on sockets and pipes. */
1763 int
1764 _sys_read_ahead (int fd)
1765 {
1766 child_process * cp;
1767 int rc;
1768
1769 if (fd < 0 || fd >= MAXDESC)
1770 return STATUS_READ_ERROR;
1771
1772 cp = fd_info[fd].cp;
1773
1774 if (cp == NULL || cp->fd != fd || cp->status != STATUS_READ_READY)
1775 return STATUS_READ_ERROR;
1776
1777 if ((fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET)) == 0
1778 || (fd_info[fd].flags & FILE_READ) == 0)
1779 {
1780 DebPrint (("_sys_read_ahead: internal error: fd %d is not a pipe or socket!\n", fd));
1781 abort ();
1782 }
1783
1784 cp->status = STATUS_READ_IN_PROGRESS;
1785
1786 if (fd_info[fd].flags & FILE_PIPE)
1787 {
1788 /* Use read to get CRLF translation */
1789 rc = _read (fd, &cp->chr, sizeof (char));
1790
1791 /* Give subprocess time to buffer some more output for us before
1792 reporting that input is available; we need this because Win95
1793 connects DOS programs to pipes by making the pipe appear to be
1794 the normal console stdout - as a result most DOS programs will
1795 write to stdout without buffering, ie. one character at a
1796 time. Even some Win32 programs do this - "dir" in a command
1797 shell on NT is very slow if we don't do this. */
1798 if (rc > 0)
1799 {
1800 int wait = XINT (Vwin32_pipe_read_delay);
1801
1802 if (wait > 0)
1803 Sleep (wait);
1804 else if (wait < 0)
1805 while (++wait <= 0)
1806 /* Yield remainder of our time slice, effectively giving a
1807 temporary priority boost to the child process. */
1808 Sleep (0);
1809 }
1810 }
1811 #ifdef HAVE_SOCKETS
1812 else if (fd_info[fd].flags & FILE_SOCKET)
1813 rc = pfn_recv (SOCK_HANDLE (fd), &cp->chr, sizeof (char), 0);
1814 #endif
1815
1816 if (rc == sizeof (char))
1817 cp->status = STATUS_READ_SUCCEEDED;
1818 else
1819 cp->status = STATUS_READ_FAILED;
1820
1821 return cp->status;
1822 }
1823
1824 int
1825 sys_read (int fd, char * buffer, unsigned int count)
1826 {
1827 int nchars;
1828 int extra = 0;
1829 int to_read;
1830 DWORD waiting;
1831
1832 if (fd < 0 || fd >= MAXDESC)
1833 {
1834 errno = EBADF;
1835 return -1;
1836 }
1837
1838 if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
1839 {
1840 child_process *cp = fd_info[fd].cp;
1841
1842 if ((fd_info[fd].flags & FILE_READ) == 0)
1843 {
1844 errno = EBADF;
1845 return -1;
1846 }
1847
1848 /* presence of a child_process structure means we are operating in
1849 non-blocking mode - otherwise we just call _read directly.
1850 Note that the child_process structure might be missing because
1851 reap_subprocess has been called; in this case the pipe is
1852 already broken, so calling _read on it is okay. */
1853 if (cp)
1854 {
1855 int current_status = cp->status;
1856
1857 switch (current_status)
1858 {
1859 case STATUS_READ_FAILED:
1860 case STATUS_READ_ERROR:
1861 /* report normal EOF */
1862 return 0;
1863
1864 case STATUS_READ_READY:
1865 case STATUS_READ_IN_PROGRESS:
1866 DebPrint (("sys_read called when read is in progress\n"));
1867 errno = EWOULDBLOCK;
1868 return -1;
1869
1870 case STATUS_READ_SUCCEEDED:
1871 /* consume read-ahead char */
1872 *buffer++ = cp->chr;
1873 count--;
1874 extra = 1;
1875 cp->status = STATUS_READ_ACKNOWLEDGED;
1876 ResetEvent (cp->char_avail);
1877
1878 case STATUS_READ_ACKNOWLEDGED:
1879 break;
1880
1881 default:
1882 DebPrint (("sys_read: bad status %d\n", current_status));
1883 errno = EBADF;
1884 return -1;
1885 }
1886
1887 if (fd_info[fd].flags & FILE_PIPE)
1888 {
1889 PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, &waiting, NULL);
1890 to_read = min (waiting, (DWORD) count);
1891
1892 /* Use read to get CRLF translation */
1893 nchars = _read (fd, buffer, to_read);
1894 }
1895 #ifdef HAVE_SOCKETS
1896 else /* FILE_SOCKET */
1897 {
1898 if (!have_winsock) abort ();
1899
1900 /* do the equivalent of a non-blocking read */
1901 pfn_ioctlsocket (SOCK_HANDLE (fd), FIONREAD, &waiting);
1902 if (waiting == 0 && extra == 0)
1903 {
1904 h_errno = errno = EWOULDBLOCK;
1905 return -1;
1906 }
1907
1908 nchars = 0;
1909 if (waiting)
1910 {
1911 /* always use binary mode for sockets */
1912 nchars = pfn_recv (SOCK_HANDLE (fd), buffer, count, 0);
1913 if (nchars == SOCKET_ERROR)
1914 {
1915 DebPrint(("sys_read.recv failed with error %d on socket %ld\n",
1916 pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
1917 if (extra == 0)
1918 {
1919 set_errno ();
1920 return -1;
1921 }
1922 nchars = 0;
1923 }
1924 }
1925 }
1926 #endif
1927 }
1928 else
1929 nchars = _read (fd, buffer, count);
1930 }
1931 else
1932 nchars = _read (fd, buffer, count);
1933
1934 return nchars + extra;
1935 }
1936
1937 /* For now, don't bother with a non-blocking mode */
1938 int
1939 sys_write (int fd, const void * buffer, unsigned int count)
1940 {
1941 int nchars;
1942
1943 if (fd < 0 || fd >= MAXDESC)
1944 {
1945 errno = EBADF;
1946 return -1;
1947 }
1948
1949 if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
1950 if ((fd_info[fd].flags & FILE_WRITE) == 0)
1951 {
1952 errno = EBADF;
1953 return -1;
1954 }
1955 #ifdef HAVE_SOCKETS
1956 if (fd_info[fd].flags & FILE_SOCKET)
1957 {
1958 if (!have_winsock) abort ();
1959 nchars = pfn_send (SOCK_HANDLE (fd), buffer, count, 0);
1960 if (nchars == SOCKET_ERROR)
1961 {
1962 DebPrint(("sys_read.send failed with error %d on socket %ld\n",
1963 pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
1964 set_errno ();
1965 }
1966 }
1967 else
1968 #endif
1969 nchars = _write (fd, buffer, count);
1970
1971 return nchars;
1972 }
1973
1974
1975 void
1976 term_ntproc ()
1977 {
1978 #ifdef HAVE_SOCKETS
1979 /* shutdown the socket interface if necessary */
1980 term_winsock ();
1981 #endif
1982 }
1983
1984 extern BOOL can_run_dos_process;
1985 extern BOOL dos_process_running;
1986
1987 void
1988 init_ntproc ()
1989 {
1990 #ifdef HAVE_SOCKETS
1991 /* initialise the socket interface if available */
1992 init_winsock ();
1993 #endif
1994
1995 /* Initial preparation for subprocess support: replace our standard
1996 handles with non-inheritable versions. */
1997 {
1998 HANDLE parent;
1999 HANDLE stdin_save = INVALID_HANDLE_VALUE;
2000 HANDLE stdout_save = INVALID_HANDLE_VALUE;
2001 HANDLE stderr_save = INVALID_HANDLE_VALUE;
2002
2003 parent = GetCurrentProcess ();
2004
2005 /* ignore errors when duplicating and closing; typically the
2006 handles will be invalid when running as a gui program. */
2007 DuplicateHandle (parent,
2008 GetStdHandle (STD_INPUT_HANDLE),
2009 parent,
2010 &stdin_save,
2011 0,
2012 FALSE,
2013 DUPLICATE_SAME_ACCESS);
2014
2015 DuplicateHandle (parent,
2016 GetStdHandle (STD_OUTPUT_HANDLE),
2017 parent,
2018 &stdout_save,
2019 0,
2020 FALSE,
2021 DUPLICATE_SAME_ACCESS);
2022
2023 DuplicateHandle (parent,
2024 GetStdHandle (STD_ERROR_HANDLE),
2025 parent,
2026 &stderr_save,
2027 0,
2028 FALSE,
2029 DUPLICATE_SAME_ACCESS);
2030
2031 fclose (stdin);
2032 fclose (stdout);
2033 fclose (stderr);
2034
2035 if (stdin_save != INVALID_HANDLE_VALUE)
2036 _open_osfhandle ((long) stdin_save, O_TEXT);
2037 else
2038 open ("nul", O_TEXT | O_NOINHERIT | O_RDONLY);
2039 fdopen (0, "r");
2040
2041 if (stdout_save != INVALID_HANDLE_VALUE)
2042 _open_osfhandle ((long) stdout_save, O_TEXT);
2043 else
2044 open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
2045 fdopen (1, "w");
2046
2047 if (stderr_save != INVALID_HANDLE_VALUE)
2048 _open_osfhandle ((long) stderr_save, O_TEXT);
2049 else
2050 open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
2051 fdopen (2, "w");
2052 }
2053
2054 /* Only allow Emacs to run DOS programs on Win95. */
2055 can_run_dos_process = (GetVersion () & 0x80000000);
2056 dos_process_running = FALSE;
2057
2058 /* unfortunately, atexit depends on implementation of malloc */
2059 /* atexit (term_ntproc); */
2060 signal (SIGABRT, term_ntproc);
2061 }
2062
2063 /* end of nt.c */