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)
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
34 /* must include CRT headers *before* config.h */
65 #ifdef HAVE_SOCKETS /* TCP connection support, if kernel can do it */
66 #include <sys/socket.h>
82 /* Get the current working directory. */
86 if (GetCurrentDirectory (MAXPATHLEN
, dir
) > 0)
92 /* Emulate gethostname. */
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
)
108 /* A faithful emulation is going to have to be saved for a rainy day. */
109 for (i
= 0; i
< nelem
; 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 extern Lisp_Object Vwin32_downcase_file_names
;
128 opendir (char *filename
)
132 /* Opening is done by FindFirstFile. However, a read is inherent to
133 this operation, so we defer the open until read time. */
135 if (!(dirp
= (DIR *) malloc (sizeof (DIR))))
137 if (dir_find_handle
!= INVALID_HANDLE_VALUE
)
144 strncpy (dir_pathname
, filename
, MAXPATHLEN
);
145 dir_pathname
[MAXPATHLEN
] = '\0';
146 dir_is_fat
= is_fat_volume (filename
, NULL
);
154 /* If we have a find-handle open, close it. */
155 if (dir_find_handle
!= INVALID_HANDLE_VALUE
)
157 FindClose (dir_find_handle
);
158 dir_find_handle
= INVALID_HANDLE_VALUE
;
160 xfree ((char *) dirp
);
166 WIN32_FIND_DATA find_data
;
168 /* If we aren't dir_finding, do a find-first, otherwise do a find-next. */
169 if (dir_find_handle
== INVALID_HANDLE_VALUE
)
171 char filename
[MAXNAMLEN
+ 3];
174 strcpy (filename
, dir_pathname
);
175 ln
= strlen (filename
) - 1;
176 if (!IS_DIRECTORY_SEP (filename
[ln
]))
177 strcat (filename
, "\\");
178 strcat (filename
, "*");
180 dir_find_handle
= FindFirstFile (filename
, &find_data
);
182 if (dir_find_handle
== INVALID_HANDLE_VALUE
)
187 if (!FindNextFile (dir_find_handle
, &find_data
))
191 /* Emacs never uses this value, so don't bother making it match
192 value returned by stat(). */
193 dir_static
.d_ino
= 1;
195 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3 +
196 dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
198 dir_static
.d_namlen
= strlen (find_data
.cFileName
);
199 strcpy (dir_static
.d_name
, find_data
.cFileName
);
201 _strlwr (dir_static
.d_name
);
202 else if (!NILP (Vwin32_downcase_file_names
))
205 for (p
= dir_static
.d_name
; *p
; p
++)
206 if (*p
>= 'a' && *p
<= 'z')
209 _strlwr (dir_static
.d_name
);
215 /* Emulate getpwuid, getpwnam and others. */
217 #define PASSWD_FIELD_SIZE 256
219 static char the_passwd_name
[PASSWD_FIELD_SIZE
];
220 static char the_passwd_passwd
[PASSWD_FIELD_SIZE
];
221 static char the_passwd_gecos
[PASSWD_FIELD_SIZE
];
222 static char the_passwd_dir
[PASSWD_FIELD_SIZE
];
223 static char the_passwd_shell
[PASSWD_FIELD_SIZE
];
225 static struct passwd the_passwd
=
240 return the_passwd
.pw_uid
;
246 /* I could imagine arguing for checking to see whether the user is
247 in the Administrators group and returning a UID of 0 for that
248 case, but I don't know how wise that would be in the long run. */
255 return the_passwd
.pw_gid
;
267 if (uid
== the_passwd
.pw_uid
)
273 getpwnam (char *name
)
277 pw
= getpwuid (getuid ());
281 if (stricmp (name
, pw
->pw_name
))
290 /* Find the user's real name by opening the process token and
291 looking up the name associated with the user-sid in that token.
293 Use the relative portion of the identifier authority value from
294 the user-sid as the user id value (same for group id using the
295 primary group sid from the process token). */
297 char user_sid
[256], name
[256], domain
[256];
298 DWORD length
= sizeof (name
), dlength
= sizeof (domain
), trash
;
300 SID_NAME_USE user_type
;
302 if (OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY
, &token
)
303 && GetTokenInformation (token
, TokenUser
,
304 (PVOID
) user_sid
, sizeof (user_sid
), &trash
)
305 && LookupAccountSid (NULL
, *((PSID
*) user_sid
), name
, &length
,
306 domain
, &dlength
, &user_type
))
308 strcpy (the_passwd
.pw_name
, name
);
309 /* Determine a reasonable uid value. */
310 if (stricmp ("administrator", name
) == 0)
312 the_passwd
.pw_uid
= 0;
313 the_passwd
.pw_gid
= 0;
317 SID_IDENTIFIER_AUTHORITY
* pSIA
;
319 pSIA
= GetSidIdentifierAuthority (*((PSID
*) user_sid
));
320 /* I believe the relative portion is the last 4 bytes (of 6)
322 the_passwd
.pw_uid
= ((pSIA
->Value
[2] << 24) +
323 (pSIA
->Value
[3] << 16) +
324 (pSIA
->Value
[4] << 8) +
325 (pSIA
->Value
[5] << 0));
326 /* restrict to conventional uid range for normal users */
327 the_passwd
.pw_uid
= the_passwd
.pw_uid
% 60001;
330 if (GetTokenInformation (token
, TokenPrimaryGroup
,
331 (PVOID
) user_sid
, sizeof (user_sid
), &trash
))
333 SID_IDENTIFIER_AUTHORITY
* pSIA
;
335 pSIA
= GetSidIdentifierAuthority (*((PSID
*) user_sid
));
336 the_passwd
.pw_gid
= ((pSIA
->Value
[2] << 24) +
337 (pSIA
->Value
[3] << 16) +
338 (pSIA
->Value
[4] << 8) +
339 (pSIA
->Value
[5] << 0));
340 /* I don't know if this is necessary, but for safety... */
341 the_passwd
.pw_gid
= the_passwd
.pw_gid
% 60001;
344 the_passwd
.pw_gid
= the_passwd
.pw_uid
;
347 /* If security calls are not supported (presumably because we
348 are running under Windows 95), fallback to this. */
349 else if (GetUserName (name
, &length
))
351 strcpy (the_passwd
.pw_name
, name
);
352 if (stricmp ("administrator", name
) == 0)
353 the_passwd
.pw_uid
= 0;
355 the_passwd
.pw_uid
= 123;
356 the_passwd
.pw_gid
= the_passwd
.pw_uid
;
360 strcpy (the_passwd
.pw_name
, "unknown");
361 the_passwd
.pw_uid
= 123;
362 the_passwd
.pw_gid
= 123;
365 /* Ensure HOME and SHELL are defined. */
366 if (getenv ("HOME") == NULL
)
368 if (getenv ("SHELL") == NULL
)
369 putenv ((GetVersion () & 0x80000000) ? "SHELL=command" : "SHELL=cmd");
371 /* Set dir and shell from environment variables. */
372 strcpy (the_passwd
.pw_dir
, getenv ("HOME"));
373 strcpy (the_passwd
.pw_shell
, getenv ("SHELL"));
382 /* rand () on NT gives us 15 random bits...hack together 30 bits. */
383 return ((rand () << 15) | rand ());
392 /* Normalize filename by converting all path separators to
393 the specified separator. Also conditionally convert upper
394 case path name components to lower case. */
397 normalize_filename (fp
, path_sep
)
404 if (NILP (Vwin32_downcase_file_names
))
408 if (*fp
== '/' || *fp
== '\\')
415 sep
= path_sep
; /* convert to this path separator */
416 elem
= fp
; /* start of current path element */
419 if (*fp
>= 'a' && *fp
<= 'z')
420 elem
= 0; /* don't convert this element */
422 if (*fp
== 0 || *fp
== ':')
424 sep
= *fp
; /* restore current separator (or 0) */
425 *fp
= '/'; /* after conversion of this element */
428 if (*fp
== '/' || *fp
== '\\')
430 if (elem
&& elem
!= fp
)
432 *fp
= 0; /* temporary end of string */
433 _strlwr (elem
); /* while we convert to lower case */
435 *fp
= sep
; /* convert (or restore) path separator */
436 elem
= fp
+ 1; /* next element starts after separator */
442 /* Destructively turn backslashes into slashes. */
444 dostounix_filename (p
)
447 normalize_filename (p
, '/');
450 /* Destructively turn slashes into backslashes. */
452 unixtodos_filename (p
)
455 normalize_filename (p
, '\\');
458 /* Remove all CR's that are followed by a LF.
459 (From msdos.c...probably should figure out a way to share it,
460 although this code isn't going to ever change.) */
464 register unsigned char *buf
;
466 unsigned char *np
= buf
;
467 unsigned char *startp
= buf
;
468 unsigned char *endp
= buf
+ n
;
472 while (buf
< endp
- 1)
476 if (*(++buf
) != 0x0a)
487 /* Routines that are no-ops on NT but are defined to get Emacs to compile. */
490 sigsetmask (int signal_mask
)
502 setpgrp (int pid
, int gid
)
514 unrequest_sigio (void)
525 #define REG_ROOT "SOFTWARE\\GNU\\Emacs"
528 nt_get_resource (key
, lpdwtype
)
533 HKEY hrootkey
= NULL
;
537 /* Check both the current user and the local machine to see if
538 we have any resources. */
540 if (RegOpenKeyEx (HKEY_CURRENT_USER
, REG_ROOT
, 0, KEY_READ
, &hrootkey
) == ERROR_SUCCESS
)
544 if (RegQueryValueEx (hrootkey
, key
, NULL
, NULL
, NULL
, &cbData
) == ERROR_SUCCESS
545 && (lpvalue
= (LPBYTE
) xmalloc (cbData
)) != NULL
546 && RegQueryValueEx (hrootkey
, key
, NULL
, lpdwtype
, lpvalue
, &cbData
) == ERROR_SUCCESS
)
551 if (lpvalue
) xfree (lpvalue
);
553 RegCloseKey (hrootkey
);
556 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE
, REG_ROOT
, 0, KEY_READ
, &hrootkey
) == ERROR_SUCCESS
)
560 if (RegQueryValueEx (hrootkey
, key
, NULL
, NULL
, NULL
, &cbData
) == ERROR_SUCCESS
&&
561 (lpvalue
= (LPBYTE
) xmalloc (cbData
)) != NULL
&&
562 RegQueryValueEx (hrootkey
, key
, NULL
, lpdwtype
, lpvalue
, &cbData
) == ERROR_SUCCESS
)
567 if (lpvalue
) xfree (lpvalue
);
569 RegCloseKey (hrootkey
);
578 /* Check for environment variables and use registry if they don't exist */
584 static char * env_vars
[] =
598 for (i
= 0; i
< (sizeof (env_vars
) / sizeof (env_vars
[0])); i
++)
600 if (!getenv (env_vars
[i
]) &&
601 (lpval
= nt_get_resource (env_vars
[i
], &dwType
)) != NULL
)
603 if (dwType
== REG_EXPAND_SZ
)
605 char buf1
[500], buf2
[500];
607 ExpandEnvironmentStrings ((LPSTR
) lpval
, buf1
, 500);
608 _snprintf (buf2
, 499, "%s=%s", env_vars
[i
], buf1
);
609 putenv (strdup (buf2
));
611 else if (dwType
== REG_SZ
)
615 _snprintf (buf
, 499, "%s=%s", env_vars
[i
], lpval
);
616 putenv (strdup (buf
));
627 /* We don't have scripts to automatically determine the system configuration
628 for Emacs before it's compiled, and we don't want to have to make the
629 user enter it, so we define EMACS_CONFIGURATION to invoke this runtime
632 static char configuration_buffer
[32];
635 get_emacs_configuration (void)
637 char *arch
, *oem
, *os
;
639 /* Determine the processor type. */
640 switch (get_processor_type ())
643 #ifdef PROCESSOR_INTEL_386
644 case PROCESSOR_INTEL_386
:
645 case PROCESSOR_INTEL_486
:
646 case PROCESSOR_INTEL_PENTIUM
:
651 #ifdef PROCESSOR_INTEL_860
652 case PROCESSOR_INTEL_860
:
657 #ifdef PROCESSOR_MIPS_R2000
658 case PROCESSOR_MIPS_R2000
:
659 case PROCESSOR_MIPS_R3000
:
660 case PROCESSOR_MIPS_R4000
:
665 #ifdef PROCESSOR_ALPHA_21064
666 case PROCESSOR_ALPHA_21064
:
676 /* Let oem be "*" until we figure out how to decode the OEM field. */
679 os
= (GetVersion () & 0x80000000) ? "win95" : "nt";
681 sprintf (configuration_buffer
, "%s-%s-%s%d.%d", arch
, oem
, os
,
682 get_nt_major_version (), get_nt_minor_version ());
683 return configuration_buffer
;
686 #include <sys/timeb.h>
688 /* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */
690 gettimeofday (struct timeval
*tv
, struct timezone
*tz
)
695 tv
->tv_sec
= tb
.time
;
696 tv
->tv_usec
= tb
.millitm
* 1000L;
699 tz
->tz_minuteswest
= tb
.timezone
; /* minutes west of Greenwich */
700 tz
->tz_dsttime
= tb
.dstflag
; /* type of dst correction */
704 /* ------------------------------------------------------------------------- */
705 /* IO support and wrapper functions for Win32 API. */
706 /* ------------------------------------------------------------------------- */
708 /* Place a wrapper around the MSVC version of ctime. It returns NULL
709 on network directories, so we handle that case here.
710 (Ulrich Leodolter, 1/11/95). */
712 sys_ctime (const time_t *t
)
714 char *str
= (char *) ctime (t
);
715 return (str
? str
: "Sun Jan 01 00:00:00 1970");
718 /* Emulate sleep...we could have done this with a define, but that
719 would necessitate including windows.h in the files that used it.
720 This is much easier. */
722 sys_sleep (int seconds
)
724 Sleep (seconds
* 1000);
727 /* Internal MSVC data and functions for low-level descriptor munging */
728 #if (_MSC_VER == 900)
729 extern char _osfile
[];
731 extern int __cdecl
_set_osfhnd (int fd
, long h
);
732 extern int __cdecl
_free_osfhnd (int fd
);
734 /* parallel array of private info on file handles */
735 filedesc fd_info
[ MAXDESC
];
745 /* Get information on the volume where name is held; set path pointer to
746 start of pathname in name (past UNC header\volume header if present). */
748 get_volume_info (const char * name
, const char ** pPath
)
751 char *rootname
= NULL
; /* default to current volume */
756 /* find the root name of the volume if given */
757 if (isalpha (name
[0]) && name
[1] == ':')
765 else if (IS_DIRECTORY_SEP (name
[0]) && IS_DIRECTORY_SEP (name
[1]))
772 if (IS_DIRECTORY_SEP (*name
) && --slashes
== 0)
785 if (GetVolumeInformation (rootname
,
786 volume_info
.name
, 32,
787 &volume_info
.serialnum
,
788 &volume_info
.maxcomp
,
790 volume_info
.type
, 32))
797 /* Determine if volume is FAT format (ie. only supports short 8.3
798 names); also set path pointer to start of pathname in name. */
800 is_fat_volume (const char * name
, const char ** pPath
)
802 if (get_volume_info (name
, pPath
))
803 return (volume_info
.maxcomp
== 12);
807 /* Map filename to a legal 8.3 name if necessary. */
809 map_win32_filename (const char * name
, const char ** pPath
)
811 static char shortname
[MAX_PATH
];
812 char * str
= shortname
;
816 if (is_fat_volume (name
, &path
)) /* truncate to 8.3 */
818 register int left
= 8; /* maximum number of chars in part */
819 register int extn
= 0; /* extension added? */
820 register int dots
= 2; /* maximum number of dots allowed */
823 *str
++ = *name
++; /* skip past UNC header */
825 while ((c
= *name
++))
832 extn
= 0; /* reset extension flags */
833 dots
= 2; /* max 2 dots */
834 left
= 8; /* max length 8 for main part */
838 extn
= 0; /* reset extension flags */
839 dots
= 2; /* max 2 dots */
840 left
= 8; /* max length 8 for main part */
845 /* Convert path components of the form .xxx to _xxx,
846 but leave . and .. as they are. This allows .emacs
847 to be read as _emacs, for example. */
851 IS_DIRECTORY_SEP (*name
))
866 extn
= 1; /* we've got an extension */
867 left
= 3; /* 3 chars in extension */
871 /* any embedded dots after the first are converted to _ */
876 case '#': /* don't lose these, they're important */
878 str
[-1] = c
; /* replace last character of part */
883 *str
++ = tolower (c
); /* map to lower case (looks nicer) */
885 dots
= 0; /* started a path component */
894 strcpy (shortname
, name
);
895 unixtodos_filename (shortname
);
899 *pPath
= shortname
+ (path
- name
);
905 /* Shadow some MSVC runtime functions to map requests for long filenames
906 to reasonable short names if necessary. This was originally added to
907 permit running Emacs on NT 3.1 on a FAT partition, which doesn't support
911 sys_access (const char * path
, int mode
)
913 return _access (map_win32_filename (path
, NULL
), mode
);
917 sys_chdir (const char * path
)
919 return _chdir (map_win32_filename (path
, NULL
));
923 sys_chmod (const char * path
, int mode
)
925 return _chmod (map_win32_filename (path
, NULL
), mode
);
929 sys_creat (const char * path
, int mode
)
931 return _creat (map_win32_filename (path
, NULL
), mode
);
935 sys_fopen(const char * path
, const char * mode
)
939 const char * mode_save
= mode
;
941 /* Force all file handles to be non-inheritable. This is necessary to
942 ensure child processes don't unwittingly inherit handles that might
943 prevent future file access. */
947 else if (mode
[0] == 'w' || mode
[0] == 'a')
948 oflag
= O_WRONLY
| O_CREAT
| O_TRUNC
;
952 /* Only do simplistic option parsing. */
956 oflag
&= ~(O_RDONLY
| O_WRONLY
);
959 else if (mode
[0] == 'b')
964 else if (mode
[0] == 't')
971 fd
= _open (map_win32_filename (path
, NULL
), oflag
| _O_NOINHERIT
, 0644);
975 return fdopen (fd
, mode_save
);
979 sys_link (const char * path1
, const char * path2
)
986 sys_mkdir (const char * path
)
988 return _mkdir (map_win32_filename (path
, NULL
));
991 /* Because of long name mapping issues, we need to implement this
992 ourselves. Also, MSVC's _mktemp returns NULL when it can't generate
993 a unique name, instead of setting the input template to an empty
996 Standard algorithm seems to be use pid or tid with a letter on the
997 front (in place of the 6 X's) and cycle through the letters to find a
998 unique name. We extend that to allow any reasonable character as the
999 first of the 6 X's. */
1001 sys_mktemp (char * template)
1005 unsigned uid
= GetCurrentThreadId ();
1006 static char first_char
[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#";
1008 if (template == NULL
)
1010 p
= template + strlen (template);
1012 /* replace up to the last 5 X's with uid in decimal */
1013 while (--p
>= template && p
[0] == 'X' && --i
>= 0)
1015 p
[0] = '0' + uid
% 10;
1019 if (i
< 0 && p
[0] == 'X')
1024 int save_errno
= errno
;
1025 p
[0] = first_char
[i
];
1026 if (sys_access (template, 0) < 0)
1032 while (++i
< sizeof (first_char
));
1035 /* Template is badly formed or else we can't generate a unique name,
1036 so return empty string */
1042 sys_open (const char * path
, int oflag
, int mode
)
1044 /* Force all file handles to be non-inheritable. */
1045 return _open (map_win32_filename (path
, NULL
), oflag
| _O_NOINHERIT
, mode
);
1049 sys_rename (const char * oldname
, const char * newname
)
1051 char temp
[MAX_PATH
];
1053 /* MoveFile on Win95 doesn't correctly change the short file name
1054 alias when oldname has a three char extension and newname has the
1055 same first three chars in its extension. To avoid problems, on
1056 Win95 we rename to a temporary name first. */
1058 strcpy (temp
, map_win32_filename (oldname
, NULL
));
1060 if (GetVersion () & 0x80000000)
1064 unixtodos_filename (temp
);
1065 if (p
= strrchr (temp
, '\\'))
1069 strcpy (p
, "__XXXXXX");
1071 if (rename (map_win32_filename (oldname
, NULL
), temp
) < 0)
1075 /* Emulate Unix behaviour - newname is deleted if it already exists
1076 (at least if it is a file; don't do this for directories). */
1077 newname
= map_win32_filename (newname
, NULL
);
1078 if (GetFileAttributes (newname
) != -1)
1080 _chmod (newname
, 0666);
1084 return rename (temp
, newname
);
1088 sys_rmdir (const char * path
)
1090 return _rmdir (map_win32_filename (path
, NULL
));
1094 sys_unlink (const char * path
)
1096 return _unlink (map_win32_filename (path
, NULL
));
1099 static FILETIME utc_base_ft
;
1100 static long double utc_base
;
1101 static int init
= 0;
1104 convert_time (FILETIME ft
)
1110 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1119 st
.wMilliseconds
= 0;
1121 SystemTimeToFileTime (&st
, &utc_base_ft
);
1122 utc_base
= (long double) utc_base_ft
.dwHighDateTime
1123 * 4096 * 1024 * 1024 + utc_base_ft
.dwLowDateTime
;
1127 if (CompareFileTime (&ft
, &utc_base_ft
) < 0)
1130 ret
= (long double) ft
.dwHighDateTime
* 4096 * 1024 * 1024 + ft
.dwLowDateTime
;
1132 return (time_t) (ret
* 1e-7);
1136 /* in case we ever have need of this */
1138 convert_from_time_t (time_t time
, FILETIME
* pft
)
1144 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1153 st
.wMilliseconds
= 0;
1155 SystemTimeToFileTime (&st
, &utc_base_ft
);
1156 utc_base
= (long double) utc_base_ft
.dwHighDateTime
1157 * 4096 * 1024 * 1024 + utc_base_ft
.dwLowDateTime
;
1161 /* time in 100ns units since 1-Jan-1601 */
1162 tmp
= (long double) time
* 1e7
+ utc_base
;
1163 pft
->dwHighDateTime
= (DWORD
) (tmp
/ (4096.0 * 1024 * 1024));
1164 pft
->dwLowDateTime
= (DWORD
) (tmp
- pft
->dwHighDateTime
);
1168 /* "PJW" algorithm (see the "Dragon" compiler book). */
1170 hashval (const char * str
)
1176 h
= (h
<< 4) + *str
++;
1177 if ((g
= h
& 0xf0000000) != 0)
1178 h
= (h
^ (g
>> 24)) & 0x0fffffff;
1183 /* Return the hash value of the canonical pathname, excluding the
1184 drive/UNC header, to get a hopefully unique inode number. */
1186 generate_inode_val (const char * name
)
1188 char fullname
[ MAX_PATH
];
1192 GetFullPathName (name
, sizeof (fullname
), fullname
, &p
);
1193 get_volume_info (fullname
, &p
);
1194 /* Normal Win32 filesystems are still case insensitive. */
1197 return (_ino_t
) (hash
^ (hash
>> 16));
1200 /* MSVC stat function can't cope with UNC names and has other bugs, so
1201 replace it with our own. This also allows us to calculate consistent
1202 inode values without hacks in the main Emacs code. */
1204 stat (const char * path
, struct stat
* buf
)
1207 WIN32_FIND_DATA wfd
;
1211 int rootdir
= FALSE
;
1213 if (path
== NULL
|| buf
== NULL
)
1219 name
= (char *) map_win32_filename (path
, &path
);
1220 /* must be valid filename, no wild cards */
1221 if (strchr (name
, '*') || strchr (name
, '?'))
1227 /* Remove trailing directory separator, unless name is the root
1228 directory of a drive or UNC volume in which case ensure there
1229 is a trailing separator. */
1230 len
= strlen (name
);
1231 rootdir
= (path
>= name
+ len
- 1
1232 && (IS_DIRECTORY_SEP (*path
) || *path
== 0));
1233 name
= strcpy (alloca (len
+ 2), name
);
1237 if (!IS_DIRECTORY_SEP (name
[len
-1]))
1238 strcat (name
, "\\");
1239 if (GetDriveType (name
) < 2)
1244 memset (&wfd
, 0, sizeof (wfd
));
1245 wfd
.dwFileAttributes
= FILE_ATTRIBUTE_DIRECTORY
;
1246 wfd
.ftCreationTime
= utc_base_ft
;
1247 wfd
.ftLastAccessTime
= utc_base_ft
;
1248 wfd
.ftLastWriteTime
= utc_base_ft
;
1249 strcpy (wfd
.cFileName
, name
);
1253 if (IS_DIRECTORY_SEP (name
[len
-1]))
1255 fh
= FindFirstFile (name
, &wfd
);
1256 if (fh
== INVALID_HANDLE_VALUE
)
1264 if (wfd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
1266 buf
->st_mode
= _S_IFDIR
;
1267 buf
->st_nlink
= 2; /* doesn't really matter */
1272 /* This is more accurate in terms of gettting the correct number
1273 of links, but is quite slow (it is noticable when Emacs is
1274 making a list of file name completions). */
1275 BY_HANDLE_FILE_INFORMATION info
;
1277 fh
= CreateFile (name
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1278 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1280 if (GetFileInformationByHandle (fh
, &info
))
1282 switch (GetFileType (fh
))
1284 case FILE_TYPE_DISK
:
1285 buf
->st_mode
= _S_IFREG
;
1287 case FILE_TYPE_PIPE
:
1288 buf
->st_mode
= _S_IFIFO
;
1290 case FILE_TYPE_CHAR
:
1291 case FILE_TYPE_UNKNOWN
:
1293 buf
->st_mode
= _S_IFCHR
;
1295 buf
->st_nlink
= info
.nNumberOfLinks
;
1296 /* Could use file index, but this is not guaranteed to be
1297 unique unless we keep a handle open all the time. */
1298 /* buf->st_ino = info.nFileIndexLow ^ info.nFileIndexHigh; */
1307 buf
->st_mode
= _S_IFREG
;
1312 /* consider files to belong to current user */
1313 buf
->st_uid
= the_passwd
.pw_uid
;
1314 buf
->st_gid
= the_passwd
.pw_gid
;
1316 /* volume_info is set indirectly by map_win32_filename */
1317 buf
->st_dev
= volume_info
.serialnum
;
1318 buf
->st_rdev
= volume_info
.serialnum
;
1320 buf
->st_ino
= generate_inode_val (name
);
1322 buf
->st_size
= wfd
.nFileSizeLow
;
1324 /* Convert timestamps to Unix format. */
1325 buf
->st_mtime
= convert_time (wfd
.ftLastWriteTime
);
1326 buf
->st_atime
= convert_time (wfd
.ftLastAccessTime
);
1327 if (buf
->st_atime
== 0) buf
->st_atime
= buf
->st_mtime
;
1328 buf
->st_ctime
= convert_time (wfd
.ftCreationTime
);
1329 if (buf
->st_ctime
== 0) buf
->st_ctime
= buf
->st_mtime
;
1331 /* determine rwx permissions */
1332 if (wfd
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
)
1333 permission
= _S_IREAD
;
1335 permission
= _S_IREAD
| _S_IWRITE
;
1337 if (wfd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
1338 permission
|= _S_IEXEC
;
1341 char * p
= strrchr (name
, '.');
1343 (stricmp (p
, ".exe") == 0 ||
1344 stricmp (p
, ".com") == 0 ||
1345 stricmp (p
, ".bat") == 0 ||
1346 stricmp (p
, ".cmd") == 0))
1347 permission
|= _S_IEXEC
;
1350 buf
->st_mode
|= permission
| (permission
>> 3) | (permission
>> 6);
1357 /* Wrappers for winsock functions to map between our file descriptors
1358 and winsock's handles; also set h_errno for convenience.
1360 To allow Emacs to run on systems which don't have winsock support
1361 installed, we dynamically link to winsock on startup if present, and
1362 otherwise provide the minimum necessary functionality
1363 (eg. gethostname). */
1365 /* function pointers for relevant socket functions */
1366 int (PASCAL
*pfn_WSAStartup
) (WORD wVersionRequired
, LPWSADATA lpWSAData
);
1367 void (PASCAL
*pfn_WSASetLastError
) (int iError
);
1368 int (PASCAL
*pfn_WSAGetLastError
) (void);
1369 int (PASCAL
*pfn_socket
) (int af
, int type
, int protocol
);
1370 int (PASCAL
*pfn_bind
) (SOCKET s
, const struct sockaddr
*addr
, int namelen
);
1371 int (PASCAL
*pfn_connect
) (SOCKET s
, const struct sockaddr
*addr
, int namelen
);
1372 int (PASCAL
*pfn_ioctlsocket
) (SOCKET s
, long cmd
, u_long
*argp
);
1373 int (PASCAL
*pfn_recv
) (SOCKET s
, char * buf
, int len
, int flags
);
1374 int (PASCAL
*pfn_send
) (SOCKET s
, const char * buf
, int len
, int flags
);
1375 int (PASCAL
*pfn_closesocket
) (SOCKET s
);
1376 int (PASCAL
*pfn_shutdown
) (SOCKET s
, int how
);
1377 int (PASCAL
*pfn_WSACleanup
) (void);
1379 u_short (PASCAL
*pfn_htons
) (u_short hostshort
);
1380 u_short (PASCAL
*pfn_ntohs
) (u_short netshort
);
1381 unsigned long (PASCAL
*pfn_inet_addr
) (const char * cp
);
1382 int (PASCAL
*pfn_gethostname
) (char * name
, int namelen
);
1383 struct hostent
* (PASCAL
*pfn_gethostbyname
) (const char * name
);
1384 struct servent
* (PASCAL
*pfn_getservbyname
) (const char * name
, const char * proto
);
1386 /* SetHandleInformation is only needed to make sockets non-inheritable. */
1387 BOOL (WINAPI
*pfn_SetHandleInformation
) (HANDLE object
, DWORD mask
, DWORD flags
);
1388 #ifndef HANDLE_FLAG_INHERIT
1389 #define HANDLE_FLAG_INHERIT 1
1392 static int have_winsock
;
1393 static HANDLE winsock_lib
;
1401 FreeLibrary (winsock_lib
);
1408 WSADATA winsockData
;
1410 have_winsock
= FALSE
;
1412 pfn_SetHandleInformation
= NULL
;
1413 pfn_SetHandleInformation
1414 = (void *) GetProcAddress (GetModuleHandle ("kernel32.dll"),
1415 "SetHandleInformation");
1417 winsock_lib
= LoadLibrary ("wsock32.dll");
1419 if (winsock_lib
!= NULL
)
1421 /* dynamically link to socket functions */
1423 #define LOAD_PROC(fn) \
1424 if ((pfn_##fn = (void *) GetProcAddress (winsock_lib, #fn)) == NULL) \
1427 LOAD_PROC( WSAStartup
);
1428 LOAD_PROC( WSASetLastError
);
1429 LOAD_PROC( WSAGetLastError
);
1430 LOAD_PROC( socket
);
1432 LOAD_PROC( connect
);
1433 LOAD_PROC( ioctlsocket
);
1436 LOAD_PROC( closesocket
);
1437 LOAD_PROC( shutdown
);
1440 LOAD_PROC( inet_addr
);
1441 LOAD_PROC( gethostname
);
1442 LOAD_PROC( gethostbyname
);
1443 LOAD_PROC( getservbyname
);
1444 LOAD_PROC( WSACleanup
);
1446 /* specify version 1.1 of winsock */
1447 if (pfn_WSAStartup (0x101, &winsockData
) == 0)
1449 have_winsock
= TRUE
;
1454 FreeLibrary (winsock_lib
);
1461 /* function to set h_errno for compatability; map winsock error codes to
1462 normal system codes where they overlap (non-overlapping definitions
1463 are already in <sys/socket.h> */
1464 static void set_errno ()
1469 h_errno
= pfn_WSAGetLastError ();
1473 case WSAEACCES
: h_errno
= EACCES
; break;
1474 case WSAEBADF
: h_errno
= EBADF
; break;
1475 case WSAEFAULT
: h_errno
= EFAULT
; break;
1476 case WSAEINTR
: h_errno
= EINTR
; break;
1477 case WSAEINVAL
: h_errno
= EINVAL
; break;
1478 case WSAEMFILE
: h_errno
= EMFILE
; break;
1479 case WSAENAMETOOLONG
: h_errno
= ENAMETOOLONG
; break;
1480 case WSAENOTEMPTY
: h_errno
= ENOTEMPTY
; break;
1485 static void check_errno ()
1487 if (h_errno
== 0 && have_winsock
)
1488 pfn_WSASetLastError (0);
1491 /* [andrewi 3-May-96] I've had conflicting results using both methods,
1492 but I believe the method of keeping the socket handle separate (and
1493 insuring it is not inheritable) is the correct one. */
1495 //#define SOCK_REPLACE_HANDLE
1497 #ifdef SOCK_REPLACE_HANDLE
1498 #define SOCK_HANDLE(fd) ((SOCKET) _get_osfhandle (fd))
1500 #define SOCK_HANDLE(fd) ((SOCKET) fd_info[fd].hnd)
1504 sys_socket(int af
, int type
, int protocol
)
1513 return INVALID_SOCKET
;
1518 /* call the real socket function */
1519 s
= (long) pfn_socket (af
, type
, protocol
);
1521 if (s
!= INVALID_SOCKET
)
1523 /* Although under NT 3.5 _open_osfhandle will accept a socket
1524 handle, if opened with SO_OPENTYPE == SO_SYNCHRONOUS_NONALERT,
1525 that does not work under NT 3.1. However, we can get the same
1526 effect by using a backdoor function to replace an existing
1527 descriptor handle with the one we want. */
1529 /* allocate a file descriptor (with appropriate flags) */
1530 fd
= _open ("NUL:", _O_RDWR
);
1533 #ifdef SOCK_REPLACE_HANDLE
1534 /* now replace handle to NUL with our socket handle */
1535 CloseHandle ((HANDLE
) _get_osfhandle (fd
));
1537 _set_osfhnd (fd
, s
);
1538 /* setmode (fd, _O_BINARY); */
1540 /* Make a non-inheritable copy of the socket handle. */
1543 HANDLE new_s
= INVALID_HANDLE_VALUE
;
1545 parent
= GetCurrentProcess ();
1547 /* Apparently there is a bug in NT 3.51 with some service
1548 packs, which prevents using DuplicateHandle to make a
1549 socket handle non-inheritable (causes WSACleanup to
1550 hang). The work-around is to use SetHandleInformation
1551 instead if it is available and implemented. */
1552 if (!pfn_SetHandleInformation
1553 || !pfn_SetHandleInformation ((HANDLE
) s
,
1554 HANDLE_FLAG_INHERIT
,
1555 HANDLE_FLAG_INHERIT
))
1557 DuplicateHandle (parent
,
1563 DUPLICATE_SAME_ACCESS
);
1564 pfn_closesocket (s
);
1567 fd_info
[fd
].hnd
= (HANDLE
) s
;
1571 /* set our own internal flags */
1572 fd_info
[fd
].flags
= FILE_SOCKET
| FILE_BINARY
| FILE_READ
| FILE_WRITE
;
1578 cp
->status
= STATUS_READ_ACKNOWLEDGED
;
1580 /* attach child_process to fd_info */
1581 if (fd_info
[ fd
].cp
!= NULL
)
1583 DebPrint (("sys_socket: fd_info[%d] apparently in use!\n", fd
));
1587 fd_info
[ fd
].cp
= cp
;
1596 pfn_closesocket (s
);
1606 sys_bind (int s
, const struct sockaddr
* addr
, int namelen
)
1611 return SOCKET_ERROR
;
1615 if (fd_info
[s
].flags
& FILE_SOCKET
)
1617 int rc
= pfn_bind (SOCK_HANDLE (s
), addr
, namelen
);
1618 if (rc
== SOCKET_ERROR
)
1623 return SOCKET_ERROR
;
1628 sys_connect (int s
, const struct sockaddr
* name
, int namelen
)
1633 return SOCKET_ERROR
;
1637 if (fd_info
[s
].flags
& FILE_SOCKET
)
1639 int rc
= pfn_connect (SOCK_HANDLE (s
), name
, namelen
);
1640 if (rc
== SOCKET_ERROR
)
1645 return SOCKET_ERROR
;
1649 sys_htons (u_short hostshort
)
1651 return (have_winsock
) ?
1652 pfn_htons (hostshort
) : hostshort
;
1656 sys_ntohs (u_short netshort
)
1658 return (have_winsock
) ?
1659 pfn_ntohs (netshort
) : netshort
;
1663 sys_inet_addr (const char * cp
)
1665 return (have_winsock
) ?
1666 pfn_inet_addr (cp
) : INADDR_NONE
;
1670 sys_gethostname (char * name
, int namelen
)
1673 return pfn_gethostname (name
, namelen
);
1675 if (namelen
> MAX_COMPUTERNAME_LENGTH
)
1676 return !GetComputerName (name
, &namelen
);
1679 return SOCKET_ERROR
;
1683 sys_gethostbyname(const char * name
)
1685 struct hostent
* host
;
1694 host
= pfn_gethostbyname (name
);
1701 sys_getservbyname(const char * name
, const char * proto
)
1703 struct servent
* serv
;
1712 serv
= pfn_getservbyname (name
, proto
);
1718 #endif /* HAVE_SOCKETS */
1721 /* Shadow main io functions: we need to handle pipes and sockets more
1722 intelligently, and implement non-blocking mode as well. */
1729 if (fd
< 0 || fd
>= MAXDESC
)
1737 child_process
* cp
= fd_info
[fd
].cp
;
1739 fd_info
[fd
].cp
= NULL
;
1741 if (CHILD_ACTIVE (cp
))
1743 /* if last descriptor to active child_process then cleanup */
1745 for (i
= 0; i
< MAXDESC
; i
++)
1749 if (fd_info
[i
].cp
== cp
)
1754 #if defined (HAVE_SOCKETS) && !defined (SOCK_REPLACE_HANDLE)
1755 if (fd_info
[fd
].flags
& FILE_SOCKET
)
1757 if (!have_winsock
) abort ();
1759 pfn_shutdown (SOCK_HANDLE (fd
), 2);
1760 rc
= pfn_closesocket (SOCK_HANDLE (fd
));
1768 /* Note that sockets do not need special treatment here (at least on
1769 NT and Win95 using the standard tcp/ip stacks) - it appears that
1770 closesocket is equivalent to CloseHandle, which is to be expected
1771 because socket handles are fully fledged kernel handles. */
1775 fd_info
[fd
].flags
= 0;
1788 /* duplicate our internal info as well */
1789 fd_info
[new_fd
] = fd_info
[fd
];
1796 sys_dup2 (int src
, int dst
)
1800 if (dst
< 0 || dst
>= MAXDESC
)
1806 /* make sure we close the destination first if it's a pipe or socket */
1807 if (src
!= dst
&& fd_info
[dst
].flags
!= 0)
1810 rc
= _dup2 (src
, dst
);
1813 /* duplicate our internal info as well */
1814 fd_info
[dst
] = fd_info
[src
];
1819 /* From callproc.c */
1820 extern Lisp_Object Vbinary_process_input
;
1821 extern Lisp_Object Vbinary_process_output
;
1823 /* Unix pipe() has only one arg */
1825 sys_pipe (int * phandles
)
1831 /* make pipe handles non-inheritable; when we spawn a child,
1832 we replace the relevant handle with an inheritable one. */
1833 rc
= _pipe (phandles
, 0, _O_NOINHERIT
);
1837 /* set internal flags, and put read and write handles into binary
1838 mode as necessary; if not in binary mode, set the MSVC internal
1839 FDEV (0x40) flag to prevent _read from treating ^Z as eof (this
1840 could otherwise allow Emacs to hang because it then waits
1841 indefinitely for the child process to exit, when it might not be
1843 flags
= FILE_PIPE
| FILE_READ
;
1844 if (!NILP (Vbinary_process_output
))
1846 flags
|= FILE_BINARY
;
1847 setmode (phandles
[0], _O_BINARY
);
1849 #if (_MSC_VER == 900)
1851 _osfile
[phandles
[0]] |= 0x40;
1854 fd_info
[phandles
[0]].flags
= flags
;
1856 flags
= FILE_PIPE
| FILE_WRITE
;
1857 if (!NILP (Vbinary_process_input
))
1859 flags
|= FILE_BINARY
;
1860 setmode (phandles
[1], _O_BINARY
);
1862 #if (_MSC_VER == 900)
1864 _osfile
[phandles
[1]] |= 0x40;
1867 fd_info
[phandles
[1]].flags
= flags
;
1874 extern Lisp_Object Vwin32_pipe_read_delay
;
1876 /* Function to do blocking read of one byte, needed to implement
1877 select. It is only allowed on sockets and pipes. */
1879 _sys_read_ahead (int fd
)
1884 if (fd
< 0 || fd
>= MAXDESC
)
1885 return STATUS_READ_ERROR
;
1887 cp
= fd_info
[fd
].cp
;
1889 if (cp
== NULL
|| cp
->fd
!= fd
|| cp
->status
!= STATUS_READ_READY
)
1890 return STATUS_READ_ERROR
;
1892 if ((fd_info
[fd
].flags
& (FILE_PIPE
| FILE_SOCKET
)) == 0
1893 || (fd_info
[fd
].flags
& FILE_READ
) == 0)
1895 DebPrint (("_sys_read_ahead: internal error: fd %d is not a pipe or socket!\n", fd
));
1899 cp
->status
= STATUS_READ_IN_PROGRESS
;
1901 if (fd_info
[fd
].flags
& FILE_PIPE
)
1903 /* Use read to get CRLF translation */
1904 rc
= _read (fd
, &cp
->chr
, sizeof (char));
1906 /* Give subprocess time to buffer some more output for us before
1907 reporting that input is available; we need this because Win95
1908 connects DOS programs to pipes by making the pipe appear to be
1909 the normal console stdout - as a result most DOS programs will
1910 write to stdout without buffering, ie. one character at a
1911 time. Even some Win32 programs do this - "dir" in a command
1912 shell on NT is very slow if we don't do this. */
1915 int wait
= XINT (Vwin32_pipe_read_delay
);
1921 /* Yield remainder of our time slice, effectively giving a
1922 temporary priority boost to the child process. */
1927 else if (fd_info
[fd
].flags
& FILE_SOCKET
)
1928 rc
= pfn_recv (SOCK_HANDLE (fd
), &cp
->chr
, sizeof (char), 0);
1931 if (rc
== sizeof (char))
1932 cp
->status
= STATUS_READ_SUCCEEDED
;
1934 cp
->status
= STATUS_READ_FAILED
;
1940 sys_read (int fd
, char * buffer
, unsigned int count
)
1947 if (fd
< 0 || fd
>= MAXDESC
)
1953 if (fd_info
[fd
].flags
& (FILE_PIPE
| FILE_SOCKET
))
1955 child_process
*cp
= fd_info
[fd
].cp
;
1957 if ((fd_info
[fd
].flags
& FILE_READ
) == 0)
1963 /* presence of a child_process structure means we are operating in
1964 non-blocking mode - otherwise we just call _read directly.
1965 Note that the child_process structure might be missing because
1966 reap_subprocess has been called; in this case the pipe is
1967 already broken, so calling _read on it is okay. */
1970 int current_status
= cp
->status
;
1972 switch (current_status
)
1974 case STATUS_READ_FAILED
:
1975 case STATUS_READ_ERROR
:
1976 /* report normal EOF */
1979 case STATUS_READ_READY
:
1980 case STATUS_READ_IN_PROGRESS
:
1981 DebPrint (("sys_read called when read is in progress\n"));
1982 errno
= EWOULDBLOCK
;
1985 case STATUS_READ_SUCCEEDED
:
1986 /* consume read-ahead char */
1987 *buffer
++ = cp
->chr
;
1990 cp
->status
= STATUS_READ_ACKNOWLEDGED
;
1991 ResetEvent (cp
->char_avail
);
1993 case STATUS_READ_ACKNOWLEDGED
:
1997 DebPrint (("sys_read: bad status %d\n", current_status
));
2002 if (fd_info
[fd
].flags
& FILE_PIPE
)
2004 PeekNamedPipe ((HANDLE
) _get_osfhandle (fd
), NULL
, 0, NULL
, &waiting
, NULL
);
2005 to_read
= min (waiting
, (DWORD
) count
);
2007 /* Use read to get CRLF translation */
2008 nchars
= _read (fd
, buffer
, to_read
);
2011 else /* FILE_SOCKET */
2013 if (!have_winsock
) abort ();
2015 /* do the equivalent of a non-blocking read */
2016 pfn_ioctlsocket (SOCK_HANDLE (fd
), FIONREAD
, &waiting
);
2017 if (waiting
== 0 && extra
== 0)
2019 h_errno
= errno
= EWOULDBLOCK
;
2026 /* always use binary mode for sockets */
2027 nchars
= pfn_recv (SOCK_HANDLE (fd
), buffer
, count
, 0);
2028 if (nchars
== SOCKET_ERROR
)
2030 DebPrint(("sys_read.recv failed with error %d on socket %ld\n",
2031 pfn_WSAGetLastError (), SOCK_HANDLE (fd
)));
2044 nchars
= _read (fd
, buffer
, count
);
2047 nchars
= _read (fd
, buffer
, count
);
2049 return nchars
+ extra
;
2052 /* For now, don't bother with a non-blocking mode */
2054 sys_write (int fd
, const void * buffer
, unsigned int count
)
2058 if (fd
< 0 || fd
>= MAXDESC
)
2064 if (fd_info
[fd
].flags
& (FILE_PIPE
| FILE_SOCKET
))
2065 if ((fd_info
[fd
].flags
& FILE_WRITE
) == 0)
2071 if (fd_info
[fd
].flags
& FILE_SOCKET
)
2073 if (!have_winsock
) abort ();
2074 nchars
= pfn_send (SOCK_HANDLE (fd
), buffer
, count
, 0);
2075 if (nchars
== SOCKET_ERROR
)
2077 DebPrint(("sys_read.send failed with error %d on socket %ld\n",
2078 pfn_WSAGetLastError (), SOCK_HANDLE (fd
)));
2084 nchars
= _write (fd
, buffer
, count
);
2094 /* shutdown the socket interface if necessary */
2099 extern BOOL can_run_dos_process
;
2100 extern BOOL dos_process_running
;
2106 /* initialise the socket interface if available */
2110 /* Initial preparation for subprocess support: replace our standard
2111 handles with non-inheritable versions. */
2114 HANDLE stdin_save
= INVALID_HANDLE_VALUE
;
2115 HANDLE stdout_save
= INVALID_HANDLE_VALUE
;
2116 HANDLE stderr_save
= INVALID_HANDLE_VALUE
;
2118 parent
= GetCurrentProcess ();
2120 /* ignore errors when duplicating and closing; typically the
2121 handles will be invalid when running as a gui program. */
2122 DuplicateHandle (parent
,
2123 GetStdHandle (STD_INPUT_HANDLE
),
2128 DUPLICATE_SAME_ACCESS
);
2130 DuplicateHandle (parent
,
2131 GetStdHandle (STD_OUTPUT_HANDLE
),
2136 DUPLICATE_SAME_ACCESS
);
2138 DuplicateHandle (parent
,
2139 GetStdHandle (STD_ERROR_HANDLE
),
2144 DUPLICATE_SAME_ACCESS
);
2150 if (stdin_save
!= INVALID_HANDLE_VALUE
)
2151 _open_osfhandle ((long) stdin_save
, O_TEXT
);
2153 open ("nul", O_TEXT
| O_NOINHERIT
| O_RDONLY
);
2156 if (stdout_save
!= INVALID_HANDLE_VALUE
)
2157 _open_osfhandle ((long) stdout_save
, O_TEXT
);
2159 open ("nul", O_TEXT
| O_NOINHERIT
| O_WRONLY
);
2162 if (stderr_save
!= INVALID_HANDLE_VALUE
)
2163 _open_osfhandle ((long) stderr_save
, O_TEXT
);
2165 open ("nul", O_TEXT
| O_NOINHERIT
| O_WRONLY
);
2169 /* Only allow Emacs to run DOS programs on Win95. */
2170 can_run_dos_process
= (GetVersion () & 0x80000000);
2171 dos_process_running
= FALSE
;
2173 /* unfortunately, atexit depends on implementation of malloc */
2174 /* atexit (term_ntproc); */
2175 signal (SIGABRT
, term_ntproc
);