(sys_read): Introduce a small delay before reading from
[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 /* 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 /* Use read to get CRLF translation */
1785 rc = _read (fd, &cp->chr, sizeof (char));
1786 #ifdef HAVE_SOCKETS
1787 else if (fd_info[fd].flags & FILE_SOCKET)
1788 rc = pfn_recv (SOCK_HANDLE (fd), &cp->chr, sizeof (char), 0);
1789 #endif
1790
1791 if (rc == sizeof (char))
1792 cp->status = STATUS_READ_SUCCEEDED;
1793 else
1794 cp->status = STATUS_READ_FAILED;
1795
1796 return cp->status;
1797 }
1798
1799 int
1800 sys_read (int fd, char * buffer, unsigned int count)
1801 {
1802 int nchars;
1803 int extra = 0;
1804 int to_read;
1805 DWORD waiting;
1806
1807 if (fd < 0 || fd >= MAXDESC)
1808 {
1809 errno = EBADF;
1810 return -1;
1811 }
1812
1813 if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
1814 {
1815 child_process *cp = fd_info[fd].cp;
1816
1817 if ((fd_info[fd].flags & FILE_READ) == 0)
1818 {
1819 errno = EBADF;
1820 return -1;
1821 }
1822
1823 /* presence of a child_process structure means we are operating in
1824 non-blocking mode - otherwise we just call _read directly.
1825 Note that the child_process structure might be missing because
1826 reap_subprocess has been called; in this case the pipe is
1827 already broken, so calling _read on it is okay. */
1828 if (cp)
1829 {
1830 int current_status = cp->status;
1831
1832 switch (current_status)
1833 {
1834 case STATUS_READ_FAILED:
1835 case STATUS_READ_ERROR:
1836 /* report normal EOF */
1837 return 0;
1838
1839 case STATUS_READ_READY:
1840 case STATUS_READ_IN_PROGRESS:
1841 DebPrint (("sys_read called when read is in progress\n"));
1842 errno = EWOULDBLOCK;
1843 return -1;
1844
1845 case STATUS_READ_SUCCEEDED:
1846 /* consume read-ahead char */
1847 *buffer++ = cp->chr;
1848 count--;
1849 extra = 1;
1850 cp->status = STATUS_READ_ACKNOWLEDGED;
1851 ResetEvent (cp->char_avail);
1852
1853 case STATUS_READ_ACKNOWLEDGED:
1854 /* Give process time to buffer some more output for us */
1855 Sleep (50);
1856 break;
1857
1858 default:
1859 DebPrint (("sys_read: bad status %d\n", current_status));
1860 errno = EBADF;
1861 return -1;
1862 }
1863
1864 if (fd_info[fd].flags & FILE_PIPE)
1865 {
1866 PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, &waiting, NULL);
1867 to_read = min (waiting, (DWORD) count);
1868
1869 /* Use read to get CRLF translation */
1870 nchars = _read (fd, buffer, to_read);
1871 }
1872 #ifdef HAVE_SOCKETS
1873 else /* FILE_SOCKET */
1874 {
1875 if (!have_winsock) abort ();
1876
1877 /* do the equivalent of a non-blocking read */
1878 pfn_ioctlsocket (SOCK_HANDLE (fd), FIONREAD, &waiting);
1879 if (waiting == 0 && extra == 0)
1880 {
1881 h_errno = errno = EWOULDBLOCK;
1882 return -1;
1883 }
1884
1885 nchars = 0;
1886 if (waiting)
1887 {
1888 /* always use binary mode for sockets */
1889 nchars = pfn_recv (SOCK_HANDLE (fd), buffer, count, 0);
1890 if (nchars == SOCKET_ERROR)
1891 {
1892 DebPrint(("sys_read.recv failed with error %d on socket %ld\n",
1893 pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
1894 if (extra == 0)
1895 {
1896 set_errno ();
1897 return -1;
1898 }
1899 nchars = 0;
1900 }
1901 }
1902 }
1903 #endif
1904 }
1905 else
1906 nchars = _read (fd, buffer, count);
1907 }
1908 else
1909 nchars = _read (fd, buffer, count);
1910
1911 return nchars + extra;
1912 }
1913
1914 /* For now, don't bother with a non-blocking mode */
1915 int
1916 sys_write (int fd, const void * buffer, unsigned int count)
1917 {
1918 int nchars;
1919
1920 if (fd < 0 || fd >= MAXDESC)
1921 {
1922 errno = EBADF;
1923 return -1;
1924 }
1925
1926 if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
1927 if ((fd_info[fd].flags & FILE_WRITE) == 0)
1928 {
1929 errno = EBADF;
1930 return -1;
1931 }
1932 #ifdef HAVE_SOCKETS
1933 if (fd_info[fd].flags & FILE_SOCKET)
1934 {
1935 if (!have_winsock) abort ();
1936 nchars = pfn_send (SOCK_HANDLE (fd), buffer, count, 0);
1937 if (nchars == SOCKET_ERROR)
1938 {
1939 DebPrint(("sys_read.send failed with error %d on socket %ld\n",
1940 pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
1941 set_errno ();
1942 }
1943 }
1944 else
1945 #endif
1946 nchars = _write (fd, buffer, count);
1947
1948 return nchars;
1949 }
1950
1951
1952 void
1953 term_ntproc ()
1954 {
1955 #ifdef HAVE_SOCKETS
1956 /* shutdown the socket interface if necessary */
1957 term_winsock ();
1958 #endif
1959 }
1960
1961 void
1962 init_ntproc ()
1963 {
1964 #ifdef HAVE_SOCKETS
1965 /* initialise the socket interface if available */
1966 init_winsock ();
1967 #endif
1968
1969 /* Initial preparation for subprocess support: replace our standard
1970 handles with non-inheritable versions. */
1971 {
1972 HANDLE parent;
1973 HANDLE stdin_save = INVALID_HANDLE_VALUE;
1974 HANDLE stdout_save = INVALID_HANDLE_VALUE;
1975 HANDLE stderr_save = INVALID_HANDLE_VALUE;
1976
1977 parent = GetCurrentProcess ();
1978
1979 /* ignore errors when duplicating and closing; typically the
1980 handles will be invalid when running as a gui program. */
1981 DuplicateHandle (parent,
1982 GetStdHandle (STD_INPUT_HANDLE),
1983 parent,
1984 &stdin_save,
1985 0,
1986 FALSE,
1987 DUPLICATE_SAME_ACCESS);
1988
1989 DuplicateHandle (parent,
1990 GetStdHandle (STD_OUTPUT_HANDLE),
1991 parent,
1992 &stdout_save,
1993 0,
1994 FALSE,
1995 DUPLICATE_SAME_ACCESS);
1996
1997 DuplicateHandle (parent,
1998 GetStdHandle (STD_ERROR_HANDLE),
1999 parent,
2000 &stderr_save,
2001 0,
2002 FALSE,
2003 DUPLICATE_SAME_ACCESS);
2004
2005 fclose (stdin);
2006 fclose (stdout);
2007 fclose (stderr);
2008
2009 if (stdin_save != INVALID_HANDLE_VALUE)
2010 _open_osfhandle ((long) stdin_save, O_TEXT);
2011 else
2012 open ("nul", O_TEXT | O_NOINHERIT | O_RDONLY);
2013 fdopen (0, "r");
2014
2015 if (stdout_save != INVALID_HANDLE_VALUE)
2016 _open_osfhandle ((long) stdout_save, O_TEXT);
2017 else
2018 open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
2019 fdopen (1, "w");
2020
2021 if (stderr_save != INVALID_HANDLE_VALUE)
2022 _open_osfhandle ((long) stderr_save, O_TEXT);
2023 else
2024 open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
2025 fdopen (2, "w");
2026 }
2027
2028 /* unfortunately, atexit depends on implementation of malloc */
2029 /* atexit (term_ntproc); */
2030 signal (SIGABRT, term_ntproc);
2031 }
2032
2033 /* end of nt.c */