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];
126 opendir (char *filename
)
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))))
135 if (dir_find_handle
!= INVALID_HANDLE_VALUE
)
142 strncpy (dir_pathname
, filename
, MAXPATHLEN
);
143 dir_pathname
[MAXPATHLEN
] = '\0';
144 dir_is_fat
= is_fat_volume (filename
, NULL
);
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
);
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];
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
)
185 if (!FindNextFile (dir_find_handle
, &find_data
))
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
);
199 _strlwr (dir_static
.d_name
);
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
=
229 return the_passwd
.pw_uid
;
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. */
244 return the_passwd
.pw_gid
;
256 if (uid
== the_passwd
.pw_uid
)
262 getpwnam (char *name
)
266 pw
= getpwuid (getuid ());
270 if (stricmp (name
, pw
->pw_name
))
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
;
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;
306 SID_IDENTIFIER_AUTHORITY
* pSIA
;
308 pSIA
= GetSidIdentifierAuthority (*((PSID
*) user_sid
));
309 /* I believe the relative portion is the last 4 bytes (of 6)
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;
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;
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;
344 the_passwd
.pw_uid
= 123;
345 the_passwd
.pw_gid
= the_passwd
.pw_uid
;
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
)
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"));
371 /* rand () on NT gives us 15 random bits...hack together 30 bits. */
372 return ((rand () << 15) | rand ());
381 /* Destructively turn backslashes into slashes. */
383 dostounix_filename (p
)
394 /* Destructively turn slashes into backslashes. */
396 unixtodos_filename (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.) */
413 register unsigned char *buf
;
415 unsigned char *np
= buf
;
416 unsigned char *startp
= buf
;
417 unsigned char *endp
= buf
+ n
;
421 while (buf
< endp
- 1)
425 if (*(++buf
) != 0x0a)
436 /* Routines that are no-ops on NT but are defined to get Emacs to compile. */
439 sigsetmask (int signal_mask
)
451 setpgrp (int pid
, int gid
)
463 unrequest_sigio (void)
474 #define REG_ROOT "SOFTWARE\\GNU\\Emacs"
477 nt_get_resource (key
, lpdwtype
)
482 HKEY hrootkey
= NULL
;
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
)
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
)
500 if (lpvalue
) xfree (lpvalue
);
502 RegCloseKey (hrootkey
);
505 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE
, REG_ROOT
, 0, KEY_READ
, &hrootkey
) == ERROR_SUCCESS
)
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
)
516 if (lpvalue
) xfree (lpvalue
);
518 RegCloseKey (hrootkey
);
527 /* Check for environment variables and use registry if they don't exist */
533 static char * env_vars
[] =
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
)
564 _snprintf (buf
, 499, "%s=%s", env_vars
[i
], lpval
);
565 putenv (strdup (buf
));
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
581 static char configuration_buffer
[32];
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
:
600 #ifdef PROCESSOR_INTEL_860
601 case PROCESSOR_INTEL_860
:
606 #ifdef PROCESSOR_MIPS_R2000
607 case PROCESSOR_MIPS_R2000
:
608 case PROCESSOR_MIPS_R3000
:
609 case PROCESSOR_MIPS_R4000
:
614 #ifdef PROCESSOR_ALPHA_21064
615 case PROCESSOR_ALPHA_21064
:
625 /* Let oem be "*" until we figure out how to decode the OEM field. */
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). */
639 gettimeofday (struct timeval
*tv
, struct timezone
*tz
)
644 tv
->tv_sec
= tb
.time
;
645 tv
->tv_usec
= tb
.millitm
* 1000L;
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). */
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. */
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
[];
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
];
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
)
700 char *rootname
= NULL
; /* default to current volume */
705 /* find the root name of the volume if given */
706 if (isalpha (name
[0]) && name
[1] == ':')
714 else if (IS_DIRECTORY_SEP (name
[0]) && IS_DIRECTORY_SEP (name
[1]))
721 if (IS_DIRECTORY_SEP (*name
) && --slashes
== 0)
737 if (GetVolumeInformation (rootname
,
738 volume_info
.name
, 32,
739 &volume_info
.serialnum
,
740 &volume_info
.maxcomp
,
742 volume_info
.type
, 32))
749 /* Determine if volume is FAT format (ie. only supports short 8.3
750 names); also set path pointer to start of pathname in name. */
752 is_fat_volume (const char * name
, const char ** pPath
)
754 if (get_volume_info (name
, pPath
))
755 return (volume_info
.maxcomp
== 12);
759 /* Map filename to a legal 8.3 name if necessary. */
761 map_win32_filename (const char * name
, const char ** pPath
)
763 static char shortname
[MAX_PATH
];
764 char * str
= shortname
;
768 if (is_fat_volume (name
, &path
)) /* truncate to 8.3 */
770 register int left
= 8; /* maximum number of chars in part */
771 register int extn
= 0; /* extension added? */
772 register int dots
= 2; /* maximum number of dots allowed */
775 *str
++ = *name
++; /* skip past UNC header */
777 while ((c
= *name
++))
784 extn
= 0; /* reset extension flags */
785 dots
= 2; /* max 2 dots */
786 left
= 8; /* max length 8 for main part */
790 extn
= 0; /* reset extension flags */
791 dots
= 2; /* max 2 dots */
792 left
= 8; /* max length 8 for main part */
797 /* Convert path components of the form .xxx to _xxx,
798 but leave . and .. as they are. This allows .emacs
799 to be read as _emacs, for example. */
803 IS_DIRECTORY_SEP (*name
))
818 extn
= 1; /* we've got an extension */
819 left
= 3; /* 3 chars in extension */
823 /* any embedded dots after the first are converted to _ */
828 case '#': /* don't lose these, they're important */
830 str
[-1] = c
; /* replace last character of part */
835 *str
++ = tolower (c
); /* map to lower case (looks nicer) */
837 dots
= 0; /* started a path component */
846 strcpy (shortname
, name
);
847 unixtodos_filename (shortname
);
851 *pPath
= shortname
+ (path
- name
);
857 /* Shadow some MSVC runtime functions to map requests for long filenames
858 to reasonable short names if necessary. This was originally added to
859 permit running Emacs on NT 3.1 on a FAT partition, which doesn't support
863 sys_access (const char * path
, int mode
)
865 return _access (map_win32_filename (path
, NULL
), mode
);
869 sys_chdir (const char * path
)
871 return _chdir (map_win32_filename (path
, NULL
));
875 sys_chmod (const char * path
, int mode
)
877 return _chmod (map_win32_filename (path
, NULL
), mode
);
881 sys_creat (const char * path
, int mode
)
883 return _creat (map_win32_filename (path
, NULL
), mode
);
887 sys_fopen(const char * path
, const char * mode
)
891 const char * mode_save
= mode
;
893 /* Force all file handles to be non-inheritable. This is necessary to
894 ensure child processes don't unwittingly inherit handles that might
895 prevent future file access. */
899 else if (mode
[0] == 'w' || mode
[0] == 'a')
900 oflag
= O_WRONLY
| O_CREAT
| O_TRUNC
;
904 /* Only do simplistic option parsing. */
908 oflag
&= ~(O_RDONLY
| O_WRONLY
);
911 else if (mode
[0] == 'b')
916 else if (mode
[0] == 't')
923 fd
= _open (map_win32_filename (path
, NULL
), oflag
| _O_NOINHERIT
, 0644);
927 return fdopen (fd
, mode_save
);
931 sys_link (const char * path1
, const char * path2
)
938 sys_mkdir (const char * path
)
940 return _mkdir (map_win32_filename (path
, NULL
));
944 sys_mktemp (char * template)
946 return (char *) map_win32_filename ((const char *) _mktemp (template), NULL
);
950 sys_open (const char * path
, int oflag
, int mode
)
952 /* Force all file handles to be non-inheritable. */
953 return _open (map_win32_filename (path
, NULL
), oflag
| _O_NOINHERIT
, mode
);
957 sys_rename (const char * oldname
, const char * newname
)
961 /* MoveFile on Win95 doesn't correctly change the short file name
962 alias when oldname has a three char extension and newname has the
963 same first three chars in its extension. To avoid problems, on
964 Win95 we rename to a temporary name first. */
966 strcpy (temp
, map_win32_filename (oldname
, NULL
));
968 if (GetVersion () & 0x80000000)
972 unixtodos_filename (temp
);
973 if (p
= strrchr (temp
, '\\'))
977 strcpy (p
, "__XXXXXX");
979 if (rename (map_win32_filename (oldname
, NULL
), temp
) < 0)
983 /* Emulate Unix behaviour - newname is deleted if it already exists
984 (at least if it is a file; don't do this for directories). */
985 newname
= map_win32_filename (newname
, NULL
);
986 if (GetFileAttributes (newname
) != -1)
988 _chmod (newname
, 0666);
992 return rename (temp
, newname
);
996 sys_rmdir (const char * path
)
998 return _rmdir (map_win32_filename (path
, NULL
));
1002 sys_unlink (const char * path
)
1004 return _unlink (map_win32_filename (path
, NULL
));
1007 static FILETIME utc_base_ft
;
1008 static long double utc_base
;
1009 static int init
= 0;
1012 convert_time (FILETIME ft
)
1018 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1027 st
.wMilliseconds
= 0;
1029 SystemTimeToFileTime (&st
, &utc_base_ft
);
1030 utc_base
= (long double) utc_base_ft
.dwHighDateTime
1031 * 4096 * 1024 * 1024 + utc_base_ft
.dwLowDateTime
;
1035 if (CompareFileTime (&ft
, &utc_base_ft
) < 0)
1038 ret
= (long double) ft
.dwHighDateTime
* 4096 * 1024 * 1024 + ft
.dwLowDateTime
;
1040 return (time_t) (ret
* 1e-7);
1044 /* in case we ever have need of this */
1046 convert_from_time_t (time_t time
, FILETIME
* pft
)
1052 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1061 st
.wMilliseconds
= 0;
1063 SystemTimeToFileTime (&st
, &utc_base_ft
);
1064 utc_base
= (long double) utc_base_ft
.dwHighDateTime
1065 * 4096 * 1024 * 1024 + utc_base_ft
.dwLowDateTime
;
1069 /* time in 100ns units since 1-Jan-1601 */
1070 tmp
= (long double) time
* 1e7
+ utc_base
;
1071 pft
->dwHighDateTime
= (DWORD
) (tmp
/ (4096.0 * 1024 * 1024));
1072 pft
->dwLowDateTime
= (DWORD
) (tmp
- pft
->dwHighDateTime
);
1076 /* "PJW" algorithm (see the "Dragon" compiler book). */
1078 hashval (const char * str
)
1084 h
= (h
<< 4) + *str
++;
1085 if ((g
= h
& 0xf0000000) != 0)
1086 h
= (h
^ (g
>> 24)) & 0x0fffffff;
1091 /* Return the hash value of the canonical pathname, excluding the
1092 drive/UNC header, to get a hopefully unique inode number. */
1094 generate_inode_val (const char * name
)
1096 char fullname
[ MAX_PATH
];
1100 GetFullPathName (name
, sizeof (fullname
), fullname
, &p
);
1101 get_volume_info (fullname
, &p
);
1102 /* Normal Win32 filesystems are still case insensitive. */
1105 return (_ino_t
) (hash
^ (hash
>> 16));
1108 /* MSVC stat function can't cope with UNC names and has other bugs, so
1109 replace it with our own. This also allows us to calculate consistent
1110 inode values without hacks in the main Emacs code. */
1112 stat (const char * path
, struct stat
* buf
)
1115 WIN32_FIND_DATA wfd
;
1119 int rootdir
= FALSE
;
1121 if (path
== NULL
|| buf
== NULL
)
1127 name
= (char *) map_win32_filename (path
, &path
);
1128 /* must be valid filename, no wild cards */
1129 if (strchr (name
, '*') || strchr (name
, '?'))
1135 /* Remove trailing directory separator, unless name is the root
1136 directory of a drive or UNC volume in which case ensure there
1137 is a trailing separator. */
1138 len
= strlen (name
);
1139 rootdir
= (path
>= name
+ len
- 1
1140 && (IS_DIRECTORY_SEP (*path
) || *path
== 0));
1141 name
= strcpy (alloca (len
+ 2), name
);
1145 if (!IS_DIRECTORY_SEP (name
[len
-1]))
1146 strcat (name
, "\\");
1147 if (GetDriveType (name
) < 2)
1152 memset (&wfd
, 0, sizeof (wfd
));
1153 wfd
.dwFileAttributes
= FILE_ATTRIBUTE_DIRECTORY
;
1154 wfd
.ftCreationTime
= utc_base_ft
;
1155 wfd
.ftLastAccessTime
= utc_base_ft
;
1156 wfd
.ftLastWriteTime
= utc_base_ft
;
1157 strcpy (wfd
.cFileName
, name
);
1161 if (IS_DIRECTORY_SEP (name
[len
-1]))
1163 fh
= FindFirstFile (name
, &wfd
);
1164 if (fh
== INVALID_HANDLE_VALUE
)
1172 if (wfd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
1174 buf
->st_mode
= _S_IFDIR
;
1175 buf
->st_nlink
= 2; /* doesn't really matter */
1180 /* This is more accurate in terms of gettting the correct number
1181 of links, but is quite slow (it is noticable when Emacs is
1182 making a list of file name completions). */
1183 BY_HANDLE_FILE_INFORMATION info
;
1185 fh
= CreateFile (name
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1186 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1188 if (GetFileInformationByHandle (fh
, &info
))
1190 switch (GetFileType (fh
))
1192 case FILE_TYPE_DISK
:
1193 buf
->st_mode
= _S_IFREG
;
1195 case FILE_TYPE_PIPE
:
1196 buf
->st_mode
= _S_IFIFO
;
1198 case FILE_TYPE_CHAR
:
1199 case FILE_TYPE_UNKNOWN
:
1201 buf
->st_mode
= _S_IFCHR
;
1203 buf
->st_nlink
= info
.nNumberOfLinks
;
1204 /* Could use file index, but this is not guaranteed to be
1205 unique unless we keep a handle open all the time. */
1206 /* buf->st_ino = info.nFileIndexLow ^ info.nFileIndexHigh; */
1215 buf
->st_mode
= _S_IFREG
;
1220 /* consider files to belong to current user */
1221 buf
->st_uid
= the_passwd
.pw_uid
;
1222 buf
->st_gid
= the_passwd
.pw_gid
;
1224 /* volume_info is set indirectly by map_win32_filename */
1225 buf
->st_dev
= volume_info
.serialnum
;
1226 buf
->st_rdev
= volume_info
.serialnum
;
1228 buf
->st_ino
= generate_inode_val (name
);
1230 buf
->st_size
= wfd
.nFileSizeLow
;
1232 /* Convert timestamps to Unix format. */
1233 buf
->st_mtime
= convert_time (wfd
.ftLastWriteTime
);
1234 buf
->st_atime
= convert_time (wfd
.ftLastAccessTime
);
1235 if (buf
->st_atime
== 0) buf
->st_atime
= buf
->st_mtime
;
1236 buf
->st_ctime
= convert_time (wfd
.ftCreationTime
);
1237 if (buf
->st_ctime
== 0) buf
->st_ctime
= buf
->st_mtime
;
1239 /* determine rwx permissions */
1240 if (wfd
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
)
1241 permission
= _S_IREAD
;
1243 permission
= _S_IREAD
| _S_IWRITE
;
1245 if (wfd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
1246 permission
|= _S_IEXEC
;
1249 char * p
= strrchr (name
, '.');
1251 (stricmp (p
, ".exe") == 0 ||
1252 stricmp (p
, ".com") == 0 ||
1253 stricmp (p
, ".bat") == 0 ||
1254 stricmp (p
, ".cmd") == 0))
1255 permission
|= _S_IEXEC
;
1258 buf
->st_mode
|= permission
| (permission
>> 3) | (permission
>> 6);
1265 /* Wrappers for winsock functions to map between our file descriptors
1266 and winsock's handles; also set h_errno for convenience.
1268 To allow Emacs to run on systems which don't have winsock support
1269 installed, we dynamically link to winsock on startup if present, and
1270 otherwise provide the minimum necessary functionality
1271 (eg. gethostname). */
1273 /* function pointers for relevant socket functions */
1274 int (PASCAL
*pfn_WSAStartup
) (WORD wVersionRequired
, LPWSADATA lpWSAData
);
1275 void (PASCAL
*pfn_WSASetLastError
) (int iError
);
1276 int (PASCAL
*pfn_WSAGetLastError
) (void);
1277 int (PASCAL
*pfn_socket
) (int af
, int type
, int protocol
);
1278 int (PASCAL
*pfn_bind
) (SOCKET s
, const struct sockaddr
*addr
, int namelen
);
1279 int (PASCAL
*pfn_connect
) (SOCKET s
, const struct sockaddr
*addr
, int namelen
);
1280 int (PASCAL
*pfn_ioctlsocket
) (SOCKET s
, long cmd
, u_long
*argp
);
1281 int (PASCAL
*pfn_recv
) (SOCKET s
, char * buf
, int len
, int flags
);
1282 int (PASCAL
*pfn_send
) (SOCKET s
, const char * buf
, int len
, int flags
);
1283 int (PASCAL
*pfn_closesocket
) (SOCKET s
);
1284 int (PASCAL
*pfn_shutdown
) (SOCKET s
, int how
);
1285 int (PASCAL
*pfn_WSACleanup
) (void);
1287 u_short (PASCAL
*pfn_htons
) (u_short hostshort
);
1288 u_short (PASCAL
*pfn_ntohs
) (u_short netshort
);
1289 unsigned long (PASCAL
*pfn_inet_addr
) (const char * cp
);
1290 int (PASCAL
*pfn_gethostname
) (char * name
, int namelen
);
1291 struct hostent
* (PASCAL
*pfn_gethostbyname
) (const char * name
);
1292 struct servent
* (PASCAL
*pfn_getservbyname
) (const char * name
, const char * proto
);
1294 static int have_winsock
;
1295 static HANDLE winsock_lib
;
1303 FreeLibrary (winsock_lib
);
1310 WSADATA winsockData
;
1312 winsock_lib
= LoadLibrary ("wsock32.dll");
1314 if (winsock_lib
!= NULL
)
1316 /* dynamically link to socket functions */
1318 #define LOAD_PROC(fn) \
1319 if ((pfn_##fn = (void *) GetProcAddress (winsock_lib, #fn)) == NULL) \
1322 LOAD_PROC( WSAStartup
);
1323 LOAD_PROC( WSASetLastError
);
1324 LOAD_PROC( WSAGetLastError
);
1325 LOAD_PROC( socket
);
1327 LOAD_PROC( connect
);
1328 LOAD_PROC( ioctlsocket
);
1331 LOAD_PROC( closesocket
);
1332 LOAD_PROC( shutdown
);
1335 LOAD_PROC( inet_addr
);
1336 LOAD_PROC( gethostname
);
1337 LOAD_PROC( gethostbyname
);
1338 LOAD_PROC( getservbyname
);
1339 LOAD_PROC( WSACleanup
);
1341 /* specify version 1.1 of winsock */
1342 if (pfn_WSAStartup (0x101, &winsockData
) == 0)
1344 have_winsock
= TRUE
;
1349 FreeLibrary (winsock_lib
);
1351 have_winsock
= FALSE
;
1357 /* function to set h_errno for compatability; map winsock error codes to
1358 normal system codes where they overlap (non-overlapping definitions
1359 are already in <sys/socket.h> */
1360 static void set_errno ()
1365 h_errno
= pfn_WSAGetLastError ();
1369 case WSAEACCES
: h_errno
= EACCES
; break;
1370 case WSAEBADF
: h_errno
= EBADF
; break;
1371 case WSAEFAULT
: h_errno
= EFAULT
; break;
1372 case WSAEINTR
: h_errno
= EINTR
; break;
1373 case WSAEINVAL
: h_errno
= EINVAL
; break;
1374 case WSAEMFILE
: h_errno
= EMFILE
; break;
1375 case WSAENAMETOOLONG
: h_errno
= ENAMETOOLONG
; break;
1376 case WSAENOTEMPTY
: h_errno
= ENOTEMPTY
; break;
1381 static void check_errno ()
1383 if (h_errno
== 0 && have_winsock
)
1384 pfn_WSASetLastError (0);
1387 /* [andrewi 3-May-96] I've had conflicting results using both methods,
1388 but I believe the method of keeping the socket handle separate (and
1389 insuring it is not inheritable) is the correct one. */
1391 //#define SOCK_REPLACE_HANDLE
1393 #ifdef SOCK_REPLACE_HANDLE
1394 #define SOCK_HANDLE(fd) ((SOCKET) _get_osfhandle (fd))
1396 #define SOCK_HANDLE(fd) ((SOCKET) fd_info[fd].hnd)
1400 sys_socket(int af
, int type
, int protocol
)
1409 return INVALID_SOCKET
;
1414 /* call the real socket function */
1415 s
= (long) pfn_socket (af
, type
, protocol
);
1417 if (s
!= INVALID_SOCKET
)
1419 /* Although under NT 3.5 _open_osfhandle will accept a socket
1420 handle, if opened with SO_OPENTYPE == SO_SYNCHRONOUS_NONALERT,
1421 that does not work under NT 3.1. However, we can get the same
1422 effect by using a backdoor function to replace an existing
1423 descriptor handle with the one we want. */
1425 /* allocate a file descriptor (with appropriate flags) */
1426 fd
= _open ("NUL:", _O_RDWR
);
1429 #ifdef SOCK_REPLACE_HANDLE
1430 /* now replace handle to NUL with our socket handle */
1431 CloseHandle ((HANDLE
) _get_osfhandle (fd
));
1433 _set_osfhnd (fd
, s
);
1434 /* setmode (fd, _O_BINARY); */
1436 /* Make a non-inheritable copy of the socket handle. */
1439 HANDLE new_s
= INVALID_HANDLE_VALUE
;
1441 parent
= GetCurrentProcess ();
1443 DuplicateHandle (parent
,
1449 DUPLICATE_SAME_ACCESS
);
1450 pfn_closesocket (s
);
1451 fd_info
[fd
].hnd
= new_s
;
1456 /* set our own internal flags */
1457 fd_info
[fd
].flags
= FILE_SOCKET
| FILE_BINARY
| FILE_READ
| FILE_WRITE
;
1463 cp
->status
= STATUS_READ_ACKNOWLEDGED
;
1465 /* attach child_process to fd_info */
1466 if (fd_info
[ fd
].cp
!= NULL
)
1468 DebPrint (("sys_socket: fd_info[%d] apparently in use!\n", fd
));
1472 fd_info
[ fd
].cp
= cp
;
1481 pfn_closesocket (s
);
1491 sys_bind (int s
, const struct sockaddr
* addr
, int namelen
)
1496 return SOCKET_ERROR
;
1500 if (fd_info
[s
].flags
& FILE_SOCKET
)
1502 int rc
= pfn_bind (SOCK_HANDLE (s
), addr
, namelen
);
1503 if (rc
== SOCKET_ERROR
)
1508 return SOCKET_ERROR
;
1513 sys_connect (int s
, const struct sockaddr
* name
, int namelen
)
1518 return SOCKET_ERROR
;
1522 if (fd_info
[s
].flags
& FILE_SOCKET
)
1524 int rc
= pfn_connect (SOCK_HANDLE (s
), name
, namelen
);
1525 if (rc
== SOCKET_ERROR
)
1530 return SOCKET_ERROR
;
1534 sys_htons (u_short hostshort
)
1536 return (have_winsock
) ?
1537 pfn_htons (hostshort
) : hostshort
;
1541 sys_ntohs (u_short netshort
)
1543 return (have_winsock
) ?
1544 pfn_ntohs (netshort
) : netshort
;
1548 sys_inet_addr (const char * cp
)
1550 return (have_winsock
) ?
1551 pfn_inet_addr (cp
) : INADDR_NONE
;
1555 sys_gethostname (char * name
, int namelen
)
1558 return pfn_gethostname (name
, namelen
);
1560 if (namelen
> MAX_COMPUTERNAME_LENGTH
)
1561 return !GetComputerName (name
, &namelen
);
1564 return SOCKET_ERROR
;
1568 sys_gethostbyname(const char * name
)
1570 struct hostent
* host
;
1579 host
= pfn_gethostbyname (name
);
1586 sys_getservbyname(const char * name
, const char * proto
)
1588 struct servent
* serv
;
1597 serv
= pfn_getservbyname (name
, proto
);
1603 #endif /* HAVE_SOCKETS */
1606 /* Shadow main io functions: we need to handle pipes and sockets more
1607 intelligently, and implement non-blocking mode as well. */
1614 if (fd
< 0 || fd
>= MAXDESC
)
1622 child_process
* cp
= fd_info
[fd
].cp
;
1624 fd_info
[fd
].cp
= NULL
;
1626 if (CHILD_ACTIVE (cp
))
1628 /* if last descriptor to active child_process then cleanup */
1630 for (i
= 0; i
< MAXDESC
; i
++)
1634 if (fd_info
[i
].cp
== cp
)
1639 #if defined (HAVE_SOCKETS) && !defined (SOCK_REPLACE_HANDLE)
1640 if (fd_info
[fd
].flags
& FILE_SOCKET
)
1642 if (!have_winsock
) abort ();
1644 pfn_shutdown (SOCK_HANDLE (fd
), 2);
1645 rc
= pfn_closesocket (SOCK_HANDLE (fd
));
1653 /* Note that sockets do not need special treatment here (at least on
1654 NT and Win95 using the standard tcp/ip stacks) - it appears that
1655 closesocket is equivalent to CloseHandle, which is to be expected
1656 because socket handles are fully fledged kernel handles. */
1660 fd_info
[fd
].flags
= 0;
1673 /* duplicate our internal info as well */
1674 fd_info
[new_fd
] = fd_info
[fd
];
1681 sys_dup2 (int src
, int dst
)
1685 if (dst
< 0 || dst
>= MAXDESC
)
1691 /* make sure we close the destination first if it's a pipe or socket */
1692 if (src
!= dst
&& fd_info
[dst
].flags
!= 0)
1695 rc
= _dup2 (src
, dst
);
1698 /* duplicate our internal info as well */
1699 fd_info
[dst
] = fd_info
[src
];
1704 /* From callproc.c */
1705 extern Lisp_Object Vbinary_process_input
;
1706 extern Lisp_Object Vbinary_process_output
;
1708 /* Unix pipe() has only one arg */
1710 sys_pipe (int * phandles
)
1716 /* make pipe handles non-inheritable; when we spawn a child,
1717 we replace the relevant handle with an inheritable one. */
1718 rc
= _pipe (phandles
, 0, _O_NOINHERIT
);
1722 /* set internal flags, and put read and write handles into binary
1723 mode as necessary; if not in binary mode, set the MSVC internal
1724 FDEV (0x40) flag to prevent _read from treating ^Z as eof (this
1725 could otherwise allow Emacs to hang because it then waits
1726 indefinitely for the child process to exit, when it might not be
1728 flags
= FILE_PIPE
| FILE_READ
;
1729 if (!NILP (Vbinary_process_output
))
1731 flags
|= FILE_BINARY
;
1732 setmode (phandles
[0], _O_BINARY
);
1734 #if (_MSC_VER == 900)
1736 _osfile
[phandles
[0]] |= 0x40;
1739 fd_info
[phandles
[0]].flags
= flags
;
1741 flags
= FILE_PIPE
| FILE_WRITE
;
1742 if (!NILP (Vbinary_process_input
))
1744 flags
|= FILE_BINARY
;
1745 setmode (phandles
[1], _O_BINARY
);
1747 #if (_MSC_VER == 900)
1749 _osfile
[phandles
[1]] |= 0x40;
1752 fd_info
[phandles
[1]].flags
= flags
;
1759 extern Lisp_Object Vwin32_pipe_read_delay
;
1761 /* Function to do blocking read of one byte, needed to implement
1762 select. It is only allowed on sockets and pipes. */
1764 _sys_read_ahead (int fd
)
1769 if (fd
< 0 || fd
>= MAXDESC
)
1770 return STATUS_READ_ERROR
;
1772 cp
= fd_info
[fd
].cp
;
1774 if (cp
== NULL
|| cp
->fd
!= fd
|| cp
->status
!= STATUS_READ_READY
)
1775 return STATUS_READ_ERROR
;
1777 if ((fd_info
[fd
].flags
& (FILE_PIPE
| FILE_SOCKET
)) == 0
1778 || (fd_info
[fd
].flags
& FILE_READ
) == 0)
1780 DebPrint (("_sys_read_ahead: internal error: fd %d is not a pipe or socket!\n", fd
));
1784 cp
->status
= STATUS_READ_IN_PROGRESS
;
1786 if (fd_info
[fd
].flags
& FILE_PIPE
)
1788 /* Use read to get CRLF translation */
1789 rc
= _read (fd
, &cp
->chr
, sizeof (char));
1791 /* Give subprocess time to buffer some more output for us before
1792 reporting that input is available; we need this because Win95
1793 connects DOS programs to pipes by making the pipe appear to be
1794 the normal console stdout - as a result most DOS programs will
1795 write to stdout without buffering, ie. one character at a
1796 time. Even some Win32 programs do this - "dir" in a command
1797 shell on NT is very slow if we don't do this. */
1800 int wait
= XINT (Vwin32_pipe_read_delay
);
1806 /* Yield remainder of our time slice, effectively giving a
1807 temporary priority boost to the child process. */
1812 else if (fd_info
[fd
].flags
& FILE_SOCKET
)
1813 rc
= pfn_recv (SOCK_HANDLE (fd
), &cp
->chr
, sizeof (char), 0);
1816 if (rc
== sizeof (char))
1817 cp
->status
= STATUS_READ_SUCCEEDED
;
1819 cp
->status
= STATUS_READ_FAILED
;
1825 sys_read (int fd
, char * buffer
, unsigned int count
)
1832 if (fd
< 0 || fd
>= MAXDESC
)
1838 if (fd_info
[fd
].flags
& (FILE_PIPE
| FILE_SOCKET
))
1840 child_process
*cp
= fd_info
[fd
].cp
;
1842 if ((fd_info
[fd
].flags
& FILE_READ
) == 0)
1848 /* presence of a child_process structure means we are operating in
1849 non-blocking mode - otherwise we just call _read directly.
1850 Note that the child_process structure might be missing because
1851 reap_subprocess has been called; in this case the pipe is
1852 already broken, so calling _read on it is okay. */
1855 int current_status
= cp
->status
;
1857 switch (current_status
)
1859 case STATUS_READ_FAILED
:
1860 case STATUS_READ_ERROR
:
1861 /* report normal EOF */
1864 case STATUS_READ_READY
:
1865 case STATUS_READ_IN_PROGRESS
:
1866 DebPrint (("sys_read called when read is in progress\n"));
1867 errno
= EWOULDBLOCK
;
1870 case STATUS_READ_SUCCEEDED
:
1871 /* consume read-ahead char */
1872 *buffer
++ = cp
->chr
;
1875 cp
->status
= STATUS_READ_ACKNOWLEDGED
;
1876 ResetEvent (cp
->char_avail
);
1878 case STATUS_READ_ACKNOWLEDGED
:
1882 DebPrint (("sys_read: bad status %d\n", current_status
));
1887 if (fd_info
[fd
].flags
& FILE_PIPE
)
1889 PeekNamedPipe ((HANDLE
) _get_osfhandle (fd
), NULL
, 0, NULL
, &waiting
, NULL
);
1890 to_read
= min (waiting
, (DWORD
) count
);
1892 /* Use read to get CRLF translation */
1893 nchars
= _read (fd
, buffer
, to_read
);
1896 else /* FILE_SOCKET */
1898 if (!have_winsock
) abort ();
1900 /* do the equivalent of a non-blocking read */
1901 pfn_ioctlsocket (SOCK_HANDLE (fd
), FIONREAD
, &waiting
);
1902 if (waiting
== 0 && extra
== 0)
1904 h_errno
= errno
= EWOULDBLOCK
;
1911 /* always use binary mode for sockets */
1912 nchars
= pfn_recv (SOCK_HANDLE (fd
), buffer
, count
, 0);
1913 if (nchars
== SOCKET_ERROR
)
1915 DebPrint(("sys_read.recv failed with error %d on socket %ld\n",
1916 pfn_WSAGetLastError (), SOCK_HANDLE (fd
)));
1929 nchars
= _read (fd
, buffer
, count
);
1932 nchars
= _read (fd
, buffer
, count
);
1934 return nchars
+ extra
;
1937 /* For now, don't bother with a non-blocking mode */
1939 sys_write (int fd
, const void * buffer
, unsigned int count
)
1943 if (fd
< 0 || fd
>= MAXDESC
)
1949 if (fd_info
[fd
].flags
& (FILE_PIPE
| FILE_SOCKET
))
1950 if ((fd_info
[fd
].flags
& FILE_WRITE
) == 0)
1956 if (fd_info
[fd
].flags
& FILE_SOCKET
)
1958 if (!have_winsock
) abort ();
1959 nchars
= pfn_send (SOCK_HANDLE (fd
), buffer
, count
, 0);
1960 if (nchars
== SOCKET_ERROR
)
1962 DebPrint(("sys_read.send failed with error %d on socket %ld\n",
1963 pfn_WSAGetLastError (), SOCK_HANDLE (fd
)));
1969 nchars
= _write (fd
, buffer
, count
);
1979 /* shutdown the socket interface if necessary */
1984 extern BOOL can_run_dos_process
;
1985 extern BOOL dos_process_running
;
1991 /* initialise the socket interface if available */
1995 /* Initial preparation for subprocess support: replace our standard
1996 handles with non-inheritable versions. */
1999 HANDLE stdin_save
= INVALID_HANDLE_VALUE
;
2000 HANDLE stdout_save
= INVALID_HANDLE_VALUE
;
2001 HANDLE stderr_save
= INVALID_HANDLE_VALUE
;
2003 parent
= GetCurrentProcess ();
2005 /* ignore errors when duplicating and closing; typically the
2006 handles will be invalid when running as a gui program. */
2007 DuplicateHandle (parent
,
2008 GetStdHandle (STD_INPUT_HANDLE
),
2013 DUPLICATE_SAME_ACCESS
);
2015 DuplicateHandle (parent
,
2016 GetStdHandle (STD_OUTPUT_HANDLE
),
2021 DUPLICATE_SAME_ACCESS
);
2023 DuplicateHandle (parent
,
2024 GetStdHandle (STD_ERROR_HANDLE
),
2029 DUPLICATE_SAME_ACCESS
);
2035 if (stdin_save
!= INVALID_HANDLE_VALUE
)
2036 _open_osfhandle ((long) stdin_save
, O_TEXT
);
2038 open ("nul", O_TEXT
| O_NOINHERIT
| O_RDONLY
);
2041 if (stdout_save
!= INVALID_HANDLE_VALUE
)
2042 _open_osfhandle ((long) stdout_save
, O_TEXT
);
2044 open ("nul", O_TEXT
| O_NOINHERIT
| O_WRONLY
);
2047 if (stderr_save
!= INVALID_HANDLE_VALUE
)
2048 _open_osfhandle ((long) stderr_save
, O_TEXT
);
2050 open ("nul", O_TEXT
| O_NOINHERIT
| O_WRONLY
);
2054 /* Only allow Emacs to run DOS programs on Win95. */
2055 can_run_dos_process
= (GetVersion () & 0x80000000);
2056 dos_process_running
= FALSE
;
2058 /* unfortunately, atexit depends on implementation of malloc */
2059 /* atexit (term_ntproc); */
2060 signal (SIGABRT
, term_ntproc
);