1 /* Utility and Unix shadow routines for GNU Emacs support programs on NT.
2 Copyright (C) 1994, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
3 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
21 Geoff Voelker (voelker@cs.washington.edu) 10-8-94
29 #include <sys/types.h>
35 #define MAXPATHLEN _MAX_PATH
37 /* Emulate sleep...we could have done this with a define, but that
38 would necessitate including windows.h in the files that used it.
39 This is much easier. */
41 sleep(unsigned long seconds
)
43 Sleep (seconds
* 1000);
46 /* Get the current working directory. */
50 if (GetCurrentDirectory (MAXPATHLEN
, dir
) > 0)
55 static HANDLE getppid_parent
;
56 static int getppid_ppid
;
64 ppid
= getenv ("EM_PARENT_PROCESS_ID");
72 getppid_ppid
= atoi (ppid
);
77 getppid_parent
= OpenProcess (SYNCHRONIZE
, FALSE
, atoi(ppid
));
80 printf ("Failed to open handle to parent process: %d\n",
86 result
= WaitForSingleObject (getppid_parent
, 0);
90 /* The parent is still alive. */
93 /* The parent is gone. Return the pid of Unix init (1). */
97 printf ("Checking parent status failed: %d\n", GetLastError());
105 static char user_name
[256];
106 DWORD length
= sizeof (user_name
);
108 if (GetUserName (user_name
, &length
))
116 char * name
= getlogin ();
118 return strcpy (s
, name
? name
: "");
141 setuid (unsigned uid
)
147 setregid (unsigned rgid
, unsigned gid
)
153 getpwuid (unsigned uid
)
159 getpass (const char * prompt
)
161 static char input
[256];
166 in
= GetStdHandle (STD_INPUT_HANDLE
);
167 err
= GetStdHandle (STD_ERROR_HANDLE
);
169 if (in
== INVALID_HANDLE_VALUE
|| err
== INVALID_HANDLE_VALUE
)
172 if (WriteFile (err
, prompt
, strlen (prompt
), &count
, NULL
))
174 int istty
= (GetFileType (in
) == FILE_TYPE_CHAR
);
180 if (GetConsoleMode (in
, &old_flags
))
181 SetConsoleMode (in
, ENABLE_LINE_INPUT
| ENABLE_PROCESSED_INPUT
);
185 rc
= ReadFile (in
, input
, sizeof (input
), &count
, NULL
);
186 if (count
>= 2 && input
[count
- 2] == '\r')
187 input
[count
- 2] = '\0';
191 while (ReadFile (in
, buf
, sizeof (buf
), &count
, NULL
) > 0)
192 if (count
>= 2 && buf
[count
- 2] == '\r')
195 WriteFile (err
, "\r\n", 2, &count
, NULL
);
197 SetConsoleMode (in
, old_flags
);
206 fchown (int fd
, unsigned uid
, unsigned gid
)
211 /* Place a wrapper around the MSVC version of ctime. It returns NULL
212 on network directories, so we handle that case here.
213 (Ulrich Leodolter, 1/11/95). */
215 sys_ctime (const time_t *t
)
217 char *str
= (char *) ctime (t
);
218 return (str
? str
: "Sun Jan 01 00:00:00 1970");
222 sys_fopen(const char * path
, const char * mode
)
224 return fopen (path
, mode
);
228 sys_chdir (const char * path
)
230 return _chdir (path
);
233 static FILETIME utc_base_ft
;
234 static long double utc_base
;
238 convert_time (FILETIME ft
)
242 if (CompareFileTime (&ft
, &utc_base_ft
) < 0)
245 ret
= (long double) ft
.dwHighDateTime
246 * 4096.0L * 1024.0L * 1024.0L + ft
.dwLowDateTime
;
248 return (time_t) (ret
* 1e-7L);
252 is_exec (const char * name
)
254 char * p
= strrchr (name
, '.');
257 && (stricmp (p
, ".exe") == 0 ||
258 stricmp (p
, ".com") == 0 ||
259 stricmp (p
, ".bat") == 0 ||
260 stricmp (p
, ".cmd") == 0));
263 #define IS_DIRECTORY_SEP(x) ((x) == '/' || (x) == '\\')
265 /* We need this because nt/inc/sys/stat.h defines struct stat that is
266 incompatible with the MS run-time libraries. */
268 stat (const char * path
, struct stat
* buf
)
275 char *name
= alloca (FILENAME_MAX
);
279 /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
288 st
.wMilliseconds
= 0;
290 SystemTimeToFileTime (&st
, &utc_base_ft
);
291 utc_base
= (long double) utc_base_ft
.dwHighDateTime
292 * 4096.0L * 1024.0L * 1024.0L + utc_base_ft
.dwLowDateTime
;
296 if (path
== NULL
|| buf
== NULL
|| *path
== '\0')
301 if (_mbspbrk (path
, "*?|<>\""))
308 /* Remove trailing directory separator, unless name is the root
309 directory of a drive in which case ensure there is a trailing
312 rootdir
= IS_DIRECTORY_SEP (name
[0])
313 || (len
== 3 && name
[1] == ':' && IS_DIRECTORY_SEP (name
[2]));
316 if (GetDriveType (name
) < 2)
321 memset (&wfd
, 0, sizeof (wfd
));
322 wfd
.dwFileAttributes
= FILE_ATTRIBUTE_DIRECTORY
;
323 wfd
.ftCreationTime
= utc_base_ft
;
324 wfd
.ftLastAccessTime
= utc_base_ft
;
325 wfd
.ftLastWriteTime
= utc_base_ft
;
326 strcpy (wfd
.cFileName
, name
);
330 if (IS_DIRECTORY_SEP (name
[len
-1]))
333 fh
= FindFirstFile (name
, &wfd
);
334 if (fh
== INVALID_HANDLE_VALUE
)
341 buf
->st_mode
= (wfd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) ?
346 if (name
[0] && name
[1] == ':')
347 buf
->st_dev
= tolower (name
[0]) - 'a' + 1;
349 buf
->st_dev
= _getdrive ();
350 buf
->st_rdev
= buf
->st_dev
;
352 buf
->st_size
= wfd
.nFileSizeLow
;
354 /* Convert timestamps to Unix format. */
355 buf
->st_mtime
= convert_time (wfd
.ftLastWriteTime
);
356 buf
->st_atime
= convert_time (wfd
.ftLastAccessTime
);
357 if (buf
->st_atime
== 0) buf
->st_atime
= buf
->st_mtime
;
358 buf
->st_ctime
= convert_time (wfd
.ftCreationTime
);
359 if (buf
->st_ctime
== 0) buf
->st_ctime
= buf
->st_mtime
;
361 /* determine rwx permissions */
362 if (wfd
.dwFileAttributes
& FILE_ATTRIBUTE_READONLY
)
363 permission
= S_IREAD
;
365 permission
= S_IREAD
| S_IWRITE
;
367 if (wfd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
368 permission
|= S_IEXEC
;
369 else if (is_exec (name
))
370 permission
|= S_IEXEC
;
372 buf
->st_mode
|= permission
| (permission
>> 3) | (permission
>> 6);
377 /* arch-tag: 7b63fb83-70ee-4124-8822-54e53e5d0773
378 (do not change this comment) */