(get_system_name): Don't crash if Vsystem_name does not contain a string.
[emacs.git] / src / w32.c
blobb0646c91e9697bcc9b16f9d4d0d66671ce90df94
1 /* Utility and Unix shadow routines for GNU Emacs on the Microsoft W32 API.
2 Copyright (C) 1994, 1995 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
21 Geoff Voelker (voelker@cs.washington.edu) 7-29-94
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <io.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <ctype.h>
31 #include <signal.h>
32 #include <sys/time.h>
34 /* must include CRT headers *before* config.h */
35 #include "config.h"
36 #undef access
37 #undef chdir
38 #undef chmod
39 #undef creat
40 #undef ctime
41 #undef fopen
42 #undef link
43 #undef mkdir
44 #undef mktemp
45 #undef open
46 #undef rename
47 #undef rmdir
48 #undef unlink
50 #undef close
51 #undef dup
52 #undef dup2
53 #undef pipe
54 #undef read
55 #undef write
57 #define getwd _getwd
58 #include "lisp.h"
59 #undef getwd
61 #include <pwd.h>
63 #include <windows.h>
65 #ifdef HAVE_SOCKETS /* TCP connection support, if kernel can do it */
66 #include <sys/socket.h>
67 #undef socket
68 #undef bind
69 #undef connect
70 #undef htons
71 #undef ntohs
72 #undef inet_addr
73 #undef gethostname
74 #undef gethostbyname
75 #undef getservbyname
76 #undef shutdown
77 #endif
79 #include "w32.h"
80 #include "ndir.h"
81 #include "w32heap.h"
83 /* Get the current working directory. */
84 char *
85 getwd (char *dir)
87 if (GetCurrentDirectory (MAXPATHLEN, dir) > 0)
88 return dir;
89 return NULL;
92 #ifndef HAVE_SOCKETS
93 /* Emulate gethostname. */
94 int
95 gethostname (char *buffer, int size)
97 /* NT only allows small host names, so the buffer is
98 certainly large enough. */
99 return !GetComputerName (buffer, &size);
101 #endif /* HAVE_SOCKETS */
103 /* Emulate getloadavg. */
105 getloadavg (double loadavg[], int nelem)
107 int i;
109 /* A faithful emulation is going to have to be saved for a rainy day. */
110 for (i = 0; i < nelem; i++)
112 loadavg[i] = 0.0;
114 return i;
117 /* Emulate the Unix directory procedures opendir, closedir,
118 and readdir. We can't use the procedures supplied in sysdep.c,
119 so we provide them here. */
121 struct direct dir_static; /* simulated directory contents */
122 static HANDLE dir_find_handle = INVALID_HANDLE_VALUE;
123 static int dir_is_fat;
124 static char dir_pathname[MAXPATHLEN+1];
126 extern Lisp_Object Vw32_downcase_file_names;
128 DIR *
129 opendir (char *filename)
131 DIR *dirp;
133 /* Opening is done by FindFirstFile. However, a read is inherent to
134 this operation, so we defer the open until read time. */
136 if (!(dirp = (DIR *) malloc (sizeof (DIR))))
137 return NULL;
138 if (dir_find_handle != INVALID_HANDLE_VALUE)
139 return NULL;
141 dirp->dd_fd = 0;
142 dirp->dd_loc = 0;
143 dirp->dd_size = 0;
145 strncpy (dir_pathname, filename, MAXPATHLEN);
146 dir_pathname[MAXPATHLEN] = '\0';
147 dir_is_fat = is_fat_volume (filename, NULL);
149 return dirp;
152 void
153 closedir (DIR *dirp)
155 /* If we have a find-handle open, close it. */
156 if (dir_find_handle != INVALID_HANDLE_VALUE)
158 FindClose (dir_find_handle);
159 dir_find_handle = INVALID_HANDLE_VALUE;
161 xfree ((char *) dirp);
164 struct direct *
165 readdir (DIR *dirp)
167 WIN32_FIND_DATA find_data;
169 /* If we aren't dir_finding, do a find-first, otherwise do a find-next. */
170 if (dir_find_handle == INVALID_HANDLE_VALUE)
172 char filename[MAXNAMLEN + 3];
173 int ln;
175 strcpy (filename, dir_pathname);
176 ln = strlen (filename) - 1;
177 if (!IS_DIRECTORY_SEP (filename[ln]))
178 strcat (filename, "\\");
179 strcat (filename, "*");
181 dir_find_handle = FindFirstFile (filename, &find_data);
183 if (dir_find_handle == INVALID_HANDLE_VALUE)
184 return NULL;
186 else
188 if (!FindNextFile (dir_find_handle, &find_data))
189 return NULL;
192 /* Emacs never uses this value, so don't bother making it match
193 value returned by stat(). */
194 dir_static.d_ino = 1;
196 dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 +
197 dir_static.d_namlen - dir_static.d_namlen % 4;
199 dir_static.d_namlen = strlen (find_data.cFileName);
200 strcpy (dir_static.d_name, find_data.cFileName);
201 if (dir_is_fat)
202 _strlwr (dir_static.d_name);
203 else if (!NILP (Vw32_downcase_file_names))
205 register char *p;
206 for (p = dir_static.d_name; *p; p++)
207 if (*p >= 'a' && *p <= 'z')
208 break;
209 if (!*p)
210 _strlwr (dir_static.d_name);
213 return &dir_static;
216 /* Emulate getpwuid, getpwnam and others. */
218 #define PASSWD_FIELD_SIZE 256
220 static char the_passwd_name[PASSWD_FIELD_SIZE];
221 static char the_passwd_passwd[PASSWD_FIELD_SIZE];
222 static char the_passwd_gecos[PASSWD_FIELD_SIZE];
223 static char the_passwd_dir[PASSWD_FIELD_SIZE];
224 static char the_passwd_shell[PASSWD_FIELD_SIZE];
226 static struct passwd the_passwd =
228 the_passwd_name,
229 the_passwd_passwd,
233 the_passwd_gecos,
234 the_passwd_dir,
235 the_passwd_shell,
238 int
239 getuid ()
241 return the_passwd.pw_uid;
244 int
245 geteuid ()
247 /* I could imagine arguing for checking to see whether the user is
248 in the Administrators group and returning a UID of 0 for that
249 case, but I don't know how wise that would be in the long run. */
250 return getuid ();
253 int
254 getgid ()
256 return the_passwd.pw_gid;
259 int
260 getegid ()
262 return getgid ();
265 struct passwd *
266 getpwuid (int uid)
268 if (uid == the_passwd.pw_uid)
269 return &the_passwd;
270 return NULL;
273 struct passwd *
274 getpwnam (char *name)
276 struct passwd *pw;
278 pw = getpwuid (getuid ());
279 if (!pw)
280 return pw;
282 if (stricmp (name, pw->pw_name))
283 return NULL;
285 return pw;
288 void
289 init_user_info ()
291 /* Find the user's real name by opening the process token and
292 looking up the name associated with the user-sid in that token.
294 Use the relative portion of the identifier authority value from
295 the user-sid as the user id value (same for group id using the
296 primary group sid from the process token). */
298 char user_sid[256], name[256], domain[256];
299 DWORD length = sizeof (name), dlength = sizeof (domain), trash;
300 HANDLE token = NULL;
301 SID_NAME_USE user_type;
303 if (OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &token)
304 && GetTokenInformation (token, TokenUser,
305 (PVOID) user_sid, sizeof (user_sid), &trash)
306 && LookupAccountSid (NULL, *((PSID *) user_sid), name, &length,
307 domain, &dlength, &user_type))
309 strcpy (the_passwd.pw_name, name);
310 /* Determine a reasonable uid value. */
311 if (stricmp ("administrator", name) == 0)
313 the_passwd.pw_uid = 0;
314 the_passwd.pw_gid = 0;
316 else
318 SID_IDENTIFIER_AUTHORITY * pSIA;
320 pSIA = GetSidIdentifierAuthority (*((PSID *) user_sid));
321 /* I believe the relative portion is the last 4 bytes (of 6)
322 with msb first. */
323 the_passwd.pw_uid = ((pSIA->Value[2] << 24) +
324 (pSIA->Value[3] << 16) +
325 (pSIA->Value[4] << 8) +
326 (pSIA->Value[5] << 0));
327 /* restrict to conventional uid range for normal users */
328 the_passwd.pw_uid = the_passwd.pw_uid % 60001;
330 /* Get group id */
331 if (GetTokenInformation (token, TokenPrimaryGroup,
332 (PVOID) user_sid, sizeof (user_sid), &trash))
334 SID_IDENTIFIER_AUTHORITY * pSIA;
336 pSIA = GetSidIdentifierAuthority (*((PSID *) user_sid));
337 the_passwd.pw_gid = ((pSIA->Value[2] << 24) +
338 (pSIA->Value[3] << 16) +
339 (pSIA->Value[4] << 8) +
340 (pSIA->Value[5] << 0));
341 /* I don't know if this is necessary, but for safety... */
342 the_passwd.pw_gid = the_passwd.pw_gid % 60001;
344 else
345 the_passwd.pw_gid = the_passwd.pw_uid;
348 /* If security calls are not supported (presumably because we
349 are running under Windows 95), fallback to this. */
350 else if (GetUserName (name, &length))
352 strcpy (the_passwd.pw_name, name);
353 if (stricmp ("administrator", name) == 0)
354 the_passwd.pw_uid = 0;
355 else
356 the_passwd.pw_uid = 123;
357 the_passwd.pw_gid = the_passwd.pw_uid;
359 else
361 strcpy (the_passwd.pw_name, "unknown");
362 the_passwd.pw_uid = 123;
363 the_passwd.pw_gid = 123;
366 /* Ensure HOME and SHELL are defined. */
367 if (getenv ("HOME") == NULL)
368 putenv ("HOME=c:/");
369 if (getenv ("SHELL") == NULL)
370 putenv ((GetVersion () & 0x80000000) ? "SHELL=command" : "SHELL=cmd");
372 /* Set dir and shell from environment variables. */
373 strcpy (the_passwd.pw_dir, getenv ("HOME"));
374 strcpy (the_passwd.pw_shell, getenv ("SHELL"));
376 if (token)
377 CloseHandle (token);
381 random ()
383 /* rand () on NT gives us 15 random bits...hack together 30 bits. */
384 return ((rand () << 15) | rand ());
387 void
388 srandom (int seed)
390 srand (seed);
393 /* Normalize filename by converting all path separators to
394 the specified separator. Also conditionally convert upper
395 case path name components to lower case. */
397 static void
398 normalize_filename (fp, path_sep)
399 register char *fp;
400 char path_sep;
402 char sep;
403 char *elem;
405 /* Always lower-case drive letters a-z, even if the filesystem
406 preserves case in filenames.
407 This is so filenames can be compared by string comparison
408 functions that are case-sensitive. Even case-preserving filesystems
409 do not distinguish case in drive letters. */
410 if (fp[1] == ':' && *fp >= 'A' && *fp <= 'Z')
412 *fp += 'a' - 'A';
413 fp += 2;
416 if (NILP (Vw32_downcase_file_names))
418 while (*fp)
420 if (*fp == '/' || *fp == '\\')
421 *fp = path_sep;
422 fp++;
424 return;
427 sep = path_sep; /* convert to this path separator */
428 elem = fp; /* start of current path element */
430 do {
431 if (*fp >= 'a' && *fp <= 'z')
432 elem = 0; /* don't convert this element */
434 if (*fp == 0 || *fp == ':')
436 sep = *fp; /* restore current separator (or 0) */
437 *fp = '/'; /* after conversion of this element */
440 if (*fp == '/' || *fp == '\\')
442 if (elem && elem != fp)
444 *fp = 0; /* temporary end of string */
445 _strlwr (elem); /* while we convert to lower case */
447 *fp = sep; /* convert (or restore) path separator */
448 elem = fp + 1; /* next element starts after separator */
449 sep = path_sep;
451 } while (*fp++);
454 /* Destructively turn backslashes into slashes. */
455 void
456 dostounix_filename (p)
457 register char *p;
459 normalize_filename (p, '/');
462 /* Destructively turn slashes into backslashes. */
463 void
464 unixtodos_filename (p)
465 register char *p;
467 normalize_filename (p, '\\');
470 /* Remove all CR's that are followed by a LF.
471 (From msdos.c...probably should figure out a way to share it,
472 although this code isn't going to ever change.) */
474 crlf_to_lf (n, buf)
475 register int n;
476 register unsigned char *buf;
478 unsigned char *np = buf;
479 unsigned char *startp = buf;
480 unsigned char *endp = buf + n;
482 if (n == 0)
483 return n;
484 while (buf < endp - 1)
486 if (*buf == 0x0d)
488 if (*(++buf) != 0x0a)
489 *np++ = 0x0d;
491 else
492 *np++ = *buf++;
494 if (buf < endp)
495 *np++ = *buf++;
496 return np - startp;
499 /* Routines that are no-ops on NT but are defined to get Emacs to compile. */
501 int
502 sigsetmask (int signal_mask)
504 return 0;
507 int
508 sigblock (int sig)
510 return 0;
513 int
514 setpgrp (int pid, int gid)
516 return 0;
519 int
520 alarm (int seconds)
522 return 0;
525 int
526 unrequest_sigio (void)
528 return 0;
531 int
532 request_sigio (void)
534 return 0;
537 #define REG_ROOT "SOFTWARE\\GNU\\Emacs"
539 LPBYTE
540 w32_get_resource (key, lpdwtype)
541 char *key;
542 LPDWORD lpdwtype;
544 LPBYTE lpvalue;
545 HKEY hrootkey = NULL;
546 DWORD cbData;
547 BOOL ok = FALSE;
549 /* Check both the current user and the local machine to see if
550 we have any resources. */
552 if (RegOpenKeyEx (HKEY_CURRENT_USER, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
554 lpvalue = NULL;
556 if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS
557 && (lpvalue = (LPBYTE) xmalloc (cbData)) != NULL
558 && RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
560 return (lpvalue);
563 if (lpvalue) xfree (lpvalue);
565 RegCloseKey (hrootkey);
568 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
570 lpvalue = NULL;
572 if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS &&
573 (lpvalue = (LPBYTE) xmalloc (cbData)) != NULL &&
574 RegQueryValueEx (hrootkey, key, NULL, lpdwtype, lpvalue, &cbData) == ERROR_SUCCESS)
576 return (lpvalue);
579 if (lpvalue) xfree (lpvalue);
581 RegCloseKey (hrootkey);
584 return (NULL);
587 char *get_emacs_configuration (void);
588 extern Lisp_Object Vsystem_configuration;
590 void
591 init_environment ()
593 /* Check for environment variables and use registry if they don't exist */
595 int i;
596 LPBYTE lpval;
597 DWORD dwType;
599 static char * env_vars[] =
601 "HOME",
602 "PRELOAD_WINSOCK",
603 "emacs_dir",
604 "EMACSLOADPATH",
605 "SHELL",
606 "EMACSDATA",
607 "EMACSPATH",
608 "EMACSLOCKDIR",
609 "INFOPATH",
610 "EMACSDOC",
611 "TERM",
614 for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++)
616 if (!getenv (env_vars[i]) &&
617 (lpval = w32_get_resource (env_vars[i], &dwType)) != NULL)
619 if (dwType == REG_EXPAND_SZ)
621 char buf1[500], buf2[500];
623 ExpandEnvironmentStrings ((LPSTR) lpval, buf1, 500);
624 _snprintf (buf2, 499, "%s=%s", env_vars[i], buf1);
625 putenv (strdup (buf2));
627 else if (dwType == REG_SZ)
629 char buf[500];
631 _snprintf (buf, 499, "%s=%s", env_vars[i], lpval);
632 putenv (strdup (buf));
635 xfree (lpval);
640 /* Rebuild system configuration to reflect invoking system. */
641 Vsystem_configuration = build_string (EMACS_CONFIGURATION);
643 init_user_info ();
646 /* We don't have scripts to automatically determine the system configuration
647 for Emacs before it's compiled, and we don't want to have to make the
648 user enter it, so we define EMACS_CONFIGURATION to invoke this runtime
649 routine. */
651 static char configuration_buffer[32];
653 char *
654 get_emacs_configuration (void)
656 char *arch, *oem, *os;
658 /* Determine the processor type. */
659 switch (get_processor_type ())
662 #ifdef PROCESSOR_INTEL_386
663 case PROCESSOR_INTEL_386:
664 case PROCESSOR_INTEL_486:
665 case PROCESSOR_INTEL_PENTIUM:
666 arch = "i386";
667 break;
668 #endif
670 #ifdef PROCESSOR_INTEL_860
671 case PROCESSOR_INTEL_860:
672 arch = "i860";
673 break;
674 #endif
676 #ifdef PROCESSOR_MIPS_R2000
677 case PROCESSOR_MIPS_R2000:
678 case PROCESSOR_MIPS_R3000:
679 case PROCESSOR_MIPS_R4000:
680 arch = "mips";
681 break;
682 #endif
684 #ifdef PROCESSOR_ALPHA_21064
685 case PROCESSOR_ALPHA_21064:
686 arch = "alpha";
687 break;
688 #endif
690 default:
691 arch = "unknown";
692 break;
695 /* Let oem be "*" until we figure out how to decode the OEM field. */
696 oem = "*";
698 os = (GetVersion () & 0x80000000) ? "windows95" : "nt";
700 sprintf (configuration_buffer, "%s-%s-%s%d.%d", arch, oem, os,
701 get_w32_major_version (), get_w32_minor_version ());
702 return configuration_buffer;
705 #include <sys/timeb.h>
707 /* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */
708 void
709 gettimeofday (struct timeval *tv, struct timezone *tz)
711 struct _timeb tb;
712 _ftime (&tb);
714 tv->tv_sec = tb.time;
715 tv->tv_usec = tb.millitm * 1000L;
716 if (tz)
718 tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich */
719 tz->tz_dsttime = tb.dstflag; /* type of dst correction */
723 /* ------------------------------------------------------------------------- */
724 /* IO support and wrapper functions for W32 API. */
725 /* ------------------------------------------------------------------------- */
727 /* Place a wrapper around the MSVC version of ctime. It returns NULL
728 on network directories, so we handle that case here.
729 (Ulrich Leodolter, 1/11/95). */
730 char *
731 sys_ctime (const time_t *t)
733 char *str = (char *) ctime (t);
734 return (str ? str : "Sun Jan 01 00:00:00 1970");
737 /* Emulate sleep...we could have done this with a define, but that
738 would necessitate including windows.h in the files that used it.
739 This is much easier. */
740 void
741 sys_sleep (int seconds)
743 Sleep (seconds * 1000);
746 /* Internal MSVC data and functions for low-level descriptor munging */
747 #if (_MSC_VER == 900)
748 extern char _osfile[];
749 #endif
750 extern int __cdecl _set_osfhnd (int fd, long h);
751 extern int __cdecl _free_osfhnd (int fd);
753 /* parallel array of private info on file handles */
754 filedesc fd_info [ MAXDESC ];
756 static struct {
757 DWORD serialnum;
758 DWORD maxcomp;
759 DWORD flags;
760 char name[32];
761 char type[32];
762 } volume_info;
764 /* Get information on the volume where name is held; set path pointer to
765 start of pathname in name (past UNC header\volume header if present). */
767 get_volume_info (const char * name, const char ** pPath)
769 char temp[MAX_PATH];
770 char *rootname = NULL; /* default to current volume */
772 if (name == NULL)
773 return FALSE;
775 /* find the root name of the volume if given */
776 if (isalpha (name[0]) && name[1] == ':')
778 rootname = temp;
779 temp[0] = *name++;
780 temp[1] = *name++;
781 temp[2] = '\\';
782 temp[3] = 0;
784 else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1]))
786 char *str = temp;
787 int slashes = 4;
788 rootname = temp;
791 if (IS_DIRECTORY_SEP (*name) && --slashes == 0)
792 break;
793 *str++ = *name++;
795 while ( *name );
797 *str++ = '\\';
798 *str = 0;
801 if (pPath)
802 *pPath = name;
804 if (GetVolumeInformation (rootname,
805 volume_info.name, 32,
806 &volume_info.serialnum,
807 &volume_info.maxcomp,
808 &volume_info.flags,
809 volume_info.type, 32))
811 return TRUE;
813 return FALSE;
816 /* Determine if volume is FAT format (ie. only supports short 8.3
817 names); also set path pointer to start of pathname in name. */
819 is_fat_volume (const char * name, const char ** pPath)
821 if (get_volume_info (name, pPath))
822 return (volume_info.maxcomp == 12);
823 return FALSE;
826 /* Map filename to a legal 8.3 name if necessary. */
827 const char *
828 map_w32_filename (const char * name, const char ** pPath)
830 static char shortname[MAX_PATH];
831 char * str = shortname;
832 char c;
833 char * path;
835 if (is_fat_volume (name, &path)) /* truncate to 8.3 */
837 register int left = 8; /* maximum number of chars in part */
838 register int extn = 0; /* extension added? */
839 register int dots = 2; /* maximum number of dots allowed */
841 while (name < path)
842 *str++ = *name++; /* skip past UNC header */
844 while ((c = *name++))
846 switch ( c )
848 case '\\':
849 case '/':
850 *str++ = '\\';
851 extn = 0; /* reset extension flags */
852 dots = 2; /* max 2 dots */
853 left = 8; /* max length 8 for main part */
854 break;
855 case ':':
856 *str++ = ':';
857 extn = 0; /* reset extension flags */
858 dots = 2; /* max 2 dots */
859 left = 8; /* max length 8 for main part */
860 break;
861 case '.':
862 if ( dots )
864 /* Convert path components of the form .xxx to _xxx,
865 but leave . and .. as they are. This allows .emacs
866 to be read as _emacs, for example. */
868 if (! *name ||
869 *name == '.' ||
870 IS_DIRECTORY_SEP (*name))
872 *str++ = '.';
873 dots--;
875 else
877 *str++ = '_';
878 left--;
879 dots = 0;
882 else if ( !extn )
884 *str++ = '.';
885 extn = 1; /* we've got an extension */
886 left = 3; /* 3 chars in extension */
888 else
890 /* any embedded dots after the first are converted to _ */
891 *str++ = '_';
893 break;
894 case '~':
895 case '#': /* don't lose these, they're important */
896 if ( ! left )
897 str[-1] = c; /* replace last character of part */
898 /* FALLTHRU */
899 default:
900 if ( left )
902 *str++ = tolower (c); /* map to lower case (looks nicer) */
903 left--;
904 dots = 0; /* started a path component */
906 break;
909 *str = '\0';
911 else
913 strcpy (shortname, name);
914 unixtodos_filename (shortname);
917 if (pPath)
918 *pPath = shortname + (path - name);
920 return shortname;
924 /* Shadow some MSVC runtime functions to map requests for long filenames
925 to reasonable short names if necessary. This was originally added to
926 permit running Emacs on NT 3.1 on a FAT partition, which doesn't support
927 long file names. */
930 sys_access (const char * path, int mode)
932 return _access (map_w32_filename (path, NULL), mode);
936 sys_chdir (const char * path)
938 return _chdir (map_w32_filename (path, NULL));
942 sys_chmod (const char * path, int mode)
944 return _chmod (map_w32_filename (path, NULL), mode);
948 sys_creat (const char * path, int mode)
950 return _creat (map_w32_filename (path, NULL), mode);
953 FILE *
954 sys_fopen(const char * path, const char * mode)
956 int fd;
957 int oflag;
958 const char * mode_save = mode;
960 /* Force all file handles to be non-inheritable. This is necessary to
961 ensure child processes don't unwittingly inherit handles that might
962 prevent future file access. */
964 if (mode[0] == 'r')
965 oflag = O_RDONLY;
966 else if (mode[0] == 'w' || mode[0] == 'a')
967 oflag = O_WRONLY | O_CREAT | O_TRUNC;
968 else
969 return NULL;
971 /* Only do simplistic option parsing. */
972 while (*++mode)
973 if (mode[0] == '+')
975 oflag &= ~(O_RDONLY | O_WRONLY);
976 oflag |= O_RDWR;
978 else if (mode[0] == 'b')
980 oflag &= ~O_TEXT;
981 oflag |= O_BINARY;
983 else if (mode[0] == 't')
985 oflag &= ~O_BINARY;
986 oflag |= O_TEXT;
988 else break;
990 fd = _open (map_w32_filename (path, NULL), oflag | _O_NOINHERIT, 0644);
991 if (fd < 0)
992 return NULL;
994 return fdopen (fd, mode_save);
998 sys_link (const char * path1, const char * path2)
1000 errno = EINVAL;
1001 return -1;
1005 sys_mkdir (const char * path)
1007 return _mkdir (map_w32_filename (path, NULL));
1010 /* Because of long name mapping issues, we need to implement this
1011 ourselves. Also, MSVC's _mktemp returns NULL when it can't generate
1012 a unique name, instead of setting the input template to an empty
1013 string.
1015 Standard algorithm seems to be use pid or tid with a letter on the
1016 front (in place of the 6 X's) and cycle through the letters to find a
1017 unique name. We extend that to allow any reasonable character as the
1018 first of the 6 X's. */
1019 char *
1020 sys_mktemp (char * template)
1022 char * p;
1023 int i;
1024 unsigned uid = GetCurrentThreadId ();
1025 static char first_char[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#";
1027 if (template == NULL)
1028 return NULL;
1029 p = template + strlen (template);
1030 i = 5;
1031 /* replace up to the last 5 X's with uid in decimal */
1032 while (--p >= template && p[0] == 'X' && --i >= 0)
1034 p[0] = '0' + uid % 10;
1035 uid /= 10;
1038 if (i < 0 && p[0] == 'X')
1040 i = 0;
1043 int save_errno = errno;
1044 p[0] = first_char[i];
1045 if (sys_access (template, 0) < 0)
1047 errno = save_errno;
1048 return template;
1051 while (++i < sizeof (first_char));
1054 /* Template is badly formed or else we can't generate a unique name,
1055 so return empty string */
1056 template[0] = 0;
1057 return template;
1061 sys_open (const char * path, int oflag, int mode)
1063 /* Force all file handles to be non-inheritable. */
1064 return _open (map_w32_filename (path, NULL), oflag | _O_NOINHERIT, mode);
1068 sys_rename (const char * oldname, const char * newname)
1070 char temp[MAX_PATH];
1071 DWORD attr;
1073 /* MoveFile on Windows 95 doesn't correctly change the short file name
1074 alias in a number of circumstances (it is not easy to predict when
1075 just by looking at oldname and newname, unfortunately). In these
1076 cases, renaming through a temporary name avoids the problem.
1078 A second problem on Windows 95 is that renaming through a temp name when
1079 newname is uppercase fails (the final long name ends up in
1080 lowercase, although the short alias might be uppercase) UNLESS the
1081 long temp name is not 8.3.
1083 So, on Windows 95 we always rename through a temp name, and we make sure
1084 the temp name has a long extension to ensure correct renaming. */
1086 strcpy (temp, map_w32_filename (oldname, NULL));
1088 if (GetVersion () & 0x80000000)
1090 char * p;
1092 if (p = strrchr (temp, '\\'))
1093 p++;
1094 else
1095 p = temp;
1096 strcpy (p, "__XXXXXX");
1097 sys_mktemp (temp);
1098 /* Force temp name to require a manufactured 8.3 alias - this
1099 seems to make the second rename work properly. */
1100 strcat (temp, ".long");
1101 if (rename (map_w32_filename (oldname, NULL), temp) < 0)
1102 return -1;
1105 /* Emulate Unix behaviour - newname is deleted if it already exists
1106 (at least if it is a file; don't do this for directories).
1107 However, don't do this if we are just changing the case of the file
1108 name - we will end up deleting the file we are trying to rename! */
1109 newname = map_w32_filename (newname, NULL);
1110 if (stricmp (newname, temp) != 0
1111 && (attr = GetFileAttributes (newname)) != -1
1112 && (attr & FILE_ATTRIBUTE_DIRECTORY) == 0)
1114 _chmod (newname, 0666);
1115 _unlink (newname);
1118 return rename (temp, newname);
1122 sys_rmdir (const char * path)
1124 return _rmdir (map_w32_filename (path, NULL));
1128 sys_unlink (const char * path)
1130 return _unlink (map_w32_filename (path, NULL));
1133 static FILETIME utc_base_ft;
1134 static long double utc_base;
1135 static int init = 0;
1137 static time_t
1138 convert_time (FILETIME ft)
1140 long double ret;
1142 if (!init)
1144 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1145 SYSTEMTIME st;
1147 st.wYear = 1970;
1148 st.wMonth = 1;
1149 st.wDay = 1;
1150 st.wHour = 0;
1151 st.wMinute = 0;
1152 st.wSecond = 0;
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;
1158 init = 1;
1161 if (CompareFileTime (&ft, &utc_base_ft) < 0)
1162 return 0;
1164 ret = (long double) ft.dwHighDateTime * 4096 * 1024 * 1024 + ft.dwLowDateTime;
1165 ret -= utc_base;
1166 return (time_t) (ret * 1e-7);
1169 #if 0
1170 /* in case we ever have need of this */
1171 void
1172 convert_from_time_t (time_t time, FILETIME * pft)
1174 long double tmp;
1176 if (!init)
1178 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1179 SYSTEMTIME st;
1181 st.wYear = 1970;
1182 st.wMonth = 1;
1183 st.wDay = 1;
1184 st.wHour = 0;
1185 st.wMinute = 0;
1186 st.wSecond = 0;
1187 st.wMilliseconds = 0;
1189 SystemTimeToFileTime (&st, &utc_base_ft);
1190 utc_base = (long double) utc_base_ft.dwHighDateTime
1191 * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime;
1192 init = 1;
1195 /* time in 100ns units since 1-Jan-1601 */
1196 tmp = (long double) time * 1e7 + utc_base;
1197 pft->dwHighDateTime = (DWORD) (tmp / (4096.0 * 1024 * 1024));
1198 pft->dwLowDateTime = (DWORD) (tmp - pft->dwHighDateTime);
1200 #endif
1202 /* "PJW" algorithm (see the "Dragon" compiler book). */
1203 static unsigned
1204 hashval (const char * str)
1206 unsigned h = 0;
1207 unsigned g;
1208 while (*str)
1210 h = (h << 4) + *str++;
1211 if ((g = h & 0xf0000000) != 0)
1212 h = (h ^ (g >> 24)) & 0x0fffffff;
1214 return h;
1217 /* Return the hash value of the canonical pathname, excluding the
1218 drive/UNC header, to get a hopefully unique inode number. */
1219 static _ino_t
1220 generate_inode_val (const char * name)
1222 char fullname[ MAX_PATH ];
1223 char * p;
1224 unsigned hash;
1226 GetFullPathName (name, sizeof (fullname), fullname, &p);
1227 get_volume_info (fullname, &p);
1228 /* Normal W32 filesystems are still case insensitive. */
1229 _strlwr (p);
1230 hash = hashval (p);
1231 return (_ino_t) (hash ^ (hash >> 16));
1234 /* MSVC stat function can't cope with UNC names and has other bugs, so
1235 replace it with our own. This also allows us to calculate consistent
1236 inode values without hacks in the main Emacs code. */
1238 stat (const char * path, struct stat * buf)
1240 char * name;
1241 WIN32_FIND_DATA wfd;
1242 HANDLE fh;
1243 int permission;
1244 int len;
1245 int rootdir = FALSE;
1247 if (path == NULL || buf == NULL)
1249 errno = EFAULT;
1250 return -1;
1253 name = (char *) map_w32_filename (path, &path);
1254 /* must be valid filename, no wild cards */
1255 if (strchr (name, '*') || strchr (name, '?'))
1257 errno = ENOENT;
1258 return -1;
1261 /* Remove trailing directory separator, unless name is the root
1262 directory of a drive or UNC volume in which case ensure there
1263 is a trailing separator. */
1264 len = strlen (name);
1265 rootdir = (path >= name + len - 1
1266 && (IS_DIRECTORY_SEP (*path) || *path == 0));
1267 name = strcpy (alloca (len + 2), name);
1269 if (rootdir)
1271 if (!IS_DIRECTORY_SEP (name[len-1]))
1272 strcat (name, "\\");
1273 if (GetDriveType (name) < 2)
1275 errno = ENOENT;
1276 return -1;
1278 memset (&wfd, 0, sizeof (wfd));
1279 wfd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
1280 wfd.ftCreationTime = utc_base_ft;
1281 wfd.ftLastAccessTime = utc_base_ft;
1282 wfd.ftLastWriteTime = utc_base_ft;
1283 strcpy (wfd.cFileName, name);
1285 else
1287 if (IS_DIRECTORY_SEP (name[len-1]))
1288 name[len - 1] = 0;
1289 fh = FindFirstFile (name, &wfd);
1290 if (fh == INVALID_HANDLE_VALUE)
1292 errno = ENOENT;
1293 return -1;
1295 FindClose (fh);
1298 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1300 buf->st_mode = _S_IFDIR;
1301 buf->st_nlink = 2; /* doesn't really matter */
1303 else
1305 #if 0
1306 /* This is more accurate in terms of gettting the correct number
1307 of links, but is quite slow (it is noticable when Emacs is
1308 making a list of file name completions). */
1309 BY_HANDLE_FILE_INFORMATION info;
1311 fh = CreateFile (name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1312 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1314 if (GetFileInformationByHandle (fh, &info))
1316 switch (GetFileType (fh))
1318 case FILE_TYPE_DISK:
1319 buf->st_mode = _S_IFREG;
1320 break;
1321 case FILE_TYPE_PIPE:
1322 buf->st_mode = _S_IFIFO;
1323 break;
1324 case FILE_TYPE_CHAR:
1325 case FILE_TYPE_UNKNOWN:
1326 default:
1327 buf->st_mode = _S_IFCHR;
1329 buf->st_nlink = info.nNumberOfLinks;
1330 /* Could use file index, but this is not guaranteed to be
1331 unique unless we keep a handle open all the time. */
1332 /* buf->st_ino = info.nFileIndexLow ^ info.nFileIndexHigh; */
1333 CloseHandle (fh);
1335 else
1337 errno = EACCES;
1338 return -1;
1340 #else
1341 buf->st_mode = _S_IFREG;
1342 buf->st_nlink = 1;
1343 #endif
1346 /* consider files to belong to current user */
1347 buf->st_uid = the_passwd.pw_uid;
1348 buf->st_gid = the_passwd.pw_gid;
1350 /* volume_info is set indirectly by map_w32_filename */
1351 buf->st_dev = volume_info.serialnum;
1352 buf->st_rdev = volume_info.serialnum;
1354 buf->st_ino = generate_inode_val (name);
1356 buf->st_size = wfd.nFileSizeLow;
1358 /* Convert timestamps to Unix format. */
1359 buf->st_mtime = convert_time (wfd.ftLastWriteTime);
1360 buf->st_atime = convert_time (wfd.ftLastAccessTime);
1361 if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
1362 buf->st_ctime = convert_time (wfd.ftCreationTime);
1363 if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
1365 /* determine rwx permissions */
1366 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
1367 permission = _S_IREAD;
1368 else
1369 permission = _S_IREAD | _S_IWRITE;
1371 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1372 permission |= _S_IEXEC;
1373 else
1375 char * p = strrchr (name, '.');
1376 if (p != NULL &&
1377 (stricmp (p, ".exe") == 0 ||
1378 stricmp (p, ".com") == 0 ||
1379 stricmp (p, ".bat") == 0 ||
1380 stricmp (p, ".cmd") == 0))
1381 permission |= _S_IEXEC;
1384 buf->st_mode |= permission | (permission >> 3) | (permission >> 6);
1386 return 0;
1389 #ifdef HAVE_SOCKETS
1391 /* Wrappers for winsock functions to map between our file descriptors
1392 and winsock's handles; also set h_errno for convenience.
1394 To allow Emacs to run on systems which don't have winsock support
1395 installed, we dynamically link to winsock on startup if present, and
1396 otherwise provide the minimum necessary functionality
1397 (eg. gethostname). */
1399 /* function pointers for relevant socket functions */
1400 int (PASCAL *pfn_WSAStartup) (WORD wVersionRequired, LPWSADATA lpWSAData);
1401 void (PASCAL *pfn_WSASetLastError) (int iError);
1402 int (PASCAL *pfn_WSAGetLastError) (void);
1403 int (PASCAL *pfn_socket) (int af, int type, int protocol);
1404 int (PASCAL *pfn_bind) (SOCKET s, const struct sockaddr *addr, int namelen);
1405 int (PASCAL *pfn_connect) (SOCKET s, const struct sockaddr *addr, int namelen);
1406 int (PASCAL *pfn_ioctlsocket) (SOCKET s, long cmd, u_long *argp);
1407 int (PASCAL *pfn_recv) (SOCKET s, char * buf, int len, int flags);
1408 int (PASCAL *pfn_send) (SOCKET s, const char * buf, int len, int flags);
1409 int (PASCAL *pfn_closesocket) (SOCKET s);
1410 int (PASCAL *pfn_shutdown) (SOCKET s, int how);
1411 int (PASCAL *pfn_WSACleanup) (void);
1413 u_short (PASCAL *pfn_htons) (u_short hostshort);
1414 u_short (PASCAL *pfn_ntohs) (u_short netshort);
1415 unsigned long (PASCAL *pfn_inet_addr) (const char * cp);
1416 int (PASCAL *pfn_gethostname) (char * name, int namelen);
1417 struct hostent * (PASCAL *pfn_gethostbyname) (const char * name);
1418 struct servent * (PASCAL *pfn_getservbyname) (const char * name, const char * proto);
1420 /* SetHandleInformation is only needed to make sockets non-inheritable. */
1421 BOOL (WINAPI *pfn_SetHandleInformation) (HANDLE object, DWORD mask, DWORD flags);
1422 #ifndef HANDLE_FLAG_INHERIT
1423 #define HANDLE_FLAG_INHERIT 1
1424 #endif
1426 HANDLE winsock_lib;
1427 static int winsock_inuse;
1429 BOOL
1430 term_winsock (void)
1432 if (winsock_lib != NULL && winsock_inuse == 0)
1434 /* Not sure what would cause WSAENETDOWN, or even if it can happen
1435 after WSAStartup returns successfully, but it seems reasonable
1436 to allow unloading winsock anyway in that case. */
1437 if (pfn_WSACleanup () == 0 ||
1438 pfn_WSAGetLastError () == WSAENETDOWN)
1440 if (FreeLibrary (winsock_lib))
1441 winsock_lib = NULL;
1442 return TRUE;
1445 return FALSE;
1448 BOOL
1449 init_winsock (int load_now)
1451 WSADATA winsockData;
1453 if (winsock_lib != NULL)
1454 return TRUE;
1456 pfn_SetHandleInformation = NULL;
1457 pfn_SetHandleInformation
1458 = (void *) GetProcAddress (GetModuleHandle ("kernel32.dll"),
1459 "SetHandleInformation");
1461 winsock_lib = LoadLibrary ("wsock32.dll");
1463 if (winsock_lib != NULL)
1465 /* dynamically link to socket functions */
1467 #define LOAD_PROC(fn) \
1468 if ((pfn_##fn = (void *) GetProcAddress (winsock_lib, #fn)) == NULL) \
1469 goto fail;
1471 LOAD_PROC( WSAStartup );
1472 LOAD_PROC( WSASetLastError );
1473 LOAD_PROC( WSAGetLastError );
1474 LOAD_PROC( socket );
1475 LOAD_PROC( bind );
1476 LOAD_PROC( connect );
1477 LOAD_PROC( ioctlsocket );
1478 LOAD_PROC( recv );
1479 LOAD_PROC( send );
1480 LOAD_PROC( closesocket );
1481 LOAD_PROC( shutdown );
1482 LOAD_PROC( htons );
1483 LOAD_PROC( ntohs );
1484 LOAD_PROC( inet_addr );
1485 LOAD_PROC( gethostname );
1486 LOAD_PROC( gethostbyname );
1487 LOAD_PROC( getservbyname );
1488 LOAD_PROC( WSACleanup );
1490 #undef LOAD_PROC
1492 /* specify version 1.1 of winsock */
1493 if (pfn_WSAStartup (0x101, &winsockData) == 0)
1495 if (winsockData.wVersion != 0x101)
1496 goto fail;
1498 if (!load_now)
1500 /* Report that winsock exists and is usable, but leave
1501 socket functions disabled. I am assuming that calling
1502 WSAStartup does not require any network interaction,
1503 and in particular does not cause or require a dial-up
1504 connection to be established. */
1506 pfn_WSACleanup ();
1507 FreeLibrary (winsock_lib);
1508 winsock_lib = NULL;
1510 winsock_inuse = 0;
1511 return TRUE;
1514 fail:
1515 FreeLibrary (winsock_lib);
1516 winsock_lib = NULL;
1519 return FALSE;
1523 int h_errno = 0;
1525 /* function to set h_errno for compatability; map winsock error codes to
1526 normal system codes where they overlap (non-overlapping definitions
1527 are already in <sys/socket.h> */
1528 static void set_errno ()
1530 if (winsock_lib == NULL)
1531 h_errno = EINVAL;
1532 else
1533 h_errno = pfn_WSAGetLastError ();
1535 switch (h_errno)
1537 case WSAEACCES: h_errno = EACCES; break;
1538 case WSAEBADF: h_errno = EBADF; break;
1539 case WSAEFAULT: h_errno = EFAULT; break;
1540 case WSAEINTR: h_errno = EINTR; break;
1541 case WSAEINVAL: h_errno = EINVAL; break;
1542 case WSAEMFILE: h_errno = EMFILE; break;
1543 case WSAENAMETOOLONG: h_errno = ENAMETOOLONG; break;
1544 case WSAENOTEMPTY: h_errno = ENOTEMPTY; break;
1546 errno = h_errno;
1549 static void check_errno ()
1551 if (h_errno == 0 && winsock_lib != NULL)
1552 pfn_WSASetLastError (0);
1555 /* [andrewi 3-May-96] I've had conflicting results using both methods,
1556 but I believe the method of keeping the socket handle separate (and
1557 insuring it is not inheritable) is the correct one. */
1559 //#define SOCK_REPLACE_HANDLE
1561 #ifdef SOCK_REPLACE_HANDLE
1562 #define SOCK_HANDLE(fd) ((SOCKET) _get_osfhandle (fd))
1563 #else
1564 #define SOCK_HANDLE(fd) ((SOCKET) fd_info[fd].hnd)
1565 #endif
1568 sys_socket(int af, int type, int protocol)
1570 int fd;
1571 long s;
1572 child_process * cp;
1574 if (winsock_lib == NULL)
1576 h_errno = ENETDOWN;
1577 return INVALID_SOCKET;
1580 check_errno ();
1582 /* call the real socket function */
1583 s = (long) pfn_socket (af, type, protocol);
1585 if (s != INVALID_SOCKET)
1587 /* Although under NT 3.5 _open_osfhandle will accept a socket
1588 handle, if opened with SO_OPENTYPE == SO_SYNCHRONOUS_NONALERT,
1589 that does not work under NT 3.1. However, we can get the same
1590 effect by using a backdoor function to replace an existing
1591 descriptor handle with the one we want. */
1593 /* allocate a file descriptor (with appropriate flags) */
1594 fd = _open ("NUL:", _O_RDWR);
1595 if (fd >= 0)
1597 #ifdef SOCK_REPLACE_HANDLE
1598 /* now replace handle to NUL with our socket handle */
1599 CloseHandle ((HANDLE) _get_osfhandle (fd));
1600 _free_osfhnd (fd);
1601 _set_osfhnd (fd, s);
1602 /* setmode (fd, _O_BINARY); */
1603 #else
1604 /* Make a non-inheritable copy of the socket handle. */
1606 HANDLE parent;
1607 HANDLE new_s = INVALID_HANDLE_VALUE;
1609 parent = GetCurrentProcess ();
1611 /* Apparently there is a bug in NT 3.51 with some service
1612 packs, which prevents using DuplicateHandle to make a
1613 socket handle non-inheritable (causes WSACleanup to
1614 hang). The work-around is to use SetHandleInformation
1615 instead if it is available and implemented. */
1616 if (!pfn_SetHandleInformation
1617 || !pfn_SetHandleInformation ((HANDLE) s,
1618 HANDLE_FLAG_INHERIT,
1619 HANDLE_FLAG_INHERIT))
1621 DuplicateHandle (parent,
1622 (HANDLE) s,
1623 parent,
1624 &new_s,
1626 FALSE,
1627 DUPLICATE_SAME_ACCESS);
1628 pfn_closesocket (s);
1629 s = (SOCKET) new_s;
1631 fd_info[fd].hnd = (HANDLE) s;
1633 #endif
1635 /* set our own internal flags */
1636 fd_info[fd].flags = FILE_SOCKET | FILE_BINARY | FILE_READ | FILE_WRITE;
1638 cp = new_child ();
1639 if (cp)
1641 cp->fd = fd;
1642 cp->status = STATUS_READ_ACKNOWLEDGED;
1644 /* attach child_process to fd_info */
1645 if (fd_info[ fd ].cp != NULL)
1647 DebPrint (("sys_socket: fd_info[%d] apparently in use!\n", fd));
1648 abort ();
1651 fd_info[ fd ].cp = cp;
1653 /* success! */
1654 winsock_inuse++; /* count open sockets */
1655 return fd;
1658 /* clean up */
1659 _close (fd);
1661 pfn_closesocket (s);
1662 h_errno = EMFILE;
1664 set_errno ();
1666 return -1;
1671 sys_bind (int s, const struct sockaddr * addr, int namelen)
1673 if (winsock_lib == NULL)
1675 h_errno = ENOTSOCK;
1676 return SOCKET_ERROR;
1679 check_errno ();
1680 if (fd_info[s].flags & FILE_SOCKET)
1682 int rc = pfn_bind (SOCK_HANDLE (s), addr, namelen);
1683 if (rc == SOCKET_ERROR)
1684 set_errno ();
1685 return rc;
1687 h_errno = ENOTSOCK;
1688 return SOCKET_ERROR;
1693 sys_connect (int s, const struct sockaddr * name, int namelen)
1695 if (winsock_lib == NULL)
1697 h_errno = ENOTSOCK;
1698 return SOCKET_ERROR;
1701 check_errno ();
1702 if (fd_info[s].flags & FILE_SOCKET)
1704 int rc = pfn_connect (SOCK_HANDLE (s), name, namelen);
1705 if (rc == SOCKET_ERROR)
1706 set_errno ();
1707 return rc;
1709 h_errno = ENOTSOCK;
1710 return SOCKET_ERROR;
1713 u_short
1714 sys_htons (u_short hostshort)
1716 return (winsock_lib != NULL) ?
1717 pfn_htons (hostshort) : hostshort;
1720 u_short
1721 sys_ntohs (u_short netshort)
1723 return (winsock_lib != NULL) ?
1724 pfn_ntohs (netshort) : netshort;
1727 unsigned long
1728 sys_inet_addr (const char * cp)
1730 return (winsock_lib != NULL) ?
1731 pfn_inet_addr (cp) : INADDR_NONE;
1735 sys_gethostname (char * name, int namelen)
1737 if (winsock_lib != NULL)
1738 return pfn_gethostname (name, namelen);
1740 if (namelen > MAX_COMPUTERNAME_LENGTH)
1741 return !GetComputerName (name, &namelen);
1743 h_errno = EFAULT;
1744 return SOCKET_ERROR;
1747 struct hostent *
1748 sys_gethostbyname(const char * name)
1750 struct hostent * host;
1752 if (winsock_lib == NULL)
1754 h_errno = ENETDOWN;
1755 return NULL;
1758 check_errno ();
1759 host = pfn_gethostbyname (name);
1760 if (!host)
1761 set_errno ();
1762 return host;
1765 struct servent *
1766 sys_getservbyname(const char * name, const char * proto)
1768 struct servent * serv;
1770 if (winsock_lib == NULL)
1772 h_errno = ENETDOWN;
1773 return NULL;
1776 check_errno ();
1777 serv = pfn_getservbyname (name, proto);
1778 if (!serv)
1779 set_errno ();
1780 return serv;
1784 sys_shutdown (int s, int how)
1786 int rc;
1788 if (winsock_lib == NULL)
1790 h_errno = ENETDOWN;
1791 return SOCKET_ERROR;
1794 check_errno ();
1795 if (fd_info[s].flags & FILE_SOCKET)
1797 int rc = pfn_shutdown (SOCK_HANDLE (s), how);
1798 if (rc == SOCKET_ERROR)
1799 set_errno ();
1800 return rc;
1802 h_errno = ENOTSOCK;
1803 return SOCKET_ERROR;
1806 #endif /* HAVE_SOCKETS */
1809 /* Shadow main io functions: we need to handle pipes and sockets more
1810 intelligently, and implement non-blocking mode as well. */
1813 sys_close (int fd)
1815 int rc;
1817 if (fd < 0 || fd >= MAXDESC)
1819 errno = EBADF;
1820 return -1;
1823 if (fd_info[fd].cp)
1825 child_process * cp = fd_info[fd].cp;
1827 fd_info[fd].cp = NULL;
1829 if (CHILD_ACTIVE (cp))
1831 /* if last descriptor to active child_process then cleanup */
1832 int i;
1833 for (i = 0; i < MAXDESC; i++)
1835 if (i == fd)
1836 continue;
1837 if (fd_info[i].cp == cp)
1838 break;
1840 if (i == MAXDESC)
1842 #ifdef HAVE_SOCKETS
1843 if (fd_info[fd].flags & FILE_SOCKET)
1845 #ifndef SOCK_REPLACE_HANDLE
1846 if (winsock_lib == NULL) abort ();
1848 pfn_shutdown (SOCK_HANDLE (fd), 2);
1849 rc = pfn_closesocket (SOCK_HANDLE (fd));
1850 #endif
1851 winsock_inuse--; /* count open sockets */
1853 #endif
1854 delete_child (cp);
1859 /* Note that sockets do not need special treatment here (at least on
1860 NT and Windows 95 using the standard tcp/ip stacks) - it appears that
1861 closesocket is equivalent to CloseHandle, which is to be expected
1862 because socket handles are fully fledged kernel handles. */
1863 rc = _close (fd);
1865 if (rc == 0)
1866 fd_info[fd].flags = 0;
1868 return rc;
1872 sys_dup (int fd)
1874 int new_fd;
1876 new_fd = _dup (fd);
1877 if (new_fd >= 0)
1879 /* duplicate our internal info as well */
1880 fd_info[new_fd] = fd_info[fd];
1882 return new_fd;
1887 sys_dup2 (int src, int dst)
1889 int rc;
1891 if (dst < 0 || dst >= MAXDESC)
1893 errno = EBADF;
1894 return -1;
1897 /* make sure we close the destination first if it's a pipe or socket */
1898 if (src != dst && fd_info[dst].flags != 0)
1899 sys_close (dst);
1901 rc = _dup2 (src, dst);
1902 if (rc == 0)
1904 /* duplicate our internal info as well */
1905 fd_info[dst] = fd_info[src];
1907 return rc;
1910 /* From callproc.c */
1911 extern Lisp_Object Vbinary_process_input;
1912 extern Lisp_Object Vbinary_process_output;
1914 /* Unix pipe() has only one arg */
1916 sys_pipe (int * phandles)
1918 int rc;
1919 unsigned flags;
1920 child_process * cp;
1922 /* make pipe handles non-inheritable; when we spawn a child,
1923 we replace the relevant handle with an inheritable one. */
1924 rc = _pipe (phandles, 0, _O_NOINHERIT);
1926 if (rc == 0)
1928 /* set internal flags, and put read and write handles into binary
1929 mode as necessary; if not in binary mode, set the MSVC internal
1930 FDEV (0x40) flag to prevent _read from treating ^Z as eof (this
1931 could otherwise allow Emacs to hang because it then waits
1932 indefinitely for the child process to exit, when it might not be
1933 finished). */
1934 flags = FILE_PIPE | FILE_READ;
1935 if (!NILP (Vbinary_process_output))
1937 flags |= FILE_BINARY;
1938 setmode (phandles[0], _O_BINARY);
1940 #if (_MSC_VER == 900)
1941 else
1942 _osfile[phandles[0]] |= 0x40;
1943 #endif
1945 fd_info[phandles[0]].flags = flags;
1947 flags = FILE_PIPE | FILE_WRITE;
1948 if (!NILP (Vbinary_process_input))
1950 flags |= FILE_BINARY;
1951 setmode (phandles[1], _O_BINARY);
1953 #if (_MSC_VER == 900)
1954 else
1955 _osfile[phandles[1]] |= 0x40;
1956 #endif
1958 fd_info[phandles[1]].flags = flags;
1961 return rc;
1964 /* From ntproc.c */
1965 extern Lisp_Object Vw32_pipe_read_delay;
1967 /* Function to do blocking read of one byte, needed to implement
1968 select. It is only allowed on sockets and pipes. */
1970 _sys_read_ahead (int fd)
1972 child_process * cp;
1973 int rc;
1975 if (fd < 0 || fd >= MAXDESC)
1976 return STATUS_READ_ERROR;
1978 cp = fd_info[fd].cp;
1980 if (cp == NULL || cp->fd != fd || cp->status != STATUS_READ_READY)
1981 return STATUS_READ_ERROR;
1983 if ((fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET)) == 0
1984 || (fd_info[fd].flags & FILE_READ) == 0)
1986 DebPrint (("_sys_read_ahead: internal error: fd %d is not a pipe or socket!\n", fd));
1987 abort ();
1990 cp->status = STATUS_READ_IN_PROGRESS;
1992 if (fd_info[fd].flags & FILE_PIPE)
1994 /* Use read to get CRLF translation */
1995 rc = _read (fd, &cp->chr, sizeof (char));
1997 /* Give subprocess time to buffer some more output for us before
1998 reporting that input is available; we need this because Windows 95
1999 connects DOS programs to pipes by making the pipe appear to be
2000 the normal console stdout - as a result most DOS programs will
2001 write to stdout without buffering, ie. one character at a
2002 time. Even some W32 programs do this - "dir" in a command
2003 shell on NT is very slow if we don't do this. */
2004 if (rc > 0)
2006 int wait = XINT (Vw32_pipe_read_delay);
2008 if (wait > 0)
2009 Sleep (wait);
2010 else if (wait < 0)
2011 while (++wait <= 0)
2012 /* Yield remainder of our time slice, effectively giving a
2013 temporary priority boost to the child process. */
2014 Sleep (0);
2017 #ifdef HAVE_SOCKETS
2018 else if (fd_info[fd].flags & FILE_SOCKET)
2019 rc = pfn_recv (SOCK_HANDLE (fd), &cp->chr, sizeof (char), 0);
2020 #endif
2022 if (rc == sizeof (char))
2023 cp->status = STATUS_READ_SUCCEEDED;
2024 else
2025 cp->status = STATUS_READ_FAILED;
2027 return cp->status;
2031 sys_read (int fd, char * buffer, unsigned int count)
2033 int nchars;
2034 int extra = 0;
2035 int to_read;
2036 DWORD waiting;
2038 if (fd < 0 || fd >= MAXDESC)
2040 errno = EBADF;
2041 return -1;
2044 if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
2046 child_process *cp = fd_info[fd].cp;
2048 if ((fd_info[fd].flags & FILE_READ) == 0)
2050 errno = EBADF;
2051 return -1;
2054 /* presence of a child_process structure means we are operating in
2055 non-blocking mode - otherwise we just call _read directly.
2056 Note that the child_process structure might be missing because
2057 reap_subprocess has been called; in this case the pipe is
2058 already broken, so calling _read on it is okay. */
2059 if (cp)
2061 int current_status = cp->status;
2063 switch (current_status)
2065 case STATUS_READ_FAILED:
2066 case STATUS_READ_ERROR:
2067 /* report normal EOF */
2068 return 0;
2070 case STATUS_READ_READY:
2071 case STATUS_READ_IN_PROGRESS:
2072 DebPrint (("sys_read called when read is in progress\n"));
2073 errno = EWOULDBLOCK;
2074 return -1;
2076 case STATUS_READ_SUCCEEDED:
2077 /* consume read-ahead char */
2078 *buffer++ = cp->chr;
2079 count--;
2080 extra = 1;
2081 cp->status = STATUS_READ_ACKNOWLEDGED;
2082 ResetEvent (cp->char_avail);
2084 case STATUS_READ_ACKNOWLEDGED:
2085 break;
2087 default:
2088 DebPrint (("sys_read: bad status %d\n", current_status));
2089 errno = EBADF;
2090 return -1;
2093 if (fd_info[fd].flags & FILE_PIPE)
2095 PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, &waiting, NULL);
2096 to_read = min (waiting, (DWORD) count);
2098 /* Use read to get CRLF translation */
2099 nchars = _read (fd, buffer, to_read);
2101 #ifdef HAVE_SOCKETS
2102 else /* FILE_SOCKET */
2104 if (winsock_lib == NULL) abort ();
2106 /* do the equivalent of a non-blocking read */
2107 pfn_ioctlsocket (SOCK_HANDLE (fd), FIONREAD, &waiting);
2108 if (waiting == 0 && extra == 0)
2110 h_errno = errno = EWOULDBLOCK;
2111 return -1;
2114 nchars = 0;
2115 if (waiting)
2117 /* always use binary mode for sockets */
2118 nchars = pfn_recv (SOCK_HANDLE (fd), buffer, count, 0);
2119 if (nchars == SOCKET_ERROR)
2121 DebPrint(("sys_read.recv failed with error %d on socket %ld\n",
2122 pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
2123 if (extra == 0)
2125 set_errno ();
2126 return -1;
2128 nchars = 0;
2132 #endif
2134 else
2135 nchars = _read (fd, buffer, count);
2137 else
2138 nchars = _read (fd, buffer, count);
2140 return nchars + extra;
2143 /* For now, don't bother with a non-blocking mode */
2145 sys_write (int fd, const void * buffer, unsigned int count)
2147 int nchars;
2149 if (fd < 0 || fd >= MAXDESC)
2151 errno = EBADF;
2152 return -1;
2155 if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
2156 if ((fd_info[fd].flags & FILE_WRITE) == 0)
2158 errno = EBADF;
2159 return -1;
2161 #ifdef HAVE_SOCKETS
2162 if (fd_info[fd].flags & FILE_SOCKET)
2164 if (winsock_lib == NULL) abort ();
2165 nchars = pfn_send (SOCK_HANDLE (fd), buffer, count, 0);
2166 if (nchars == SOCKET_ERROR)
2168 DebPrint(("sys_read.send failed with error %d on socket %ld\n",
2169 pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
2170 set_errno ();
2173 else
2174 #endif
2175 nchars = _write (fd, buffer, count);
2177 return nchars;
2181 void
2182 term_ntproc ()
2184 #ifdef HAVE_SOCKETS
2185 /* shutdown the socket interface if necessary */
2186 term_winsock ();
2187 #endif
2190 extern BOOL dos_process_running;
2192 void
2193 init_ntproc ()
2195 #ifdef HAVE_SOCKETS
2196 /* Initialise the socket interface now if available and requested by
2197 the user by defining PRELOAD_WINSOCK; otherwise loading will be
2198 delayed until open-network-stream is called (w32-has-winsock can
2199 also be used to dynamically load or reload winsock).
2201 Conveniently, init_environment is called before us, so
2202 PRELOAD_WINSOCK can be set in the registry. */
2204 /* Always initialize this correctly. */
2205 winsock_lib = NULL;
2207 if (getenv ("PRELOAD_WINSOCK") != NULL)
2208 init_winsock (TRUE);
2209 #endif
2211 /* Initial preparation for subprocess support: replace our standard
2212 handles with non-inheritable versions. */
2214 HANDLE parent;
2215 HANDLE stdin_save = INVALID_HANDLE_VALUE;
2216 HANDLE stdout_save = INVALID_HANDLE_VALUE;
2217 HANDLE stderr_save = INVALID_HANDLE_VALUE;
2219 parent = GetCurrentProcess ();
2221 /* ignore errors when duplicating and closing; typically the
2222 handles will be invalid when running as a gui program. */
2223 DuplicateHandle (parent,
2224 GetStdHandle (STD_INPUT_HANDLE),
2225 parent,
2226 &stdin_save,
2228 FALSE,
2229 DUPLICATE_SAME_ACCESS);
2231 DuplicateHandle (parent,
2232 GetStdHandle (STD_OUTPUT_HANDLE),
2233 parent,
2234 &stdout_save,
2236 FALSE,
2237 DUPLICATE_SAME_ACCESS);
2239 DuplicateHandle (parent,
2240 GetStdHandle (STD_ERROR_HANDLE),
2241 parent,
2242 &stderr_save,
2244 FALSE,
2245 DUPLICATE_SAME_ACCESS);
2247 fclose (stdin);
2248 fclose (stdout);
2249 fclose (stderr);
2251 if (stdin_save != INVALID_HANDLE_VALUE)
2252 _open_osfhandle ((long) stdin_save, O_TEXT);
2253 else
2254 open ("nul", O_TEXT | O_NOINHERIT | O_RDONLY);
2255 fdopen (0, "r");
2257 if (stdout_save != INVALID_HANDLE_VALUE)
2258 _open_osfhandle ((long) stdout_save, O_TEXT);
2259 else
2260 open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
2261 fdopen (1, "w");
2263 if (stderr_save != INVALID_HANDLE_VALUE)
2264 _open_osfhandle ((long) stderr_save, O_TEXT);
2265 else
2266 open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
2267 fdopen (2, "w");
2270 /* Restrict Emacs to running only one DOS program at a time (with any
2271 number of W32 programs). This is to prevent the user from
2272 running into problems with DOS programs being run in the same VDM
2273 under both Windows 95 and Windows NT.
2275 Note that it is possible for Emacs to run DOS programs in separate
2276 VDMs, but unfortunately the pipe implementation on Windows 95 then
2277 fails to report when the DOS process exits (which is supposed to
2278 break the pipe). Until this bug is fixed, or we can devise a
2279 work-around, we must try to avoid letting the user start more than
2280 one DOS program if possible. */
2282 dos_process_running = FALSE;
2284 /* unfortunately, atexit depends on implementation of malloc */
2285 /* atexit (term_ntproc); */
2286 signal (SIGABRT, term_ntproc);
2289 /* end of nt.c */