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