(get_volume_info): Always update *pPath correctly, even if
[emacs.git] / src / w32.c
blob845203a774e42deff4475e5c76afc4c67ee89ab6
1 /* Utility and Unix shadow routines for GNU Emacs on Windows NT.
2 Copyright (C) 1994, 1995 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
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.
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.
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.
21 Geoff Voelker (voelker@cs.washington.edu) 7-29-94
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>
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
50 #undef close
51 #undef dup
52 #undef dup2
53 #undef pipe
54 #undef read
55 #undef write
57 #define getwd _getwd
58 #include "lisp.h"
59 #undef getwd
61 #include <pwd.h>
63 #include <windows.h>
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
78 #include "nt.h"
79 #include "ndir.h"
80 #include "ntheap.h"
82 /* Get the current working directory. */
83 char *
84 getwd (char *dir)
86 if (GetCurrentDirectory (MAXPATHLEN, dir) > 0)
87 return dir;
88 return NULL;
91 #ifndef HAVE_SOCKETS
92 /* Emulate gethostname. */
93 int
94 gethostname (char *buffer, int size)
96 /* NT only allows small host names, so the buffer is
97 certainly large enough. */
98 return !GetComputerName (buffer, &size);
100 #endif /* HAVE_SOCKETS */
102 /* Emulate getloadavg. */
104 getloadavg (double loadavg[], int nelem)
106 int i;
108 /* A faithful emulation is going to have to be saved for a rainy day. */
109 for (i = 0; i < nelem; i++)
111 loadavg[i] = 0.0;
113 return i;
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. */
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];
125 DIR *
126 opendir (char *filename)
128 DIR *dirp;
130 /* Opening is done by FindFirstFile. However, a read is inherent to
131 this operation, so we defer the open until read time. */
133 if (!(dirp = (DIR *) malloc (sizeof (DIR))))
134 return NULL;
135 if (dir_find_handle != INVALID_HANDLE_VALUE)
136 return NULL;
138 dirp->dd_fd = 0;
139 dirp->dd_loc = 0;
140 dirp->dd_size = 0;
142 strncpy (dir_pathname, filename, MAXPATHLEN);
143 dir_pathname[MAXPATHLEN] = '\0';
144 dir_is_fat = is_fat_volume (filename, NULL);
146 return dirp;
149 void
150 closedir (DIR *dirp)
152 /* If we have a find-handle open, close it. */
153 if (dir_find_handle != INVALID_HANDLE_VALUE)
155 FindClose (dir_find_handle);
156 dir_find_handle = INVALID_HANDLE_VALUE;
158 xfree ((char *) dirp);
161 struct direct *
162 readdir (DIR *dirp)
164 WIN32_FIND_DATA find_data;
166 /* If we aren't dir_finding, do a find-first, otherwise do a find-next. */
167 if (dir_find_handle == INVALID_HANDLE_VALUE)
169 char filename[MAXNAMLEN + 3];
170 int ln;
172 strcpy (filename, dir_pathname);
173 ln = strlen (filename) - 1;
174 if (!IS_DIRECTORY_SEP (filename[ln]))
175 strcat (filename, "\\");
176 strcat (filename, "*");
178 dir_find_handle = FindFirstFile (filename, &find_data);
180 if (dir_find_handle == INVALID_HANDLE_VALUE)
181 return NULL;
183 else
185 if (!FindNextFile (dir_find_handle, &find_data))
186 return NULL;
189 /* Emacs never uses this value, so don't bother making it match
190 value returned by stat(). */
191 dir_static.d_ino = 1;
193 dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 +
194 dir_static.d_namlen - dir_static.d_namlen % 4;
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);
201 return &dir_static;
204 /* Emulate getpwuid, getpwnam and others. */
206 #define PASSWD_FIELD_SIZE 256
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];
214 static struct passwd the_passwd =
216 the_passwd_name,
217 the_passwd_passwd,
221 the_passwd_gecos,
222 the_passwd_dir,
223 the_passwd_shell,
226 int
227 getuid ()
229 return the_passwd.pw_uid;
232 int
233 geteuid ()
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 ();
241 int
242 getgid ()
244 return the_passwd.pw_gid;
247 int
248 getegid ()
250 return getgid ();
253 struct passwd *
254 getpwuid (int uid)
256 if (uid == the_passwd.pw_uid)
257 return &the_passwd;
258 return NULL;
261 struct passwd *
262 getpwnam (char *name)
264 struct passwd *pw;
266 pw = getpwuid (getuid ());
267 if (!pw)
268 return pw;
270 if (stricmp (name, pw->pw_name))
271 return NULL;
273 return pw;
276 void
277 init_user_info ()
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.
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). */
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;
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))
297 strcpy (the_passwd.pw_name, name);
298 /* Determine a reasonable uid value. */
299 if (stricmp ("administrator", name) == 0)
301 the_passwd.pw_uid = 0;
302 the_passwd.pw_gid = 0;
304 else
306 SID_IDENTIFIER_AUTHORITY * pSIA;
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;
318 /* Get group id */
319 if (GetTokenInformation (token, TokenPrimaryGroup,
320 (PVOID) user_sid, sizeof (user_sid), &trash))
322 SID_IDENTIFIER_AUTHORITY * pSIA;
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;
332 else
333 the_passwd.pw_gid = the_passwd.pw_uid;
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))
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;
347 else
349 strcpy (the_passwd.pw_name, "unknown");
350 the_passwd.pw_uid = 123;
351 the_passwd.pw_gid = 123;
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");
360 /* Set dir and shell from environment variables. */
361 strcpy (the_passwd.pw_dir, getenv ("HOME"));
362 strcpy (the_passwd.pw_shell, getenv ("SHELL"));
364 if (token)
365 CloseHandle (token);
369 random ()
371 /* rand () on NT gives us 15 random bits...hack together 30 bits. */
372 return ((rand () << 15) | rand ());
375 void
376 srandom (int seed)
378 srand (seed);
381 /* Destructively turn backslashes into slashes. */
382 void
383 dostounix_filename (p)
384 register char *p;
386 while (*p)
388 if (*p == '\\')
389 *p = '/';
390 p++;
394 /* Destructively turn slashes into backslashes. */
395 void
396 unixtodos_filename (p)
397 register char *p;
399 while (*p)
401 if (*p == '/')
402 *p = '\\';
403 p++;
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.) */
411 crlf_to_lf (n, buf)
412 register int n;
413 register unsigned char *buf;
415 unsigned char *np = buf;
416 unsigned char *startp = buf;
417 unsigned char *endp = buf + n;
419 if (n == 0)
420 return n;
421 while (buf < endp - 1)
423 if (*buf == 0x0d)
425 if (*(++buf) != 0x0a)
426 *np++ = 0x0d;
428 else
429 *np++ = *buf++;
431 if (buf < endp)
432 *np++ = *buf++;
433 return np - startp;
436 /* Routines that are no-ops on NT but are defined to get Emacs to compile. */
438 int
439 sigsetmask (int signal_mask)
441 return 0;
444 int
445 sigblock (int sig)
447 return 0;
450 int
451 setpgrp (int pid, int gid)
453 return 0;
456 int
457 alarm (int seconds)
459 return 0;
462 int
463 unrequest_sigio (void)
465 return 0;
468 int
469 request_sigio (void)
471 return 0;
474 #define REG_ROOT "SOFTWARE\\GNU\\Emacs"
476 LPBYTE
477 nt_get_resource (key, lpdwtype)
478 char *key;
479 LPDWORD lpdwtype;
481 LPBYTE lpvalue;
482 HKEY hrootkey = NULL;
483 DWORD cbData;
484 BOOL ok = FALSE;
486 /* Check both the current user and the local machine to see if
487 we have any resources. */
489 if (RegOpenKeyEx (HKEY_CURRENT_USER, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
491 lpvalue = NULL;
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)
497 return (lpvalue);
500 if (lpvalue) xfree (lpvalue);
502 RegCloseKey (hrootkey);
505 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
507 lpvalue = NULL;
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)
513 return (lpvalue);
516 if (lpvalue) xfree (lpvalue);
518 RegCloseKey (hrootkey);
521 return (NULL);
524 void
525 init_environment ()
527 /* Check for environment variables and use registry if they don't exist */
529 int i;
530 LPBYTE lpval;
531 DWORD dwType;
533 static char * env_vars[] =
535 "HOME",
536 "emacs_dir",
537 "EMACSLOADPATH",
538 "SHELL",
539 "EMACSDATA",
540 "EMACSPATH",
541 "EMACSLOCKDIR",
542 "INFOPATH",
543 "EMACSDOC",
544 "TERM",
547 for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++)
549 if (!getenv (env_vars[i]) &&
550 (lpval = nt_get_resource (env_vars[i], &dwType)) != NULL)
552 if (dwType == REG_EXPAND_SZ)
554 char buf1[500], buf2[500];
556 ExpandEnvironmentStrings ((LPSTR) lpval, buf1, 500);
557 _snprintf (buf2, 499, "%s=%s", env_vars[i], buf1);
558 putenv (strdup (buf2));
560 else if (dwType == REG_SZ)
562 char buf[500];
564 _snprintf (buf, 499, "%s=%s", env_vars[i], lpval);
565 putenv (strdup (buf));
568 xfree (lpval);
573 init_user_info ();
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. */
581 static char configuration_buffer[32];
583 char *
584 get_emacs_configuration (void)
586 char *arch, *oem, *os;
588 /* Determine the processor type. */
589 switch (get_processor_type ())
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
600 #ifdef PROCESSOR_INTEL_860
601 case PROCESSOR_INTEL_860:
602 arch = "i860";
603 break;
604 #endif
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
614 #ifdef PROCESSOR_ALPHA_21064
615 case PROCESSOR_ALPHA_21064:
616 arch = "alpha";
617 break;
618 #endif
620 default:
621 arch = "unknown";
622 break;
625 /* Let oem be "*" until we figure out how to decode the OEM field. */
626 oem = "*";
628 os = (GetVersion () & 0x80000000) ? "win95" : "nt";
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;
635 #include <sys/timeb.h>
637 /* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */
638 void
639 gettimeofday (struct timeval *tv, struct timezone *tz)
641 struct _timeb tb;
642 _ftime (&tb);
644 tv->tv_sec = tb.time;
645 tv->tv_usec = tb.millitm * 1000L;
646 if (tz)
648 tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich */
649 tz->tz_dsttime = tb.dstflag; /* type of dst correction */
653 /* ------------------------------------------------------------------------- */
654 /* IO support and wrapper functions for Win32 API. */
655 /* ------------------------------------------------------------------------- */
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)
663 char *str = (char *) ctime (t);
664 return (str ? str : "Sun Jan 01 00:00:00 1970");
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)
673 Sleep (seconds * 1000);
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);
683 /* parallel array of private info on file handles */
684 filedesc fd_info [ MAXDESC ];
686 static struct {
687 DWORD serialnum;
688 DWORD maxcomp;
689 DWORD flags;
690 char name[32];
691 char type[32];
692 } volume_info;
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). */
697 get_volume_info (const char * name, const char ** pPath)
699 char temp[MAX_PATH];
700 char *rootname = NULL; /* default to current volume */
702 if (name == NULL)
703 return FALSE;
705 /* find the root name of the volume if given */
706 if (isalpha (name[0]) && name[1] == ':')
708 rootname = temp;
709 temp[0] = *name++;
710 temp[1] = *name++;
711 temp[2] = '\\';
712 temp[3] = 0;
714 else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1]))
716 char *str = temp;
717 int slashes = 4;
718 rootname = temp;
721 if (IS_DIRECTORY_SEP (*name) && --slashes == 0)
722 break;
723 *str++ = *name++;
725 while ( *name );
727 *str++ = '\\';
728 *str = 0;
731 if (pPath)
732 *pPath = name;
734 if (GetVolumeInformation (rootname,
735 volume_info.name, 32,
736 &volume_info.serialnum,
737 &volume_info.maxcomp,
738 &volume_info.flags,
739 volume_info.type, 32))
741 return TRUE;
743 return FALSE;
746 /* Determine if volume is FAT format (ie. only supports short 8.3
747 names); also set path pointer to start of pathname in name. */
749 is_fat_volume (const char * name, const char ** pPath)
751 if (get_volume_info (name, pPath))
752 return (volume_info.maxcomp == 12);
753 return FALSE;
756 /* Map filename to a legal 8.3 name if necessary. */
757 const char *
758 map_win32_filename (const char * name, const char ** pPath)
760 static char shortname[MAX_PATH];
761 char * str = shortname;
762 char c;
763 char * path;
765 if (is_fat_volume (name, &path)) /* truncate to 8.3 */
767 register int left = 8; /* maximum number of chars in part */
768 register int extn = 0; /* extension added? */
769 register int dots = 2; /* maximum number of dots allowed */
771 while (name < path)
772 *str++ = *name++; /* skip past UNC header */
774 while ((c = *name++))
776 switch ( c )
778 case '\\':
779 case '/':
780 *str++ = '\\';
781 extn = 0; /* reset extension flags */
782 dots = 2; /* max 2 dots */
783 left = 8; /* max length 8 for main part */
784 break;
785 case ':':
786 *str++ = ':';
787 extn = 0; /* reset extension flags */
788 dots = 2; /* max 2 dots */
789 left = 8; /* max length 8 for main part */
790 break;
791 case '.':
792 if ( dots )
794 /* Convert path components of the form .xxx to _xxx,
795 but leave . and .. as they are. This allows .emacs
796 to be read as _emacs, for example. */
798 if (! *name ||
799 *name == '.' ||
800 IS_DIRECTORY_SEP (*name))
802 *str++ = '.';
803 dots--;
805 else
807 *str++ = '_';
808 left--;
809 dots = 0;
812 else if ( !extn )
814 *str++ = '.';
815 extn = 1; /* we've got an extension */
816 left = 3; /* 3 chars in extension */
818 else
820 /* any embedded dots after the first are converted to _ */
821 *str++ = '_';
823 break;
824 case '~':
825 case '#': /* don't lose these, they're important */
826 if ( ! left )
827 str[-1] = c; /* replace last character of part */
828 /* FALLTHRU */
829 default:
830 if ( left )
832 *str++ = tolower (c); /* map to lower case (looks nicer) */
833 left--;
834 dots = 0; /* started a path component */
836 break;
839 *str = '\0';
841 else
843 strcpy (shortname, name);
844 unixtodos_filename (shortname);
847 if (pPath)
848 *pPath = shortname + (path - name);
850 return shortname;
854 /* Shadow some MSVC runtime functions to map requests for long filenames
855 to reasonable short names if necessary. This was originally added to
856 permit running Emacs on NT 3.1 on a FAT partition, which doesn't support
857 long file names. */
860 sys_access (const char * path, int mode)
862 return _access (map_win32_filename (path, NULL), mode);
866 sys_chdir (const char * path)
868 return _chdir (map_win32_filename (path, NULL));
872 sys_chmod (const char * path, int mode)
874 return _chmod (map_win32_filename (path, NULL), mode);
878 sys_creat (const char * path, int mode)
880 return _creat (map_win32_filename (path, NULL), mode);
883 FILE *
884 sys_fopen(const char * path, const char * mode)
886 int fd;
887 int oflag;
888 const char * mode_save = mode;
890 /* Force all file handles to be non-inheritable. This is necessary to
891 ensure child processes don't unwittingly inherit handles that might
892 prevent future file access. */
894 if (mode[0] == 'r')
895 oflag = O_RDONLY;
896 else if (mode[0] == 'w' || mode[0] == 'a')
897 oflag = O_WRONLY | O_CREAT | O_TRUNC;
898 else
899 return NULL;
901 /* Only do simplistic option parsing. */
902 while (*++mode)
903 if (mode[0] == '+')
905 oflag &= ~(O_RDONLY | O_WRONLY);
906 oflag |= O_RDWR;
908 else if (mode[0] == 'b')
910 oflag &= ~O_TEXT;
911 oflag |= O_BINARY;
913 else if (mode[0] == 't')
915 oflag &= ~O_BINARY;
916 oflag |= O_TEXT;
918 else break;
920 fd = _open (map_win32_filename (path, NULL), oflag | _O_NOINHERIT, 0644);
921 if (fd < 0)
922 return NULL;
924 return fdopen (fd, mode_save);
928 sys_link (const char * path1, const char * path2)
930 errno = EINVAL;
931 return -1;
935 sys_mkdir (const char * path)
937 return _mkdir (map_win32_filename (path, NULL));
940 char *
941 sys_mktemp (char * template)
943 return (char *) map_win32_filename ((const char *) _mktemp (template), NULL);
947 sys_open (const char * path, int oflag, int mode)
949 /* Force all file handles to be non-inheritable. */
950 return _open (map_win32_filename (path, NULL), oflag | _O_NOINHERIT, mode);
954 sys_rename (const char * oldname, const char * newname)
956 char temp[MAX_PATH];
958 /* MoveFile on Win95 doesn't correctly change the short file name
959 alias when oldname has a three char extension and newname has the
960 same first three chars in its extension. To avoid problems, on
961 Win95 we rename to a temporary name first. */
963 strcpy (temp, map_win32_filename (oldname, NULL));
965 if (GetVersion () & 0x80000000)
967 char * p;
969 unixtodos_filename (temp);
970 if (p = strrchr (temp, '\\'))
971 p++;
972 else
973 p = temp;
974 strcpy (p, "__XXXXXX");
975 _mktemp (temp);
976 if (rename (map_win32_filename (oldname, NULL), temp) < 0)
977 return -1;
980 /* Emulate Unix behaviour - newname is deleted if it already exists
981 (at least if it is a file; don't do this for directories). */
982 newname = map_win32_filename (newname, NULL);
983 if (GetFileAttributes (newname) != -1)
985 _chmod (newname, 0666);
986 _unlink (newname);
989 return rename (temp, newname);
993 sys_rmdir (const char * path)
995 return _rmdir (map_win32_filename (path, NULL));
999 sys_unlink (const char * path)
1001 return _unlink (map_win32_filename (path, NULL));
1004 static FILETIME utc_base_ft;
1005 static long double utc_base;
1006 static int init = 0;
1008 static time_t
1009 convert_time (FILETIME ft)
1011 long double ret;
1013 if (!init)
1015 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1016 SYSTEMTIME st;
1018 st.wYear = 1970;
1019 st.wMonth = 1;
1020 st.wDay = 1;
1021 st.wHour = 0;
1022 st.wMinute = 0;
1023 st.wSecond = 0;
1024 st.wMilliseconds = 0;
1026 SystemTimeToFileTime (&st, &utc_base_ft);
1027 utc_base = (long double) utc_base_ft.dwHighDateTime
1028 * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime;
1029 init = 1;
1032 if (CompareFileTime (&ft, &utc_base_ft) < 0)
1033 return 0;
1035 ret = (long double) ft.dwHighDateTime * 4096 * 1024 * 1024 + ft.dwLowDateTime;
1036 ret -= utc_base;
1037 return (time_t) (ret * 1e-7);
1040 #if 0
1041 /* in case we ever have need of this */
1042 void
1043 convert_from_time_t (time_t time, FILETIME * pft)
1045 long double tmp;
1047 if (!init)
1049 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1050 SYSTEMTIME st;
1052 st.wYear = 1970;
1053 st.wMonth = 1;
1054 st.wDay = 1;
1055 st.wHour = 0;
1056 st.wMinute = 0;
1057 st.wSecond = 0;
1058 st.wMilliseconds = 0;
1060 SystemTimeToFileTime (&st, &utc_base_ft);
1061 utc_base = (long double) utc_base_ft.dwHighDateTime
1062 * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime;
1063 init = 1;
1066 /* time in 100ns units since 1-Jan-1601 */
1067 tmp = (long double) time * 1e7 + utc_base;
1068 pft->dwHighDateTime = (DWORD) (tmp / (4096.0 * 1024 * 1024));
1069 pft->dwLowDateTime = (DWORD) (tmp - pft->dwHighDateTime);
1071 #endif
1073 /* "PJW" algorithm (see the "Dragon" compiler book). */
1074 static unsigned
1075 hashval (const char * str)
1077 unsigned h = 0;
1078 unsigned g;
1079 while (*str)
1081 h = (h << 4) + *str++;
1082 if ((g = h & 0xf0000000) != 0)
1083 h = (h ^ (g >> 24)) & 0x0fffffff;
1085 return h;
1088 /* Return the hash value of the canonical pathname, excluding the
1089 drive/UNC header, to get a hopefully unique inode number. */
1090 static _ino_t
1091 generate_inode_val (const char * name)
1093 char fullname[ MAX_PATH ];
1094 char * p;
1095 unsigned hash;
1097 GetFullPathName (name, sizeof (fullname), fullname, &p);
1098 get_volume_info (fullname, &p);
1099 /* Normal Win32 filesystems are still case insensitive. */
1100 _strlwr (p);
1101 hash = hashval (p);
1102 return (_ino_t) (hash ^ (hash >> 16));
1105 /* MSVC stat function can't cope with UNC names and has other bugs, so
1106 replace it with our own. This also allows us to calculate consistent
1107 inode values without hacks in the main Emacs code. */
1109 stat (const char * path, struct stat * buf)
1111 char * name;
1112 WIN32_FIND_DATA wfd;
1113 HANDLE fh;
1114 int permission;
1115 int len;
1116 int rootdir = FALSE;
1118 if (path == NULL || buf == NULL)
1120 errno = EFAULT;
1121 return -1;
1124 name = (char *) map_win32_filename (path, &path);
1125 /* must be valid filename, no wild cards */
1126 if (strchr (name, '*') || strchr (name, '?'))
1128 errno = ENOENT;
1129 return -1;
1132 /* Remove trailing directory separator, unless name is the root
1133 directory of a drive or UNC volume in which case ensure there
1134 is a trailing separator. */
1135 len = strlen (name);
1136 rootdir = (path >= name + len - 1
1137 && (IS_DIRECTORY_SEP (*path) || *path == 0));
1138 name = strcpy (alloca (len + 2), name);
1140 if (rootdir)
1142 if (!IS_DIRECTORY_SEP (name[len-1]))
1143 strcat (name, "\\");
1144 if (GetDriveType (name) < 2)
1146 errno = ENOENT;
1147 return -1;
1149 memset (&wfd, 0, sizeof (wfd));
1150 wfd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
1151 wfd.ftCreationTime = utc_base_ft;
1152 wfd.ftLastAccessTime = utc_base_ft;
1153 wfd.ftLastWriteTime = utc_base_ft;
1154 strcpy (wfd.cFileName, name);
1156 else
1158 if (IS_DIRECTORY_SEP (name[len-1]))
1159 name[len - 1] = 0;
1160 fh = FindFirstFile (name, &wfd);
1161 if (fh == INVALID_HANDLE_VALUE)
1163 errno = ENOENT;
1164 return -1;
1166 FindClose (fh);
1169 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1171 buf->st_mode = _S_IFDIR;
1172 buf->st_nlink = 2; /* doesn't really matter */
1174 else
1176 #if 0
1177 /* This is more accurate in terms of gettting the correct number
1178 of links, but is quite slow (it is noticable when Emacs is
1179 making a list of file name completions). */
1180 BY_HANDLE_FILE_INFORMATION info;
1182 fh = CreateFile (name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1183 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1185 if (GetFileInformationByHandle (fh, &info))
1187 switch (GetFileType (fh))
1189 case FILE_TYPE_DISK:
1190 buf->st_mode = _S_IFREG;
1191 break;
1192 case FILE_TYPE_PIPE:
1193 buf->st_mode = _S_IFIFO;
1194 break;
1195 case FILE_TYPE_CHAR:
1196 case FILE_TYPE_UNKNOWN:
1197 default:
1198 buf->st_mode = _S_IFCHR;
1200 buf->st_nlink = info.nNumberOfLinks;
1201 /* Could use file index, but this is not guaranteed to be
1202 unique unless we keep a handle open all the time. */
1203 /* buf->st_ino = info.nFileIndexLow ^ info.nFileIndexHigh; */
1204 CloseHandle (fh);
1206 else
1208 errno = EACCES;
1209 return -1;
1211 #else
1212 buf->st_mode = _S_IFREG;
1213 buf->st_nlink = 1;
1214 #endif
1217 /* consider files to belong to current user */
1218 buf->st_uid = the_passwd.pw_uid;
1219 buf->st_gid = the_passwd.pw_gid;
1221 /* volume_info is set indirectly by map_win32_filename */
1222 buf->st_dev = volume_info.serialnum;
1223 buf->st_rdev = volume_info.serialnum;
1225 buf->st_ino = generate_inode_val (name);
1227 buf->st_size = wfd.nFileSizeLow;
1229 /* Convert timestamps to Unix format. */
1230 buf->st_mtime = convert_time (wfd.ftLastWriteTime);
1231 buf->st_atime = convert_time (wfd.ftLastAccessTime);
1232 if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
1233 buf->st_ctime = convert_time (wfd.ftCreationTime);
1234 if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
1236 /* determine rwx permissions */
1237 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
1238 permission = _S_IREAD;
1239 else
1240 permission = _S_IREAD | _S_IWRITE;
1242 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1243 permission |= _S_IEXEC;
1244 else
1246 char * p = strrchr (name, '.');
1247 if (p != NULL &&
1248 (stricmp (p, ".exe") == 0 ||
1249 stricmp (p, ".com") == 0 ||
1250 stricmp (p, ".bat") == 0 ||
1251 stricmp (p, ".cmd") == 0))
1252 permission |= _S_IEXEC;
1255 buf->st_mode |= permission | (permission >> 3) | (permission >> 6);
1257 return 0;
1260 #ifdef HAVE_SOCKETS
1262 /* Wrappers for winsock functions to map between our file descriptors
1263 and winsock's handles; also set h_errno for convenience.
1265 To allow Emacs to run on systems which don't have winsock support
1266 installed, we dynamically link to winsock on startup if present, and
1267 otherwise provide the minimum necessary functionality
1268 (eg. gethostname). */
1270 /* function pointers for relevant socket functions */
1271 int (PASCAL *pfn_WSAStartup) (WORD wVersionRequired, LPWSADATA lpWSAData);
1272 void (PASCAL *pfn_WSASetLastError) (int iError);
1273 int (PASCAL *pfn_WSAGetLastError) (void);
1274 int (PASCAL *pfn_socket) (int af, int type, int protocol);
1275 int (PASCAL *pfn_bind) (SOCKET s, const struct sockaddr *addr, int namelen);
1276 int (PASCAL *pfn_connect) (SOCKET s, const struct sockaddr *addr, int namelen);
1277 int (PASCAL *pfn_ioctlsocket) (SOCKET s, long cmd, u_long *argp);
1278 int (PASCAL *pfn_recv) (SOCKET s, char * buf, int len, int flags);
1279 int (PASCAL *pfn_send) (SOCKET s, const char * buf, int len, int flags);
1280 int (PASCAL *pfn_closesocket) (SOCKET s);
1281 int (PASCAL *pfn_shutdown) (SOCKET s, int how);
1282 int (PASCAL *pfn_WSACleanup) (void);
1284 u_short (PASCAL *pfn_htons) (u_short hostshort);
1285 u_short (PASCAL *pfn_ntohs) (u_short netshort);
1286 unsigned long (PASCAL *pfn_inet_addr) (const char * cp);
1287 int (PASCAL *pfn_gethostname) (char * name, int namelen);
1288 struct hostent * (PASCAL *pfn_gethostbyname) (const char * name);
1289 struct servent * (PASCAL *pfn_getservbyname) (const char * name, const char * proto);
1291 static int have_winsock;
1292 static HANDLE winsock_lib;
1294 static void
1295 term_winsock (void)
1297 if (have_winsock)
1299 pfn_WSACleanup ();
1300 FreeLibrary (winsock_lib);
1304 static void
1305 init_winsock ()
1307 WSADATA winsockData;
1309 winsock_lib = LoadLibrary ("wsock32.dll");
1311 if (winsock_lib != NULL)
1313 /* dynamically link to socket functions */
1315 #define LOAD_PROC(fn) \
1316 if ((pfn_##fn = (void *) GetProcAddress (winsock_lib, #fn)) == NULL) \
1317 goto fail;
1319 LOAD_PROC( WSAStartup );
1320 LOAD_PROC( WSASetLastError );
1321 LOAD_PROC( WSAGetLastError );
1322 LOAD_PROC( socket );
1323 LOAD_PROC( bind );
1324 LOAD_PROC( connect );
1325 LOAD_PROC( ioctlsocket );
1326 LOAD_PROC( recv );
1327 LOAD_PROC( send );
1328 LOAD_PROC( closesocket );
1329 LOAD_PROC( shutdown );
1330 LOAD_PROC( htons );
1331 LOAD_PROC( ntohs );
1332 LOAD_PROC( inet_addr );
1333 LOAD_PROC( gethostname );
1334 LOAD_PROC( gethostbyname );
1335 LOAD_PROC( getservbyname );
1336 LOAD_PROC( WSACleanup );
1338 /* specify version 1.1 of winsock */
1339 if (pfn_WSAStartup (0x101, &winsockData) == 0)
1341 have_winsock = TRUE;
1342 return;
1345 fail:
1346 FreeLibrary (winsock_lib);
1348 have_winsock = FALSE;
1352 int h_errno = 0;
1354 /* function to set h_errno for compatability; map winsock error codes to
1355 normal system codes where they overlap (non-overlapping definitions
1356 are already in <sys/socket.h> */
1357 static void set_errno ()
1359 if (!have_winsock)
1360 h_errno = EINVAL;
1361 else
1362 h_errno = pfn_WSAGetLastError ();
1364 switch (h_errno)
1366 case WSAEACCES: h_errno = EACCES; break;
1367 case WSAEBADF: h_errno = EBADF; break;
1368 case WSAEFAULT: h_errno = EFAULT; break;
1369 case WSAEINTR: h_errno = EINTR; break;
1370 case WSAEINVAL: h_errno = EINVAL; break;
1371 case WSAEMFILE: h_errno = EMFILE; break;
1372 case WSAENAMETOOLONG: h_errno = ENAMETOOLONG; break;
1373 case WSAENOTEMPTY: h_errno = ENOTEMPTY; break;
1375 errno = h_errno;
1378 static void check_errno ()
1380 if (h_errno == 0 && have_winsock)
1381 pfn_WSASetLastError (0);
1384 /* [andrewi 3-May-96] I've had conflicting results using both methods,
1385 but I believe the method of keeping the socket handle separate (and
1386 insuring it is not inheritable) is the correct one. */
1388 //#define SOCK_REPLACE_HANDLE
1390 #ifdef SOCK_REPLACE_HANDLE
1391 #define SOCK_HANDLE(fd) ((SOCKET) _get_osfhandle (fd))
1392 #else
1393 #define SOCK_HANDLE(fd) ((SOCKET) fd_info[fd].hnd)
1394 #endif
1397 sys_socket(int af, int type, int protocol)
1399 int fd;
1400 long s;
1401 child_process * cp;
1403 if (!have_winsock)
1405 h_errno = ENETDOWN;
1406 return INVALID_SOCKET;
1409 check_errno ();
1411 /* call the real socket function */
1412 s = (long) pfn_socket (af, type, protocol);
1414 if (s != INVALID_SOCKET)
1416 /* Although under NT 3.5 _open_osfhandle will accept a socket
1417 handle, if opened with SO_OPENTYPE == SO_SYNCHRONOUS_NONALERT,
1418 that does not work under NT 3.1. However, we can get the same
1419 effect by using a backdoor function to replace an existing
1420 descriptor handle with the one we want. */
1422 /* allocate a file descriptor (with appropriate flags) */
1423 fd = _open ("NUL:", _O_RDWR);
1424 if (fd >= 0)
1426 #ifdef SOCK_REPLACE_HANDLE
1427 /* now replace handle to NUL with our socket handle */
1428 CloseHandle ((HANDLE) _get_osfhandle (fd));
1429 _free_osfhnd (fd);
1430 _set_osfhnd (fd, s);
1431 /* setmode (fd, _O_BINARY); */
1432 #else
1433 /* Make a non-inheritable copy of the socket handle. */
1435 HANDLE parent;
1436 HANDLE new_s = INVALID_HANDLE_VALUE;
1438 parent = GetCurrentProcess ();
1440 DuplicateHandle (parent,
1441 (HANDLE) s,
1442 parent,
1443 &new_s,
1445 FALSE,
1446 DUPLICATE_SAME_ACCESS);
1447 pfn_closesocket (s);
1448 fd_info[fd].hnd = new_s;
1449 s = (SOCKET) new_s;
1451 #endif
1453 /* set our own internal flags */
1454 fd_info[fd].flags = FILE_SOCKET | FILE_BINARY | FILE_READ | FILE_WRITE;
1456 cp = new_child ();
1457 if (cp)
1459 cp->fd = fd;
1460 cp->status = STATUS_READ_ACKNOWLEDGED;
1462 /* attach child_process to fd_info */
1463 if (fd_info[ fd ].cp != NULL)
1465 DebPrint (("sys_socket: fd_info[%d] apparently in use!\n", fd));
1466 abort ();
1469 fd_info[ fd ].cp = cp;
1471 /* success! */
1472 return fd;
1475 /* clean up */
1476 _close (fd);
1478 pfn_closesocket (s);
1479 h_errno = EMFILE;
1481 set_errno ();
1483 return -1;
1488 sys_bind (int s, const struct sockaddr * addr, int namelen)
1490 if (!have_winsock)
1492 h_errno = ENOTSOCK;
1493 return SOCKET_ERROR;
1496 check_errno ();
1497 if (fd_info[s].flags & FILE_SOCKET)
1499 int rc = pfn_bind (SOCK_HANDLE (s), addr, namelen);
1500 if (rc == SOCKET_ERROR)
1501 set_errno ();
1502 return rc;
1504 h_errno = ENOTSOCK;
1505 return SOCKET_ERROR;
1510 sys_connect (int s, const struct sockaddr * name, int namelen)
1512 if (!have_winsock)
1514 h_errno = ENOTSOCK;
1515 return SOCKET_ERROR;
1518 check_errno ();
1519 if (fd_info[s].flags & FILE_SOCKET)
1521 int rc = pfn_connect (SOCK_HANDLE (s), name, namelen);
1522 if (rc == SOCKET_ERROR)
1523 set_errno ();
1524 return rc;
1526 h_errno = ENOTSOCK;
1527 return SOCKET_ERROR;
1530 u_short
1531 sys_htons (u_short hostshort)
1533 return (have_winsock) ?
1534 pfn_htons (hostshort) : hostshort;
1537 u_short
1538 sys_ntohs (u_short netshort)
1540 return (have_winsock) ?
1541 pfn_ntohs (netshort) : netshort;
1544 unsigned long
1545 sys_inet_addr (const char * cp)
1547 return (have_winsock) ?
1548 pfn_inet_addr (cp) : INADDR_NONE;
1552 sys_gethostname (char * name, int namelen)
1554 if (have_winsock)
1555 return pfn_gethostname (name, namelen);
1557 if (namelen > MAX_COMPUTERNAME_LENGTH)
1558 return !GetComputerName (name, &namelen);
1560 h_errno = EFAULT;
1561 return SOCKET_ERROR;
1564 struct hostent *
1565 sys_gethostbyname(const char * name)
1567 struct hostent * host;
1569 if (!have_winsock)
1571 h_errno = ENETDOWN;
1572 return NULL;
1575 check_errno ();
1576 host = pfn_gethostbyname (name);
1577 if (!host)
1578 set_errno ();
1579 return host;
1582 struct servent *
1583 sys_getservbyname(const char * name, const char * proto)
1585 struct servent * serv;
1587 if (!have_winsock)
1589 h_errno = ENETDOWN;
1590 return NULL;
1593 check_errno ();
1594 serv = pfn_getservbyname (name, proto);
1595 if (!serv)
1596 set_errno ();
1597 return serv;
1600 #endif /* HAVE_SOCKETS */
1603 /* Shadow main io functions: we need to handle pipes and sockets more
1604 intelligently, and implement non-blocking mode as well. */
1607 sys_close (int fd)
1609 int rc;
1611 if (fd < 0 || fd >= MAXDESC)
1613 errno = EBADF;
1614 return -1;
1617 if (fd_info[fd].cp)
1619 child_process * cp = fd_info[fd].cp;
1621 fd_info[fd].cp = NULL;
1623 if (CHILD_ACTIVE (cp))
1625 /* if last descriptor to active child_process then cleanup */
1626 int i;
1627 for (i = 0; i < MAXDESC; i++)
1629 if (i == fd)
1630 continue;
1631 if (fd_info[i].cp == cp)
1632 break;
1634 if (i == MAXDESC)
1636 #if defined (HAVE_SOCKETS) && !defined (SOCK_REPLACE_HANDLE)
1637 if (fd_info[fd].flags & FILE_SOCKET)
1639 if (!have_winsock) abort ();
1641 pfn_shutdown (SOCK_HANDLE (fd), 2);
1642 rc = pfn_closesocket (SOCK_HANDLE (fd));
1644 #endif
1645 delete_child (cp);
1650 /* Note that sockets do not need special treatment here (at least on
1651 NT and Win95 using the standard tcp/ip stacks) - it appears that
1652 closesocket is equivalent to CloseHandle, which is to be expected
1653 because socket handles are fully fledged kernel handles. */
1654 rc = _close (fd);
1656 if (rc == 0)
1657 fd_info[fd].flags = 0;
1659 return rc;
1663 sys_dup (int fd)
1665 int new_fd;
1667 new_fd = _dup (fd);
1668 if (new_fd >= 0)
1670 /* duplicate our internal info as well */
1671 fd_info[new_fd] = fd_info[fd];
1673 return new_fd;
1678 sys_dup2 (int src, int dst)
1680 int rc;
1682 if (dst < 0 || dst >= MAXDESC)
1684 errno = EBADF;
1685 return -1;
1688 /* make sure we close the destination first if it's a pipe or socket */
1689 if (src != dst && fd_info[dst].flags != 0)
1690 sys_close (dst);
1692 rc = _dup2 (src, dst);
1693 if (rc == 0)
1695 /* duplicate our internal info as well */
1696 fd_info[dst] = fd_info[src];
1698 return rc;
1701 /* From callproc.c */
1702 extern Lisp_Object Vbinary_process_input;
1703 extern Lisp_Object Vbinary_process_output;
1705 /* Unix pipe() has only one arg */
1707 sys_pipe (int * phandles)
1709 int rc;
1710 unsigned flags;
1711 child_process * cp;
1713 /* make pipe handles non-inheritable; when we spawn a child,
1714 we replace the relevant handle with an inheritable one. */
1715 rc = _pipe (phandles, 0, _O_NOINHERIT);
1717 if (rc == 0)
1719 /* set internal flags, and put read and write handles into binary
1720 mode as necessary; if not in binary mode, set the MSVC internal
1721 FDEV (0x40) flag to prevent _read from treating ^Z as eof (this
1722 could otherwise allow Emacs to hang because it then waits
1723 indefinitely for the child process to exit, when it might not be
1724 finished). */
1725 flags = FILE_PIPE | FILE_READ;
1726 if (!NILP (Vbinary_process_output))
1728 flags |= FILE_BINARY;
1729 setmode (phandles[0], _O_BINARY);
1731 #if (_MSC_VER == 900)
1732 else
1733 _osfile[phandles[0]] |= 0x40;
1734 #endif
1736 fd_info[phandles[0]].flags = flags;
1738 flags = FILE_PIPE | FILE_WRITE;
1739 if (!NILP (Vbinary_process_input))
1741 flags |= FILE_BINARY;
1742 setmode (phandles[1], _O_BINARY);
1744 #if (_MSC_VER == 900)
1745 else
1746 _osfile[phandles[1]] |= 0x40;
1747 #endif
1749 fd_info[phandles[1]].flags = flags;
1752 return rc;
1755 /* From ntproc.c */
1756 extern Lisp_Object Vwin32_pipe_read_delay;
1758 /* Function to do blocking read of one byte, needed to implement
1759 select. It is only allowed on sockets and pipes. */
1761 _sys_read_ahead (int fd)
1763 child_process * cp;
1764 int rc;
1766 if (fd < 0 || fd >= MAXDESC)
1767 return STATUS_READ_ERROR;
1769 cp = fd_info[fd].cp;
1771 if (cp == NULL || cp->fd != fd || cp->status != STATUS_READ_READY)
1772 return STATUS_READ_ERROR;
1774 if ((fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET)) == 0
1775 || (fd_info[fd].flags & FILE_READ) == 0)
1777 DebPrint (("_sys_read_ahead: internal error: fd %d is not a pipe or socket!\n", fd));
1778 abort ();
1781 cp->status = STATUS_READ_IN_PROGRESS;
1783 if (fd_info[fd].flags & FILE_PIPE)
1785 /* Use read to get CRLF translation */
1786 rc = _read (fd, &cp->chr, sizeof (char));
1788 /* Give subprocess time to buffer some more output for us before
1789 reporting that input is available; we need this because Win95
1790 connects DOS programs to pipes by making the pipe appear to be
1791 the normal console stdout - as a result most DOS programs will
1792 write to stdout without buffering, ie. one character at a
1793 time. Even some Win32 programs do this - "dir" in a command
1794 shell on NT is very slow if we don't do this. */
1795 if (rc > 0)
1797 int wait = XINT (Vwin32_pipe_read_delay);
1799 if (wait > 0)
1800 Sleep (wait);
1801 else if (wait < 0)
1802 while (++wait <= 0)
1803 /* Yield remainder of our time slice, effectively giving a
1804 temporary priority boost to the child process. */
1805 Sleep (0);
1808 #ifdef HAVE_SOCKETS
1809 else if (fd_info[fd].flags & FILE_SOCKET)
1810 rc = pfn_recv (SOCK_HANDLE (fd), &cp->chr, sizeof (char), 0);
1811 #endif
1813 if (rc == sizeof (char))
1814 cp->status = STATUS_READ_SUCCEEDED;
1815 else
1816 cp->status = STATUS_READ_FAILED;
1818 return cp->status;
1822 sys_read (int fd, char * buffer, unsigned int count)
1824 int nchars;
1825 int extra = 0;
1826 int to_read;
1827 DWORD waiting;
1829 if (fd < 0 || fd >= MAXDESC)
1831 errno = EBADF;
1832 return -1;
1835 if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
1837 child_process *cp = fd_info[fd].cp;
1839 if ((fd_info[fd].flags & FILE_READ) == 0)
1841 errno = EBADF;
1842 return -1;
1845 /* presence of a child_process structure means we are operating in
1846 non-blocking mode - otherwise we just call _read directly.
1847 Note that the child_process structure might be missing because
1848 reap_subprocess has been called; in this case the pipe is
1849 already broken, so calling _read on it is okay. */
1850 if (cp)
1852 int current_status = cp->status;
1854 switch (current_status)
1856 case STATUS_READ_FAILED:
1857 case STATUS_READ_ERROR:
1858 /* report normal EOF */
1859 return 0;
1861 case STATUS_READ_READY:
1862 case STATUS_READ_IN_PROGRESS:
1863 DebPrint (("sys_read called when read is in progress\n"));
1864 errno = EWOULDBLOCK;
1865 return -1;
1867 case STATUS_READ_SUCCEEDED:
1868 /* consume read-ahead char */
1869 *buffer++ = cp->chr;
1870 count--;
1871 extra = 1;
1872 cp->status = STATUS_READ_ACKNOWLEDGED;
1873 ResetEvent (cp->char_avail);
1875 case STATUS_READ_ACKNOWLEDGED:
1876 break;
1878 default:
1879 DebPrint (("sys_read: bad status %d\n", current_status));
1880 errno = EBADF;
1881 return -1;
1884 if (fd_info[fd].flags & FILE_PIPE)
1886 PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, &waiting, NULL);
1887 to_read = min (waiting, (DWORD) count);
1889 /* Use read to get CRLF translation */
1890 nchars = _read (fd, buffer, to_read);
1892 #ifdef HAVE_SOCKETS
1893 else /* FILE_SOCKET */
1895 if (!have_winsock) abort ();
1897 /* do the equivalent of a non-blocking read */
1898 pfn_ioctlsocket (SOCK_HANDLE (fd), FIONREAD, &waiting);
1899 if (waiting == 0 && extra == 0)
1901 h_errno = errno = EWOULDBLOCK;
1902 return -1;
1905 nchars = 0;
1906 if (waiting)
1908 /* always use binary mode for sockets */
1909 nchars = pfn_recv (SOCK_HANDLE (fd), buffer, count, 0);
1910 if (nchars == SOCKET_ERROR)
1912 DebPrint(("sys_read.recv failed with error %d on socket %ld\n",
1913 pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
1914 if (extra == 0)
1916 set_errno ();
1917 return -1;
1919 nchars = 0;
1923 #endif
1925 else
1926 nchars = _read (fd, buffer, count);
1928 else
1929 nchars = _read (fd, buffer, count);
1931 return nchars + extra;
1934 /* For now, don't bother with a non-blocking mode */
1936 sys_write (int fd, const void * buffer, unsigned int count)
1938 int nchars;
1940 if (fd < 0 || fd >= MAXDESC)
1942 errno = EBADF;
1943 return -1;
1946 if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
1947 if ((fd_info[fd].flags & FILE_WRITE) == 0)
1949 errno = EBADF;
1950 return -1;
1952 #ifdef HAVE_SOCKETS
1953 if (fd_info[fd].flags & FILE_SOCKET)
1955 if (!have_winsock) abort ();
1956 nchars = pfn_send (SOCK_HANDLE (fd), buffer, count, 0);
1957 if (nchars == SOCKET_ERROR)
1959 DebPrint(("sys_read.send failed with error %d on socket %ld\n",
1960 pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
1961 set_errno ();
1964 else
1965 #endif
1966 nchars = _write (fd, buffer, count);
1968 return nchars;
1972 void
1973 term_ntproc ()
1975 #ifdef HAVE_SOCKETS
1976 /* shutdown the socket interface if necessary */
1977 term_winsock ();
1978 #endif
1981 extern BOOL can_run_dos_process;
1982 extern BOOL dos_process_running;
1984 void
1985 init_ntproc ()
1987 #ifdef HAVE_SOCKETS
1988 /* initialise the socket interface if available */
1989 init_winsock ();
1990 #endif
1992 /* Initial preparation for subprocess support: replace our standard
1993 handles with non-inheritable versions. */
1995 HANDLE parent;
1996 HANDLE stdin_save = INVALID_HANDLE_VALUE;
1997 HANDLE stdout_save = INVALID_HANDLE_VALUE;
1998 HANDLE stderr_save = INVALID_HANDLE_VALUE;
2000 parent = GetCurrentProcess ();
2002 /* ignore errors when duplicating and closing; typically the
2003 handles will be invalid when running as a gui program. */
2004 DuplicateHandle (parent,
2005 GetStdHandle (STD_INPUT_HANDLE),
2006 parent,
2007 &stdin_save,
2009 FALSE,
2010 DUPLICATE_SAME_ACCESS);
2012 DuplicateHandle (parent,
2013 GetStdHandle (STD_OUTPUT_HANDLE),
2014 parent,
2015 &stdout_save,
2017 FALSE,
2018 DUPLICATE_SAME_ACCESS);
2020 DuplicateHandle (parent,
2021 GetStdHandle (STD_ERROR_HANDLE),
2022 parent,
2023 &stderr_save,
2025 FALSE,
2026 DUPLICATE_SAME_ACCESS);
2028 fclose (stdin);
2029 fclose (stdout);
2030 fclose (stderr);
2032 if (stdin_save != INVALID_HANDLE_VALUE)
2033 _open_osfhandle ((long) stdin_save, O_TEXT);
2034 else
2035 open ("nul", O_TEXT | O_NOINHERIT | O_RDONLY);
2036 fdopen (0, "r");
2038 if (stdout_save != INVALID_HANDLE_VALUE)
2039 _open_osfhandle ((long) stdout_save, O_TEXT);
2040 else
2041 open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
2042 fdopen (1, "w");
2044 if (stderr_save != INVALID_HANDLE_VALUE)
2045 _open_osfhandle ((long) stderr_save, O_TEXT);
2046 else
2047 open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
2048 fdopen (2, "w");
2051 /* Only allow Emacs to run DOS programs on Win95. */
2052 can_run_dos_process = (GetVersion () & 0x80000000);
2053 dos_process_running = FALSE;
2055 /* unfortunately, atexit depends on implementation of malloc */
2056 /* atexit (term_ntproc); */
2057 signal (SIGABRT, term_ntproc);
2060 /* end of nt.c */