(sys_mktemp): Complete rewrite.
[bpt/emacs.git] / src / w32.c
1 /* Utility and Unix shadow routines for GNU Emacs on Windows NT.
2 Copyright (C) 1994, 1995 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
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.
10
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.
15
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.
20
21 Geoff Voelker (voelker@cs.washington.edu) 7-29-94
22 */
23
24
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>
33
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
49
50 #undef close
51 #undef dup
52 #undef dup2
53 #undef pipe
54 #undef read
55 #undef write
56
57 #define getwd _getwd
58 #include "lisp.h"
59 #undef getwd
60
61 #include <pwd.h>
62
63 #include <windows.h>
64
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
77
78 #include "nt.h"
79 #include "ndir.h"
80 #include "ntheap.h"
81
82 /* Get the current working directory. */
83 char *
84 getwd (char *dir)
85 {
86 if (GetCurrentDirectory (MAXPATHLEN, dir) > 0)
87 return dir;
88 return NULL;
89 }
90
91 #ifndef HAVE_SOCKETS
92 /* Emulate gethostname. */
93 int
94 gethostname (char *buffer, int size)
95 {
96 /* NT only allows small host names, so the buffer is
97 certainly large enough. */
98 return !GetComputerName (buffer, &size);
99 }
100 #endif /* HAVE_SOCKETS */
101
102 /* Emulate getloadavg. */
103 int
104 getloadavg (double loadavg[], int nelem)
105 {
106 int i;
107
108 /* A faithful emulation is going to have to be saved for a rainy day. */
109 for (i = 0; i < nelem; i++)
110 {
111 loadavg[i] = 0.0;
112 }
113 return i;
114 }
115
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. */
119
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];
124
125 extern Lisp_Object Vwin32_downcase_file_names;
126
127 DIR *
128 opendir (char *filename)
129 {
130 DIR *dirp;
131
132 /* Opening is done by FindFirstFile. However, a read is inherent to
133 this operation, so we defer the open until read time. */
134
135 if (!(dirp = (DIR *) malloc (sizeof (DIR))))
136 return NULL;
137 if (dir_find_handle != INVALID_HANDLE_VALUE)
138 return NULL;
139
140 dirp->dd_fd = 0;
141 dirp->dd_loc = 0;
142 dirp->dd_size = 0;
143
144 strncpy (dir_pathname, filename, MAXPATHLEN);
145 dir_pathname[MAXPATHLEN] = '\0';
146 dir_is_fat = is_fat_volume (filename, NULL);
147
148 return dirp;
149 }
150
151 void
152 closedir (DIR *dirp)
153 {
154 /* If we have a find-handle open, close it. */
155 if (dir_find_handle != INVALID_HANDLE_VALUE)
156 {
157 FindClose (dir_find_handle);
158 dir_find_handle = INVALID_HANDLE_VALUE;
159 }
160 xfree ((char *) dirp);
161 }
162
163 struct direct *
164 readdir (DIR *dirp)
165 {
166 WIN32_FIND_DATA find_data;
167
168 /* If we aren't dir_finding, do a find-first, otherwise do a find-next. */
169 if (dir_find_handle == INVALID_HANDLE_VALUE)
170 {
171 char filename[MAXNAMLEN + 3];
172 int ln;
173
174 strcpy (filename, dir_pathname);
175 ln = strlen (filename) - 1;
176 if (!IS_DIRECTORY_SEP (filename[ln]))
177 strcat (filename, "\\");
178 strcat (filename, "*");
179
180 dir_find_handle = FindFirstFile (filename, &find_data);
181
182 if (dir_find_handle == INVALID_HANDLE_VALUE)
183 return NULL;
184 }
185 else
186 {
187 if (!FindNextFile (dir_find_handle, &find_data))
188 return NULL;
189 }
190
191 /* Emacs never uses this value, so don't bother making it match
192 value returned by stat(). */
193 dir_static.d_ino = 1;
194
195 dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 +
196 dir_static.d_namlen - dir_static.d_namlen % 4;
197
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))
203 {
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);
210 }
211
212 return &dir_static;
213 }
214
215 /* Emulate getpwuid, getpwnam and others. */
216
217 #define PASSWD_FIELD_SIZE 256
218
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];
224
225 static struct passwd the_passwd =
226 {
227 the_passwd_name,
228 the_passwd_passwd,
229 0,
230 0,
231 0,
232 the_passwd_gecos,
233 the_passwd_dir,
234 the_passwd_shell,
235 };
236
237 int
238 getuid ()
239 {
240 return the_passwd.pw_uid;
241 }
242
243 int
244 geteuid ()
245 {
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 ();
250 }
251
252 int
253 getgid ()
254 {
255 return the_passwd.pw_gid;
256 }
257
258 int
259 getegid ()
260 {
261 return getgid ();
262 }
263
264 struct passwd *
265 getpwuid (int uid)
266 {
267 if (uid == the_passwd.pw_uid)
268 return &the_passwd;
269 return NULL;
270 }
271
272 struct passwd *
273 getpwnam (char *name)
274 {
275 struct passwd *pw;
276
277 pw = getpwuid (getuid ());
278 if (!pw)
279 return pw;
280
281 if (stricmp (name, pw->pw_name))
282 return NULL;
283
284 return pw;
285 }
286
287 void
288 init_user_info ()
289 {
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.
292
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). */
296
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;
301
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))
307 {
308 strcpy (the_passwd.pw_name, name);
309 /* Determine a reasonable uid value. */
310 if (stricmp ("administrator", name) == 0)
311 {
312 the_passwd.pw_uid = 0;
313 the_passwd.pw_gid = 0;
314 }
315 else
316 {
317 SID_IDENTIFIER_AUTHORITY * pSIA;
318
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;
328
329 /* Get group id */
330 if (GetTokenInformation (token, TokenPrimaryGroup,
331 (PVOID) user_sid, sizeof (user_sid), &trash))
332 {
333 SID_IDENTIFIER_AUTHORITY * pSIA;
334
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;
342 }
343 else
344 the_passwd.pw_gid = the_passwd.pw_uid;
345 }
346 }
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))
350 {
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;
357 }
358 else
359 {
360 strcpy (the_passwd.pw_name, "unknown");
361 the_passwd.pw_uid = 123;
362 the_passwd.pw_gid = 123;
363 }
364
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");
370
371 /* Set dir and shell from environment variables. */
372 strcpy (the_passwd.pw_dir, getenv ("HOME"));
373 strcpy (the_passwd.pw_shell, getenv ("SHELL"));
374
375 if (token)
376 CloseHandle (token);
377 }
378
379 int
380 random ()
381 {
382 /* rand () on NT gives us 15 random bits...hack together 30 bits. */
383 return ((rand () << 15) | rand ());
384 }
385
386 void
387 srandom (int seed)
388 {
389 srand (seed);
390 }
391
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. */
395
396 static void
397 normalize_filename (fp, path_sep)
398 register char *fp;
399 char path_sep;
400 {
401 char sep;
402 char *elem;
403
404 if (NILP (Vwin32_downcase_file_names))
405 {
406 while (*fp)
407 {
408 if (*fp == '/' || *fp == '\\')
409 *fp = path_sep;
410 fp++;
411 }
412 return;
413 }
414
415 sep = path_sep; /* convert to this path separator */
416 elem = fp; /* start of current path element */
417
418 do {
419 if (*fp >= 'a' && *fp <= 'z')
420 elem = 0; /* don't convert this element */
421
422 if (*fp == 0 || *fp == ':')
423 {
424 sep = *fp; /* restore current separator (or 0) */
425 *fp = '/'; /* after conversion of this element */
426 }
427
428 if (*fp == '/' || *fp == '\\')
429 {
430 if (elem && elem != fp)
431 {
432 *fp = 0; /* temporary end of string */
433 _strlwr (elem); /* while we convert to lower case */
434 }
435 *fp = sep; /* convert (or restore) path separator */
436 elem = fp + 1; /* next element starts after separator */
437 sep = path_sep;
438 }
439 } while (*fp++);
440 }
441
442 /* Destructively turn backslashes into slashes. */
443 void
444 dostounix_filename (p)
445 register char *p;
446 {
447 normalize_filename (p, '/');
448 }
449
450 /* Destructively turn slashes into backslashes. */
451 void
452 unixtodos_filename (p)
453 register char *p;
454 {
455 normalize_filename (p, '\\');
456 }
457
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.) */
461 int
462 crlf_to_lf (n, buf)
463 register int n;
464 register unsigned char *buf;
465 {
466 unsigned char *np = buf;
467 unsigned char *startp = buf;
468 unsigned char *endp = buf + n;
469
470 if (n == 0)
471 return n;
472 while (buf < endp - 1)
473 {
474 if (*buf == 0x0d)
475 {
476 if (*(++buf) != 0x0a)
477 *np++ = 0x0d;
478 }
479 else
480 *np++ = *buf++;
481 }
482 if (buf < endp)
483 *np++ = *buf++;
484 return np - startp;
485 }
486
487 /* Routines that are no-ops on NT but are defined to get Emacs to compile. */
488
489 int
490 sigsetmask (int signal_mask)
491 {
492 return 0;
493 }
494
495 int
496 sigblock (int sig)
497 {
498 return 0;
499 }
500
501 int
502 setpgrp (int pid, int gid)
503 {
504 return 0;
505 }
506
507 int
508 alarm (int seconds)
509 {
510 return 0;
511 }
512
513 int
514 unrequest_sigio (void)
515 {
516 return 0;
517 }
518
519 int
520 request_sigio (void)
521 {
522 return 0;
523 }
524
525 #define REG_ROOT "SOFTWARE\\GNU\\Emacs"
526
527 LPBYTE
528 nt_get_resource (key, lpdwtype)
529 char *key;
530 LPDWORD lpdwtype;
531 {
532 LPBYTE lpvalue;
533 HKEY hrootkey = NULL;
534 DWORD cbData;
535 BOOL ok = FALSE;
536
537 /* Check both the current user and the local machine to see if
538 we have any resources. */
539
540 if (RegOpenKeyEx (HKEY_CURRENT_USER, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
541 {
542 lpvalue = NULL;
543
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)
547 {
548 return (lpvalue);
549 }
550
551 if (lpvalue) xfree (lpvalue);
552
553 RegCloseKey (hrootkey);
554 }
555
556 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
557 {
558 lpvalue = NULL;
559
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)
563 {
564 return (lpvalue);
565 }
566
567 if (lpvalue) xfree (lpvalue);
568
569 RegCloseKey (hrootkey);
570 }
571
572 return (NULL);
573 }
574
575 void
576 init_environment ()
577 {
578 /* Check for environment variables and use registry if they don't exist */
579 {
580 int i;
581 LPBYTE lpval;
582 DWORD dwType;
583
584 static char * env_vars[] =
585 {
586 "HOME",
587 "emacs_dir",
588 "EMACSLOADPATH",
589 "SHELL",
590 "EMACSDATA",
591 "EMACSPATH",
592 "EMACSLOCKDIR",
593 "INFOPATH",
594 "EMACSDOC",
595 "TERM",
596 };
597
598 for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++)
599 {
600 if (!getenv (env_vars[i]) &&
601 (lpval = nt_get_resource (env_vars[i], &dwType)) != NULL)
602 {
603 if (dwType == REG_EXPAND_SZ)
604 {
605 char buf1[500], buf2[500];
606
607 ExpandEnvironmentStrings ((LPSTR) lpval, buf1, 500);
608 _snprintf (buf2, 499, "%s=%s", env_vars[i], buf1);
609 putenv (strdup (buf2));
610 }
611 else if (dwType == REG_SZ)
612 {
613 char buf[500];
614
615 _snprintf (buf, 499, "%s=%s", env_vars[i], lpval);
616 putenv (strdup (buf));
617 }
618
619 xfree (lpval);
620 }
621 }
622 }
623
624 init_user_info ();
625 }
626
627 /* We don't have scripts to automatically determine the system configuration
628 for Emacs before it's compiled, and we don't want to have to make the
629 user enter it, so we define EMACS_CONFIGURATION to invoke this runtime
630 routine. */
631
632 static char configuration_buffer[32];
633
634 char *
635 get_emacs_configuration (void)
636 {
637 char *arch, *oem, *os;
638
639 /* Determine the processor type. */
640 switch (get_processor_type ())
641 {
642
643 #ifdef PROCESSOR_INTEL_386
644 case PROCESSOR_INTEL_386:
645 case PROCESSOR_INTEL_486:
646 case PROCESSOR_INTEL_PENTIUM:
647 arch = "i386";
648 break;
649 #endif
650
651 #ifdef PROCESSOR_INTEL_860
652 case PROCESSOR_INTEL_860:
653 arch = "i860";
654 break;
655 #endif
656
657 #ifdef PROCESSOR_MIPS_R2000
658 case PROCESSOR_MIPS_R2000:
659 case PROCESSOR_MIPS_R3000:
660 case PROCESSOR_MIPS_R4000:
661 arch = "mips";
662 break;
663 #endif
664
665 #ifdef PROCESSOR_ALPHA_21064
666 case PROCESSOR_ALPHA_21064:
667 arch = "alpha";
668 break;
669 #endif
670
671 default:
672 arch = "unknown";
673 break;
674 }
675
676 /* Let oem be "*" until we figure out how to decode the OEM field. */
677 oem = "*";
678
679 os = (GetVersion () & 0x80000000) ? "win95" : "nt";
680
681 sprintf (configuration_buffer, "%s-%s-%s%d.%d", arch, oem, os,
682 get_nt_major_version (), get_nt_minor_version ());
683 return configuration_buffer;
684 }
685
686 #include <sys/timeb.h>
687
688 /* Emulate gettimeofday (Ulrich Leodolter, 1/11/95). */
689 void
690 gettimeofday (struct timeval *tv, struct timezone *tz)
691 {
692 struct _timeb tb;
693 _ftime (&tb);
694
695 tv->tv_sec = tb.time;
696 tv->tv_usec = tb.millitm * 1000L;
697 if (tz)
698 {
699 tz->tz_minuteswest = tb.timezone; /* minutes west of Greenwich */
700 tz->tz_dsttime = tb.dstflag; /* type of dst correction */
701 }
702 }
703
704 /* ------------------------------------------------------------------------- */
705 /* IO support and wrapper functions for Win32 API. */
706 /* ------------------------------------------------------------------------- */
707
708 /* Place a wrapper around the MSVC version of ctime. It returns NULL
709 on network directories, so we handle that case here.
710 (Ulrich Leodolter, 1/11/95). */
711 char *
712 sys_ctime (const time_t *t)
713 {
714 char *str = (char *) ctime (t);
715 return (str ? str : "Sun Jan 01 00:00:00 1970");
716 }
717
718 /* Emulate sleep...we could have done this with a define, but that
719 would necessitate including windows.h in the files that used it.
720 This is much easier. */
721 void
722 sys_sleep (int seconds)
723 {
724 Sleep (seconds * 1000);
725 }
726
727 /* Internal MSVC data and functions for low-level descriptor munging */
728 #if (_MSC_VER == 900)
729 extern char _osfile[];
730 #endif
731 extern int __cdecl _set_osfhnd (int fd, long h);
732 extern int __cdecl _free_osfhnd (int fd);
733
734 /* parallel array of private info on file handles */
735 filedesc fd_info [ MAXDESC ];
736
737 static struct {
738 DWORD serialnum;
739 DWORD maxcomp;
740 DWORD flags;
741 char name[32];
742 char type[32];
743 } volume_info;
744
745 /* Get information on the volume where name is held; set path pointer to
746 start of pathname in name (past UNC header\volume header if present). */
747 int
748 get_volume_info (const char * name, const char ** pPath)
749 {
750 char temp[MAX_PATH];
751 char *rootname = NULL; /* default to current volume */
752
753 if (name == NULL)
754 return FALSE;
755
756 /* find the root name of the volume if given */
757 if (isalpha (name[0]) && name[1] == ':')
758 {
759 rootname = temp;
760 temp[0] = *name++;
761 temp[1] = *name++;
762 temp[2] = '\\';
763 temp[3] = 0;
764 }
765 else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1]))
766 {
767 char *str = temp;
768 int slashes = 4;
769 rootname = temp;
770 do
771 {
772 if (IS_DIRECTORY_SEP (*name) && --slashes == 0)
773 break;
774 *str++ = *name++;
775 }
776 while ( *name );
777
778 *str++ = '\\';
779 *str = 0;
780 }
781
782 if (pPath)
783 *pPath = name;
784
785 if (GetVolumeInformation (rootname,
786 volume_info.name, 32,
787 &volume_info.serialnum,
788 &volume_info.maxcomp,
789 &volume_info.flags,
790 volume_info.type, 32))
791 {
792 return TRUE;
793 }
794 return FALSE;
795 }
796
797 /* Determine if volume is FAT format (ie. only supports short 8.3
798 names); also set path pointer to start of pathname in name. */
799 int
800 is_fat_volume (const char * name, const char ** pPath)
801 {
802 if (get_volume_info (name, pPath))
803 return (volume_info.maxcomp == 12);
804 return FALSE;
805 }
806
807 /* Map filename to a legal 8.3 name if necessary. */
808 const char *
809 map_win32_filename (const char * name, const char ** pPath)
810 {
811 static char shortname[MAX_PATH];
812 char * str = shortname;
813 char c;
814 char * path;
815
816 if (is_fat_volume (name, &path)) /* truncate to 8.3 */
817 {
818 register int left = 8; /* maximum number of chars in part */
819 register int extn = 0; /* extension added? */
820 register int dots = 2; /* maximum number of dots allowed */
821
822 while (name < path)
823 *str++ = *name++; /* skip past UNC header */
824
825 while ((c = *name++))
826 {
827 switch ( c )
828 {
829 case '\\':
830 case '/':
831 *str++ = '\\';
832 extn = 0; /* reset extension flags */
833 dots = 2; /* max 2 dots */
834 left = 8; /* max length 8 for main part */
835 break;
836 case ':':
837 *str++ = ':';
838 extn = 0; /* reset extension flags */
839 dots = 2; /* max 2 dots */
840 left = 8; /* max length 8 for main part */
841 break;
842 case '.':
843 if ( dots )
844 {
845 /* Convert path components of the form .xxx to _xxx,
846 but leave . and .. as they are. This allows .emacs
847 to be read as _emacs, for example. */
848
849 if (! *name ||
850 *name == '.' ||
851 IS_DIRECTORY_SEP (*name))
852 {
853 *str++ = '.';
854 dots--;
855 }
856 else
857 {
858 *str++ = '_';
859 left--;
860 dots = 0;
861 }
862 }
863 else if ( !extn )
864 {
865 *str++ = '.';
866 extn = 1; /* we've got an extension */
867 left = 3; /* 3 chars in extension */
868 }
869 else
870 {
871 /* any embedded dots after the first are converted to _ */
872 *str++ = '_';
873 }
874 break;
875 case '~':
876 case '#': /* don't lose these, they're important */
877 if ( ! left )
878 str[-1] = c; /* replace last character of part */
879 /* FALLTHRU */
880 default:
881 if ( left )
882 {
883 *str++ = tolower (c); /* map to lower case (looks nicer) */
884 left--;
885 dots = 0; /* started a path component */
886 }
887 break;
888 }
889 }
890 *str = '\0';
891 }
892 else
893 {
894 strcpy (shortname, name);
895 unixtodos_filename (shortname);
896 }
897
898 if (pPath)
899 *pPath = shortname + (path - name);
900
901 return shortname;
902 }
903
904
905 /* Shadow some MSVC runtime functions to map requests for long filenames
906 to reasonable short names if necessary. This was originally added to
907 permit running Emacs on NT 3.1 on a FAT partition, which doesn't support
908 long file names. */
909
910 int
911 sys_access (const char * path, int mode)
912 {
913 return _access (map_win32_filename (path, NULL), mode);
914 }
915
916 int
917 sys_chdir (const char * path)
918 {
919 return _chdir (map_win32_filename (path, NULL));
920 }
921
922 int
923 sys_chmod (const char * path, int mode)
924 {
925 return _chmod (map_win32_filename (path, NULL), mode);
926 }
927
928 int
929 sys_creat (const char * path, int mode)
930 {
931 return _creat (map_win32_filename (path, NULL), mode);
932 }
933
934 FILE *
935 sys_fopen(const char * path, const char * mode)
936 {
937 int fd;
938 int oflag;
939 const char * mode_save = mode;
940
941 /* Force all file handles to be non-inheritable. This is necessary to
942 ensure child processes don't unwittingly inherit handles that might
943 prevent future file access. */
944
945 if (mode[0] == 'r')
946 oflag = O_RDONLY;
947 else if (mode[0] == 'w' || mode[0] == 'a')
948 oflag = O_WRONLY | O_CREAT | O_TRUNC;
949 else
950 return NULL;
951
952 /* Only do simplistic option parsing. */
953 while (*++mode)
954 if (mode[0] == '+')
955 {
956 oflag &= ~(O_RDONLY | O_WRONLY);
957 oflag |= O_RDWR;
958 }
959 else if (mode[0] == 'b')
960 {
961 oflag &= ~O_TEXT;
962 oflag |= O_BINARY;
963 }
964 else if (mode[0] == 't')
965 {
966 oflag &= ~O_BINARY;
967 oflag |= O_TEXT;
968 }
969 else break;
970
971 fd = _open (map_win32_filename (path, NULL), oflag | _O_NOINHERIT, 0644);
972 if (fd < 0)
973 return NULL;
974
975 return fdopen (fd, mode_save);
976 }
977
978 int
979 sys_link (const char * path1, const char * path2)
980 {
981 errno = EINVAL;
982 return -1;
983 }
984
985 int
986 sys_mkdir (const char * path)
987 {
988 return _mkdir (map_win32_filename (path, NULL));
989 }
990
991 /* Because of long name mapping issues, we need to implement this
992 ourselves. Also, MSVC's _mktemp returns NULL when it can't generate
993 a unique name, instead of setting the input template to an empty
994 string.
995
996 Standard algorithm seems to be use pid or tid with a letter on the
997 front (in place of the 6 X's) and cycle through the letters to find a
998 unique name. We extend that to allow any reasonable character as the
999 first of the 6 X's. */
1000 char *
1001 sys_mktemp (char * template)
1002 {
1003 char * p;
1004 int i;
1005 unsigned uid = GetCurrentThreadId ();
1006 static char first_char[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#";
1007
1008 if (template == NULL)
1009 return NULL;
1010 p = template + strlen (template);
1011 i = 5;
1012 /* replace up to the last 5 X's with uid in decimal */
1013 while (--p >= template && p[0] == 'X' && --i >= 0)
1014 {
1015 p[0] = '0' + uid % 10;
1016 uid /= 10;
1017 }
1018
1019 if (i < 0 && p[0] == 'X')
1020 {
1021 i = 0;
1022 do
1023 {
1024 int save_errno = errno;
1025 p[0] = first_char[i];
1026 if (sys_access (template, 0) < 0)
1027 {
1028 errno = save_errno;
1029 return template;
1030 }
1031 }
1032 while (++i < sizeof (first_char));
1033 }
1034
1035 /* Template is badly formed or else we can't generate a unique name,
1036 so return empty string */
1037 template[0] = 0;
1038 return template;
1039 }
1040
1041 int
1042 sys_open (const char * path, int oflag, int mode)
1043 {
1044 /* Force all file handles to be non-inheritable. */
1045 return _open (map_win32_filename (path, NULL), oflag | _O_NOINHERIT, mode);
1046 }
1047
1048 int
1049 sys_rename (const char * oldname, const char * newname)
1050 {
1051 char temp[MAX_PATH];
1052
1053 /* MoveFile on Win95 doesn't correctly change the short file name
1054 alias when oldname has a three char extension and newname has the
1055 same first three chars in its extension. To avoid problems, on
1056 Win95 we rename to a temporary name first. */
1057
1058 strcpy (temp, map_win32_filename (oldname, NULL));
1059
1060 if (GetVersion () & 0x80000000)
1061 {
1062 char * p;
1063
1064 unixtodos_filename (temp);
1065 if (p = strrchr (temp, '\\'))
1066 p++;
1067 else
1068 p = temp;
1069 strcpy (p, "__XXXXXX");
1070 _mktemp (temp);
1071 if (rename (map_win32_filename (oldname, NULL), temp) < 0)
1072 return -1;
1073 }
1074
1075 /* Emulate Unix behaviour - newname is deleted if it already exists
1076 (at least if it is a file; don't do this for directories). */
1077 newname = map_win32_filename (newname, NULL);
1078 if (GetFileAttributes (newname) != -1)
1079 {
1080 _chmod (newname, 0666);
1081 _unlink (newname);
1082 }
1083
1084 return rename (temp, newname);
1085 }
1086
1087 int
1088 sys_rmdir (const char * path)
1089 {
1090 return _rmdir (map_win32_filename (path, NULL));
1091 }
1092
1093 int
1094 sys_unlink (const char * path)
1095 {
1096 return _unlink (map_win32_filename (path, NULL));
1097 }
1098
1099 static FILETIME utc_base_ft;
1100 static long double utc_base;
1101 static int init = 0;
1102
1103 static time_t
1104 convert_time (FILETIME ft)
1105 {
1106 long double ret;
1107
1108 if (!init)
1109 {
1110 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1111 SYSTEMTIME st;
1112
1113 st.wYear = 1970;
1114 st.wMonth = 1;
1115 st.wDay = 1;
1116 st.wHour = 0;
1117 st.wMinute = 0;
1118 st.wSecond = 0;
1119 st.wMilliseconds = 0;
1120
1121 SystemTimeToFileTime (&st, &utc_base_ft);
1122 utc_base = (long double) utc_base_ft.dwHighDateTime
1123 * 4096 * 1024 * 1024 + utc_base_ft.dwLowDateTime;
1124 init = 1;
1125 }
1126
1127 if (CompareFileTime (&ft, &utc_base_ft) < 0)
1128 return 0;
1129
1130 ret = (long double) ft.dwHighDateTime * 4096 * 1024 * 1024 + ft.dwLowDateTime;
1131 ret -= utc_base;
1132 return (time_t) (ret * 1e-7);
1133 }
1134
1135 #if 0
1136 /* in case we ever have need of this */
1137 void
1138 convert_from_time_t (time_t time, FILETIME * pft)
1139 {
1140 long double tmp;
1141
1142 if (!init)
1143 {
1144 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
1145 SYSTEMTIME st;
1146
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;
1154
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;
1159 }
1160
1161 /* time in 100ns units since 1-Jan-1601 */
1162 tmp = (long double) time * 1e7 + utc_base;
1163 pft->dwHighDateTime = (DWORD) (tmp / (4096.0 * 1024 * 1024));
1164 pft->dwLowDateTime = (DWORD) (tmp - pft->dwHighDateTime);
1165 }
1166 #endif
1167
1168 /* "PJW" algorithm (see the "Dragon" compiler book). */
1169 static unsigned
1170 hashval (const char * str)
1171 {
1172 unsigned h = 0;
1173 unsigned g;
1174 while (*str)
1175 {
1176 h = (h << 4) + *str++;
1177 if ((g = h & 0xf0000000) != 0)
1178 h = (h ^ (g >> 24)) & 0x0fffffff;
1179 }
1180 return h;
1181 }
1182
1183 /* Return the hash value of the canonical pathname, excluding the
1184 drive/UNC header, to get a hopefully unique inode number. */
1185 static _ino_t
1186 generate_inode_val (const char * name)
1187 {
1188 char fullname[ MAX_PATH ];
1189 char * p;
1190 unsigned hash;
1191
1192 GetFullPathName (name, sizeof (fullname), fullname, &p);
1193 get_volume_info (fullname, &p);
1194 /* Normal Win32 filesystems are still case insensitive. */
1195 _strlwr (p);
1196 hash = hashval (p);
1197 return (_ino_t) (hash ^ (hash >> 16));
1198 }
1199
1200 /* MSVC stat function can't cope with UNC names and has other bugs, so
1201 replace it with our own. This also allows us to calculate consistent
1202 inode values without hacks in the main Emacs code. */
1203 int
1204 stat (const char * path, struct stat * buf)
1205 {
1206 char * name;
1207 WIN32_FIND_DATA wfd;
1208 HANDLE fh;
1209 int permission;
1210 int len;
1211 int rootdir = FALSE;
1212
1213 if (path == NULL || buf == NULL)
1214 {
1215 errno = EFAULT;
1216 return -1;
1217 }
1218
1219 name = (char *) map_win32_filename (path, &path);
1220 /* must be valid filename, no wild cards */
1221 if (strchr (name, '*') || strchr (name, '?'))
1222 {
1223 errno = ENOENT;
1224 return -1;
1225 }
1226
1227 /* Remove trailing directory separator, unless name is the root
1228 directory of a drive or UNC volume in which case ensure there
1229 is a trailing separator. */
1230 len = strlen (name);
1231 rootdir = (path >= name + len - 1
1232 && (IS_DIRECTORY_SEP (*path) || *path == 0));
1233 name = strcpy (alloca (len + 2), name);
1234
1235 if (rootdir)
1236 {
1237 if (!IS_DIRECTORY_SEP (name[len-1]))
1238 strcat (name, "\\");
1239 if (GetDriveType (name) < 2)
1240 {
1241 errno = ENOENT;
1242 return -1;
1243 }
1244 memset (&wfd, 0, sizeof (wfd));
1245 wfd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
1246 wfd.ftCreationTime = utc_base_ft;
1247 wfd.ftLastAccessTime = utc_base_ft;
1248 wfd.ftLastWriteTime = utc_base_ft;
1249 strcpy (wfd.cFileName, name);
1250 }
1251 else
1252 {
1253 if (IS_DIRECTORY_SEP (name[len-1]))
1254 name[len - 1] = 0;
1255 fh = FindFirstFile (name, &wfd);
1256 if (fh == INVALID_HANDLE_VALUE)
1257 {
1258 errno = ENOENT;
1259 return -1;
1260 }
1261 FindClose (fh);
1262 }
1263
1264 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1265 {
1266 buf->st_mode = _S_IFDIR;
1267 buf->st_nlink = 2; /* doesn't really matter */
1268 }
1269 else
1270 {
1271 #if 0
1272 /* This is more accurate in terms of gettting the correct number
1273 of links, but is quite slow (it is noticable when Emacs is
1274 making a list of file name completions). */
1275 BY_HANDLE_FILE_INFORMATION info;
1276
1277 fh = CreateFile (name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
1278 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1279
1280 if (GetFileInformationByHandle (fh, &info))
1281 {
1282 switch (GetFileType (fh))
1283 {
1284 case FILE_TYPE_DISK:
1285 buf->st_mode = _S_IFREG;
1286 break;
1287 case FILE_TYPE_PIPE:
1288 buf->st_mode = _S_IFIFO;
1289 break;
1290 case FILE_TYPE_CHAR:
1291 case FILE_TYPE_UNKNOWN:
1292 default:
1293 buf->st_mode = _S_IFCHR;
1294 }
1295 buf->st_nlink = info.nNumberOfLinks;
1296 /* Could use file index, but this is not guaranteed to be
1297 unique unless we keep a handle open all the time. */
1298 /* buf->st_ino = info.nFileIndexLow ^ info.nFileIndexHigh; */
1299 CloseHandle (fh);
1300 }
1301 else
1302 {
1303 errno = EACCES;
1304 return -1;
1305 }
1306 #else
1307 buf->st_mode = _S_IFREG;
1308 buf->st_nlink = 1;
1309 #endif
1310 }
1311
1312 /* consider files to belong to current user */
1313 buf->st_uid = the_passwd.pw_uid;
1314 buf->st_gid = the_passwd.pw_gid;
1315
1316 /* volume_info is set indirectly by map_win32_filename */
1317 buf->st_dev = volume_info.serialnum;
1318 buf->st_rdev = volume_info.serialnum;
1319
1320 buf->st_ino = generate_inode_val (name);
1321
1322 buf->st_size = wfd.nFileSizeLow;
1323
1324 /* Convert timestamps to Unix format. */
1325 buf->st_mtime = convert_time (wfd.ftLastWriteTime);
1326 buf->st_atime = convert_time (wfd.ftLastAccessTime);
1327 if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
1328 buf->st_ctime = convert_time (wfd.ftCreationTime);
1329 if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
1330
1331 /* determine rwx permissions */
1332 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
1333 permission = _S_IREAD;
1334 else
1335 permission = _S_IREAD | _S_IWRITE;
1336
1337 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1338 permission |= _S_IEXEC;
1339 else
1340 {
1341 char * p = strrchr (name, '.');
1342 if (p != NULL &&
1343 (stricmp (p, ".exe") == 0 ||
1344 stricmp (p, ".com") == 0 ||
1345 stricmp (p, ".bat") == 0 ||
1346 stricmp (p, ".cmd") == 0))
1347 permission |= _S_IEXEC;
1348 }
1349
1350 buf->st_mode |= permission | (permission >> 3) | (permission >> 6);
1351
1352 return 0;
1353 }
1354
1355 #ifdef HAVE_SOCKETS
1356
1357 /* Wrappers for winsock functions to map between our file descriptors
1358 and winsock's handles; also set h_errno for convenience.
1359
1360 To allow Emacs to run on systems which don't have winsock support
1361 installed, we dynamically link to winsock on startup if present, and
1362 otherwise provide the minimum necessary functionality
1363 (eg. gethostname). */
1364
1365 /* function pointers for relevant socket functions */
1366 int (PASCAL *pfn_WSAStartup) (WORD wVersionRequired, LPWSADATA lpWSAData);
1367 void (PASCAL *pfn_WSASetLastError) (int iError);
1368 int (PASCAL *pfn_WSAGetLastError) (void);
1369 int (PASCAL *pfn_socket) (int af, int type, int protocol);
1370 int (PASCAL *pfn_bind) (SOCKET s, const struct sockaddr *addr, int namelen);
1371 int (PASCAL *pfn_connect) (SOCKET s, const struct sockaddr *addr, int namelen);
1372 int (PASCAL *pfn_ioctlsocket) (SOCKET s, long cmd, u_long *argp);
1373 int (PASCAL *pfn_recv) (SOCKET s, char * buf, int len, int flags);
1374 int (PASCAL *pfn_send) (SOCKET s, const char * buf, int len, int flags);
1375 int (PASCAL *pfn_closesocket) (SOCKET s);
1376 int (PASCAL *pfn_shutdown) (SOCKET s, int how);
1377 int (PASCAL *pfn_WSACleanup) (void);
1378
1379 u_short (PASCAL *pfn_htons) (u_short hostshort);
1380 u_short (PASCAL *pfn_ntohs) (u_short netshort);
1381 unsigned long (PASCAL *pfn_inet_addr) (const char * cp);
1382 int (PASCAL *pfn_gethostname) (char * name, int namelen);
1383 struct hostent * (PASCAL *pfn_gethostbyname) (const char * name);
1384 struct servent * (PASCAL *pfn_getservbyname) (const char * name, const char * proto);
1385
1386 /* SetHandleInformation is only needed to make sockets non-inheritable. */
1387 BOOL (WINAPI *pfn_SetHandleInformation) (HANDLE object, DWORD mask, DWORD flags);
1388 #ifndef HANDLE_FLAG_INHERIT
1389 #define HANDLE_FLAG_INHERIT 1
1390 #endif
1391
1392 static int have_winsock;
1393 static HANDLE winsock_lib;
1394
1395 static void
1396 term_winsock (void)
1397 {
1398 if (have_winsock)
1399 {
1400 pfn_WSACleanup ();
1401 FreeLibrary (winsock_lib);
1402 }
1403 }
1404
1405 static void
1406 init_winsock ()
1407 {
1408 WSADATA winsockData;
1409
1410 have_winsock = FALSE;
1411
1412 pfn_SetHandleInformation = NULL;
1413 pfn_SetHandleInformation
1414 = (void *) GetProcAddress (GetModuleHandle ("kernel32.dll"),
1415 "SetHandleInformation");
1416
1417 winsock_lib = LoadLibrary ("wsock32.dll");
1418
1419 if (winsock_lib != NULL)
1420 {
1421 /* dynamically link to socket functions */
1422
1423 #define LOAD_PROC(fn) \
1424 if ((pfn_##fn = (void *) GetProcAddress (winsock_lib, #fn)) == NULL) \
1425 goto fail;
1426
1427 LOAD_PROC( WSAStartup );
1428 LOAD_PROC( WSASetLastError );
1429 LOAD_PROC( WSAGetLastError );
1430 LOAD_PROC( socket );
1431 LOAD_PROC( bind );
1432 LOAD_PROC( connect );
1433 LOAD_PROC( ioctlsocket );
1434 LOAD_PROC( recv );
1435 LOAD_PROC( send );
1436 LOAD_PROC( closesocket );
1437 LOAD_PROC( shutdown );
1438 LOAD_PROC( htons );
1439 LOAD_PROC( ntohs );
1440 LOAD_PROC( inet_addr );
1441 LOAD_PROC( gethostname );
1442 LOAD_PROC( gethostbyname );
1443 LOAD_PROC( getservbyname );
1444 LOAD_PROC( WSACleanup );
1445
1446 /* specify version 1.1 of winsock */
1447 if (pfn_WSAStartup (0x101, &winsockData) == 0)
1448 {
1449 have_winsock = TRUE;
1450 return;
1451 }
1452
1453 fail:
1454 FreeLibrary (winsock_lib);
1455 }
1456 }
1457
1458
1459 int h_errno = 0;
1460
1461 /* function to set h_errno for compatability; map winsock error codes to
1462 normal system codes where they overlap (non-overlapping definitions
1463 are already in <sys/socket.h> */
1464 static void set_errno ()
1465 {
1466 if (!have_winsock)
1467 h_errno = EINVAL;
1468 else
1469 h_errno = pfn_WSAGetLastError ();
1470
1471 switch (h_errno)
1472 {
1473 case WSAEACCES: h_errno = EACCES; break;
1474 case WSAEBADF: h_errno = EBADF; break;
1475 case WSAEFAULT: h_errno = EFAULT; break;
1476 case WSAEINTR: h_errno = EINTR; break;
1477 case WSAEINVAL: h_errno = EINVAL; break;
1478 case WSAEMFILE: h_errno = EMFILE; break;
1479 case WSAENAMETOOLONG: h_errno = ENAMETOOLONG; break;
1480 case WSAENOTEMPTY: h_errno = ENOTEMPTY; break;
1481 }
1482 errno = h_errno;
1483 }
1484
1485 static void check_errno ()
1486 {
1487 if (h_errno == 0 && have_winsock)
1488 pfn_WSASetLastError (0);
1489 }
1490
1491 /* [andrewi 3-May-96] I've had conflicting results using both methods,
1492 but I believe the method of keeping the socket handle separate (and
1493 insuring it is not inheritable) is the correct one. */
1494
1495 //#define SOCK_REPLACE_HANDLE
1496
1497 #ifdef SOCK_REPLACE_HANDLE
1498 #define SOCK_HANDLE(fd) ((SOCKET) _get_osfhandle (fd))
1499 #else
1500 #define SOCK_HANDLE(fd) ((SOCKET) fd_info[fd].hnd)
1501 #endif
1502
1503 int
1504 sys_socket(int af, int type, int protocol)
1505 {
1506 int fd;
1507 long s;
1508 child_process * cp;
1509
1510 if (!have_winsock)
1511 {
1512 h_errno = ENETDOWN;
1513 return INVALID_SOCKET;
1514 }
1515
1516 check_errno ();
1517
1518 /* call the real socket function */
1519 s = (long) pfn_socket (af, type, protocol);
1520
1521 if (s != INVALID_SOCKET)
1522 {
1523 /* Although under NT 3.5 _open_osfhandle will accept a socket
1524 handle, if opened with SO_OPENTYPE == SO_SYNCHRONOUS_NONALERT,
1525 that does not work under NT 3.1. However, we can get the same
1526 effect by using a backdoor function to replace an existing
1527 descriptor handle with the one we want. */
1528
1529 /* allocate a file descriptor (with appropriate flags) */
1530 fd = _open ("NUL:", _O_RDWR);
1531 if (fd >= 0)
1532 {
1533 #ifdef SOCK_REPLACE_HANDLE
1534 /* now replace handle to NUL with our socket handle */
1535 CloseHandle ((HANDLE) _get_osfhandle (fd));
1536 _free_osfhnd (fd);
1537 _set_osfhnd (fd, s);
1538 /* setmode (fd, _O_BINARY); */
1539 #else
1540 /* Make a non-inheritable copy of the socket handle. */
1541 {
1542 HANDLE parent;
1543 HANDLE new_s = INVALID_HANDLE_VALUE;
1544
1545 parent = GetCurrentProcess ();
1546
1547 /* Apparently there is a bug in NT 3.51 with some service
1548 packs, which prevents using DuplicateHandle to make a
1549 socket handle non-inheritable (causes WSACleanup to
1550 hang). The work-around is to use SetHandleInformation
1551 instead if it is available and implemented. */
1552 if (!pfn_SetHandleInformation
1553 || !pfn_SetHandleInformation ((HANDLE) s,
1554 HANDLE_FLAG_INHERIT,
1555 HANDLE_FLAG_INHERIT))
1556 {
1557 DuplicateHandle (parent,
1558 (HANDLE) s,
1559 parent,
1560 &new_s,
1561 0,
1562 FALSE,
1563 DUPLICATE_SAME_ACCESS);
1564 pfn_closesocket (s);
1565 s = (SOCKET) new_s;
1566 }
1567 fd_info[fd].hnd = (HANDLE) s;
1568 }
1569 #endif
1570
1571 /* set our own internal flags */
1572 fd_info[fd].flags = FILE_SOCKET | FILE_BINARY | FILE_READ | FILE_WRITE;
1573
1574 cp = new_child ();
1575 if (cp)
1576 {
1577 cp->fd = fd;
1578 cp->status = STATUS_READ_ACKNOWLEDGED;
1579
1580 /* attach child_process to fd_info */
1581 if (fd_info[ fd ].cp != NULL)
1582 {
1583 DebPrint (("sys_socket: fd_info[%d] apparently in use!\n", fd));
1584 abort ();
1585 }
1586
1587 fd_info[ fd ].cp = cp;
1588
1589 /* success! */
1590 return fd;
1591 }
1592
1593 /* clean up */
1594 _close (fd);
1595 }
1596 pfn_closesocket (s);
1597 h_errno = EMFILE;
1598 }
1599 set_errno ();
1600
1601 return -1;
1602 }
1603
1604
1605 int
1606 sys_bind (int s, const struct sockaddr * addr, int namelen)
1607 {
1608 if (!have_winsock)
1609 {
1610 h_errno = ENOTSOCK;
1611 return SOCKET_ERROR;
1612 }
1613
1614 check_errno ();
1615 if (fd_info[s].flags & FILE_SOCKET)
1616 {
1617 int rc = pfn_bind (SOCK_HANDLE (s), addr, namelen);
1618 if (rc == SOCKET_ERROR)
1619 set_errno ();
1620 return rc;
1621 }
1622 h_errno = ENOTSOCK;
1623 return SOCKET_ERROR;
1624 }
1625
1626
1627 int
1628 sys_connect (int s, const struct sockaddr * name, int namelen)
1629 {
1630 if (!have_winsock)
1631 {
1632 h_errno = ENOTSOCK;
1633 return SOCKET_ERROR;
1634 }
1635
1636 check_errno ();
1637 if (fd_info[s].flags & FILE_SOCKET)
1638 {
1639 int rc = pfn_connect (SOCK_HANDLE (s), name, namelen);
1640 if (rc == SOCKET_ERROR)
1641 set_errno ();
1642 return rc;
1643 }
1644 h_errno = ENOTSOCK;
1645 return SOCKET_ERROR;
1646 }
1647
1648 u_short
1649 sys_htons (u_short hostshort)
1650 {
1651 return (have_winsock) ?
1652 pfn_htons (hostshort) : hostshort;
1653 }
1654
1655 u_short
1656 sys_ntohs (u_short netshort)
1657 {
1658 return (have_winsock) ?
1659 pfn_ntohs (netshort) : netshort;
1660 }
1661
1662 unsigned long
1663 sys_inet_addr (const char * cp)
1664 {
1665 return (have_winsock) ?
1666 pfn_inet_addr (cp) : INADDR_NONE;
1667 }
1668
1669 int
1670 sys_gethostname (char * name, int namelen)
1671 {
1672 if (have_winsock)
1673 return pfn_gethostname (name, namelen);
1674
1675 if (namelen > MAX_COMPUTERNAME_LENGTH)
1676 return !GetComputerName (name, &namelen);
1677
1678 h_errno = EFAULT;
1679 return SOCKET_ERROR;
1680 }
1681
1682 struct hostent *
1683 sys_gethostbyname(const char * name)
1684 {
1685 struct hostent * host;
1686
1687 if (!have_winsock)
1688 {
1689 h_errno = ENETDOWN;
1690 return NULL;
1691 }
1692
1693 check_errno ();
1694 host = pfn_gethostbyname (name);
1695 if (!host)
1696 set_errno ();
1697 return host;
1698 }
1699
1700 struct servent *
1701 sys_getservbyname(const char * name, const char * proto)
1702 {
1703 struct servent * serv;
1704
1705 if (!have_winsock)
1706 {
1707 h_errno = ENETDOWN;
1708 return NULL;
1709 }
1710
1711 check_errno ();
1712 serv = pfn_getservbyname (name, proto);
1713 if (!serv)
1714 set_errno ();
1715 return serv;
1716 }
1717
1718 #endif /* HAVE_SOCKETS */
1719
1720
1721 /* Shadow main io functions: we need to handle pipes and sockets more
1722 intelligently, and implement non-blocking mode as well. */
1723
1724 int
1725 sys_close (int fd)
1726 {
1727 int rc;
1728
1729 if (fd < 0 || fd >= MAXDESC)
1730 {
1731 errno = EBADF;
1732 return -1;
1733 }
1734
1735 if (fd_info[fd].cp)
1736 {
1737 child_process * cp = fd_info[fd].cp;
1738
1739 fd_info[fd].cp = NULL;
1740
1741 if (CHILD_ACTIVE (cp))
1742 {
1743 /* if last descriptor to active child_process then cleanup */
1744 int i;
1745 for (i = 0; i < MAXDESC; i++)
1746 {
1747 if (i == fd)
1748 continue;
1749 if (fd_info[i].cp == cp)
1750 break;
1751 }
1752 if (i == MAXDESC)
1753 {
1754 #if defined (HAVE_SOCKETS) && !defined (SOCK_REPLACE_HANDLE)
1755 if (fd_info[fd].flags & FILE_SOCKET)
1756 {
1757 if (!have_winsock) abort ();
1758
1759 pfn_shutdown (SOCK_HANDLE (fd), 2);
1760 rc = pfn_closesocket (SOCK_HANDLE (fd));
1761 }
1762 #endif
1763 delete_child (cp);
1764 }
1765 }
1766 }
1767
1768 /* Note that sockets do not need special treatment here (at least on
1769 NT and Win95 using the standard tcp/ip stacks) - it appears that
1770 closesocket is equivalent to CloseHandle, which is to be expected
1771 because socket handles are fully fledged kernel handles. */
1772 rc = _close (fd);
1773
1774 if (rc == 0)
1775 fd_info[fd].flags = 0;
1776
1777 return rc;
1778 }
1779
1780 int
1781 sys_dup (int fd)
1782 {
1783 int new_fd;
1784
1785 new_fd = _dup (fd);
1786 if (new_fd >= 0)
1787 {
1788 /* duplicate our internal info as well */
1789 fd_info[new_fd] = fd_info[fd];
1790 }
1791 return new_fd;
1792 }
1793
1794
1795 int
1796 sys_dup2 (int src, int dst)
1797 {
1798 int rc;
1799
1800 if (dst < 0 || dst >= MAXDESC)
1801 {
1802 errno = EBADF;
1803 return -1;
1804 }
1805
1806 /* make sure we close the destination first if it's a pipe or socket */
1807 if (src != dst && fd_info[dst].flags != 0)
1808 sys_close (dst);
1809
1810 rc = _dup2 (src, dst);
1811 if (rc == 0)
1812 {
1813 /* duplicate our internal info as well */
1814 fd_info[dst] = fd_info[src];
1815 }
1816 return rc;
1817 }
1818
1819 /* From callproc.c */
1820 extern Lisp_Object Vbinary_process_input;
1821 extern Lisp_Object Vbinary_process_output;
1822
1823 /* Unix pipe() has only one arg */
1824 int
1825 sys_pipe (int * phandles)
1826 {
1827 int rc;
1828 unsigned flags;
1829 child_process * cp;
1830
1831 /* make pipe handles non-inheritable; when we spawn a child,
1832 we replace the relevant handle with an inheritable one. */
1833 rc = _pipe (phandles, 0, _O_NOINHERIT);
1834
1835 if (rc == 0)
1836 {
1837 /* set internal flags, and put read and write handles into binary
1838 mode as necessary; if not in binary mode, set the MSVC internal
1839 FDEV (0x40) flag to prevent _read from treating ^Z as eof (this
1840 could otherwise allow Emacs to hang because it then waits
1841 indefinitely for the child process to exit, when it might not be
1842 finished). */
1843 flags = FILE_PIPE | FILE_READ;
1844 if (!NILP (Vbinary_process_output))
1845 {
1846 flags |= FILE_BINARY;
1847 setmode (phandles[0], _O_BINARY);
1848 }
1849 #if (_MSC_VER == 900)
1850 else
1851 _osfile[phandles[0]] |= 0x40;
1852 #endif
1853
1854 fd_info[phandles[0]].flags = flags;
1855
1856 flags = FILE_PIPE | FILE_WRITE;
1857 if (!NILP (Vbinary_process_input))
1858 {
1859 flags |= FILE_BINARY;
1860 setmode (phandles[1], _O_BINARY);
1861 }
1862 #if (_MSC_VER == 900)
1863 else
1864 _osfile[phandles[1]] |= 0x40;
1865 #endif
1866
1867 fd_info[phandles[1]].flags = flags;
1868 }
1869
1870 return rc;
1871 }
1872
1873 /* From ntproc.c */
1874 extern Lisp_Object Vwin32_pipe_read_delay;
1875
1876 /* Function to do blocking read of one byte, needed to implement
1877 select. It is only allowed on sockets and pipes. */
1878 int
1879 _sys_read_ahead (int fd)
1880 {
1881 child_process * cp;
1882 int rc;
1883
1884 if (fd < 0 || fd >= MAXDESC)
1885 return STATUS_READ_ERROR;
1886
1887 cp = fd_info[fd].cp;
1888
1889 if (cp == NULL || cp->fd != fd || cp->status != STATUS_READ_READY)
1890 return STATUS_READ_ERROR;
1891
1892 if ((fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET)) == 0
1893 || (fd_info[fd].flags & FILE_READ) == 0)
1894 {
1895 DebPrint (("_sys_read_ahead: internal error: fd %d is not a pipe or socket!\n", fd));
1896 abort ();
1897 }
1898
1899 cp->status = STATUS_READ_IN_PROGRESS;
1900
1901 if (fd_info[fd].flags & FILE_PIPE)
1902 {
1903 /* Use read to get CRLF translation */
1904 rc = _read (fd, &cp->chr, sizeof (char));
1905
1906 /* Give subprocess time to buffer some more output for us before
1907 reporting that input is available; we need this because Win95
1908 connects DOS programs to pipes by making the pipe appear to be
1909 the normal console stdout - as a result most DOS programs will
1910 write to stdout without buffering, ie. one character at a
1911 time. Even some Win32 programs do this - "dir" in a command
1912 shell on NT is very slow if we don't do this. */
1913 if (rc > 0)
1914 {
1915 int wait = XINT (Vwin32_pipe_read_delay);
1916
1917 if (wait > 0)
1918 Sleep (wait);
1919 else if (wait < 0)
1920 while (++wait <= 0)
1921 /* Yield remainder of our time slice, effectively giving a
1922 temporary priority boost to the child process. */
1923 Sleep (0);
1924 }
1925 }
1926 #ifdef HAVE_SOCKETS
1927 else if (fd_info[fd].flags & FILE_SOCKET)
1928 rc = pfn_recv (SOCK_HANDLE (fd), &cp->chr, sizeof (char), 0);
1929 #endif
1930
1931 if (rc == sizeof (char))
1932 cp->status = STATUS_READ_SUCCEEDED;
1933 else
1934 cp->status = STATUS_READ_FAILED;
1935
1936 return cp->status;
1937 }
1938
1939 int
1940 sys_read (int fd, char * buffer, unsigned int count)
1941 {
1942 int nchars;
1943 int extra = 0;
1944 int to_read;
1945 DWORD waiting;
1946
1947 if (fd < 0 || fd >= MAXDESC)
1948 {
1949 errno = EBADF;
1950 return -1;
1951 }
1952
1953 if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
1954 {
1955 child_process *cp = fd_info[fd].cp;
1956
1957 if ((fd_info[fd].flags & FILE_READ) == 0)
1958 {
1959 errno = EBADF;
1960 return -1;
1961 }
1962
1963 /* presence of a child_process structure means we are operating in
1964 non-blocking mode - otherwise we just call _read directly.
1965 Note that the child_process structure might be missing because
1966 reap_subprocess has been called; in this case the pipe is
1967 already broken, so calling _read on it is okay. */
1968 if (cp)
1969 {
1970 int current_status = cp->status;
1971
1972 switch (current_status)
1973 {
1974 case STATUS_READ_FAILED:
1975 case STATUS_READ_ERROR:
1976 /* report normal EOF */
1977 return 0;
1978
1979 case STATUS_READ_READY:
1980 case STATUS_READ_IN_PROGRESS:
1981 DebPrint (("sys_read called when read is in progress\n"));
1982 errno = EWOULDBLOCK;
1983 return -1;
1984
1985 case STATUS_READ_SUCCEEDED:
1986 /* consume read-ahead char */
1987 *buffer++ = cp->chr;
1988 count--;
1989 extra = 1;
1990 cp->status = STATUS_READ_ACKNOWLEDGED;
1991 ResetEvent (cp->char_avail);
1992
1993 case STATUS_READ_ACKNOWLEDGED:
1994 break;
1995
1996 default:
1997 DebPrint (("sys_read: bad status %d\n", current_status));
1998 errno = EBADF;
1999 return -1;
2000 }
2001
2002 if (fd_info[fd].flags & FILE_PIPE)
2003 {
2004 PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, &waiting, NULL);
2005 to_read = min (waiting, (DWORD) count);
2006
2007 /* Use read to get CRLF translation */
2008 nchars = _read (fd, buffer, to_read);
2009 }
2010 #ifdef HAVE_SOCKETS
2011 else /* FILE_SOCKET */
2012 {
2013 if (!have_winsock) abort ();
2014
2015 /* do the equivalent of a non-blocking read */
2016 pfn_ioctlsocket (SOCK_HANDLE (fd), FIONREAD, &waiting);
2017 if (waiting == 0 && extra == 0)
2018 {
2019 h_errno = errno = EWOULDBLOCK;
2020 return -1;
2021 }
2022
2023 nchars = 0;
2024 if (waiting)
2025 {
2026 /* always use binary mode for sockets */
2027 nchars = pfn_recv (SOCK_HANDLE (fd), buffer, count, 0);
2028 if (nchars == SOCKET_ERROR)
2029 {
2030 DebPrint(("sys_read.recv failed with error %d on socket %ld\n",
2031 pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
2032 if (extra == 0)
2033 {
2034 set_errno ();
2035 return -1;
2036 }
2037 nchars = 0;
2038 }
2039 }
2040 }
2041 #endif
2042 }
2043 else
2044 nchars = _read (fd, buffer, count);
2045 }
2046 else
2047 nchars = _read (fd, buffer, count);
2048
2049 return nchars + extra;
2050 }
2051
2052 /* For now, don't bother with a non-blocking mode */
2053 int
2054 sys_write (int fd, const void * buffer, unsigned int count)
2055 {
2056 int nchars;
2057
2058 if (fd < 0 || fd >= MAXDESC)
2059 {
2060 errno = EBADF;
2061 return -1;
2062 }
2063
2064 if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
2065 if ((fd_info[fd].flags & FILE_WRITE) == 0)
2066 {
2067 errno = EBADF;
2068 return -1;
2069 }
2070 #ifdef HAVE_SOCKETS
2071 if (fd_info[fd].flags & FILE_SOCKET)
2072 {
2073 if (!have_winsock) abort ();
2074 nchars = pfn_send (SOCK_HANDLE (fd), buffer, count, 0);
2075 if (nchars == SOCKET_ERROR)
2076 {
2077 DebPrint(("sys_read.send failed with error %d on socket %ld\n",
2078 pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
2079 set_errno ();
2080 }
2081 }
2082 else
2083 #endif
2084 nchars = _write (fd, buffer, count);
2085
2086 return nchars;
2087 }
2088
2089
2090 void
2091 term_ntproc ()
2092 {
2093 #ifdef HAVE_SOCKETS
2094 /* shutdown the socket interface if necessary */
2095 term_winsock ();
2096 #endif
2097 }
2098
2099 extern BOOL can_run_dos_process;
2100 extern BOOL dos_process_running;
2101
2102 void
2103 init_ntproc ()
2104 {
2105 #ifdef HAVE_SOCKETS
2106 /* initialise the socket interface if available */
2107 init_winsock ();
2108 #endif
2109
2110 /* Initial preparation for subprocess support: replace our standard
2111 handles with non-inheritable versions. */
2112 {
2113 HANDLE parent;
2114 HANDLE stdin_save = INVALID_HANDLE_VALUE;
2115 HANDLE stdout_save = INVALID_HANDLE_VALUE;
2116 HANDLE stderr_save = INVALID_HANDLE_VALUE;
2117
2118 parent = GetCurrentProcess ();
2119
2120 /* ignore errors when duplicating and closing; typically the
2121 handles will be invalid when running as a gui program. */
2122 DuplicateHandle (parent,
2123 GetStdHandle (STD_INPUT_HANDLE),
2124 parent,
2125 &stdin_save,
2126 0,
2127 FALSE,
2128 DUPLICATE_SAME_ACCESS);
2129
2130 DuplicateHandle (parent,
2131 GetStdHandle (STD_OUTPUT_HANDLE),
2132 parent,
2133 &stdout_save,
2134 0,
2135 FALSE,
2136 DUPLICATE_SAME_ACCESS);
2137
2138 DuplicateHandle (parent,
2139 GetStdHandle (STD_ERROR_HANDLE),
2140 parent,
2141 &stderr_save,
2142 0,
2143 FALSE,
2144 DUPLICATE_SAME_ACCESS);
2145
2146 fclose (stdin);
2147 fclose (stdout);
2148 fclose (stderr);
2149
2150 if (stdin_save != INVALID_HANDLE_VALUE)
2151 _open_osfhandle ((long) stdin_save, O_TEXT);
2152 else
2153 open ("nul", O_TEXT | O_NOINHERIT | O_RDONLY);
2154 fdopen (0, "r");
2155
2156 if (stdout_save != INVALID_HANDLE_VALUE)
2157 _open_osfhandle ((long) stdout_save, O_TEXT);
2158 else
2159 open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
2160 fdopen (1, "w");
2161
2162 if (stderr_save != INVALID_HANDLE_VALUE)
2163 _open_osfhandle ((long) stderr_save, O_TEXT);
2164 else
2165 open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
2166 fdopen (2, "w");
2167 }
2168
2169 /* Only allow Emacs to run DOS programs on Win95. */
2170 can_run_dos_process = (GetVersion () & 0x80000000);
2171 dos_process_running = FALSE;
2172
2173 /* unfortunately, atexit depends on implementation of malloc */
2174 /* atexit (term_ntproc); */
2175 signal (SIGABRT, term_ntproc);
2176 }
2177
2178 /* end of nt.c */