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