comparison src/nt.c @ 100:4be1180a9e89 r20-1b2

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