(mail-user-agent): Replaces mua-paradigm.
[emacs.git] / src / w32.c
blob4c621fc8fa4246872db4c3cbe16db3e0f72105c0
1 /* Utility and Unix shadow routines for GNU Emacs on Windows NT.
2 Copyright (C) 1994, 1995 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
21 Geoff Voelker (voelker@cs.washington.edu) 7-29-94
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <io.h>
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <ctype.h>
31 #include <signal.h>
32 #include <sys/time.h>
34 /* must include CRT headers *before* config.h */
35 #include "config.h"
36 #undef access
37 #undef chdir
38 #undef chmod
39 #undef creat
40 #undef ctime
41 #undef fopen
42 #undef link
43 #undef mkdir
44 #undef mktemp
45 #undef open
46 #undef rename
47 #undef rmdir
48 #undef unlink
50 #undef close
51 #undef dup
52 #undef dup2
53 #undef pipe
54 #undef read
55 #undef write
57 #define getwd _getwd
58 #include "lisp.h"
59 #undef getwd
61 #include <pwd.h>
63 #include <windows.h>
65 #ifdef HAVE_SOCKETS /* TCP connection support, if kernel can do it */
66 #include <sys/socket.h>
67 #undef socket
68 #undef bind
69 #undef connect
70 #undef htons
71 #undef ntohs
72 #undef inet_addr
73 #undef gethostname
74 #undef gethostbyname
75 #undef getservbyname
76 #endif
78 #include "nt.h"
79 #include "ndir.h"
80 #include "ntheap.h"
82 /* Get the current working directory. */
83 char *
84 getwd (char *dir)
86 if (GetCurrentDirectory (MAXPATHLEN, dir) > 0)
87 return dir;
88 return NULL;
91 #ifndef HAVE_SOCKETS
92 /* Emulate gethostname. */
93 int
94 gethostname (char *buffer, int size)
96 /* NT only allows small host names, so the buffer is
97 certainly large enough. */
98 return !GetComputerName (buffer, &size);
100 #endif /* HAVE_SOCKETS */
102 /* Emulate getloadavg. */
104 getloadavg (double loadavg[], int nelem)
106 int i;
108 /* A faithful emulation is going to have to be saved for a rainy day. */
109 for (i = 0; i < nelem; i++)
111 loadavg[i] = 0.0;
113 return i;
116 /* Emulate the Unix directory procedures opendir, closedir,
117 and readdir. We can't use the procedures supplied in sysdep.c,
118 so we provide them here. */
120 struct direct dir_static; /* simulated directory contents */
121 static HANDLE dir_find_handle = INVALID_HANDLE_VALUE;
122 static int dir_is_fat;
123 static char dir_pathname[MAXPATHLEN+1];
125 extern Lisp_Object Vwin32_downcase_file_names;
127 DIR *
128 opendir (char *filename)
130 DIR *dirp;
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))))
136 return NULL;
137 if (dir_find_handle != INVALID_HANDLE_VALUE)
138 return NULL;
140 dirp->dd_fd = 0;
141 dirp->dd_loc = 0;
142 dirp->dd_size = 0;
144 strncpy (dir_pathname, filename, MAXPATHLEN);
145 dir_pathname[MAXPATHLEN] = '\0';
146 dir_is_fat = is_fat_volume (filename, NULL);
148 return dirp;
151 void
152 closedir (DIR *dirp)
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);
163 struct direct *
164 readdir (DIR *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];
172 int ln;
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)
183 return NULL;
185 else
187 if (!FindNextFile (dir_find_handle, &find_data))
188 return NULL;
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);
200 if (dir_is_fat)
201 _strlwr (dir_static.d_name);
202 else if (!NILP (Vwin32_downcase_file_names))
204 register char *p;
205 for (p = dir_static.d_name; *p; p++)
206 if (*p >= 'a' && *p <= 'z')
207 break;
208 if (!*p)
209 _strlwr (dir_static.d_name);
212 return &dir_static;
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 =
227 the_passwd_name,
228 the_passwd_passwd,
232 the_passwd_gecos,
233 the_passwd_dir,
234 the_passwd_shell,
237 int
238 getuid ()
240 return the_passwd.pw_uid;
243 int
244 geteuid ()
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. */
249 return getuid ();
252 int
253 getgid ()
255 return the_passwd.pw_gid;
258 int
259 getegid ()
261 return getgid ();
264 struct passwd *
265 getpwuid (int uid)
267 if (uid == the_passwd.pw_uid)
268 return &the_passwd;
269 return NULL;
272 struct passwd *
273 getpwnam (char *name)
275 struct passwd *pw;
277 pw = getpwuid (getuid ());
278 if (!pw)
279 return pw;
281 if (stricmp (name, pw->pw_name))
282 return NULL;
284 return pw;
287 void
288 init_user_info ()
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;
299 HANDLE token = NULL;
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;
315 else
317 SID_IDENTIFIER_AUTHORITY * pSIA;
319 pSIA = GetSidIdentifierAuthority (*((PSID *) user_sid));
320 /* I believe the relative portion is the last 4 bytes (of 6)
321 with msb first. */
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;
329 /* Get group id */
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;
343 else
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;
354 else
355 the_passwd.pw_uid = 123;
356 the_passwd.pw_gid = the_passwd.pw_uid;
358 else
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)
367 putenv ("HOME=c:/");
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"));
375 if (token)
376 CloseHandle (token);
380 random ()
382 /* rand () on NT gives us 15 random bits...hack together 30 bits. */
383 return ((rand () << 15) | rand ());
386 void
387 srandom (int seed)
389 srand (seed);
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. */
396 static void
397 normalize_filename (fp, path_sep)
398 register char *fp;
399 char path_sep;
401 char sep;
402 char *elem;
404 if (NILP (Vwin32_downcase_file_names))
406 while (*fp)
408 if (*fp == '/' || *fp == '\\')
409 *fp = path_sep;
410 fp++;
412 return;
415 sep = path_sep; /* convert to this path separator */
416 elem = fp; /* start of current path element */
418 do {
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 */
437 sep = path_sep;
439 } while (*fp++);
442 /* Destructively turn backslashes into slashes. */
443 void
444 dostounix_filename (p)
445 register char *p;
447 normalize_filename (p, '/');
450 /* Destructively turn slashes into backslashes. */
451 void
452 unixtodos_filename (p)
453 register char *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.) */
462 crlf_to_lf (n, buf)
463 register int n;
464 register unsigned char *buf;
466 unsigned char *np = buf;
467 unsigned char *startp = buf;
468 unsigned char *endp = buf + n;
470 if (n == 0)
471 return n;
472 while (buf < endp - 1)
474 if (*buf == 0x0d)
476 if (*(++buf) != 0x0a)
477 *np++ = 0x0d;
479 else
480 *np++ = *buf++;
482 if (buf < endp)
483 *np++ = *buf++;
484 return np - startp;
487 /* Routines that are no-ops on NT but are defined to get Emacs to compile. */
489 int
490 sigsetmask (int signal_mask)
492 return 0;
495 int
496 sigblock (int sig)
498 return 0;
501 int
502 setpgrp (int pid, int gid)
504 return 0;
507 int
508 alarm (int seconds)
510 return 0;
513 int
514 unrequest_sigio (void)
516 return 0;
519 int
520 request_sigio (void)
522 return 0;
525 #define REG_ROOT "SOFTWARE\\GNU\\Emacs"
527 LPBYTE
528 nt_get_resource (key, lpdwtype)
529 char *key;
530 LPDWORD lpdwtype;
532 LPBYTE lpvalue;
533 HKEY hrootkey = NULL;
534 DWORD cbData;
535 BOOL ok = FALSE;
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)
542 lpvalue = NULL;
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)
548 return (lpvalue);
551 if (lpvalue) xfree (lpvalue);
553 RegCloseKey (hrootkey);
556 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
558 lpvalue = NULL;
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)
564 return (lpvalue);
567 if (lpvalue) xfree (lpvalue);
569 RegCloseKey (hrootkey);
572 return (NULL);
575 void
576 init_environment ()
578 /* Check for environment variables and use registry if they don't exist */
580 int i;
581 LPBYTE lpval;
582 DWORD dwType;
584 static char * env_vars[] =
586 "HOME",
587 "PRELOAD_WINSOCK",
588 "emacs_dir",
589 "EMACSLOADPATH",
590 "SHELL",
591 "EMACSDATA",
592 "EMACSPATH",
593 "EMACSLOCKDIR",
594 "INFOPATH",
595 "EMACSDOC",
596 "TERM",
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)
614 char buf[500];
616 _snprintf (buf, 499, "%s=%s", env_vars[i], lpval);
617 putenv (strdup (buf));
620 xfree (lpval);
625 init_user_info ();
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
631 routine. */
633 static char configuration_buffer[32];
635 char *
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:
648 arch = "i386";
649 break;
650 #endif
652 #ifdef PROCESSOR_INTEL_860
653 case PROCESSOR_INTEL_860:
654 arch = "i860";
655 break;
656 #endif
658 #ifdef PROCESSOR_MIPS_R2000
659 case PROCESSOR_MIPS_R2000:
660 case PROCESSOR_MIPS_R3000:
661 case PROCESSOR_MIPS_R4000:
662 arch = "mips";
663 break;
664 #endif
666 #ifdef PROCESSOR_ALPHA_21064
667 case PROCESSOR_ALPHA_21064:
668 arch = "alpha";
669 break;
670 #endif
672 default:
673 arch = "unknown";
674 break;
677 /* Let oem be "*" until we figure out how to decode the OEM field. */
678 oem = "*";
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). */
690 void
691 gettimeofday (struct timeval *tv, struct timezone *tz)
693 struct _timeb tb;
694 _ftime (&tb);
696 tv->tv_sec = tb.time;
697 tv->tv_usec = tb.millitm * 1000L;
698 if (tz)
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). */
712 char *
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. */
722 void
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[];
731 #endif
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 ];
738 static struct {
739 DWORD serialnum;
740 DWORD maxcomp;
741 DWORD flags;
742 char name[32];
743 char type[32];
744 } volume_info;
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)
751 char temp[MAX_PATH];
752 char *rootname = NULL; /* default to current volume */
754 if (name == NULL)
755 return FALSE;
757 /* find the root name of the volume if given */
758 if (isalpha (name[0]) && name[1] == ':')
760 rootname = temp;
761 temp[0] = *name++;
762 temp[1] = *name++;
763 temp[2] = '\\';
764 temp[3] = 0;
766 else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1]))
768 char *str = temp;
769 int slashes = 4;
770 rootname = temp;
773 if (IS_DIRECTORY_SEP (*name) && --slashes == 0)
774 break;
775 *str++ = *name++;
777 while ( *name );
779 *str++ = '\\';
780 *str = 0;
783 if (pPath)
784 *pPath = name;
786 if (GetVolumeInformation (rootname,
787 volume_info.name, 32,
788 &volume_info.serialnum,
789 &volume_info.maxcomp,
790 &volume_info.flags,
791 volume_info.type, 32))
793 return TRUE;
795 return FALSE;
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);
805 return FALSE;
808 /* Map filename to a legal 8.3 name if necessary. */
809 const char *
810 map_win32_filename (const char * name, const char ** pPath)
812 static char shortname[MAX_PATH];
813 char * str = shortname;
814 char c;
815 char * path;
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 */
823 while (name < path)
824 *str++ = *name++; /* skip past UNC header */
826 while ((c = *name++))
828 switch ( c )
830 case '\\':
831 case '/':
832 *str++ = '\\';
833 extn = 0; /* reset extension flags */
834 dots = 2; /* max 2 dots */
835 left = 8; /* max length 8 for main part */
836 break;
837 case ':':
838 *str++ = ':';
839 extn = 0; /* reset extension flags */
840 dots = 2; /* max 2 dots */
841 left = 8; /* max length 8 for main part */
842 break;
843 case '.':
844 if ( dots )
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. */
850 if (! *name ||
851 *name == '.' ||
852 IS_DIRECTORY_SEP (*name))
854 *str++ = '.';
855 dots--;
857 else
859 *str++ = '_';
860 left--;
861 dots = 0;
864 else if ( !extn )
866 *str++ = '.';
867 extn = 1; /* we've got an extension */
868 left = 3; /* 3 chars in extension */
870 else
872 /* any embedded dots after the first are converted to _ */
873 *str++ = '_';
875 break;
876 case '~':
877 case '#': /* don't lose these, they're important */
878 if ( ! left )
879 str[-1] = c; /* replace last character of part */
880 /* FALLTHRU */
881 default:
882 if ( left )
884 *str++ = tolower (c); /* map to lower case (looks nicer) */
885 left--;
886 dots = 0; /* started a path component */
888 break;
891 *str = '\0';
893 else
895 strcpy (shortname, name);
896 unixtodos_filename (shortname);
899 if (pPath)
900 *pPath = shortname + (path - name);
902 return shortname;
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
909 long file names. */
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);
935 FILE *
936 sys_fopen(const char * path, const char * mode)
938 int fd;
939 int oflag;
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. */
946 if (mode[0] == 'r')
947 oflag = O_RDONLY;
948 else if (mode[0] == 'w' || mode[0] == 'a')
949 oflag = O_WRONLY | O_CREAT | O_TRUNC;
950 else
951 return NULL;
953 /* Only do simplistic option parsing. */
954 while (*++mode)
955 if (mode[0] == '+')
957 oflag &= ~(O_RDONLY | O_WRONLY);
958 oflag |= O_RDWR;
960 else if (mode[0] == 'b')
962 oflag &= ~O_TEXT;
963 oflag |= O_BINARY;
965 else if (mode[0] == 't')
967 oflag &= ~O_BINARY;
968 oflag |= O_TEXT;
970 else break;
972 fd = _open (map_win32_filename (path, NULL), oflag | _O_NOINHERIT, 0644);
973 if (fd < 0)
974 return NULL;
976 return fdopen (fd, mode_save);
980 sys_link (const char * path1, const char * path2)
982 errno = EINVAL;
983 return -1;
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
995 string.
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. */
1001 char *
1002 sys_mktemp (char * template)
1004 char * p;
1005 int i;
1006 unsigned uid = GetCurrentThreadId ();
1007 static char first_char[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#";
1009 if (template == NULL)
1010 return NULL;
1011 p = template + strlen (template);
1012 i = 5;
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;
1017 uid /= 10;
1020 if (i < 0 && p[0] == 'X')
1022 i = 0;
1025 int save_errno = errno;
1026 p[0] = first_char[i];
1027 if (sys_access (template, 0) < 0)
1029 errno = save_errno;
1030 return template;
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 */
1038 template[0] = 0;
1039 return template;
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)
1063 char * p;
1065 unixtodos_filename (temp);
1066 if (p = strrchr (temp, '\\'))
1067 p++;
1068 else
1069 p = temp;
1070 strcpy (p, "__XXXXXX");
1071 _mktemp (temp);
1072 if (rename (map_win32_filename (oldname, NULL), temp) < 0)
1073 return -1;
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);
1082 _unlink (newname);
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;
1104 static time_t
1105 convert_time (FILETIME ft)
1107 long double ret;
1109 if (!init)
1111 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1112 SYSTEMTIME st;
1114 st.wYear = 1970;
1115 st.wMonth = 1;
1116 st.wDay = 1;
1117 st.wHour = 0;
1118 st.wMinute = 0;
1119 st.wSecond = 0;
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;
1125 init = 1;
1128 if (CompareFileTime (&ft, &utc_base_ft) < 0)
1129 return 0;
1131 ret = (long double) ft.dwHighDateTime * 4096 * 1024 * 1024 + ft.dwLowDateTime;
1132 ret -= utc_base;
1133 return (time_t) (ret * 1e-7);
1136 #if 0
1137 /* in case we ever have need of this */
1138 void
1139 convert_from_time_t (time_t time, FILETIME * pft)
1141 long double tmp;
1143 if (!init)
1145 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1146 SYSTEMTIME st;
1148 st.wYear = 1970;
1149 st.wMonth = 1;
1150 st.wDay = 1;
1151 st.wHour = 0;
1152 st.wMinute = 0;
1153 st.wSecond = 0;
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;
1159 init = 1;
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);
1167 #endif
1169 /* "PJW" algorithm (see the "Dragon" compiler book). */
1170 static unsigned
1171 hashval (const char * str)
1173 unsigned h = 0;
1174 unsigned g;
1175 while (*str)
1177 h = (h << 4) + *str++;
1178 if ((g = h & 0xf0000000) != 0)
1179 h = (h ^ (g >> 24)) & 0x0fffffff;
1181 return h;
1184 /* Return the hash value of the canonical pathname, excluding the
1185 drive/UNC header, to get a hopefully unique inode number. */
1186 static _ino_t
1187 generate_inode_val (const char * name)
1189 char fullname[ MAX_PATH ];
1190 char * p;
1191 unsigned hash;
1193 GetFullPathName (name, sizeof (fullname), fullname, &p);
1194 get_volume_info (fullname, &p);
1195 /* Normal Win32 filesystems are still case insensitive. */
1196 _strlwr (p);
1197 hash = hashval (p);
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)
1207 char * name;
1208 WIN32_FIND_DATA wfd;
1209 HANDLE fh;
1210 int permission;
1211 int len;
1212 int rootdir = FALSE;
1214 if (path == NULL || buf == NULL)
1216 errno = EFAULT;
1217 return -1;
1220 name = (char *) map_win32_filename (path, &path);
1221 /* must be valid filename, no wild cards */
1222 if (strchr (name, '*') || strchr (name, '?'))
1224 errno = ENOENT;
1225 return -1;
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);
1236 if (rootdir)
1238 if (!IS_DIRECTORY_SEP (name[len-1]))
1239 strcat (name, "\\");
1240 if (GetDriveType (name) < 2)
1242 errno = ENOENT;
1243 return -1;
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);
1252 else
1254 if (IS_DIRECTORY_SEP (name[len-1]))
1255 name[len - 1] = 0;
1256 fh = FindFirstFile (name, &wfd);
1257 if (fh == INVALID_HANDLE_VALUE)
1259 errno = ENOENT;
1260 return -1;
1262 FindClose (fh);
1265 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1267 buf->st_mode = _S_IFDIR;
1268 buf->st_nlink = 2; /* doesn't really matter */
1270 else
1272 #if 0
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;
1287 break;
1288 case FILE_TYPE_PIPE:
1289 buf->st_mode = _S_IFIFO;
1290 break;
1291 case FILE_TYPE_CHAR:
1292 case FILE_TYPE_UNKNOWN:
1293 default:
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; */
1300 CloseHandle (fh);
1302 else
1304 errno = EACCES;
1305 return -1;
1307 #else
1308 buf->st_mode = _S_IFREG;
1309 buf->st_nlink = 1;
1310 #endif
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;
1335 else
1336 permission = _S_IREAD | _S_IWRITE;
1338 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1339 permission |= _S_IEXEC;
1340 else
1342 char * p = strrchr (name, '.');
1343 if (p != NULL &&
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);
1353 return 0;
1356 #ifdef HAVE_SOCKETS
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
1391 #endif
1393 HANDLE winsock_lib;
1394 static int winsock_inuse;
1396 BOOL
1397 term_winsock (void)
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))
1408 winsock_lib = NULL;
1409 return TRUE;
1412 return FALSE;
1415 BOOL
1416 init_winsock (int load_now)
1418 WSADATA winsockData;
1420 if (winsock_lib != NULL)
1421 return TRUE;
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) \
1436 goto fail;
1438 LOAD_PROC( WSAStartup );
1439 LOAD_PROC( WSASetLastError );
1440 LOAD_PROC( WSAGetLastError );
1441 LOAD_PROC( socket );
1442 LOAD_PROC( bind );
1443 LOAD_PROC( connect );
1444 LOAD_PROC( ioctlsocket );
1445 LOAD_PROC( recv );
1446 LOAD_PROC( send );
1447 LOAD_PROC( closesocket );
1448 LOAD_PROC( shutdown );
1449 LOAD_PROC( htons );
1450 LOAD_PROC( ntohs );
1451 LOAD_PROC( inet_addr );
1452 LOAD_PROC( gethostname );
1453 LOAD_PROC( gethostbyname );
1454 LOAD_PROC( getservbyname );
1455 LOAD_PROC( WSACleanup );
1457 #undef LOAD_PROC
1459 /* specify version 1.1 of winsock */
1460 if (pfn_WSAStartup (0x101, &winsockData) == 0)
1462 if (winsockData.wVersion != 0x101)
1463 goto fail;
1465 if (!load_now)
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. */
1473 pfn_WSACleanup ();
1474 FreeLibrary (winsock_lib);
1475 winsock_lib = NULL;
1477 winsock_inuse = 0;
1478 return TRUE;
1481 fail:
1482 FreeLibrary (winsock_lib);
1483 winsock_lib = NULL;
1486 return FALSE;
1490 int h_errno = 0;
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)
1498 h_errno = EINVAL;
1499 else
1500 h_errno = pfn_WSAGetLastError ();
1502 switch (h_errno)
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;
1513 errno = h_errno;
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))
1530 #else
1531 #define SOCK_HANDLE(fd) ((SOCKET) fd_info[fd].hnd)
1532 #endif
1535 sys_socket(int af, int type, int protocol)
1537 int fd;
1538 long s;
1539 child_process * cp;
1541 if (winsock_lib == NULL)
1543 h_errno = ENETDOWN;
1544 return INVALID_SOCKET;
1547 check_errno ();
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);
1562 if (fd >= 0)
1564 #ifdef SOCK_REPLACE_HANDLE
1565 /* now replace handle to NUL with our socket handle */
1566 CloseHandle ((HANDLE) _get_osfhandle (fd));
1567 _free_osfhnd (fd);
1568 _set_osfhnd (fd, s);
1569 /* setmode (fd, _O_BINARY); */
1570 #else
1571 /* Make a non-inheritable copy of the socket handle. */
1573 HANDLE parent;
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,
1589 (HANDLE) s,
1590 parent,
1591 &new_s,
1593 FALSE,
1594 DUPLICATE_SAME_ACCESS);
1595 pfn_closesocket (s);
1596 s = (SOCKET) new_s;
1598 fd_info[fd].hnd = (HANDLE) s;
1600 #endif
1602 /* set our own internal flags */
1603 fd_info[fd].flags = FILE_SOCKET | FILE_BINARY | FILE_READ | FILE_WRITE;
1605 cp = new_child ();
1606 if (cp)
1608 cp->fd = fd;
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));
1615 abort ();
1618 fd_info[ fd ].cp = cp;
1620 /* success! */
1621 winsock_inuse++; /* count open sockets */
1622 return fd;
1625 /* clean up */
1626 _close (fd);
1628 pfn_closesocket (s);
1629 h_errno = EMFILE;
1631 set_errno ();
1633 return -1;
1638 sys_bind (int s, const struct sockaddr * addr, int namelen)
1640 if (winsock_lib == NULL)
1642 h_errno = ENOTSOCK;
1643 return SOCKET_ERROR;
1646 check_errno ();
1647 if (fd_info[s].flags & FILE_SOCKET)
1649 int rc = pfn_bind (SOCK_HANDLE (s), addr, namelen);
1650 if (rc == SOCKET_ERROR)
1651 set_errno ();
1652 return rc;
1654 h_errno = ENOTSOCK;
1655 return SOCKET_ERROR;
1660 sys_connect (int s, const struct sockaddr * name, int namelen)
1662 if (winsock_lib == NULL)
1664 h_errno = ENOTSOCK;
1665 return SOCKET_ERROR;
1668 check_errno ();
1669 if (fd_info[s].flags & FILE_SOCKET)
1671 int rc = pfn_connect (SOCK_HANDLE (s), name, namelen);
1672 if (rc == SOCKET_ERROR)
1673 set_errno ();
1674 return rc;
1676 h_errno = ENOTSOCK;
1677 return SOCKET_ERROR;
1680 u_short
1681 sys_htons (u_short hostshort)
1683 return (winsock_lib != NULL) ?
1684 pfn_htons (hostshort) : hostshort;
1687 u_short
1688 sys_ntohs (u_short netshort)
1690 return (winsock_lib != NULL) ?
1691 pfn_ntohs (netshort) : netshort;
1694 unsigned long
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);
1710 h_errno = EFAULT;
1711 return SOCKET_ERROR;
1714 struct hostent *
1715 sys_gethostbyname(const char * name)
1717 struct hostent * host;
1719 if (winsock_lib == NULL)
1721 h_errno = ENETDOWN;
1722 return NULL;
1725 check_errno ();
1726 host = pfn_gethostbyname (name);
1727 if (!host)
1728 set_errno ();
1729 return host;
1732 struct servent *
1733 sys_getservbyname(const char * name, const char * proto)
1735 struct servent * serv;
1737 if (winsock_lib == NULL)
1739 h_errno = ENETDOWN;
1740 return NULL;
1743 check_errno ();
1744 serv = pfn_getservbyname (name, proto);
1745 if (!serv)
1746 set_errno ();
1747 return serv;
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. */
1757 sys_close (int fd)
1759 int rc;
1761 if (fd < 0 || fd >= MAXDESC)
1763 errno = EBADF;
1764 return -1;
1767 if (fd_info[fd].cp)
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 */
1776 int i;
1777 for (i = 0; i < MAXDESC; i++)
1779 if (i == fd)
1780 continue;
1781 if (fd_info[i].cp == cp)
1782 break;
1784 if (i == MAXDESC)
1786 #ifdef HAVE_SOCKETS
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));
1794 #endif
1795 winsock_inuse--; /* count open sockets */
1797 #endif
1798 delete_child (cp);
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. */
1807 rc = _close (fd);
1809 if (rc == 0)
1810 fd_info[fd].flags = 0;
1812 return rc;
1816 sys_dup (int fd)
1818 int new_fd;
1820 new_fd = _dup (fd);
1821 if (new_fd >= 0)
1823 /* duplicate our internal info as well */
1824 fd_info[new_fd] = fd_info[fd];
1826 return new_fd;
1831 sys_dup2 (int src, int dst)
1833 int rc;
1835 if (dst < 0 || dst >= MAXDESC)
1837 errno = EBADF;
1838 return -1;
1841 /* make sure we close the destination first if it's a pipe or socket */
1842 if (src != dst && fd_info[dst].flags != 0)
1843 sys_close (dst);
1845 rc = _dup2 (src, dst);
1846 if (rc == 0)
1848 /* duplicate our internal info as well */
1849 fd_info[dst] = fd_info[src];
1851 return rc;
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)
1862 int rc;
1863 unsigned flags;
1864 child_process * cp;
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);
1870 if (rc == 0)
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
1877 finished). */
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)
1885 else
1886 _osfile[phandles[0]] |= 0x40;
1887 #endif
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)
1898 else
1899 _osfile[phandles[1]] |= 0x40;
1900 #endif
1902 fd_info[phandles[1]].flags = flags;
1905 return rc;
1908 /* From ntproc.c */
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)
1916 child_process * cp;
1917 int rc;
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));
1931 abort ();
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. */
1948 if (rc > 0)
1950 int wait = XINT (Vwin32_pipe_read_delay);
1952 if (wait > 0)
1953 Sleep (wait);
1954 else if (wait < 0)
1955 while (++wait <= 0)
1956 /* Yield remainder of our time slice, effectively giving a
1957 temporary priority boost to the child process. */
1958 Sleep (0);
1961 #ifdef HAVE_SOCKETS
1962 else if (fd_info[fd].flags & FILE_SOCKET)
1963 rc = pfn_recv (SOCK_HANDLE (fd), &cp->chr, sizeof (char), 0);
1964 #endif
1966 if (rc == sizeof (char))
1967 cp->status = STATUS_READ_SUCCEEDED;
1968 else
1969 cp->status = STATUS_READ_FAILED;
1971 return cp->status;
1975 sys_read (int fd, char * buffer, unsigned int count)
1977 int nchars;
1978 int extra = 0;
1979 int to_read;
1980 DWORD waiting;
1982 if (fd < 0 || fd >= MAXDESC)
1984 errno = EBADF;
1985 return -1;
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)
1994 errno = EBADF;
1995 return -1;
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. */
2003 if (cp)
2005 int current_status = cp->status;
2007 switch (current_status)
2009 case STATUS_READ_FAILED:
2010 case STATUS_READ_ERROR:
2011 /* report normal EOF */
2012 return 0;
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;
2018 return -1;
2020 case STATUS_READ_SUCCEEDED:
2021 /* consume read-ahead char */
2022 *buffer++ = cp->chr;
2023 count--;
2024 extra = 1;
2025 cp->status = STATUS_READ_ACKNOWLEDGED;
2026 ResetEvent (cp->char_avail);
2028 case STATUS_READ_ACKNOWLEDGED:
2029 break;
2031 default:
2032 DebPrint (("sys_read: bad status %d\n", current_status));
2033 errno = EBADF;
2034 return -1;
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);
2045 #ifdef HAVE_SOCKETS
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;
2055 return -1;
2058 nchars = 0;
2059 if (waiting)
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)));
2067 if (extra == 0)
2069 set_errno ();
2070 return -1;
2072 nchars = 0;
2076 #endif
2078 else
2079 nchars = _read (fd, buffer, count);
2081 else
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)
2091 int nchars;
2093 if (fd < 0 || fd >= MAXDESC)
2095 errno = EBADF;
2096 return -1;
2099 if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
2100 if ((fd_info[fd].flags & FILE_WRITE) == 0)
2102 errno = EBADF;
2103 return -1;
2105 #ifdef HAVE_SOCKETS
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)));
2114 set_errno ();
2117 else
2118 #endif
2119 nchars = _write (fd, buffer, count);
2121 return nchars;
2125 void
2126 term_ntproc ()
2128 #ifdef HAVE_SOCKETS
2129 /* shutdown the socket interface if necessary */
2130 term_winsock ();
2131 #endif
2134 extern BOOL dos_process_running;
2136 void
2137 init_ntproc ()
2139 #ifdef HAVE_SOCKETS
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. */
2149 winsock_lib = NULL;
2151 if (getenv ("PRELOAD_WINSOCK") != NULL)
2152 init_winsock (TRUE);
2153 #endif
2155 /* Initial preparation for subprocess support: replace our standard
2156 handles with non-inheritable versions. */
2158 HANDLE parent;
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),
2169 parent,
2170 &stdin_save,
2172 FALSE,
2173 DUPLICATE_SAME_ACCESS);
2175 DuplicateHandle (parent,
2176 GetStdHandle (STD_OUTPUT_HANDLE),
2177 parent,
2178 &stdout_save,
2180 FALSE,
2181 DUPLICATE_SAME_ACCESS);
2183 DuplicateHandle (parent,
2184 GetStdHandle (STD_ERROR_HANDLE),
2185 parent,
2186 &stderr_save,
2188 FALSE,
2189 DUPLICATE_SAME_ACCESS);
2191 fclose (stdin);
2192 fclose (stdout);
2193 fclose (stderr);
2195 if (stdin_save != INVALID_HANDLE_VALUE)
2196 _open_osfhandle ((long) stdin_save, O_TEXT);
2197 else
2198 open ("nul", O_TEXT | O_NOINHERIT | O_RDONLY);
2199 fdopen (0, "r");
2201 if (stdout_save != INVALID_HANDLE_VALUE)
2202 _open_osfhandle ((long) stdout_save, O_TEXT);
2203 else
2204 open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
2205 fdopen (1, "w");
2207 if (stderr_save != INVALID_HANDLE_VALUE)
2208 _open_osfhandle ((long) stderr_save, O_TEXT);
2209 else
2210 open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
2211 fdopen (2, "w");
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);
2233 /* end of nt.c */