comparison src/nt.c @ 209:41ff10fd062f r20-4b3

Import from CVS: tag r20-4b3
author cvs
date Mon, 13 Aug 2007 10:04:58 +0200
parents 850242ba4a81
children 78478c60bfcd
comparison
equal deleted inserted replaced
208:f427b8ec4379 209:41ff10fd062f
20 20
21 21
22 Geoff Voelker (voelker@cs.washington.edu) 7-29-94 */ 22 Geoff Voelker (voelker@cs.washington.edu) 7-29-94 */
23 23
24 /* Adapted for XEmacs by David Hobley <david@spook-le0.cia.com.au> */ 24 /* Adapted for XEmacs by David Hobley <david@spook-le0.cia.com.au> */
25 25 /* Sync'ed with Emacs 19.34.6 by Marc Paquette <marcpa@cam.org> */
26
27 #include <stddef.h> /* for offsetof */
28 #include <string.h>
26 #include <stdlib.h> 29 #include <stdlib.h>
27 #include <stdio.h> 30 #include <stdio.h>
28 #include <io.h> 31 #include <io.h>
29 #include <errno.h> 32 #include <errno.h>
30 #include <fcntl.h> 33 #include <fcntl.h>
79 82
80 #include "nt.h" 83 #include "nt.h"
81 #include <sys/dir.h> 84 #include <sys/dir.h>
82 #include "ntheap.h" 85 #include "ntheap.h"
83 86
87
88 extern Lisp_Object Vwin32_downcase_file_names;
89 extern Lisp_Object Vwin32_generate_fake_inodes;
90 extern Lisp_Object Vwin32_get_true_file_attributes;
91
92 static char startup_dir[ MAXPATHLEN ];
93
84 /* Get the current working directory. */ 94 /* Get the current working directory. */
85 char * 95 char *
86 getwd (char *dir) 96 getwd (char *dir)
87 { 97 {
98 #if 0
88 if (GetCurrentDirectory (MAXPATHLEN, dir) > 0) 99 if (GetCurrentDirectory (MAXPATHLEN, dir) > 0)
89 return dir; 100 return dir;
90 return NULL; 101 return NULL;
102 #else
103 /* Emacs doesn't actually change directory itself, and we want to
104 force our real wd to be where emacs.exe is to avoid unnecessary
105 conflicts when trying to rename or delete directories. */
106 strcpy (dir, startup_dir);
107 return dir;
108 #endif
91 } 109 }
92 110
93 #ifndef HAVE_SOCKETS 111 #ifndef HAVE_SOCKETS
94 /* Emulate gethostname. */ 112 /* Emulate gethostname. */
95 int 113 int
111 for (i = 0; i < nelem; i++) 129 for (i = 0; i < nelem; i++)
112 { 130 {
113 loadavg[i] = 0.0; 131 loadavg[i] = 0.0;
114 } 132 }
115 return i; 133 return i;
116 }
117
118 /* Emulate the Unix directory procedures opendir, closedir,
119 and readdir. We can't use the procedures supplied in sysdep.c,
120 so we provide them here. */
121
122 struct direct dir_static; /* simulated directory contents */
123 static HANDLE dir_find_handle = INVALID_HANDLE_VALUE;
124 static int dir_is_fat;
125 static char dir_pathname[MAXPATHLEN+1];
126
127 extern Lisp_Object Vwin32_downcase_file_names;
128
129 DIR *
130 opendir (char *filename)
131 {
132 DIR *dirp;
133
134 /* Opening is done by FindFirstFile. However, a read is inherent to
135 this operation, so we defer the open until read time. */
136
137 if (!(dirp = (DIR *) xmalloc (sizeof (DIR))))
138 return NULL;
139 if (dir_find_handle != INVALID_HANDLE_VALUE)
140 return NULL;
141
142 dirp->dd_fd = 0;
143 dirp->dd_loc = 0;
144 dirp->dd_size = 0;
145
146 strncpy (dir_pathname, filename, MAXPATHLEN);
147 dir_pathname[MAXPATHLEN] = '\0';
148 dir_is_fat = is_fat_volume (filename, NULL);
149
150 return dirp;
151 }
152
153 void
154 closedir (DIR *dirp)
155 {
156 /* If we have a find-handle open, close it. */
157 if (dir_find_handle != INVALID_HANDLE_VALUE)
158 {
159 FindClose (dir_find_handle);
160 dir_find_handle = INVALID_HANDLE_VALUE;
161 }
162 xfree ((char *) dirp);
163 }
164
165 struct direct *
166 readdir (DIR *dirp)
167 {
168 WIN32_FIND_DATA find_data;
169
170 /* If we aren't dir_finding, do a find-first, otherwise do a find-next. */
171 if (dir_find_handle == INVALID_HANDLE_VALUE)
172 {
173 char filename[MAXNAMLEN + 3];
174 int ln;
175
176 strcpy (filename, dir_pathname);
177 ln = strlen (filename) - 1;
178 if (!IS_DIRECTORY_SEP (filename[ln]))
179 strcat (filename, "\\");
180 strcat (filename, "*");
181
182 dir_find_handle = FindFirstFile (filename, &find_data);
183
184 if (dir_find_handle == INVALID_HANDLE_VALUE)
185 return NULL;
186 }
187 else
188 {
189 if (!FindNextFile (dir_find_handle, &find_data))
190 return NULL;
191 }
192
193 /* Emacs never uses this value, so don't bother making it match
194 value returned by stat(). */
195 dir_static.d_ino = 1;
196
197 dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 +
198 dir_static.d_namlen - dir_static.d_namlen % 4;
199
200 dir_static.d_namlen = strlen (find_data.cFileName);
201 strcpy (dir_static.d_name, find_data.cFileName);
202 if (dir_is_fat)
203 _strlwr (dir_static.d_name);
204 else if (!NILP (Vwin32_downcase_file_names))
205 {
206 REGISTER char *p;
207 for (p = dir_static.d_name; *p; p++)
208 if (*p >= 'a' && *p <= 'z')
209 break;
210 if (!*p)
211 _strlwr (dir_static.d_name);
212 }
213
214 return &dir_static;
215 } 134 }
216 135
217 /* Emulate getpwuid, getpwnam and others. */ 136 /* Emulate getpwuid, getpwnam and others. */
218 137
219 #define PASSWD_FIELD_SIZE 256 138 #define PASSWD_FIELD_SIZE 256
470 389
471 /* Remove all CR's that are followed by a LF. 390 /* Remove all CR's that are followed by a LF.
472 (From msdos.c...probably should figure out a way to share it, 391 (From msdos.c...probably should figure out a way to share it,
473 although this code isn't going to ever change.) */ 392 although this code isn't going to ever change.) */
474 int 393 int
475 crlf_to_lf (n, buf) 394 crlf_to_lf (n, buf, lf_count)
476 REGISTER int n; 395 REGISTER int n;
477 REGISTER unsigned char *buf; 396 REGISTER unsigned char *buf;
397 REGISTER unsigned *lf_count;
478 { 398 {
479 unsigned char *np = buf; 399 unsigned char *np = buf;
480 unsigned char *startp = buf; 400 unsigned char *startp = buf;
481 unsigned char *endp = buf + n; 401 unsigned char *endp = buf + n;
482 402
483 if (n == 0) 403 if (n == 0)
484 return n; 404 return n;
485 while (buf < endp - 1) 405 while (buf < endp - 1)
486 { 406 {
407 if (*buf == 0x0a)
408 (*lf_count)++;
487 if (*buf == 0x0d) 409 if (*buf == 0x0d)
488 { 410 {
489 if (*(++buf) != 0x0a) 411 if (*(++buf) != 0x0a)
490 *np++ = 0x0d; 412 *np++ = 0x0d;
491 } 413 }
492 else 414 else
493 *np++ = *buf++; 415 *np++ = *buf++;
494 } 416 }
495 if (buf < endp) 417 if (buf < endp)
418 {
419 if (*buf == 0x0a)
420 (*lf_count)++;
496 *np++ = *buf++; 421 *np++ = *buf++;
422 }
497 return np - startp; 423 return np - startp;
498 } 424 }
425
426 /* Parse the root part of file name, if present. Return length and
427 optionally store pointer to char after root. */
428 static int
429 parse_root (char * name, char ** pPath)
430 {
431 char * start = name;
432
433 if (name == NULL)
434 return 0;
435
436 /* find the root name of the volume if given */
437 if (isalpha (name[0]) && name[1] == ':')
438 {
439 /* skip past drive specifier */
440 name += 2;
441 if (IS_DIRECTORY_SEP (name[0]))
442 name++;
443 }
444 else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1]))
445 {
446 int slashes = 2;
447 name += 2;
448 do
449 {
450 if (IS_DIRECTORY_SEP (*name) && --slashes == 0)
451 break;
452 name++;
453 }
454 while ( *name );
455 if (IS_DIRECTORY_SEP (name[0]))
456 name++;
457 }
458
459 if (pPath)
460 *pPath = name;
461
462 return name - start;
463 }
464
465 /* Get long base name for name; name is assumed to be absolute. */
466 static int
467 get_long_basename (char * name, char * buf, int size)
468 {
469 WIN32_FIND_DATA find_data;
470 HANDLE dir_handle;
471 int len = 0;
472 #ifdef PIGSFLY
473 char *p;
474
475 /* If the last component of NAME has a wildcard character,
476 return it as the basename. */
477 p = name + strlen (name);
478 while (*p != '\\' && *p != ':' && p > name) p--;
479 if (p > name) p++;
480 if (strchr (p, '*') || strchr (p, '?'))
481 {
482 if ((len = strlen (p)) < size)
483 memcpy (buf, p, len + 1);
484 else
485 len = 0;
486 return len;
487 }
488 #endif
489
490 dir_handle = FindFirstFile (name, &find_data);
491 if (dir_handle != INVALID_HANDLE_VALUE)
492 {
493 if ((len = strlen (find_data.cFileName)) < size)
494 memcpy (buf, find_data.cFileName, len + 1);
495 else
496 len = 0;
497 FindClose (dir_handle);
498 }
499 return len;
500 }
501
502 /* Get long name for file, if possible (assumed to be absolute). */
503 BOOL
504 win32_get_long_filename (char * name, char * buf, int size)
505 {
506 char * o = buf;
507 char * p;
508 char * q;
509 char full[ MAX_PATH ];
510 int len;
511
512 len = strlen (name);
513 if (len >= MAX_PATH)
514 return FALSE;
515
516 /* Use local copy for destructive modification. */
517 memcpy (full, name, len+1);
518 unixtodos_filename (full);
519
520 /* Copy root part verbatim. */
521 len = parse_root (full, &p);
522 memcpy (o, full, len);
523 o += len;
524 size -= len;
525
526 do
527 {
528 q = p;
529 p = strchr (q, '\\');
530 if (p) *p = '\0';
531 len = get_long_basename (full, o, size);
532 if (len > 0)
533 {
534 o += len;
535 size -= len;
536 if (p != NULL)
537 {
538 *p++ = '\\';
539 if (size < 2)
540 return FALSE;
541 *o++ = '\\';
542 size--;
543 *o = '\0';
544 }
545 }
546 else
547 return FALSE;
548 }
549 while (p != NULL && *p);
550
551 return TRUE;
552 }
553
499 554
500 /* Routines that are no-ops on NT but are defined to get Emacs to compile. */ 555 /* Routines that are no-ops on NT but are defined to get Emacs to compile. */
501 556
502 int 557 int
503 sigsetmask (int signal_mask) 558 sigsetmask (int signal_mask)
599 "HOME", 654 "HOME",
600 "PRELOAD_WINSOCK", 655 "PRELOAD_WINSOCK",
601 "emacs_dir", 656 "emacs_dir",
602 "EMACSLOADPATH", 657 "EMACSLOADPATH",
603 "SHELL", 658 "SHELL",
659 "CMDPROXY",
604 "EMACSDATA", 660 "EMACSDATA",
605 "EMACSPATH", 661 "EMACSPATH",
606 "EMACSLOCKDIR", 662 "EMACSLOCKDIR",
607 "INFOPATH", 663 /* We no longer set INFOPATH because Info-default-directory-list
664 is then ignored. We use a hook in winnt.el instead. */
665 /* "INFOPATH", */
608 "EMACSDOC", 666 "EMACSDOC",
609 "TERM", 667 "TERM",
610 }; 668 };
611 669
612 for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++) 670 for (i = 0; i < (sizeof (env_vars) / sizeof (env_vars[0])); i++)
633 xfree (lpval); 691 xfree (lpval);
634 } 692 }
635 } 693 }
636 } 694 }
637 695
696 /* Another special case: on NT, the PATH variable is actually named
697 "Path" although cmd.exe (perhaps NT itself) arranges for
698 environment variable lookup and setting to be case insensitive.
699 However, Emacs assumes a fully case sensitive environment, so we
700 need to change "Path" to "PATH" to match the expectations of
701 various elisp packages. We do this by the sneaky method of
702 modifying the string in the C runtime environ entry.
703
704 The same applies to COMSPEC. */
705 {
706 char ** envp;
707
708 for (envp = environ; *envp; envp++)
709 if (_strnicmp (*envp, "PATH=", 5) == 0)
710 memcpy (*envp, "PATH=", 5);
711 else if (_strnicmp (*envp, "COMSPEC=", 8) == 0)
712 memcpy (*envp, "COMSPEC=", 8);
713 }
714
715 /* Remember the initial working directory for getwd, then make the
716 real wd be the location of emacs.exe to avoid conflicts when
717 renaming or deleting directories. (We also don't call chdir when
718 running subprocesses for the same reason.) */
719 if (!GetCurrentDirectory (MAXPATHLEN, startup_dir))
720 abort ();
721
722 {
723 char *p;
724 char modname[MAX_PATH];
725
726 if (!GetModuleFileName (NULL, modname, MAX_PATH))
727 abort ();
728 if ((p = strrchr (modname, '\\')) == NULL)
729 abort ();
730 *p = 0;
731
732 SetCurrentDirectory (modname);
733 }
734
638 init_user_info (); 735 init_user_info ();
639 } 736 }
640 737
641 /* We don't have scripts to automatically determine the system configuration 738 /* We don't have scripts to automatically determine the system configuration
642 for Emacs before it's compiled, and we don't want to have to make the 739 for Emacs before it's compiled, and we don't want to have to make the
754 extern int __cdecl _free_osfhnd (int fd); 851 extern int __cdecl _free_osfhnd (int fd);
755 852
756 /* parallel array of private info on file handles */ 853 /* parallel array of private info on file handles */
757 filedesc fd_info [ MAXDESC ]; 854 filedesc fd_info [ MAXDESC ];
758 855
759 static struct { 856 typedef struct volume_info_data {
857 struct volume_info_data * next;
858
859 /* time when info was obtained */
860 DWORD timestamp;
861
862 /* actual volume info */
863 char * root_dir;
760 DWORD serialnum; 864 DWORD serialnum;
761 DWORD maxcomp; 865 DWORD maxcomp;
762 DWORD flags; 866 DWORD flags;
763 char name[32]; 867 char * name;
764 char type[32]; 868 char * type;
765 } volume_info; 869 } volume_info_data;
870
871 /* Global referenced by various functions. */
872 static volume_info_data volume_info;
873
874 /* Vector to indicate which drives are local and fixed (for which cached
875 data never expires). */
876 static BOOL fixed_drives[26];
877
878 /* Consider cached volume information to be stale if older than 10s,
879 at least for non-local drives. Info for fixed drives is never stale. */
880 #define DRIVE_INDEX( c ) ( (c) <= 'Z' ? (c) - 'A' : (c) - 'a' )
881 #define VOLINFO_STILL_VALID( root_dir, info ) \
882 ( ( isalpha (root_dir[0]) && \
883 fixed_drives[ DRIVE_INDEX (root_dir[0]) ] ) \
884 || GetTickCount () - info->timestamp < 10000 )
885
886 /* Cache support functions. */
887
888 /* Simple linked list with linear search is sufficient. */
889 static volume_info_data *volume_cache = NULL;
890
891 static volume_info_data *
892 lookup_volume_info (char * root_dir)
893 {
894 volume_info_data * info;
895
896 for (info = volume_cache; info; info = info->next)
897 if (stricmp (info->root_dir, root_dir) == 0)
898 break;
899 return info;
900 }
901
902 static void
903 add_volume_info (char * root_dir, volume_info_data * info)
904 {
905 info->root_dir = xstrdup (root_dir);
906 info->next = volume_cache;
907 volume_cache = info;
908 }
909
910
911 /* Wrapper for GetVolumeInformation, which uses caching to avoid
912 performance penalty (~2ms on 486 for local drives, 7.5ms for local
913 cdrom drive, ~5-10ms or more for remote drives on LAN). */
914 volume_info_data *
915 GetCachedVolumeInformation (char * root_dir)
916 {
917 volume_info_data * info;
918 char default_root[ MAX_PATH ];
919
920 /* NULL for root_dir means use root from current directory. */
921 if (root_dir == NULL)
922 {
923 if (GetCurrentDirectory (MAX_PATH, default_root) == 0)
924 return NULL;
925 parse_root (default_root, &root_dir);
926 *root_dir = 0;
927 root_dir = default_root;
928 }
929
930 /* Local fixed drives can be cached permanently. Removable drives
931 cannot be cached permanently, since the volume name and serial
932 number (if nothing else) can change. Remote drives should be
933 treated as if they are removable, since there is no sure way to
934 tell whether they are or not. Also, the UNC association of drive
935 letters mapped to remote volumes can be changed at any time (even
936 by other processes) without notice.
937
938 As a compromise, so we can benefit from caching info for remote
939 volumes, we use a simple expiry mechanism to invalidate cache
940 entries that are more than ten seconds old. */
941
942 #if 0
943 /* No point doing this, because WNetGetConnection is even slower than
944 GetVolumeInformation, consistently taking ~50ms on a 486 (FWIW,
945 GetDriveType is about the only call of this type which does not
946 involve network access, and so is extremely quick). */
947
948 /* Map drive letter to UNC if remote. */
949 if ( isalpha( root_dir[0] ) && !fixed[ DRIVE_INDEX( root_dir[0] ) ] )
950 {
951 char remote_name[ 256 ];
952 char drive[3] = { root_dir[0], ':' };
953
954 if (WNetGetConnection (drive, remote_name, sizeof (remote_name))
955 == NO_ERROR)
956 /* do something */ ;
957 }
958 #endif
959
960 info = lookup_volume_info (root_dir);
961
962 if (info == NULL || ! VOLINFO_STILL_VALID (root_dir, info))
963 {
964 char name[ 256 ];
965 DWORD serialnum;
966 DWORD maxcomp;
967 DWORD flags;
968 char type[ 256 ];
969
970 /* Info is not cached, or is stale. */
971 if (!GetVolumeInformation (root_dir,
972 name, sizeof (name),
973 &serialnum,
974 &maxcomp,
975 &flags,
976 type, sizeof (type)))
977 return NULL;
978
979 /* Cache the volume information for future use, overwriting existing
980 entry if present. */
981 if (info == NULL)
982 {
983 info = (volume_info_data *) xmalloc (sizeof (volume_info_data));
984 add_volume_info (root_dir, info);
985 }
986 else
987 {
988 free (info->name);
989 free (info->type);
990 }
991
992 info->name = xstrdup (name);
993 info->serialnum = serialnum;
994 info->maxcomp = maxcomp;
995 info->flags = flags;
996 info->type = xstrdup (type);
997 info->timestamp = GetTickCount ();
998 }
999
1000 return info;
1001 }
766 1002
767 /* Get information on the volume where name is held; set path pointer to 1003 /* Get information on the volume where name is held; set path pointer to
768 start of pathname in name (past UNC header\volume header if present). */ 1004 start of pathname in name (past UNC header\volume header if present). */
769 int 1005 int
770 get_volume_info (const char * name, const char ** pPath) 1006 get_volume_info (const char * name, const char ** pPath)
771 { 1007 {
772 char temp[MAX_PATH]; 1008 char temp[MAX_PATH];
773 char *rootname = NULL; /* default to current volume */ 1009 char *rootname = NULL; /* default to current volume */
1010 volume_info_data * info;
774 1011
775 if (name == NULL) 1012 if (name == NULL)
776 return FALSE; 1013 return FALSE;
777 1014
778 /* find the root name of the volume if given */ 1015 /* find the root name of the volume if given */
802 } 1039 }
803 1040
804 if (pPath) 1041 if (pPath)
805 *pPath = name; 1042 *pPath = name;
806 1043
807 if (GetVolumeInformation (rootname, 1044 info = GetCachedVolumeInformation (rootname);
808 volume_info.name, 32, 1045 if (info != NULL)
809 &volume_info.serialnum, 1046 {
810 &volume_info.maxcomp, 1047 /* Set global referenced by other functions. */
811 &volume_info.flags, 1048 volume_info = *info;
812 volume_info.type, 32))
813 {
814 return TRUE; 1049 return TRUE;
815 } 1050 }
816 return FALSE; 1051 return FALSE;
817 } 1052 }
818 1053
832 { 1067 {
833 static char shortname[MAX_PATH]; 1068 static char shortname[MAX_PATH];
834 char * str = shortname; 1069 char * str = shortname;
835 char c; 1070 char c;
836 char * path; 1071 char * path;
1072 const char * save_name = name;
837 1073
838 if (is_fat_volume (name, &path)) /* truncate to 8.3 */ 1074 if (is_fat_volume (name, &path)) /* truncate to 8.3 */
839 { 1075 {
840 REGISTER int left = 8; /* maximum number of chars in part */ 1076 REGISTER int left = 8; /* maximum number of chars in part */
841 REGISTER int extn = 0; /* extension added? */ 1077 REGISTER int extn = 0; /* extension added? */
916 strcpy (shortname, name); 1152 strcpy (shortname, name);
917 unixtodos_filename (shortname); 1153 unixtodos_filename (shortname);
918 } 1154 }
919 1155
920 if (pPath) 1156 if (pPath)
921 *pPath = shortname + (path - name); 1157 *pPath = shortname + (path - save_name);
922 1158
923 return shortname; 1159 return shortname;
924 } 1160 }
925 1161
1162
1163 /* Emulate the Unix directory procedures opendir, closedir,
1164 and readdir. We can't use the procedures supplied in sysdep.c,
1165 so we provide them here. */
1166
1167 struct direct dir_static; /* simulated directory contents */
1168 static HANDLE dir_find_handle = INVALID_HANDLE_VALUE;
1169 static int dir_is_fat;
1170 static char dir_pathname[MAXPATHLEN+1];
1171 static WIN32_FIND_DATA dir_find_data;
1172
1173 DIR *
1174 opendir (char *filename)
1175 {
1176 DIR *dirp;
1177
1178 /* Opening is done by FindFirstFile. However, a read is inherent to
1179 this operation, so we defer the open until read time. */
1180
1181 if (!(dirp = (DIR *) xmalloc (sizeof (DIR))))
1182 return NULL;
1183 if (dir_find_handle != INVALID_HANDLE_VALUE)
1184 return NULL;
1185
1186 dirp->dd_fd = 0;
1187 dirp->dd_loc = 0;
1188 dirp->dd_size = 0;
1189
1190 strncpy (dir_pathname, map_win32_filename (filename, NULL), MAXPATHLEN);
1191 dir_pathname[MAXPATHLEN] = '\0';
1192 dir_is_fat = is_fat_volume (filename, NULL);
1193
1194 return dirp;
1195 }
1196
1197 void
1198 closedir (DIR *dirp)
1199 {
1200 /* If we have a find-handle open, close it. */
1201 if (dir_find_handle != INVALID_HANDLE_VALUE)
1202 {
1203 FindClose (dir_find_handle);
1204 dir_find_handle = INVALID_HANDLE_VALUE;
1205 }
1206 xfree ((char *) dirp);
1207 }
1208
1209 struct direct *
1210 readdir (DIR *dirp)
1211 {
1212 /* If we aren't dir_finding, do a find-first, otherwise do a find-next. */
1213 if (dir_find_handle == INVALID_HANDLE_VALUE)
1214 {
1215 char filename[MAXNAMLEN + 3];
1216 int ln;
1217
1218 strcpy (filename, dir_pathname);
1219 ln = strlen (filename) - 1;
1220 if (!IS_DIRECTORY_SEP (filename[ln]))
1221 strcat (filename, "\\");
1222 strcat (filename, "*");
1223
1224 dir_find_handle = FindFirstFile (filename, &dir_find_data);
1225
1226 if (dir_find_handle == INVALID_HANDLE_VALUE)
1227 return NULL;
1228 }
1229 else
1230 {
1231 if (!FindNextFile (dir_find_handle, &dir_find_data))
1232 return NULL;
1233 }
1234
1235 /* Emacs never uses this value, so don't bother making it match
1236 value returned by stat(). */
1237 dir_static.d_ino = 1;
1238
1239 dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 +
1240 dir_static.d_namlen - dir_static.d_namlen % 4;
1241
1242 dir_static.d_namlen = strlen (dir_find_data.cFileName);
1243 strcpy (dir_static.d_name, dir_find_data.cFileName);
1244 if (dir_is_fat)
1245 _strlwr (dir_static.d_name);
1246 else if (!NILP (Vwin32_downcase_file_names))
1247 {
1248 REGISTER char *p;
1249 for (p = dir_static.d_name; *p; p++)
1250 if (*p >= 'a' && *p <= 'z')
1251 break;
1252 if (!*p)
1253 _strlwr (dir_static.d_name);
1254 }
1255
1256 return &dir_static;
1257 }
926 1258
927 /* Shadow some MSVC runtime functions to map requests for long filenames 1259 /* Shadow some MSVC runtime functions to map requests for long filenames
928 to reasonable short names if necessary. This was originally added to 1260 to reasonable short names if necessary. This was originally added to
929 permit running Emacs on NT 3.1 on a FAT partition, which doesn't support 1261 permit running Emacs on NT 3.1 on a FAT partition, which doesn't support
930 long file names. */ 1262 long file names. */
992 1324
993 fd = _open (map_win32_filename (path, NULL), oflag | _O_NOINHERIT, 0644); 1325 fd = _open (map_win32_filename (path, NULL), oflag | _O_NOINHERIT, 0644);
994 if (fd < 0) 1326 if (fd < 0)
995 return NULL; 1327 return NULL;
996 1328
997 return fdopen (fd, mode_save); 1329 return _fdopen (fd, mode_save);
998 } 1330 }
999 1331
1332 /* This only works on NTFS volumes, but is useful to have. */
1000 int 1333 int
1001 sys_link (const char * path1, const char * path2) 1334 sys_link (const char * old, const char * new)
1002 { 1335 {
1003 errno = EINVAL; 1336 HANDLE fileh;
1337 int result = -1;
1338 char oldname[MAX_PATH], newname[MAX_PATH];
1339
1340 if (old == NULL || new == NULL)
1341 {
1342 errno = ENOENT;
1004 return -1; 1343 return -1;
1344 }
1345
1346 strcpy (oldname, map_win32_filename (old, NULL));
1347 strcpy (newname, map_win32_filename (new, NULL));
1348
1349 fileh = CreateFile (oldname, 0, 0, NULL, OPEN_EXISTING,
1350 FILE_FLAG_BACKUP_SEMANTICS, NULL);
1351 if (fileh != INVALID_HANDLE_VALUE)
1352 {
1353 int wlen;
1354
1355 /* Confusingly, the "alternate" stream name field does not apply
1356 when restoring a hard link, and instead contains the actual
1357 stream data for the link (ie. the name of the link to create).
1358 The WIN32_STREAM_ID structure before the cStreamName field is
1359 the stream header, which is then immediately followed by the
1360 stream data. */
1361
1362 struct {
1363 WIN32_STREAM_ID wid;
1364 WCHAR wbuffer[MAX_PATH]; /* extra space for link name */
1365 } data;
1366
1367 wlen = MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, newname, -1,
1368 data.wid.cStreamName, MAX_PATH);
1369 if (wlen > 0)
1370 {
1371 LPVOID context = NULL;
1372 DWORD wbytes = 0;
1373
1374 data.wid.dwStreamId = BACKUP_LINK;
1375 data.wid.dwStreamAttributes = 0;
1376 data.wid.Size.LowPart = wlen * sizeof(WCHAR);
1377 data.wid.Size.HighPart = 0;
1378 data.wid.dwStreamNameSize = 0;
1379
1380 if (BackupWrite (fileh, (LPBYTE)&data,
1381 offsetof (WIN32_STREAM_ID, cStreamName)
1382 + data.wid.Size.LowPart,
1383 &wbytes, FALSE, FALSE, &context)
1384 && BackupWrite (fileh, NULL, 0, &wbytes, TRUE, FALSE, &context))
1385 {
1386 /* succeeded */
1387 result = 0;
1388 }
1389 else
1390 {
1391 /* Should try mapping GetLastError to errno; for now just
1392 indicate a general error (eg. links not supported). */
1393 errno = EINVAL; // perhaps EMLINK?
1394 }
1395 }
1396
1397 CloseHandle (fileh);
1398 }
1399 else
1400 errno = ENOENT;
1401
1402 return result;
1005 } 1403 }
1006 1404
1007 int 1405 int
1008 sys_mkdir (const char * path) 1406 sys_mkdir (const char * path)
1009 { 1407 {
1094 1492
1095 if (p = strrchr (temp, '\\')) 1493 if (p = strrchr (temp, '\\'))
1096 p++; 1494 p++;
1097 else 1495 else
1098 p = temp; 1496 p = temp;
1099 strcpy (p, "__XXXXXX");
1100 sys_mktemp (temp);
1101 /* Force temp name to require a manufactured 8.3 alias - this 1497 /* Force temp name to require a manufactured 8.3 alias - this
1102 seems to make the second rename work properly. */ 1498 seems to make the second rename work properly. */
1103 strcat (temp, ".long"); 1499 strcpy (p, "_rename_temp.XXXXXX");
1500 sys_mktemp (temp);
1104 if (rename (map_win32_filename (oldname, NULL), temp) < 0) 1501 if (rename (map_win32_filename (oldname, NULL), temp) < 0)
1105 return -1; 1502 return -1;
1106 } 1503 }
1107 1504
1108 /* Emulate Unix behaviour - newname is deleted if it already exists 1505 /* Emulate Unix behaviour - newname is deleted if it already exists
1109 (at least if it is a file; don't do this for directories). 1506 (at least if it is a file; don't do this for directories).
1110 However, don't do this if we are just changing the case of the file 1507 However, don't do this if we are just changing the case of the file
1111 name - we will end up deleting the file we are trying to rename! */ 1508 name - we will end up deleting the file we are trying to rename! */
1112 newname = map_win32_filename (newname, NULL); 1509 newname = map_win32_filename (newname, NULL);
1510
1511 /* TODO: Use GetInformationByHandle (on NT) to ensure newname and temp
1512 do not refer to the same file, eg. through share aliases. */
1113 if (stricmp (newname, temp) != 0 1513 if (stricmp (newname, temp) != 0
1114 && (attr = GetFileAttributes (newname)) != -1 1514 && (attr = GetFileAttributes (newname)) != -1
1115 && (attr & FILE_ATTRIBUTE_DIRECTORY) == 0) 1515 && (attr & FILE_ATTRIBUTE_DIRECTORY) == 0)
1116 { 1516 {
1117 _chmod (newname, 0666); 1517 _chmod (newname, 0666);
1200 pft->dwHighDateTime = (DWORD) (tmp / (4096.0 * 1024 * 1024)); 1600 pft->dwHighDateTime = (DWORD) (tmp / (4096.0 * 1024 * 1024));
1201 pft->dwLowDateTime = (DWORD) (tmp - pft->dwHighDateTime); 1601 pft->dwLowDateTime = (DWORD) (tmp - pft->dwHighDateTime);
1202 } 1602 }
1203 #endif 1603 #endif
1204 1604
1205 /* "PJW" algorithm (see the "Dragon" compiler book). */ 1605 #if 0
1606 /* No reason to keep this; faking inode values either by hashing or even
1607 using the file index from GetInformationByHandle, is not perfect and
1608 so by default Emacs doesn't use the inode values on Windows.
1609 Instead, we now determine file-truename correctly (except for
1610 possible drive aliasing etc). */
1611
1612 /* Modified version of "PJW" algorithm (see the "Dragon" compiler book). */
1206 static unsigned 1613 static unsigned
1207 hashval (const char * str) 1614 hashval (const unsigned char * str)
1208 { 1615 {
1209 unsigned h = 0; 1616 unsigned h = 0;
1210 unsigned g;
1211 while (*str) 1617 while (*str)
1212 { 1618 {
1213 h = (h << 4) + *str++; 1619 h = (h << 4) + *str++;
1214 if ((g = h & 0xf0000000) != 0) 1620 h ^= (h >> 28);
1215 h = (h ^ (g >> 24)) & 0x0fffffff;
1216 } 1621 }
1217 return h; 1622 return h;
1218 } 1623 }
1219 1624
1220 /* Return the hash value of the canonical pathname, excluding the 1625 /* Return the hash value of the canonical pathname, excluding the
1221 drive/UNC header, to get a hopefully unique inode number. */ 1626 drive/UNC header, to get a hopefully unique inode number. */
1222 static _ino_t 1627 static DWORD
1223 generate_inode_val (const char * name) 1628 generate_inode_val (const char * name)
1224 { 1629 {
1225 char fullname[ MAX_PATH ]; 1630 char fullname[ MAX_PATH ];
1226 char * p; 1631 char * p;
1227 unsigned hash; 1632 unsigned hash;
1228 1633
1229 GetFullPathName (name, sizeof (fullname), fullname, &p); 1634 /* Get the truly canonical filename, if it exists. (Note: this
1230 get_volume_info (fullname, &p); 1635 doesn't resolve aliasing due to subst commands, or recognise hard
1636 links. */
1637 if (!win32_get_long_filename ((char *)name, fullname, MAX_PATH))
1638 abort ();
1639
1640 parse_root (fullname, &p);
1231 /* Normal Win32 filesystems are still case insensitive. */ 1641 /* Normal Win32 filesystems are still case insensitive. */
1232 _strlwr (p); 1642 _strlwr (p);
1233 hash = hashval (p); 1643 return hashval (p);
1234 return (_ino_t) (hash ^ (hash >> 16)); 1644 }
1235 } 1645
1646 #endif
1236 1647
1237 /* MSVC stat function can't cope with UNC names and has other bugs, so 1648 /* MSVC stat function can't cope with UNC names and has other bugs, so
1238 replace it with our own. This also allows us to calculate consistent 1649 replace it with our own. This also allows us to calculate consistent
1239 inode values without hacks in the main Emacs code. */ 1650 inode values without hacks in the main Emacs code. */
1240 int 1651 int
1241 stat (const char * path, struct stat * buf) 1652 stat (const char * path, struct stat * buf)
1242 { 1653 {
1243 char * name; 1654 char * name;
1244 WIN32_FIND_DATA wfd; 1655 WIN32_FIND_DATA wfd;
1245 HANDLE fh; 1656 HANDLE fh;
1657 DWORD fake_inode;
1246 int permission; 1658 int permission;
1247 int len; 1659 int len;
1248 int rootdir = FALSE; 1660 int rootdir = FALSE;
1249 1661
1250 if (path == NULL || buf == NULL) 1662 if (path == NULL || buf == NULL)
1287 } 1699 }
1288 else 1700 else
1289 { 1701 {
1290 if (IS_DIRECTORY_SEP (name[len-1])) 1702 if (IS_DIRECTORY_SEP (name[len-1]))
1291 name[len - 1] = 0; 1703 name[len - 1] = 0;
1704
1705 /* (This is hacky, but helps when doing file completions on
1706 network drives.) Optimize by using information available from
1707 active readdir if possible. */
1708 if (dir_find_handle != INVALID_HANDLE_VALUE &&
1709 (len = strlen (dir_pathname)),
1710 strnicmp (name, dir_pathname, len) == 0 &&
1711 IS_DIRECTORY_SEP (name[len]) &&
1712 stricmp (name + len + 1, dir_static.d_name) == 0)
1713 {
1714 /* This was the last entry returned by readdir. */
1715 wfd = dir_find_data;
1716 }
1717 else
1718 {
1292 fh = FindFirstFile (name, &wfd); 1719 fh = FindFirstFile (name, &wfd);
1293 if (fh == INVALID_HANDLE_VALUE) 1720 if (fh == INVALID_HANDLE_VALUE)
1294 { 1721 {
1295 errno = ENOENT; 1722 errno = ENOENT;
1296 return -1; 1723 return -1;
1297 } 1724 }
1298 FindClose (fh); 1725 FindClose (fh);
1299 } 1726 }
1727 }
1300 1728
1301 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 1729 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1302 { 1730 {
1303 buf->st_mode = _S_IFDIR; 1731 buf->st_mode = _S_IFDIR;
1304 buf->st_nlink = 2; /* doesn't really matter */ 1732 buf->st_nlink = 2; /* doesn't really matter */
1305 } 1733 fake_inode = 0; /* this doesn't either I think */
1306 else 1734 }
1307 { 1735 else if (!NILP (Vwin32_get_true_file_attributes))
1308 #if 0 1736 {
1309 /* This is more accurate in terms of gettting the correct number 1737 /* This is more accurate in terms of gettting the correct number
1310 of links, but is quite slow (it is noticable when Emacs is 1738 of links, but is quite slow (it is noticable when Emacs is
1311 making a list of file name completions). */ 1739 making a list of file name completions). */
1312 BY_HANDLE_FILE_INFORMATION info; 1740 BY_HANDLE_FILE_INFORMATION info;
1313 1741
1314 fh = CreateFile (name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 1742 /* No access rights required to get info. */
1315 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 1743 fh = CreateFile (name, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
1316 1744
1317 if (GetFileInformationByHandle (fh, &info)) 1745 if (GetFileInformationByHandle (fh, &info))
1318 { 1746 {
1319 switch (GetFileType (fh)) 1747 switch (GetFileType (fh))
1320 { 1748 {
1328 case FILE_TYPE_UNKNOWN: 1756 case FILE_TYPE_UNKNOWN:
1329 default: 1757 default:
1330 buf->st_mode = _S_IFCHR; 1758 buf->st_mode = _S_IFCHR;
1331 } 1759 }
1332 buf->st_nlink = info.nNumberOfLinks; 1760 buf->st_nlink = info.nNumberOfLinks;
1333 /* Could use file index, but this is not guaranteed to be 1761 /* Might as well use file index to fake inode values, but this
1334 unique unless we keep a handle open all the time. */ 1762 is not guaranteed to be unique unless we keep a handle open
1335 /* buf->st_ino = info.nFileIndexLow ^ info.nFileIndexHigh; */ 1763 all the time (even then there are situations where it is
1764 not unique). Reputedly, there are at most 48 bits of info
1765 (on NTFS, presumably less on FAT). */
1766 fake_inode = info.nFileIndexLow ^ info.nFileIndexHigh;
1336 CloseHandle (fh); 1767 CloseHandle (fh);
1337 } 1768 }
1338 else 1769 else
1339 { 1770 {
1340 errno = EACCES; 1771 errno = EACCES;
1341 return -1; 1772 return -1;
1342 } 1773 }
1343 #else 1774 }
1775 else
1776 {
1777 /* Don't bother to make this information more accurate. */
1344 buf->st_mode = _S_IFREG; 1778 buf->st_mode = _S_IFREG;
1345 buf->st_nlink = 1; 1779 buf->st_nlink = 1;
1780 fake_inode = 0;
1781 }
1782
1783 #if 0
1784 /* Not sure if there is any point in this. */
1785 if (!NILP (Vwin32_generate_fake_inodes))
1786 fake_inode = generate_inode_val (name);
1787 else if (fake_inode == 0)
1788 {
1789 /* For want of something better, try to make everything unique. */
1790 static DWORD gen_num = 0;
1791 fake_inode = ++gen_num;
1792 }
1346 #endif 1793 #endif
1347 } 1794
1795 /* MSVC defines _ino_t to be short; other libc's might not. */
1796 if (sizeof (buf->st_ino) == 2)
1797 buf->st_ino = fake_inode ^ (fake_inode >> 16);
1798 else
1799 buf->st_ino = fake_inode;
1348 1800
1349 /* consider files to belong to current user */ 1801 /* consider files to belong to current user */
1350 buf->st_uid = the_passwd.pw_uid; 1802 buf->st_uid = the_passwd.pw_uid;
1351 buf->st_gid = the_passwd.pw_gid; 1803 buf->st_gid = the_passwd.pw_gid;
1352 1804
1353 /* volume_info is set indirectly by map_win32_filename */ 1805 /* volume_info is set indirectly by map_win32_filename */
1354 buf->st_dev = volume_info.serialnum; 1806 buf->st_dev = volume_info.serialnum;
1355 buf->st_rdev = volume_info.serialnum; 1807 buf->st_rdev = volume_info.serialnum;
1356 1808
1357 buf->st_ino = generate_inode_val (name);
1358 1809
1359 buf->st_size = wfd.nFileSizeLow; 1810 buf->st_size = wfd.nFileSizeLow;
1360 1811
1361 /* Convert timestamps to Unix format. */ 1812 /* Convert timestamps to Unix format. */
1362 buf->st_mtime = convert_time (wfd.ftLastWriteTime); 1813 buf->st_mtime = convert_time (wfd.ftLastWriteTime);
1897 { 2348 {
1898 int rc; 2349 int rc;
1899 unsigned flags; 2350 unsigned flags;
1900 child_process * cp; 2351 child_process * cp;
1901 2352
1902 /* make pipe handles non-inheritable; when we spawn a child, 2353 /* make pipe handles non-inheritable; when we spawn a child, we
1903 we replace the relevant handle with an inheritable one. */ 2354 replace the relevant handle with an inheritable one. Also put
1904 rc = _pipe (phandles, 0, _O_NOINHERIT); 2355 pipes into binary mode; we will do text mode translation ourselves
2356 if required. */
2357 rc = _pipe (phandles, 0, _O_NOINHERIT | _O_BINARY);
1905 2358
1906 if (rc == 0) 2359 if (rc == 0)
1907 { 2360 {
1908 /* set internal flags, and put read and write handles into binary
1909 mode as necessary; if not in binary mode, set the MSVC internal
1910 FDEV (0x40) flag to prevent _read from treating ^Z as eof (this
1911 could otherwise allow Emacs to hang because it then waits
1912 indefinitely for the child process to exit, when it might not be
1913 finished). */
1914 flags = FILE_PIPE | FILE_READ; 2361 flags = FILE_PIPE | FILE_READ;
1915 if (!NILP (Vbinary_process_output)) 2362 if (!NILP (Vbinary_process_output))
1916 {
1917 flags |= FILE_BINARY; 2363 flags |= FILE_BINARY;
1918 setmode (phandles[0], _O_BINARY);
1919 }
1920 #if (_MSC_VER == 900)
1921 else
1922 _osfile[phandles[0]] |= 0x40;
1923 #endif
1924
1925 fd_info[phandles[0]].flags = flags; 2364 fd_info[phandles[0]].flags = flags;
1926 2365
1927 flags = FILE_PIPE | FILE_WRITE; 2366 flags = FILE_PIPE | FILE_WRITE;
1928 if (!NILP (Vbinary_process_input)) 2367 if (!NILP (Vbinary_process_input))
1929 {
1930 flags |= FILE_BINARY; 2368 flags |= FILE_BINARY;
1931 setmode (phandles[1], _O_BINARY);
1932 }
1933 #if (_MSC_VER == 900)
1934 else
1935 _osfile[phandles[1]] |= 0x40;
1936 #endif
1937
1938 fd_info[phandles[1]].flags = flags; 2369 fd_info[phandles[1]].flags = flags;
1939 } 2370 }
1940 2371
1941 return rc; 2372 return rc;
1942 } 2373 }
1969 2400
1970 cp->status = STATUS_READ_IN_PROGRESS; 2401 cp->status = STATUS_READ_IN_PROGRESS;
1971 2402
1972 if (fd_info[fd].flags & FILE_PIPE) 2403 if (fd_info[fd].flags & FILE_PIPE)
1973 { 2404 {
1974 /* Use read to get CRLF translation */
1975 rc = _read (fd, &cp->chr, sizeof (char)); 2405 rc = _read (fd, &cp->chr, sizeof (char));
1976 2406
1977 /* Give subprocess time to buffer some more output for us before 2407 /* Give subprocess time to buffer some more output for us before
1978 reporting that input is available; we need this because Win95 2408 reporting that input is available; we need this because Win95
1979 connects DOS programs to pipes by making the pipe appear to be 2409 connects DOS programs to pipes by making the pipe appear to be
2009 2439
2010 int 2440 int
2011 sys_read (int fd, char * buffer, unsigned int count) 2441 sys_read (int fd, char * buffer, unsigned int count)
2012 { 2442 {
2013 int nchars; 2443 int nchars;
2014 int extra = 0;
2015 int to_read; 2444 int to_read;
2016 DWORD waiting; 2445 DWORD waiting;
2446 char * orig_buffer = buffer;
2017 2447
2018 if (fd < 0 || fd >= MAXDESC) 2448 if (fd < 0 || fd >= MAXDESC)
2019 { 2449 {
2020 errno = EBADF; 2450 errno = EBADF;
2021 return -1; 2451 return -1;
2027 2457
2028 if ((fd_info[fd].flags & FILE_READ) == 0) 2458 if ((fd_info[fd].flags & FILE_READ) == 0)
2029 { 2459 {
2030 errno = EBADF; 2460 errno = EBADF;
2031 return -1; 2461 return -1;
2462 }
2463
2464 nchars = 0;
2465
2466 /* re-read CR carried over from last read */
2467 if (fd_info[fd].flags & FILE_LAST_CR)
2468 {
2469 if (fd_info[fd].flags & FILE_BINARY) abort ();
2470 *buffer++ = 0x0d;
2471 count--;
2472 nchars++;
2473 fd_info[fd].flags &= ~FILE_LAST_CR;
2032 } 2474 }
2033 2475
2034 /* presence of a child_process structure means we are operating in 2476 /* presence of a child_process structure means we are operating in
2035 non-blocking mode - otherwise we just call _read directly. 2477 non-blocking mode - otherwise we just call _read directly.
2036 Note that the child_process structure might be missing because 2478 Note that the child_process structure might be missing because
2042 2484
2043 switch (current_status) 2485 switch (current_status)
2044 { 2486 {
2045 case STATUS_READ_FAILED: 2487 case STATUS_READ_FAILED:
2046 case STATUS_READ_ERROR: 2488 case STATUS_READ_ERROR:
2047 /* report normal EOF */ 2489 /* report normal EOF if nothing in buffer */
2048 return 0; 2490 if (nchars <= 0)
2491 fd_info[fd].flags |= FILE_AT_EOF;
2492 return nchars;
2049 2493
2050 case STATUS_READ_READY: 2494 case STATUS_READ_READY:
2051 case STATUS_READ_IN_PROGRESS: 2495 case STATUS_READ_IN_PROGRESS:
2052 DebPrint (("sys_read called when read is in progress\n")); 2496 DebPrint (("sys_read called when read is in progress\n"));
2053 errno = EWOULDBLOCK; 2497 errno = EWOULDBLOCK;
2055 2499
2056 case STATUS_READ_SUCCEEDED: 2500 case STATUS_READ_SUCCEEDED:
2057 /* consume read-ahead char */ 2501 /* consume read-ahead char */
2058 *buffer++ = cp->chr; 2502 *buffer++ = cp->chr;
2059 count--; 2503 count--;
2060 extra = 1; 2504 nchars++;
2061 cp->status = STATUS_READ_ACKNOWLEDGED; 2505 cp->status = STATUS_READ_ACKNOWLEDGED;
2062 ResetEvent (cp->char_avail); 2506 ResetEvent (cp->char_avail);
2063 2507
2064 case STATUS_READ_ACKNOWLEDGED: 2508 case STATUS_READ_ACKNOWLEDGED:
2065 break; 2509 break;
2073 if (fd_info[fd].flags & FILE_PIPE) 2517 if (fd_info[fd].flags & FILE_PIPE)
2074 { 2518 {
2075 PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, &waiting, NULL); 2519 PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, &waiting, NULL);
2076 to_read = min (waiting, (DWORD) count); 2520 to_read = min (waiting, (DWORD) count);
2077 2521
2078 /* Use read to get CRLF translation */ 2522 if (to_read > 0)
2079 nchars = _read (fd, buffer, to_read); 2523 nchars += _read (fd, buffer, to_read);
2080 } 2524 }
2081 #ifdef HAVE_SOCKETS 2525 #ifdef HAVE_SOCKETS
2082 else /* FILE_SOCKET */ 2526 else /* FILE_SOCKET */
2083 { 2527 {
2084 if (winsock_lib == NULL) abort (); 2528 if (winsock_lib == NULL) abort ();
2085 2529
2086 /* do the equivalent of a non-blocking read */ 2530 /* do the equivalent of a non-blocking read */
2087 pfn_ioctlsocket (SOCK_HANDLE (fd), FIONREAD, &waiting); 2531 pfn_ioctlsocket (SOCK_HANDLE (fd), FIONREAD, &waiting);
2088 if (waiting == 0 && extra == 0) 2532 if (waiting == 0 && nchars == 0)
2089 { 2533 {
2090 h_errno = errno = EWOULDBLOCK; 2534 h_errno = errno = EWOULDBLOCK;
2091 return -1; 2535 return -1;
2092 } 2536 }
2093 2537
2094 nchars = 0;
2095 if (waiting) 2538 if (waiting)
2096 { 2539 {
2097 /* always use binary mode for sockets */ 2540 /* always use binary mode for sockets */
2098 nchars = pfn_recv (SOCK_HANDLE (fd), buffer, count, 0); 2541 int res = pfn_recv (SOCK_HANDLE (fd), buffer, count, 0);
2099 if (nchars == SOCKET_ERROR) 2542 if (res == SOCKET_ERROR)
2100 { 2543 {
2101 DebPrint(("sys_read.recv failed with error %d on socket %ld\n", 2544 DebPrint(("sys_read.recv failed with error %d on socket %ld\n",
2102 pfn_WSAGetLastError (), SOCK_HANDLE (fd))); 2545 pfn_WSAGetLastError (), SOCK_HANDLE (fd)));
2103 if (extra == 0)
2104 {
2105 set_errno (); 2546 set_errno ();
2106 return -1; 2547 return -1;
2107 } 2548 }
2108 nchars = 0; 2549 nchars += res;
2109 }
2110 } 2550 }
2111 } 2551 }
2112 #endif 2552 #endif
2113 } 2553 }
2114 else 2554 else
2115 nchars = _read (fd, buffer, count); 2555 {
2556 int nread = _read (fd, buffer, count);
2557 if (nread >= 0)
2558 nchars += nread;
2559 else if (nchars == 0)
2560 nchars = nread;
2561 }
2562
2563 if (nchars <= 0)
2564 fd_info[fd].flags |= FILE_AT_EOF;
2565 /* Perform text mode translation if required. */
2566 else if ((fd_info[fd].flags & FILE_BINARY) == 0)
2567 {
2568 unsigned lf_count = 0;
2569 nchars = crlf_to_lf (nchars, orig_buffer, &lf_count);
2570 /* If buffer contains only CR, return that. To be absolutely
2571 sure we should attempt to read the next char, but in
2572 practice a CR to be followed by LF would not appear by
2573 itself in the buffer. */
2574 if (nchars > 1 && orig_buffer[nchars - 1] == 0x0d)
2575 {
2576 fd_info[fd].flags |= FILE_LAST_CR;
2577 nchars--;
2578 }
2579 }
2116 } 2580 }
2117 else 2581 else
2118 nchars = _read (fd, buffer, count); 2582 nchars = _read (fd, buffer, count);
2119 2583
2120 return nchars + extra; 2584 return nchars;
2121 } 2585 }
2122 2586
2123 /* For now, don't bother with a non-blocking mode */ 2587 /* For now, don't bother with a non-blocking mode */
2124 int 2588 int
2125 sys_write (int fd, const void * buffer, unsigned int count) 2589 sys_write (int fd, const void * buffer, unsigned int count)
2131 errno = EBADF; 2595 errno = EBADF;
2132 return -1; 2596 return -1;
2133 } 2597 }
2134 2598
2135 if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET)) 2599 if (fd_info[fd].flags & (FILE_PIPE | FILE_SOCKET))
2600 {
2136 if ((fd_info[fd].flags & FILE_WRITE) == 0) 2601 if ((fd_info[fd].flags & FILE_WRITE) == 0)
2137 { 2602 {
2138 errno = EBADF; 2603 errno = EBADF;
2139 return -1; 2604 return -1;
2140 } 2605 }
2606
2607 /* Perform text mode translation if required. */
2608 if ((fd_info[fd].flags & FILE_BINARY) == 0)
2609 {
2610 char * tmpbuf = alloca (count * 2);
2611 unsigned char * src = (void *)buffer;
2612 unsigned char * dst = tmpbuf;
2613 int nbytes = count;
2614
2615 while (1)
2616 {
2617 unsigned char *next;
2618 /* copy next line or remaining bytes */
2619 next = _memccpy (dst, src, '\n', nbytes);
2620 if (next)
2621 {
2622 /* copied one line ending with '\n' */
2623 int copied = next - dst;
2624 nbytes -= copied;
2625 src += copied;
2626 /* insert '\r' before '\n' */
2627 next[-1] = '\r';
2628 next[0] = '\n';
2629 dst = next + 1;
2630 count++;
2631 }
2632 else
2633 /* copied remaining partial line -> now finished */
2634 break;
2635 }
2636 buffer = tmpbuf;
2637 }
2638 }
2639
2141 #ifdef HAVE_SOCKETS 2640 #ifdef HAVE_SOCKETS
2142 if (fd_info[fd].flags & FILE_SOCKET) 2641 if (fd_info[fd].flags & FILE_SOCKET)
2143 { 2642 {
2144 if (winsock_lib == NULL) abort (); 2643 if (winsock_lib == NULL) abort ();
2145 nchars = pfn_send (SOCK_HANDLE (fd), buffer, count, 0); 2644 nchars = pfn_send (SOCK_HANDLE (fd), buffer, count, 0);
2164 #ifdef HAVE_SOCKETS 2663 #ifdef HAVE_SOCKETS
2165 /* shutdown the socket interface if necessary */ 2664 /* shutdown the socket interface if necessary */
2166 term_winsock (); 2665 term_winsock ();
2167 #endif 2666 #endif
2168 } 2667 }
2169
2170 extern BOOL dos_process_running;
2171 2668
2172 void 2669 void
2173 init_ntproc () 2670 init_ntproc ()
2174 { 2671 {
2175 #ifdef HAVE_SOCKETS 2672 #ifdef HAVE_SOCKETS
2230 2727
2231 if (stdin_save != INVALID_HANDLE_VALUE) 2728 if (stdin_save != INVALID_HANDLE_VALUE)
2232 _open_osfhandle ((long) stdin_save, O_TEXT); 2729 _open_osfhandle ((long) stdin_save, O_TEXT);
2233 else 2730 else
2234 _open ("nul", O_TEXT | O_NOINHERIT | O_RDONLY); 2731 _open ("nul", O_TEXT | O_NOINHERIT | O_RDONLY);
2235 fdopen (0, "r"); 2732 _fdopen (0, "r");
2236 2733
2237 if (stdout_save != INVALID_HANDLE_VALUE) 2734 if (stdout_save != INVALID_HANDLE_VALUE)
2238 _open_osfhandle ((long) stdout_save, O_TEXT); 2735 _open_osfhandle ((long) stdout_save, O_TEXT);
2239 else 2736 else
2240 _open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY); 2737 _open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
2241 fdopen (1, "w"); 2738 _fdopen (1, "w");
2242 2739
2243 if (stderr_save != INVALID_HANDLE_VALUE) 2740 if (stderr_save != INVALID_HANDLE_VALUE)
2244 _open_osfhandle ((long) stderr_save, O_TEXT); 2741 _open_osfhandle ((long) stderr_save, O_TEXT);
2245 else 2742 else
2246 _open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY); 2743 _open ("nul", O_TEXT | O_NOINHERIT | O_WRONLY);
2247 fdopen (2, "w"); 2744 _fdopen (2, "w");
2248 } 2745 }
2249
2250 /* Restrict Emacs to running only one DOS program at a time (with any
2251 number of Win32 programs). This is to prevent the user from
2252 running into problems with DOS programs being run in the same VDM
2253 under both Windows 95 and Windows NT.
2254
2255 Note that it is possible for Emacs to run DOS programs in separate
2256 VDMs, but unfortunately the pipe implementation on Windows 95 then
2257 fails to report when the DOS process exits (which is supposed to
2258 break the pipe). Until this bug is fixed, or we can devise a
2259 work-around, we must try to avoid letting the user start more than
2260 one DOS program if possible. */
2261
2262 dos_process_running = FALSE;
2263 2746
2264 /* unfortunately, atexit depends on implementation of malloc */ 2747 /* unfortunately, atexit depends on implementation of malloc */
2265 /* atexit (term_ntproc); */ 2748 /* atexit (term_ntproc); */
2266 signal (SIGABRT, term_ntproc); 2749 signal (SIGABRT, term_ntproc);
2267 } 2750
2268 2751 /* determine which drives are fixed, for GetCachedVolumeInformation */
2752 {
2753 /* GetDriveType must have trailing backslash. */
2754 char drive[] = "A:\\";
2755
2756 /* Loop over all possible drive letters */
2757 while ( *drive <= 'Z' )
2758 {
2759 /* Record if this drive letter refers to a fixed drive. */
2760 fixed_drives[ DRIVE_INDEX (*drive) ] =
2761 (GetDriveType (drive) == DRIVE_FIXED);
2762
2763 (*drive)++;
2764 }
2765 }
2766 }
2269 #ifndef HAVE_TTY 2767 #ifndef HAVE_TTY
2270 Lisp_Object Vstdio_str; 2768 Lisp_Object Vstdio_str;
2271 2769
2272 Lisp_Object 2770 Lisp_Object
2273 tty_semi_canonicalize_console_connection (Lisp_Object connection, 2771 tty_semi_canonicalize_console_connection (Lisp_Object connection,