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
[] =
599 for (i
= 0; i
< (sizeof (env_vars
) / sizeof (env_vars
[0])); i
++)
601 if (!getenv (env_vars
[i
]) &&
602 (lpval
= nt_get_resource (env_vars
[i
], &dwType
)) != NULL
)
604 if (dwType
== REG_EXPAND_SZ
)
606 char buf1
[500], buf2
[500];
608 ExpandEnvironmentStrings ((LPSTR
) lpval
, buf1
, 500);
609 _snprintf (buf2
, 499, "%s=%s", env_vars
[i
], buf1
);
610 putenv (strdup (buf2
));
612 else if (dwType
== REG_SZ
)
616 _snprintf (buf
, 499, "%s=%s", env_vars
[i
], lpval
);
617 putenv (strdup (buf
));
628 /* We don't have scripts to automatically determine the system configuration
629 for Emacs before it's compiled, and we don't want to have to make the
630 user enter it, so we define EMACS_CONFIGURATION to invoke this runtime
633 static char configuration_buffer
[32];
636 get_emacs_configuration (void)
638 char *arch
, *oem
, *os
;
640 /* Determine the processor type. */
641 switch (get_processor_type ())
644 #ifdef PROCESSOR_INTEL_386
645 case PROCESSOR_INTEL_386
:
646 case PROCESSOR_INTEL_486
:
647 case PROCESSOR_INTEL_PENTIUM
:
652 #ifdef PROCESSOR_INTEL_860
653 case PROCESSOR_INTEL_860
:
658 #ifdef PROCESSOR_MIPS_R2000
659 case PROCESSOR_MIPS_R2000
:
660 case PROCESSOR_MIPS_R3000
:
661 case PROCESSOR_MIPS_R4000
:
666 #ifdef PROCESSOR_ALPHA_21064
667 case PROCESSOR_ALPHA_21064
:
677 /* Let oem be "*" until we figure out how to decode the OEM field. */
680 os
= (GetVersion () & 0x80000000) ? "win95" : "nt";
682 sprintf (configuration_buffer
, "%s-%s-%s%d.%d", arch
, oem
, os
,
683 get_nt_major_version (), get_nt_minor_version ());
684 return configuration_buffer
;
687 #include <sys/timeb.h>
689 /* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */
691 gettimeofday (struct timeval
*tv
, struct timezone
*tz
)
696 tv
->tv_sec
= tb
.time
;
697 tv
->tv_usec
= tb
.millitm
* 1000L;
700 tz
->tz_minuteswest
= tb
.timezone
; /* minutes west of Greenwich */
701 tz
->tz_dsttime
= tb
.dstflag
; /* type of dst correction */
705 /* ------------------------------------------------------------------------- */
706 /* IO support and wrapper functions for Win32 API. */
707 /* ------------------------------------------------------------------------- */
709 /* Place a wrapper around the MSVC version of ctime. It returns NULL
710 on network directories, so we handle that case here.
711 (Ulrich Leodolter, 1/11/95). */
713 sys_ctime (const time_t *t
)
715 char *str
= (char *) ctime (t
);
716 return (str
? str
: "Sun Jan 01 00:00:00 1970");
719 /* Emulate sleep...we could have done this with a define, but that
720 would necessitate including windows.h in the files that used it.
721 This is much easier. */
723 sys_sleep (int seconds
)
725 Sleep (seconds
* 1000);
728 /* Internal MSVC data and functions for low-level descriptor munging */
729 #if (_MSC_VER == 900)
730 extern char _osfile
[];
732 extern int __cdecl
_set_osfhnd (int fd
, long h
);
733 extern int __cdecl
_free_osfhnd (int fd
);
735 /* parallel array of private info on file handles */
736 filedesc fd_info
[ MAXDESC
];
746 /* Get information on the volume where name is held; set path pointer to
747 start of pathname in name (past UNC header\volume header if present). */
749 get_volume_info (const char * name
, const char ** pPath
)
752 char *rootname
= NULL
; /* default to current volume */
757 /* find the root name of the volume if given */
758 if (isalpha (name
[0]) && name
[1] == ':')
766 else if (IS_DIRECTORY_SEP (name
[0]) && IS_DIRECTORY_SEP (name
[1]))
773 if (IS_DIRECTORY_SEP (*name
) && --slashes
== 0)
786 if (GetVolumeInformation (rootname
,
787 volume_info
.name
, 32,
788 &volume_info
.serialnum
,
789 &volume_info
.maxcomp
,
791 volume_info
.type
, 32))
798 /* Determine if volume is FAT format (ie. only supports short 8.3
799 names); also set path pointer to start of pathname in name. */
801 is_fat_volume (const char * name
, const char ** pPath
)
803 if (get_volume_info (name
, pPath
))
804 return (volume_info
.maxcomp
== 12);
808 /* Map filename to a legal 8.3 name if necessary. */
810 map_win32_filename (const char * name
, const char ** pPath
)
812 static char shortname
[MAX_PATH
];
813 char * str
= shortname
;
817 if (is_fat_volume (name
, &path
)) /* truncate to 8.3 */
819 register int left
= 8; /* maximum number of chars in part */
820 register int extn
= 0; /* extension added? */
821 register int dots
= 2; /* maximum number of dots allowed */
824 *str
++ = *name
++; /* skip past UNC header */
826 while ((c
= *name
++))
833 extn
= 0; /* reset extension flags */
834 dots
= 2; /* max 2 dots */
835 left
= 8; /* max length 8 for main part */
839 extn
= 0; /* reset extension flags */
840 dots
= 2; /* max 2 dots */
841 left
= 8; /* max length 8 for main part */
846 /* Convert path components of the form .xxx to _xxx,
847 but leave . and .. as they are. This allows .emacs
848 to be read as _emacs, for example. */
852 IS_DIRECTORY_SEP (*name
))
867 extn
= 1; /* we've got an extension */
868 left
= 3; /* 3 chars in extension */
872 /* any embedded dots after the first are converted to _ */
877 case '#': /* don't lose these, they're important */
879 str
[-1] = c
; /* replace last character of part */
884 *str
++ = tolower (c
); /* map to lower case (looks nicer) */
886 dots
= 0; /* started a path component */
895 strcpy (shortname
, name
);
896 unixtodos_filename (shortname
);
900 *pPath
= shortname
+ (path
- name
);
906 /* Shadow some MSVC runtime functions to map requests for long filenames
907 to reasonable short names if necessary. This was originally added to
908 permit running Emacs on NT 3.1 on a FAT partition, which doesn't support
912 sys_access (const char * path
, int mode
)
914 return _access (map_win32_filename (path
, NULL
), mode
);
918 sys_chdir (const char * path
)
920 return _chdir (map_win32_filename (path
, NULL
));
924 sys_chmod (const char * path
, int mode
)
926 return _chmod (map_win32_filename (path
, NULL
), mode
);
930 sys_creat (const char * path
, int mode
)
932 return _creat (map_win32_filename (path
, NULL
), mode
);
936 sys_fopen(const char * path
, const char * mode
)
940 const char * mode_save
= mode
;
942 /* Force all file handles to be non-inheritable. This is necessary to
943 ensure child processes don't unwittingly inherit handles that might
944 prevent future file access. */
948 else if (mode
[0] == 'w' || mode
[0] == 'a')
949 oflag
= O_WRONLY
| O_CREAT
| O_TRUNC
;
953 /* Only do simplistic option parsing. */
957 oflag
&= ~(O_RDONLY
| O_WRONLY
);
960 else if (mode
[0] == 'b')
965 else if (mode
[0] == 't')
972 fd
= _open (map_win32_filename (path
, NULL
), oflag
| _O_NOINHERIT
, 0644);
976 return fdopen (fd
, mode_save
);
980 sys_link (const char * path1
, const char * path2
)
987 sys_mkdir (const char * path
)
989 return _mkdir (map_win32_filename (path
, NULL
));
992 /* Because of long name mapping issues, we need to implement this
993 ourselves. Also, MSVC's _mktemp returns NULL when it can't generate
994 a unique name, instead of setting the input template to an empty
997 Standard algorithm seems to be use pid or tid with a letter on the
998 front (in place of the 6 X's) and cycle through the letters to find a
999 unique name. We extend that to allow any reasonable character as the
1000 first of the 6 X's. */
1002 sys_mktemp (char * template)
1006 unsigned uid
= GetCurrentThreadId ();
1007 static char first_char
[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#";
1009 if (template == NULL
)
1011 p
= template + strlen (template);
1013 /* replace up to the last 5 X's with uid in decimal */
1014 while (--p
>= template && p
[0] == 'X' && --i
>= 0)
1016 p
[0] = '0' + uid
% 10;
1020 if (i
< 0 && p
[0] == 'X')
1025 int save_errno
= errno
;
1026 p
[0] = first_char
[i
];
1027 if (sys_access (template, 0) < 0)
1033 while (++i
< sizeof (first_char
));
1036 /* Template is badly formed or else we can't generate a unique name,
1037 so return empty string */
1043 sys_open (const char * path
, int oflag
, int mode
)
1045 /* Force all file handles to be non-inheritable. */
1046 return _open (map_win32_filename (path
, NULL
), oflag
| _O_NOINHERIT
, mode
);
1050 sys_rename (const char * oldname
, const char * newname
)
1052 char temp
[MAX_PATH
];
1054 /* MoveFile on Win95 doesn't correctly change the short file name
1055 alias when oldname has a three char extension and newname has the
1056 same first three chars in its extension. To avoid problems, on
1057 Win95 we rename to a temporary name first. */
1059 strcpy (temp
, map_win32_filename (oldname
, NULL
));
1061 if (GetVersion () & 0x80000000)
1065 unixtodos_filename (temp
);
1066 if (p
= strrchr (temp
, '\\'))
1070 strcpy (p
, "__XXXXXX");
1072 if (rename (map_win32_filename (oldname
, NULL
), temp
) < 0)
1076 /* Emulate Unix behaviour - newname is deleted if it already exists
1077 (at least if it is a file; don't do this for directories). */
1078 newname
= map_win32_filename (newname
, NULL
);
1079 if (GetFileAttributes (newname
) != -1)
1081 _chmod (newname
, 0666);
1085 return rename (temp
, newname
);
1089 sys_rmdir (const char * path
)
1091 return _rmdir (map_win32_filename (path
, NULL
));
1095 sys_unlink (const char * path
)
1097 return _unlink (map_win32_filename (path
, NULL
));
1100 static FILETIME utc_base_ft
;
1101 static long double utc_base
;
1102 static int init
= 0;
1105 convert_time (FILETIME ft
)
1111 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1120 st
.wMilliseconds
= 0;
1122 SystemTimeToFileTime (&st
, &utc_base_ft
);
1123 utc_base
= (long double) utc_base_ft
.dwHighDateTime
1124 * 4096 * 1024 * 1024 + utc_base_ft
.dwLowDateTime
;
1128 if (CompareFileTime (&ft
, &utc_base_ft
) < 0)
1131 ret
= (long double) ft
.dwHighDateTime
* 4096 * 1024 * 1024 + ft
.dwLowDateTime
;
1133 return (time_t) (ret
* 1e-7);
1137 /* in case we ever have need of this */
1139 convert_from_time_t (time_t time
, FILETIME
* pft
)
1145 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1154 st
.wMilliseconds
= 0;
1156 SystemTimeToFileTime (&st
, &utc_base_ft
);
1157 utc_base
= (long double) utc_base_ft
.dwHighDateTime
1158 * 4096 * 1024 * 1024 + utc_base_ft
.dwLowDateTime
;
1162 /* time in 100ns units since 1-Jan-1601 */
1163 tmp
= (long double) time
* 1e7
+ utc_base
;
1164 pft
->dwHighDateTime
= (DWORD
) (tmp
/ (4096.0 * 1024 * 1024));
1165 pft
->dwLowDateTime
= (DWORD
) (tmp
- pft
->dwHighDateTime
);
1169 /* "PJW" algorithm (see the "Dragon" compiler book). */
1171 hashval (const char * str
)
1177 h
= (h
<< 4) + *str
++;
1178 if ((g
= h
& 0xf0000000) != 0)
1179 h
= (h
^ (g
>> 24)) & 0x0fffffff;
1184 /* Return the hash value of the canonical pathname, excluding the
1185 drive/UNC header, to get a hopefully unique inode number. */
1187 generate_inode_val (const char * name
)
1189 char fullname
[ MAX_PATH
];
1193 GetFullPathName (name
, sizeof (fullname
), fullname
, &p
);
1194 get_volume_info (fullname
, &p
);
1195 /* Normal Win32 filesystems are still case insensitive. */
1198 return (_ino_t
) (hash
^ (hash
>> 16));
1201 /* MSVC stat function can't cope with UNC names and has other bugs, so
1202 replace it with our own. This also allows us to calculate consistent
1203 inode values without hacks in the main Emacs code. */
1205 stat (const char * path
, struct stat
* buf
)
1208 WIN32_FIND_DATA wfd
;
1212 int rootdir
= FALSE
;
1214 if (path
== NULL
|| buf
== NULL
)
1220 name
= (char *) map_win32_filename (path
, &path
);
1221 /* must be valid filename, no wild cards */
1222 if (strchr (name
, '*') || strchr (name
, '?'))
1228 /* Remove trailing directory separator, unless name is the root
1229 directory of a drive or UNC volume in which case ensure there
1230 is a trailing separator. */
1231 len
= strlen (name
);
1232 rootdir
= (path
>= name
+ len
- 1
1233 && (IS_DIRECTORY_SEP (*path
) || *path
== 0));
1234 name
= strcpy (alloca (len
+ 2), name
);
1238 if (!IS_DIRECTORY_SEP (name
[len
-1]))
1239 strcat (name
, "\\");
1240 if (GetDriveType (name
) < 2)
1245 memset (&wfd
, 0, sizeof (wfd
));
1246 wfd
.dwFileAttributes
= FILE_ATTRIBUTE_DIRECTORY
;
1247 wfd
.ftCreationTime
= utc_base_ft
;
1248 wfd
.ftLastAccessTime
= utc_base_ft
;
1249 wfd
.ftLastWriteTime
= utc_base_ft
;
1250 strcpy (wfd
.cFileName
, name
);
1254 if (IS_DIRECTORY_SEP (name
[len
-1]))
1256 fh
= FindFirstFile (name
, &wfd
);
1257 if (fh
== INVALID_HANDLE_VALUE
)
1265 if (wfd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
1267 buf
->st_mode
= _S_IFDIR
;
1268 buf
->st_nlink
= 2; /* doesn't really matter */
1273 /* This is more accurate in terms of gettting the correct number
1274 of links, but is quite slow (it is noticable when Emacs is
1275 making a list of file name completions). */
1276 BY_HANDLE_FILE_INFORMATION info
;
1278 fh
= CreateFile (name
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1279 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1281 if (GetFileInformationByHandle (fh
, &info
))
1283 switch (GetFileType (fh
))
1285 case FILE_TYPE_DISK
:
1286 buf
->st_mode
= _S_IFREG
;
1288 case FILE_TYPE_PIPE
:
1289 buf
->st_mode
= _S_IFIFO
;
1291 case FILE_TYPE_CHAR
:
1292 case FILE_TYPE_UNKNOWN
:
1294 buf
->st_mode
= _S_IFCHR
;
1296 buf
->st_nlink
= info
.nNumberOfLinks
;
1297 /* Could use file index, but this is not guaranteed to be
1298 unique unless we keep a handle open all the time. */
1299 /* buf->st_ino = info.nFileIndexLow ^ info.nFileIndexHigh; */
1308 buf
->st_mode
= _S_IFREG
;
1313 /* consider files to belong to current user */
1314 buf
->st_uid
= the_passwd
.pw_uid
;
1315 buf
->st_gid
= the_passwd
.pw_gid
;
1317 /* volume_info is set indirectly by map_win32_filename */
1318 buf
->st_dev
= volume_info
.serialnum
;
1319 buf
->st_rdev
= volume_info
.serialnum
;
1321 buf
->st_ino
= generate_inode_val (name
);
1323 buf
->st_size
= wfd
.nFileSizeLow
;
1325 /* Convert timestamps to Unix format. */
1326 buf
->st_mtime
= convert_time (wfd
.ftLastWriteTime
);
1327 buf
->st_atime
= convert_time (wfd
.ftLastAccessTime
);
1328 if (buf
->st_atime
== 0) buf
->st_atime
= buf
->st_mtime
;
1329 buf
->st_ctime
= convert_time (wfd
.ftCreationTime
);
1330 if (buf
->st_ctime
== 0) buf
->st_ctime
= buf
->st_mtime
;
1332 /* determine rwx permissions */
1333 if (wfd
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
)
1334 permission
= _S_IREAD
;
1336 permission
= _S_IREAD
| _S_IWRITE
;
1338 if (wfd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
1339 permission
|= _S_IEXEC
;
1342 char * p
= strrchr (name
, '.');
1344 (stricmp (p
, ".exe") == 0 ||
1345 stricmp (p
, ".com") == 0 ||
1346 stricmp (p
, ".bat") == 0 ||
1347 stricmp (p
, ".cmd") == 0))
1348 permission
|= _S_IEXEC
;
1351 buf
->st_mode
|= permission
| (permission
>> 3) | (permission
>> 6);
1358 /* Wrappers for winsock functions to map between our file descriptors
1359 and winsock's handles; also set h_errno for convenience.
1361 To allow Emacs to run on systems which don't have winsock support
1362 installed, we dynamically link to winsock on startup if present, and
1363 otherwise provide the minimum necessary functionality
1364 (eg. gethostname). */
1366 /* function pointers for relevant socket functions */
1367 int (PASCAL
*pfn_WSAStartup
) (WORD wVersionRequired
, LPWSADATA lpWSAData
);
1368 void (PASCAL
*pfn_WSASetLastError
) (int iError
);
1369 int (PASCAL
*pfn_WSAGetLastError
) (void);
1370 int (PASCAL
*pfn_socket
) (int af
, int type
, int protocol
);
1371 int (PASCAL
*pfn_bind
) (SOCKET s
, const struct sockaddr
*addr
, int namelen
);
1372 int (PASCAL
*pfn_connect
) (SOCKET s
, const struct sockaddr
*addr
, int namelen
);
1373 int (PASCAL
*pfn_ioctlsocket
) (SOCKET s
, long cmd
, u_long
*argp
);
1374 int (PASCAL
*pfn_recv
) (SOCKET s
, char * buf
, int len
, int flags
);
1375 int (PASCAL
*pfn_send
) (SOCKET s
, const char * buf
, int len
, int flags
);
1376 int (PASCAL
*pfn_closesocket
) (SOCKET s
);
1377 int (PASCAL
*pfn_shutdown
) (SOCKET s
, int how
);
1378 int (PASCAL
*pfn_WSACleanup
) (void);
1380 u_short (PASCAL
*pfn_htons
) (u_short hostshort
);
1381 u_short (PASCAL
*pfn_ntohs
) (u_short netshort
);
1382 unsigned long (PASCAL
*pfn_inet_addr
) (const char * cp
);
1383 int (PASCAL
*pfn_gethostname
) (char * name
, int namelen
);
1384 struct hostent
* (PASCAL
*pfn_gethostbyname
) (const char * name
);
1385 struct servent
* (PASCAL
*pfn_getservbyname
) (const char * name
, const char * proto
);
1387 /* SetHandleInformation is only needed to make sockets non-inheritable. */
1388 BOOL (WINAPI
*pfn_SetHandleInformation
) (HANDLE object
, DWORD mask
, DWORD flags
);
1389 #ifndef HANDLE_FLAG_INHERIT
1390 #define HANDLE_FLAG_INHERIT 1
1394 static int winsock_inuse
;
1399 if (winsock_lib
!= NULL
&& winsock_inuse
== 0)
1401 /* Not sure what would cause WSAENETDOWN, or even if it can happen
1402 after WSAStartup returns successfully, but it seems reasonable
1403 to allow unloading winsock anyway in that case. */
1404 if (pfn_WSACleanup () == 0 ||
1405 pfn_WSAGetLastError () == WSAENETDOWN
)
1407 if (FreeLibrary (winsock_lib
))
1416 init_winsock (int load_now
)
1418 WSADATA winsockData
;
1420 if (winsock_lib
!= NULL
)
1423 pfn_SetHandleInformation
= NULL
;
1424 pfn_SetHandleInformation
1425 = (void *) GetProcAddress (GetModuleHandle ("kernel32.dll"),
1426 "SetHandleInformation");
1428 winsock_lib
= LoadLibrary ("wsock32.dll");
1430 if (winsock_lib
!= NULL
)
1432 /* dynamically link to socket functions */
1434 #define LOAD_PROC(fn) \
1435 if ((pfn_##fn = (void *) GetProcAddress (winsock_lib, #fn)) == NULL) \
1438 LOAD_PROC( WSAStartup
);
1439 LOAD_PROC( WSASetLastError
);
1440 LOAD_PROC( WSAGetLastError
);
1441 LOAD_PROC( socket
);
1443 LOAD_PROC( connect
);
1444 LOAD_PROC( ioctlsocket
);
1447 LOAD_PROC( closesocket
);
1448 LOAD_PROC( shutdown
);
1451 LOAD_PROC( inet_addr
);
1452 LOAD_PROC( gethostname
);
1453 LOAD_PROC( gethostbyname
);
1454 LOAD_PROC( getservbyname
);
1455 LOAD_PROC( WSACleanup
);
1459 /* specify version 1.1 of winsock */
1460 if (pfn_WSAStartup (0x101, &winsockData
) == 0)
1462 if (winsockData
.wVersion
!= 0x101)
1467 /* Report that winsock exists and is usable, but leave
1468 socket functions disabled. I am assuming that calling
1469 WSAStartup does not require any network interaction,
1470 and in particular does not cause or require a dial-up
1471 connection to be established. */
1474 FreeLibrary (winsock_lib
);
1482 FreeLibrary (winsock_lib
);
1492 /* function to set h_errno for compatability; map winsock error codes to
1493 normal system codes where they overlap (non-overlapping definitions
1494 are already in <sys/socket.h> */
1495 static void set_errno ()
1497 if (winsock_lib
== NULL
)
1500 h_errno
= pfn_WSAGetLastError ();
1504 case WSAEACCES
: h_errno
= EACCES
; break;
1505 case WSAEBADF
: h_errno
= EBADF
; break;
1506 case WSAEFAULT
: h_errno
= EFAULT
; break;
1507 case WSAEINTR
: h_errno
= EINTR
; break;
1508 case WSAEINVAL
: h_errno
= EINVAL
; break;
1509 case WSAEMFILE
: h_errno
= EMFILE
; break;
1510 case WSAENAMETOOLONG
: h_errno
= ENAMETOOLONG
; break;
1511 case WSAENOTEMPTY
: h_errno
= ENOTEMPTY
; break;
1516 static void check_errno ()
1518 if (h_errno
== 0 && winsock_lib
!= NULL
)
1519 pfn_WSASetLastError (0);
1522 /* [andrewi 3-May-96] I've had conflicting results using both methods,
1523 but I believe the method of keeping the socket handle separate (and
1524 insuring it is not inheritable) is the correct one. */
1526 //#define SOCK_REPLACE_HANDLE
1528 #ifdef SOCK_REPLACE_HANDLE
1529 #define SOCK_HANDLE(fd) ((SOCKET) _get_osfhandle (fd))
1531 #define SOCK_HANDLE(fd) ((SOCKET) fd_info[fd].hnd)
1535 sys_socket(int af
, int type
, int protocol
)
1541 if (winsock_lib
== NULL
)
1544 return INVALID_SOCKET
;
1549 /* call the real socket function */
1550 s
= (long) pfn_socket (af
, type
, protocol
);
1552 if (s
!= INVALID_SOCKET
)
1554 /* Although under NT 3.5 _open_osfhandle will accept a socket
1555 handle, if opened with SO_OPENTYPE == SO_SYNCHRONOUS_NONALERT,
1556 that does not work under NT 3.1. However, we can get the same
1557 effect by using a backdoor function to replace an existing
1558 descriptor handle with the one we want. */
1560 /* allocate a file descriptor (with appropriate flags) */
1561 fd
= _open ("NUL:", _O_RDWR
);
1564 #ifdef SOCK_REPLACE_HANDLE
1565 /* now replace handle to NUL with our socket handle */
1566 CloseHandle ((HANDLE
) _get_osfhandle (fd
));
1568 _set_osfhnd (fd
, s
);
1569 /* setmode (fd, _O_BINARY); */
1571 /* Make a non-inheritable copy of the socket handle. */
1574 HANDLE new_s
= INVALID_HANDLE_VALUE
;
1576 parent
= GetCurrentProcess ();
1578 /* Apparently there is a bug in NT 3.51 with some service
1579 packs, which prevents using DuplicateHandle to make a
1580 socket handle non-inheritable (causes WSACleanup to
1581 hang). The work-around is to use SetHandleInformation
1582 instead if it is available and implemented. */
1583 if (!pfn_SetHandleInformation
1584 || !pfn_SetHandleInformation ((HANDLE
) s
,
1585 HANDLE_FLAG_INHERIT
,
1586 HANDLE_FLAG_INHERIT
))
1588 DuplicateHandle (parent
,
1594 DUPLICATE_SAME_ACCESS
);
1595 pfn_closesocket (s
);
1598 fd_info
[fd
].hnd
= (HANDLE
) s
;
1602 /* set our own internal flags */
1603 fd_info
[fd
].flags
= FILE_SOCKET
| FILE_BINARY
| FILE_READ
| FILE_WRITE
;
1609 cp
->status
= STATUS_READ_ACKNOWLEDGED
;
1611 /* attach child_process to fd_info */
1612 if (fd_info
[ fd
].cp
!= NULL
)
1614 DebPrint (("sys_socket: fd_info[%d] apparently in use!\n", fd
));
1618 fd_info
[ fd
].cp
= cp
;
1621 winsock_inuse
++; /* count open sockets */
1628 pfn_closesocket (s
);
1638 sys_bind (int s
, const struct sockaddr
* addr
, int namelen
)
1640 if (winsock_lib
== NULL
)
1643 return SOCKET_ERROR
;
1647 if (fd_info
[s
].flags
& FILE_SOCKET
)
1649 int rc
= pfn_bind (SOCK_HANDLE (s
), addr
, namelen
);
1650 if (rc
== SOCKET_ERROR
)
1655 return SOCKET_ERROR
;
1660 sys_connect (int s
, const struct sockaddr
* name
, int namelen
)
1662 if (winsock_lib
== NULL
)
1665 return SOCKET_ERROR
;
1669 if (fd_info
[s
].flags
& FILE_SOCKET
)
1671 int rc
= pfn_connect (SOCK_HANDLE (s
), name
, namelen
);
1672 if (rc
== SOCKET_ERROR
)
1677 return SOCKET_ERROR
;
1681 sys_htons (u_short hostshort
)
1683 return (winsock_lib
!= NULL
) ?
1684 pfn_htons (hostshort
) : hostshort
;
1688 sys_ntohs (u_short netshort
)
1690 return (winsock_lib
!= NULL
) ?
1691 pfn_ntohs (netshort
) : netshort
;
1695 sys_inet_addr (const char * cp
)
1697 return (winsock_lib
!= NULL
) ?
1698 pfn_inet_addr (cp
) : INADDR_NONE
;
1702 sys_gethostname (char * name
, int namelen
)
1704 if (winsock_lib
!= NULL
)
1705 return pfn_gethostname (name
, namelen
);
1707 if (namelen
> MAX_COMPUTERNAME_LENGTH
)
1708 return !GetComputerName (name
, &namelen
);
1711 return SOCKET_ERROR
;
1715 sys_gethostbyname(const char * name
)
1717 struct hostent
* host
;
1719 if (winsock_lib
== NULL
)
1726 host
= pfn_gethostbyname (name
);
1733 sys_getservbyname(const char * name
, const char * proto
)
1735 struct servent
* serv
;
1737 if (winsock_lib
== NULL
)
1744 serv
= pfn_getservbyname (name
, proto
);
1750 #endif /* HAVE_SOCKETS */
1753 /* Shadow main io functions: we need to handle pipes and sockets more
1754 intelligently, and implement non-blocking mode as well. */
1761 if (fd
< 0 || fd
>= MAXDESC
)
1769 child_process
* cp
= fd_info
[fd
].cp
;
1771 fd_info
[fd
].cp
= NULL
;
1773 if (CHILD_ACTIVE (cp
))
1775 /* if last descriptor to active child_process then cleanup */
1777 for (i
= 0; i
< MAXDESC
; i
++)
1781 if (fd_info
[i
].cp
== cp
)
1787 if (fd_info
[fd
].flags
& FILE_SOCKET
)
1789 #ifndef SOCK_REPLACE_HANDLE
1790 if (winsock_lib
== NULL
) abort ();
1792 pfn_shutdown (SOCK_HANDLE (fd
), 2);
1793 rc
= pfn_closesocket (SOCK_HANDLE (fd
));
1795 winsock_inuse
--; /* count open sockets */
1803 /* Note that sockets do not need special treatment here (at least on
1804 NT and Win95 using the standard tcp/ip stacks) - it appears that
1805 closesocket is equivalent to CloseHandle, which is to be expected
1806 because socket handles are fully fledged kernel handles. */
1810 fd_info
[fd
].flags
= 0;
1823 /* duplicate our internal info as well */
1824 fd_info
[new_fd
] = fd_info
[fd
];
1831 sys_dup2 (int src
, int dst
)
1835 if (dst
< 0 || dst
>= MAXDESC
)
1841 /* make sure we close the destination first if it's a pipe or socket */
1842 if (src
!= dst
&& fd_info
[dst
].flags
!= 0)
1845 rc
= _dup2 (src
, dst
);
1848 /* duplicate our internal info as well */
1849 fd_info
[dst
] = fd_info
[src
];
1854 /* From callproc.c */
1855 extern Lisp_Object Vbinary_process_input
;
1856 extern Lisp_Object Vbinary_process_output
;
1858 /* Unix pipe() has only one arg */
1860 sys_pipe (int * phandles
)
1866 /* make pipe handles non-inheritable; when we spawn a child,
1867 we replace the relevant handle with an inheritable one. */
1868 rc
= _pipe (phandles
, 0, _O_NOINHERIT
);
1872 /* set internal flags, and put read and write handles into binary
1873 mode as necessary; if not in binary mode, set the MSVC internal
1874 FDEV (0x40) flag to prevent _read from treating ^Z as eof (this
1875 could otherwise allow Emacs to hang because it then waits
1876 indefinitely for the child process to exit, when it might not be
1878 flags
= FILE_PIPE
| FILE_READ
;
1879 if (!NILP (Vbinary_process_output
))
1881 flags
|= FILE_BINARY
;
1882 setmode (phandles
[0], _O_BINARY
);
1884 #if (_MSC_VER == 900)
1886 _osfile
[phandles
[0]] |= 0x40;
1889 fd_info
[phandles
[0]].flags
= flags
;
1891 flags
= FILE_PIPE
| FILE_WRITE
;
1892 if (!NILP (Vbinary_process_input
))
1894 flags
|= FILE_BINARY
;
1895 setmode (phandles
[1], _O_BINARY
);
1897 #if (_MSC_VER == 900)
1899 _osfile
[phandles
[1]] |= 0x40;
1902 fd_info
[phandles
[1]].flags
= flags
;
1909 extern Lisp_Object Vwin32_pipe_read_delay
;
1911 /* Function to do blocking read of one byte, needed to implement
1912 select. It is only allowed on sockets and pipes. */
1914 _sys_read_ahead (int fd
)
1919 if (fd
< 0 || fd
>= MAXDESC
)
1920 return STATUS_READ_ERROR
;
1922 cp
= fd_info
[fd
].cp
;
1924 if (cp
== NULL
|| cp
->fd
!= fd
|| cp
->status
!= STATUS_READ_READY
)
1925 return STATUS_READ_ERROR
;
1927 if ((fd_info
[fd
].flags
& (FILE_PIPE
| FILE_SOCKET
)) == 0
1928 || (fd_info
[fd
].flags
& FILE_READ
) == 0)
1930 DebPrint (("_sys_read_ahead: internal error: fd %d is not a pipe or socket!\n", fd
));
1934 cp
->status
= STATUS_READ_IN_PROGRESS
;
1936 if (fd_info
[fd
].flags
& FILE_PIPE
)
1938 /* Use read to get CRLF translation */
1939 rc
= _read (fd
, &cp
->chr
, sizeof (char));
1941 /* Give subprocess time to buffer some more output for us before
1942 reporting that input is available; we need this because Win95
1943 connects DOS programs to pipes by making the pipe appear to be
1944 the normal console stdout - as a result most DOS programs will
1945 write to stdout without buffering, ie. one character at a
1946 time. Even some Win32 programs do this - "dir" in a command
1947 shell on NT is very slow if we don't do this. */
1950 int wait
= XINT (Vwin32_pipe_read_delay
);
1956 /* Yield remainder of our time slice, effectively giving a
1957 temporary priority boost to the child process. */
1962 else if (fd_info
[fd
].flags
& FILE_SOCKET
)
1963 rc
= pfn_recv (SOCK_HANDLE (fd
), &cp
->chr
, sizeof (char), 0);
1966 if (rc
== sizeof (char))
1967 cp
->status
= STATUS_READ_SUCCEEDED
;
1969 cp
->status
= STATUS_READ_FAILED
;
1975 sys_read (int fd
, char * buffer
, unsigned int count
)
1982 if (fd
< 0 || fd
>= MAXDESC
)
1988 if (fd_info
[fd
].flags
& (FILE_PIPE
| FILE_SOCKET
))
1990 child_process
*cp
= fd_info
[fd
].cp
;
1992 if ((fd_info
[fd
].flags
& FILE_READ
) == 0)
1998 /* presence of a child_process structure means we are operating in
1999 non-blocking mode - otherwise we just call _read directly.
2000 Note that the child_process structure might be missing because
2001 reap_subprocess has been called; in this case the pipe is
2002 already broken, so calling _read on it is okay. */
2005 int current_status
= cp
->status
;
2007 switch (current_status
)
2009 case STATUS_READ_FAILED
:
2010 case STATUS_READ_ERROR
:
2011 /* report normal EOF */
2014 case STATUS_READ_READY
:
2015 case STATUS_READ_IN_PROGRESS
:
2016 DebPrint (("sys_read called when read is in progress\n"));
2017 errno
= EWOULDBLOCK
;
2020 case STATUS_READ_SUCCEEDED
:
2021 /* consume read-ahead char */
2022 *buffer
++ = cp
->chr
;
2025 cp
->status
= STATUS_READ_ACKNOWLEDGED
;
2026 ResetEvent (cp
->char_avail
);
2028 case STATUS_READ_ACKNOWLEDGED
:
2032 DebPrint (("sys_read: bad status %d\n", current_status
));
2037 if (fd_info
[fd
].flags
& FILE_PIPE
)
2039 PeekNamedPipe ((HANDLE
) _get_osfhandle (fd
), NULL
, 0, NULL
, &waiting
, NULL
);
2040 to_read
= min (waiting
, (DWORD
) count
);
2042 /* Use read to get CRLF translation */
2043 nchars
= _read (fd
, buffer
, to_read
);
2046 else /* FILE_SOCKET */
2048 if (winsock_lib
== NULL
) abort ();
2050 /* do the equivalent of a non-blocking read */
2051 pfn_ioctlsocket (SOCK_HANDLE (fd
), FIONREAD
, &waiting
);
2052 if (waiting
== 0 && extra
== 0)
2054 h_errno
= errno
= EWOULDBLOCK
;
2061 /* always use binary mode for sockets */
2062 nchars
= pfn_recv (SOCK_HANDLE (fd
), buffer
, count
, 0);
2063 if (nchars
== SOCKET_ERROR
)
2065 DebPrint(("sys_read.recv failed with error %d on socket %ld\n",
2066 pfn_WSAGetLastError (), SOCK_HANDLE (fd
)));
2079 nchars
= _read (fd
, buffer
, count
);
2082 nchars
= _read (fd
, buffer
, count
);
2084 return nchars
+ extra
;
2087 /* For now, don't bother with a non-blocking mode */
2089 sys_write (int fd
, const void * buffer
, unsigned int count
)
2093 if (fd
< 0 || fd
>= MAXDESC
)
2099 if (fd_info
[fd
].flags
& (FILE_PIPE
| FILE_SOCKET
))
2100 if ((fd_info
[fd
].flags
& FILE_WRITE
) == 0)
2106 if (fd_info
[fd
].flags
& FILE_SOCKET
)
2108 if (winsock_lib
== NULL
) abort ();
2109 nchars
= pfn_send (SOCK_HANDLE (fd
), buffer
, count
, 0);
2110 if (nchars
== SOCKET_ERROR
)
2112 DebPrint(("sys_read.send failed with error %d on socket %ld\n",
2113 pfn_WSAGetLastError (), SOCK_HANDLE (fd
)));
2119 nchars
= _write (fd
, buffer
, count
);
2129 /* shutdown the socket interface if necessary */
2134 extern BOOL dos_process_running
;
2140 /* Initialise the socket interface now if available and requested by
2141 the user by defining PRELOAD_WINSOCK; otherwise loading will be
2142 delayed until open-network-stream is called (win32-has-winsock can
2143 also be used to dynamically load or reload winsock).
2145 Conveniently, init_environment is called before us, so
2146 PRELOAD_WINSOCK can be set in the registry. */
2148 /* Always initialize this correctly. */
2151 if (getenv ("PRELOAD_WINSOCK") != NULL
)
2152 init_winsock (TRUE
);
2155 /* Initial preparation for subprocess support: replace our standard
2156 handles with non-inheritable versions. */
2159 HANDLE stdin_save
= INVALID_HANDLE_VALUE
;
2160 HANDLE stdout_save
= INVALID_HANDLE_VALUE
;
2161 HANDLE stderr_save
= INVALID_HANDLE_VALUE
;
2163 parent
= GetCurrentProcess ();
2165 /* ignore errors when duplicating and closing; typically the
2166 handles will be invalid when running as a gui program. */
2167 DuplicateHandle (parent
,
2168 GetStdHandle (STD_INPUT_HANDLE
),
2173 DUPLICATE_SAME_ACCESS
);
2175 DuplicateHandle (parent
,
2176 GetStdHandle (STD_OUTPUT_HANDLE
),
2181 DUPLICATE_SAME_ACCESS
);
2183 DuplicateHandle (parent
,
2184 GetStdHandle (STD_ERROR_HANDLE
),
2189 DUPLICATE_SAME_ACCESS
);
2195 if (stdin_save
!= INVALID_HANDLE_VALUE
)
2196 _open_osfhandle ((long) stdin_save
, O_TEXT
);
2198 open ("nul", O_TEXT
| O_NOINHERIT
| O_RDONLY
);
2201 if (stdout_save
!= INVALID_HANDLE_VALUE
)
2202 _open_osfhandle ((long) stdout_save
, O_TEXT
);
2204 open ("nul", O_TEXT
| O_NOINHERIT
| O_WRONLY
);
2207 if (stderr_save
!= INVALID_HANDLE_VALUE
)
2208 _open_osfhandle ((long) stderr_save
, O_TEXT
);
2210 open ("nul", O_TEXT
| O_NOINHERIT
| O_WRONLY
);
2214 /* Restrict Emacs to running only one DOS program at a time (with any
2215 number of Win32 programs). This is to prevent the user from
2216 running into problems with DOS programs being run in the same VDM
2217 under both Windows 95 and Windows NT.
2219 Note that it is possible for Emacs to run DOS programs in separate
2220 VDMs, but unfortunately the pipe implementation on Windows 95 then
2221 fails to report when the DOS process exits (which is supposed to
2222 break the pipe). Until this bug is fixed, or we can devise a
2223 work-around, we must try to avoid letting the user start more than
2224 one DOS program if possible. */
2226 dos_process_running
= FALSE
;
2228 /* unfortunately, atexit depends on implementation of malloc */
2229 /* atexit (term_ntproc); */
2230 signal (SIGABRT
, term_ntproc
);