* cygerrno.h: New file. Use this throughout whenever errno manipulation is

required.
* errno.cc: Use DWORD to hold Windows errors.
(geterrno_from_win_error): New function.
(seterrno_from_win_error): Use geterrno_from_win_error to convert supplied
windows error (suggested by Corinna Vinschen).
* path.cc (symlink_info): Add error element.
* path.cc (path_conv::check): Remove errno setting.  Use new symlink_info errno
element to set path_conv error, where appropriate.
(symlink_info::check): Set error element rather than attempting to manipulate
errno.  Add more checks for trailing / and /..  even though they are currently
useless.  Avoid setting EINVAL.
* path.cc (normalize_posix_path): Correct check for trailing /.
This commit is contained in:
Christopher Faylor 2000-08-22 03:58:47 +00:00
parent 6b85369f82
commit 9e2baf8dfa
45 changed files with 202 additions and 132 deletions

View File

@ -1,3 +1,22 @@
Mon Aug 21 23:49:05 2000 Christopher Faylor <cgf@cygnus.com>
* cygerrno.h: New file. Use this throughout whenever errno
manipulation is required.
* errno.cc: Use DWORD to hold Windows errors.
(geterrno_from_win_error): New function.
(seterrno_from_win_error): Use geterrno_from_win_error to convert
supplied windows error (suggested by Corinna Vinschen).
* path.cc (symlink_info): Add error element.
* path.cc (path_conv::check): Remove errno setting. Use new
symlink_info errno element to set path_conv error, where appropriate.
(symlink_info::check): Set error element rather than attempting to
manipulate errno. Add more checks for trailing / and /.. even though
they are currently useless. Avoid setting EINVAL.
Mon Aug 21 23:49:05 2000 Corinna Vinschen <corinna@vinschen.de>
* path.cc (normalize_posix_path): Correct check for trailing /.
2000-08-21 DJ Delorie <dj@redhat.com> 2000-08-21 DJ Delorie <dj@redhat.com>
* include/cygwin/cygwin_dll.h (DECLARE_CYGWIN_DLL): hinstance, * include/cygwin/cygwin_dll.h (DECLARE_CYGWIN_DLL): hinstance,

34
winsup/cygwin/cygerrno.h Normal file
View File

@ -0,0 +1,34 @@
/* cygerrno.h: main Cygwin header file.
Copyright 2000 Red Hat, Inc.
This file is part of Cygwin.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
void __stdcall seterrno_from_win_error (const char *file, int line, DWORD code);
void __stdcall seterrno (const char *, int line);
int __stdcall geterrno_from_win_error (DWORD code, int deferrno);
#define __seterrno() seterrno (__FILE__, __LINE__)
#define __seterrno_from_win_error(val) seterrno_from_win_error (__FILE__, __LINE__, val)
#define set_errno(val) (_impure_ptr->_errno = (val))
#define get_errno() (_impure_ptr->_errno)
extern "C" void __stdcall set_sig_errno (int e);
class save_errno
{
int saved;
public:
save_errno () {saved = get_errno ();}
save_errno (int what) {saved = get_errno (); set_errno (what); }
void set (int what) {set_errno (what); saved = what;}
void reset () {saved = get_errno ();}
~save_errno () {set_errno (saved);}
};
extern const char *__sp_fn;
extern int __sp_ln;

View File

@ -18,6 +18,7 @@ details. */
#include <ctype.h> #include <ctype.h>
#include "dtable.h" #include "dtable.h"
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
#define MAX_AT_FILE_LEVEL 10 #define MAX_AT_FILE_LEVEL 10

View File

@ -14,6 +14,7 @@ details. */
#include <sys/stat.h> #include <sys/stat.h>
#include <errno.h> #include <errno.h>
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
#define _COMPILING_NEWLIB #define _COMPILING_NEWLIB
#include "dirent.h" #include "dirent.h"

View File

@ -10,6 +10,7 @@ details. */
#include <stdlib.h> #include <stdlib.h>
#include "exceptions.h" #include "exceptions.h"
#include "dll_init.h" #include "dll_init.h"
#include "cygerrno.h"
extern void __stdcall check_sanity_and_sync (per_process *); extern void __stdcall check_sanity_and_sync (per_process *);

View File

@ -22,6 +22,7 @@ details. */
#include <winsock.h> #include <winsock.h>
#include "dtable.h" #include "dtable.h"
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
dtable fdtab; dtable fdtab;

View File

@ -14,6 +14,7 @@ details. */
#include <ctype.h> #include <ctype.h>
#include <fcntl.h> #include <fcntl.h>
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
extern BOOL allow_glob; extern BOOL allow_glob;
extern BOOL allow_ntea; extern BOOL allow_ntea;

View File

@ -12,6 +12,7 @@ details. */
#define _REENT_ONLY #define _REENT_ONLY
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#include "cygerrno.h"
/* Table to map Windows error codes to Errno values. */ /* Table to map Windows error codes to Errno values. */
/* FIXME: Doing things this way is a little slow. It's trivial to change /* FIXME: Doing things this way is a little slow. It's trivial to change
@ -21,7 +22,7 @@ details. */
static const struct static const struct
{ {
int w; /* windows version of error */ DWORD w; /* windows version of error */
const char *s; /* text of windows version */ const char *s; /* text of windows version */
int e; /* errno version of error */ int e; /* errno version of error */
} }
@ -108,34 +109,33 @@ errmap[] =
{ 0, NULL, 0} { 0, NULL, 0}
}; };
int __stdcall
geterrno_from_win_error (DWORD code, int deferrno)
{
for (int i = 0; errmap[i].w != 0; ++i)
if (code == errmap[i].w)
{
syscall_printf ("windows error %u == errno %d", code, errmap[i].e);
return errmap[i].e;
}
syscall_printf ("unknown windows error %u, setting errno to %d", code,
deferrno);
return deferrno; /* FIXME: what's so special about EACCESS? */
}
/* seterrno_from_win_error: Given a Windows error code, set errno /* seterrno_from_win_error: Given a Windows error code, set errno
as appropriate. */ as appropriate. */
void void __stdcall
seterrno_from_win_error (const char *file, int line, int code) seterrno_from_win_error (const char *file, int line, DWORD code)
{ {
int i; syscall_printf ("%s:%d \b");
set_errno (geterrno_from_win_error (code, EACCES));
for (i = 0; errmap[i].w != 0; ++i) return;
if (code == errmap[i].w)
break;
if (errmap[i].w != 0)
{
if (strace.active)
strace.prntf (_STRACE_SYSCALL, NULL, "%s:%d seterrno: %d (%s) -> %d",
file, line, code, errmap[i].s, errmap[i].e);
set_errno (errmap[i].e);
}
else
{
if (strace.active)
strace.prntf (_STRACE_SYSCALL, NULL, "%s:%d seterrno: unknown error %d", file, line, code);
set_errno (EACCES);
}
} }
/* seterrno: Set `errno' based on GetLastError (). */ /* seterrno: Set `errno' based on GetLastError (). */
void void __stdcall
seterrno (const char *file, int line) seterrno (const char *file, int line)
{ {
seterrno_from_win_error (file, line, GetLastError ()); seterrno_from_win_error (file, line, GetLastError ());
@ -672,4 +672,3 @@ strerror (int errnum)
include files. */ include files. */
return (char *) error; return (char *) error;
} }

View File

@ -16,6 +16,7 @@ details. */
#include "exceptions.h" #include "exceptions.h"
#include <imagehlp.h> #include <imagehlp.h>
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
char debugger_command[2 * MAX_PATH + 20]; char debugger_command[2 * MAX_PATH + 20];

View File

@ -14,6 +14,7 @@ details. */
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include "dtable.h" #include "dtable.h"
#include "cygerrno.h"
extern "C" extern "C"
int int

View File

@ -14,6 +14,7 @@ details. */
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "cygerrno.h"
static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */ static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */

View File

@ -23,6 +23,7 @@ details. */
#include <winuser.h> #include <winuser.h>
#include <ctype.h> #include <ctype.h>
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
/* /*
* Scroll the screen context. * Scroll the screen context.

View File

@ -13,6 +13,7 @@ details. */
#include "winsup.h" #include "winsup.h"
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
#include "cygerrno.h"
#define RANDOM 8 #define RANDOM 8
#define URANDOM 9 #define URANDOM 9

View File

@ -16,6 +16,7 @@
#include <cygwin/rdevio.h> #include <cygwin/rdevio.h>
#include <sys/mtio.h> #include <sys/mtio.h>
#include "cygerrno.h"
/* static wrapper functions to hide the effect of media changes and /* static wrapper functions to hide the effect of media changes and
bus resets which occurs after a new media is inserted. This is bus resets which occurs after a new media is inserted. This is

View File

@ -14,6 +14,7 @@ details. */
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
/**********************************************************************/ /**********************************************************************/
/* fhandler_serial */ /* fhandler_serial */

View File

@ -16,6 +16,7 @@ details. */
#include <unistd.h> #include <unistd.h>
#include <sys/mtio.h> #include <sys/mtio.h>
#include "cygerrno.h"
/**********************************************************************/ /**********************************************************************/
/* fhandler_dev_tape */ /* fhandler_dev_tape */

View File

@ -15,6 +15,7 @@ details. */
#include <errno.h> #include <errno.h>
#include <ctype.h> #include <ctype.h>
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
/* Common functions shared by tty/console */ /* Common functions shared by tty/console */

View File

@ -18,6 +18,7 @@ details. */
#include <limits.h> #include <limits.h>
#include "dtable.h" #include "dtable.h"
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
/* Tty master stuff */ /* Tty master stuff */

View File

@ -15,6 +15,7 @@ details. */
#include <errno.h> #include <errno.h>
#include <wingdi.h> #include <wingdi.h>
#include <winuser.h> #include <winuser.h>
#include "cygerrno.h"
/* /*
The following unix-style calls are supported: The following unix-style calls are supported:

View File

@ -18,6 +18,7 @@ details. */
#include "dll_init.h" #include "dll_init.h"
#include "dtable.h" #include "dtable.h"
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
DWORD NO_COPY chunksize = 0; DWORD NO_COPY chunksize = 0;
/* Timeout to wait for child to start, parent to init child, etc. */ /* Timeout to wait for child to start, parent to init child, etc. */

View File

@ -11,6 +11,7 @@ details. */
#include "winsup.h" #include "winsup.h"
#include <errno.h> #include <errno.h>
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
#define brksize ((char *) user_data->heaptop - (char *) user_data->heapbase) #define brksize ((char *) user_data->heaptop - (char *) user_data->heapbase)
#define brk (user_data->heapptr) #define brk (user_data->heapptr)

View File

@ -15,6 +15,7 @@ details. */
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <errno.h> #include <errno.h>
#include "dtable.h" #include "dtable.h"
#include "cygerrno.h"
extern "C" extern "C"
int int

View File

@ -15,6 +15,7 @@ details. */
#include <errno.h> #include <errno.h>
#include "dtable.h" #include "dtable.h"
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
/* /*
* Simple class used to keep a record of all current * Simple class used to keep a record of all current

View File

@ -25,6 +25,7 @@ details. */
#include <winsock.h> #include <winsock.h>
#include "dtable.h" #include "dtable.h"
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
/* We only want to initialize WinSock in a child process if socket /* We only want to initialize WinSock in a child process if socket
handles are inheritted. This global allows us to know whether this handles are inheritted. This global allows us to know whether this

View File

@ -15,6 +15,7 @@ details. */
#include <errno.h> #include <errno.h>
#include "dtable.h" #include "dtable.h"
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
/* Read /etc/passwd only once for better performance. This is done /* Read /etc/passwd only once for better performance. This is done
on the first call that needs information from it. */ on the first call that needs information from it. */

View File

@ -82,6 +82,7 @@ details. */
#include <ctype.h> #include <ctype.h>
#include <winioctl.h> #include <winioctl.h>
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
static int normalize_win32_path (const char *cwd, const char *src, char *dst); static int normalize_win32_path (const char *cwd, const char *src, char *dst);
static char *getcwd_inner (char *buf, size_t ulen, int posix_p, int with_chroot); static char *getcwd_inner (char *buf, size_t ulen, int posix_p, int with_chroot);
@ -101,6 +102,7 @@ struct symlink_info
unsigned pflags; unsigned pflags;
DWORD fileattr; DWORD fileattr;
int is_symlink; int is_symlink;
int error;
symlink_info (): known_suffix (NULL), contents (buf + MAX_PATH + 1) {} symlink_info (): known_suffix (NULL), contents (buf + MAX_PATH + 1) {}
int check (const char *path, const suffix_info *suffixes); int check (const char *path, const suffix_info *suffixes);
}; };
@ -154,9 +156,9 @@ static unsigned long cwd_hash;
#endif #endif
#define ischrootpath(path) \ #define ischrootpath(path) \
(myself->rootlen && \ (myself->rootlen && \
strncasematch (myself->root, path, myself->rootlen) && \ strncasematch (myself->root, path, myself->rootlen) && \
(path[myself->rootlen] == '/' || path[myself->rootlen] == '\0')) (path[myself->rootlen] == '/' || path[myself->rootlen] == '\0'))
static int static int
path_prefix_p_ (const char *path1, const char *path2, int len1) path_prefix_p_ (const char *path1, const char *path2, int len1)
@ -224,7 +226,7 @@ path_conv::check (const char *src, unsigned opt,
full_path, full_path,
devn, unit, &path_flags); devn, unit, &path_flags);
MALLOC_CHECK; MALLOC_CHECK;
if (error != 0) if (error)
return; return;
if (devn != FH_BAD) if (devn != FH_BAD)
{ {
@ -265,7 +267,6 @@ path_conv::check (const char *src, unsigned opt,
for (;;) for (;;)
{ {
save_errno s (0);
const suffix_info *suff; const suffix_info *suff;
/* Don't allow symlink.check to set anything in the path_conv /* Don't allow symlink.check to set anything in the path_conv
@ -287,10 +288,11 @@ path_conv::check (const char *src, unsigned opt,
path_flags = sym.pflags; path_flags = sym.pflags;
/* If symlink.check found an existing non-symlink file, then /* If symlink.check found an existing non-symlink file, then
it returns a length of 0 and sets errno to EINVAL. It also sets it sets the appropriate flag. It also sets any suffix found
any suffix found into `ext_here'. */ into `ext_here'. */
if (!sym.is_symlink && sym.fileattr != (DWORD) -1) if (!sym.is_symlink && sym.fileattr != (DWORD) -1)
{ {
error = sym.error;
if (component == 0) if (component == 0)
{ {
fileattr = sym.fileattr; fileattr = sym.fileattr;
@ -317,11 +319,10 @@ path_conv::check (const char *src, unsigned opt,
} }
/* No existing file found. */ /* No existing file found. */
s.reset (); // remember errno from symlink.check
if (!(tail = strrchr (path_copy, '\\')) || if (!(tail = strrchr (path_copy, '\\')) ||
(tail > path_copy && tail[-1] == ':')) (tail > path_copy && tail[-1] == ':'))
goto out; // all done goto out; // all done
/* Haven't found a valid pathname component yet. /* Haven't found a valid pathname component yet.
Pinch off the tail and try again. */ Pinch off the tail and try again. */
@ -392,13 +393,13 @@ out:
!GetVolumeInformation (tmp_buf, NULL, 0, &serial, NULL, &volflags, NULL, 0)) !GetVolumeInformation (tmp_buf, NULL, 0, &serial, NULL, &volflags, NULL, 0))
{ {
debug_printf ("GetVolumeInformation(%s) = ERR, full_path(%s), set_has_acls(FALSE)", debug_printf ("GetVolumeInformation(%s) = ERR, full_path(%s), set_has_acls(FALSE)",
tmp_buf, full_path, GetLastError ()); tmp_buf, full_path, GetLastError ());
set_has_acls (FALSE); set_has_acls (FALSE);
} }
else else
{ {
debug_printf ("GetVolumeInformation(%s) = OK, full_path(%s), set_has_acls(%d)", debug_printf ("GetVolumeInformation(%s) = OK, full_path(%s), set_has_acls(%d)",
tmp_buf, full_path, volflags & FS_PERSISTENT_ACLS); tmp_buf, full_path, volflags & FS_PERSISTENT_ACLS);
set_has_acls (volflags & FS_PERSISTENT_ACLS); set_has_acls (volflags & FS_PERSISTENT_ACLS);
} }
} }
@ -504,10 +505,10 @@ get_device_number (const char *name, int &unit, BOOL from_conv)
else if (deveq ("zero")) else if (deveq ("zero"))
devn = FH_ZERO; devn = FH_ZERO;
else if (deveq ("random") || deveq ("urandom")) else if (deveq ("random") || deveq ("urandom"))
{ {
devn = FH_RANDOM; devn = FH_RANDOM;
unit = 8 + (deveqn ("u", 1) ? 1 : 0); /* Keep unit Linux conformant */ unit = 8 + (deveqn ("u", 1) ? 1 : 0); /* Keep unit Linux conformant */
} }
else if (deveqn ("com", 3) && (unit = digits (name + 3)) >= 0) else if (deveqn ("com", 3) && (unit = digits (name + 3)) >= 0)
devn = FH_SERIAL; devn = FH_SERIAL;
else if (deveq ("pipe") || deveq ("piper") || deveq ("pipew")) else if (deveq ("pipe") || deveq ("piper") || deveq ("pipew"))
@ -591,10 +592,10 @@ normalize_posix_path (const char *cwd, const char *src, char *dst)
else if (isslash (src[1])) else if (isslash (src[1]))
{ {
if (myself->rootlen) if (myself->rootlen)
{ {
debug_printf ("ENOENT = normalize_posix_path (%s)", src); debug_printf ("ENOENT = normalize_posix_path (%s)", src);
return ENOENT; return ENOENT;
} }
*dst++ = '/'; *dst++ = '/';
*dst++ = '/'; *dst++ = '/';
src += 2; src += 2;
@ -630,16 +631,16 @@ normalize_posix_path (const char *cwd, const char *src, char *dst)
sawdot: sawdot:
if (src[1] != '.') if (src[1] != '.')
{ {
if ((src[1] && !isslash (src[1]))) if (!src[1] || !isslash (src[1]))
break; break;
} }
else else
{ {
if (src[2] && !isslash (src[2])) if (src[2] && !isslash (src[2]))
break; break;
if (!ischrootpath (dst_start) || if (!ischrootpath (dst_start) ||
dst - dst_start != (int) myself->rootlen) dst - dst_start != (int) myself->rootlen)
while (dst > dst_start && !isslash (*--dst)) while (dst > dst_start && !isslash (*--dst))
continue; continue;
src++; src++;
} }
@ -686,10 +687,10 @@ normalize_win32_path (const char *cwd, const char *src, char *dst)
else if (SLASH_P (src[0]) && SLASH_P (src[1])) else if (SLASH_P (src[0]) && SLASH_P (src[1]))
{ {
if (myself->rootlen) if (myself->rootlen)
{ {
debug_printf ("ENOENT = normalize_win32_path (%s)", src); debug_printf ("ENOENT = normalize_win32_path (%s)", src);
return ENOENT; return ENOENT;
} }
*dst++ = '\\'; *dst++ = '\\';
++src; ++src;
} }
@ -699,7 +700,7 @@ normalize_win32_path (const char *cwd, const char *src, char *dst)
strcpy (dst, myself->root); strcpy (dst, myself->root);
char *c; char *c;
while ((c = strchr (dst, '/')) != NULL) while ((c = strchr (dst, '/')) != NULL)
*c = '\\'; *c = '\\';
dst += myself->rootlen; dst += myself->rootlen;
dst_root_start = dst; dst_root_start = dst;
*dst++ = '\\'; *dst++ = '\\';
@ -913,7 +914,7 @@ mount_info::init ()
int int
mount_info::conv_to_win32_path (const char *src_path, char *win32_path, mount_info::conv_to_win32_path (const char *src_path, char *win32_path,
char *full_win32_path, DWORD &devn, int &unit, char *full_win32_path, DWORD &devn, int &unit,
unsigned *flags) unsigned *flags)
{ {
int src_path_len = strlen (src_path); int src_path_len = strlen (src_path);
int trailing_slash_p = (src_path_len > 1 int trailing_slash_p = (src_path_len > 1
@ -968,21 +969,21 @@ mount_info::conv_to_win32_path (const char *src_path, char *win32_path,
isrelpath = !isabspath (src_path); isrelpath = !isabspath (src_path);
*flags = set_flags_from_win32_path (dst); *flags = set_flags_from_win32_path (dst);
if (myself->rootlen && dst[0] && dst[1] == ':') if (myself->rootlen && dst[0] && dst[1] == ':')
{ {
char posix_path[MAX_PATH + 1]; char posix_path[MAX_PATH + 1];
rc = cygwin_shared->mount.conv_to_posix_path (dst, posix_path, 0); rc = cygwin_shared->mount.conv_to_posix_path (dst, posix_path, 0);
if (rc) if (rc)
{ {
debug_printf ("conv_to_posix_path failed, rc %d", rc); debug_printf ("conv_to_posix_path failed, rc %d", rc);
return rc; return rc;
} }
if (!ischrootpath (posix_path)) if (!ischrootpath (posix_path))
{ {
debug_printf ("ischrootpath failed"); debug_printf ("ischrootpath failed");
return ENOENT; return ENOENT;
} }
} }
goto fillin; goto fillin;
} }
@ -1459,13 +1460,13 @@ mount_info::del_reg_mount (const char * posix_path, unsigned flags)
{ {
int killres; int killres;
if ((flags & MOUNT_SYSTEM) == 0) /* Delete from user registry */ if ((flags & MOUNT_SYSTEM) == 0) /* Delete from user registry */
{ {
reg_key reg_user (KEY_ALL_ACCESS, reg_key reg_user (KEY_ALL_ACCESS,
CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME, NULL); CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME, NULL);
killres = reg_user.kill (posix_path); killres = reg_user.kill (posix_path);
} }
else /* Delete from system registry */ else /* Delete from system registry */
{ {
reg_key reg_sys (HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS, "SOFTWARE", reg_key reg_sys (HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS, "SOFTWARE",
CYGWIN_INFO_CYGNUS_REGISTRY_NAME, CYGWIN_INFO_CYGNUS_REGISTRY_NAME,
@ -1514,23 +1515,23 @@ mount_info::read_cygdrive_info_from_registry ()
if (r2.get_string ("cygdrive prefix", cygdrive, sizeof (cygdrive), "") != 0) if (r2.get_string ("cygdrive prefix", cygdrive, sizeof (cygdrive), "") != 0)
{ {
/* Didn't find either so write the default to the registry and use it. /* Didn't find either so write the default to the registry and use it.
NOTE: We are writing and using the user path prefix. */ NOTE: We are writing and using the user path prefix. */
write_cygdrive_info_to_registry ("/cygdrive", MOUNT_AUTO); write_cygdrive_info_to_registry ("/cygdrive", MOUNT_AUTO);
} }
else else
{ {
/* Fetch system cygdrive_flags from registry; returns MOUNT_AUTO on /* Fetch system cygdrive_flags from registry; returns MOUNT_AUTO on
error. */ error. */
cygdrive_flags = r2.get_int ("cygdrive flags", MOUNT_AUTO); cygdrive_flags = r2.get_int ("cygdrive flags", MOUNT_AUTO);
slashify (cygdrive, cygdrive, 1); slashify (cygdrive, cygdrive, 1);
cygdrive_len = strlen(cygdrive); cygdrive_len = strlen(cygdrive);
} }
} }
else else
{ {
/* Fetch user cygdrive_flags from registry; returns MOUNT_AUTO on /* Fetch user cygdrive_flags from registry; returns MOUNT_AUTO on
error. */ error. */
cygdrive_flags = r.get_int ("cygdrive flags", MOUNT_AUTO); cygdrive_flags = r.get_int ("cygdrive flags", MOUNT_AUTO);
slashify (cygdrive, cygdrive, 1); slashify (cygdrive, cygdrive, 1);
cygdrive_len = strlen(cygdrive); cygdrive_len = strlen(cygdrive);
@ -1959,12 +1960,12 @@ mount_item::getmntent ()
strcpy (cygwin_shared->mount.mnt_dir, posix_path); strcpy (cygwin_shared->mount.mnt_dir, posix_path);
ret.mnt_dir = cygwin_shared->mount.mnt_dir; ret.mnt_dir = cygwin_shared->mount.mnt_dir;
if (!(flags & MOUNT_SYSTEM)) /* user mount */ if (!(flags & MOUNT_SYSTEM)) /* user mount */
strcpy (cygwin_shared->mount.mnt_type, (char *) "user"); strcpy (cygwin_shared->mount.mnt_type, (char *) "user");
else /* system mount */ else /* system mount */
strcpy (cygwin_shared->mount.mnt_type, (char *) "system"); strcpy (cygwin_shared->mount.mnt_type, (char *) "system");
if ((flags & MOUNT_AUTO)) /* cygdrive */ if ((flags & MOUNT_AUTO)) /* cygdrive */
strcat (cygwin_shared->mount.mnt_type, (char *) ",auto"); strcat (cygwin_shared->mount.mnt_type, (char *) ",auto");
ret.mnt_type = cygwin_shared->mount.mnt_type; ret.mnt_type = cygwin_shared->mount.mnt_type;
@ -2068,7 +2069,7 @@ cygwin_umount (const char *path, unsigned flags)
if (flags & MOUNT_AUTO) if (flags & MOUNT_AUTO)
{ {
/* When flags include MOUNT_AUTO, take this to mean that we actually want /* When flags include MOUNT_AUTO, take this to mean that we actually want
to remove the cygdrive prefix and flags without actually unmounting to remove the cygdrive prefix and flags without actually unmounting
anything. */ anything. */
res = cygwin_shared->mount.remove_cygdrive_info_from_registry (path, flags); res = cygwin_shared->mount.remove_cygdrive_info_from_registry (path, flags);
} }
@ -2169,10 +2170,10 @@ symlink (const char *topath, const char *frompath)
else else
{ {
CloseHandle (h); CloseHandle (h);
set_file_attribute (win32_path.has_acls (), set_file_attribute (win32_path.has_acls (),
win32_path.get_win32 (), win32_path.get_win32 (),
S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO); S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO);
SetFileAttributesA (win32_path.get_win32 (), FILE_ATTRIBUTE_SYSTEM); SetFileAttributesA (win32_path.get_win32 (), FILE_ATTRIBUTE_SYSTEM);
res = 0; res = 0;
} }
} }
@ -2236,6 +2237,7 @@ symlink_info::check (const char *in_path, const suffix_info *suffixes)
char extbuf[MAX_PATH + 5]; char extbuf[MAX_PATH + 5];
const char *path = in_path; const char *path = in_path;
error = 0;
if (!suffixes) if (!suffixes)
ext_here = NULL; ext_here = NULL;
else if ((known_suffix = has_suffix (in_path, suffixes)) != NULL) else if ((known_suffix = has_suffix (in_path, suffixes)) != NULL)
@ -2262,19 +2264,23 @@ symlink_info::check (const char *in_path, const suffix_info *suffixes)
matter, so we just return 0. For example, getting the matter, so we just return 0. For example, getting the
attributes of \\HOST will typically fail. */ attributes of \\HOST will typically fail. */
debug_printf ("GetFileAttributesA (%s) failed", path); debug_printf ("GetFileAttributesA (%s) failed", path);
__seterrno (); error = geterrno_from_win_error (GetLastError (), EACCES);
continue; continue;
} }
/* Windows allows path\. even when `path' isn't a directory. /* Windows allows path\. even when `path' isn't a directory.
Detect this scenario and disallow it, since it is non-UNIX like. */ Detect this scenario and disallow it, since it is non-UNIX like.
char *p = strchr (path, '\0'); FIXME: This code actually checks for things like foo/ and foo/..
if (p > path + 1 && p[-1] == '.' && SLASH_P (p[-2]) && even though those usages have already been (erroneously?) eaten
!(fileattr & FILE_ATTRIBUTE_DIRECTORY)) by cygwin_shared->mount.conv_to_win32_path in path_conv::check. */
char *p = strrchr (path, '\\');
if (p && !(fileattr & FILE_ATTRIBUTE_DIRECTORY) &&
(*++p == '\0' || (*p == '.' && (*++p == '\0' || (*p == '.' && p[1] == '\0')))))
{ {
debug_printf ("\\. specified on non-directory"); debug_printf ("%s is a non-directory", path);
set_errno (ENOTDIR); error = ENOTDIR;
return 0; goto file_not_symlink;
} }
/* A symlink will have the `system' file attribute. */ /* A symlink will have the `system' file attribute. */
@ -2295,7 +2301,7 @@ symlink_info::check (const char *in_path, const suffix_info *suffixes)
DWORD got; DWORD got;
if (! ReadFile (h, cookie_buf, sizeof (cookie_buf), &got, 0)) if (! ReadFile (h, cookie_buf, sizeof (cookie_buf), &got, 0))
set_errno (EIO); error = EIO;
else if (got == sizeof (cookie_buf) else if (got == sizeof (cookie_buf)
&& memcmp (cookie_buf, SYMLINK_COOKIE, && memcmp (cookie_buf, SYMLINK_COOKIE,
sizeof (cookie_buf)) == 0) sizeof (cookie_buf)) == 0)
@ -2305,7 +2311,7 @@ symlink_info::check (const char *in_path, const suffix_info *suffixes)
res = ReadFile (h, contents, MAX_PATH + 1, &got, 0); res = ReadFile (h, contents, MAX_PATH + 1, &got, 0);
if (!res) if (!res)
set_errno (EIO); error = EIO;
else else
{ {
/* Versions prior to b16 stored several trailing /* Versions prior to b16 stored several trailing
@ -2347,7 +2353,6 @@ symlink_info::check (const char *in_path, const suffix_info *suffixes)
goto out; goto out;
file_not_symlink: file_not_symlink:
set_errno (EINVAL);
is_symlink = FALSE; is_symlink = FALSE;
syscall_printf ("not a symlink"); syscall_printf ("not a symlink");
res = 0; res = 0;
@ -2516,12 +2521,12 @@ getcwd_inner (char *buf, size_t ulen, int posix_p, int with_chroot)
if (strlen (cwd_posix) >= len) if (strlen (cwd_posix) >= len)
set_errno (ERANGE); set_errno (ERANGE);
else if (with_chroot && ischrootpath(cwd_posix)) else if (with_chroot && ischrootpath(cwd_posix))
{ {
strcpy (buf, cwd_posix + myself->rootlen); strcpy (buf, cwd_posix + myself->rootlen);
if (!buf[0]) if (!buf[0])
strcpy (buf, "/"); strcpy (buf, "/");
resbuf = buf; resbuf = buf;
} }
else else
{ {
strcpy (buf, cwd_posix); strcpy (buf, cwd_posix);
@ -2550,9 +2555,9 @@ getcwd_inner (char *buf, size_t ulen, int posix_p, int with_chroot)
if (cwd_posix != NULL) if (cwd_posix != NULL)
if (with_chroot && ischrootpath (temp)) if (with_chroot && ischrootpath (temp))
{ {
strcpy (cwd_posix, temp + myself->rootlen); strcpy (cwd_posix, temp + myself->rootlen);
if (!buf[0]) if (!buf[0])
strcpy (buf, "/"); strcpy (buf, "/");
} }
else else
strcpy (cwd_posix, temp); strcpy (cwd_posix, temp);
@ -2639,12 +2644,12 @@ chdir (const char *dir)
char pathbuf[MAX_PATH]; char pathbuf[MAX_PATH];
(void) normalize_posix_path (cwd_posix, dir, pathbuf); (void) normalize_posix_path (cwd_posix, dir, pathbuf);
/* Look for trailing path component consisting entirely of dots. This /* Look for trailing path component consisting entirely of dots. This
is needed only in case of chdir since Windows simply ignores count is needed only in case of chdir since Windows simply ignores count
of dots > 2 here instead of returning an error code. Counts of dots of dots > 2 here instead of returning an error code. Counts of dots
<= 2 are already eliminated by normalize_posix_path. */ <= 2 are already eliminated by normalize_posix_path. */
char *last_slash = strrchr (pathbuf, '/'); char *last_slash = strrchr (pathbuf, '/');
if (last_slash > pathbuf && strspn (last_slash + 1, ".") == strlen (last_slash + 1)) if (last_slash > pathbuf && strspn (last_slash + 1, ".") == strlen (last_slash + 1))
*last_slash = '\0'; *last_slash = '\0';
free (cwd_posix); free (cwd_posix);
cwd_posix = strdup (pathbuf); cwd_posix = strdup (pathbuf);
} }

View File

@ -15,6 +15,7 @@ details. */
#include <limits.h> #include <limits.h>
#include "dtable.h" #include "dtable.h"
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
static char NO_COPY pinfo_dummy[sizeof(pinfo)] = {0}; static char NO_COPY pinfo_dummy[sizeof(pinfo)] = {0};

View File

@ -13,6 +13,7 @@ details. */
#include <sys/fcntl.h> #include <sys/fcntl.h>
#include <errno.h> #include <errno.h>
#include "dtable.h" #include "dtable.h"
#include "cygerrno.h"
static int static int
make_pipe (int fildes[2], unsigned int psize, int mode) make_pipe (int fildes[2], unsigned int psize, int mode)

View File

@ -12,6 +12,7 @@
#include <sys/poll.h> #include <sys/poll.h>
#include <errno.h> #include <errno.h>
#include "dtable.h" #include "dtable.h"
#include "cygerrno.h"
extern "C" extern "C"
int int

View File

@ -15,6 +15,7 @@ details. */
#include "winsup.h" #include "winsup.h"
#include <errno.h> #include <errno.h>
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
/* add timeval values */ /* add timeval values */
static void static void

View File

@ -14,6 +14,7 @@
#include <dirent.h> #include <dirent.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include "cygerrno.h"
extern "C" extern "C"
int int

View File

@ -24,6 +24,7 @@ details. */
#include <ctype.h> #include <ctype.h>
#include "dtable.h" #include "dtable.h"
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
extern BOOL allow_ntea; extern BOOL allow_ntea;
BOOL allow_ntsec = FALSE; BOOL allow_ntsec = FALSE;

View File

@ -34,6 +34,7 @@ details. */
#include <winsock.h> #include <winsock.h>
#include "select.h" #include "select.h"
#include "dtable.h" #include "dtable.h"
#include "cygerrno.h"
/* /*
* All these defines below should be in sys/types.h * All these defines below should be in sys/types.h

View File

@ -14,6 +14,7 @@ details. */
#include "winsup.h" #include "winsup.h"
#include <errno.h> #include <errno.h>
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
extern "C" extern "C"
_sig_func_ptr _sig_func_ptr

View File

@ -17,6 +17,7 @@ details. */
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
extern BOOL allow_ntsec; extern BOOL allow_ntsec;

View File

@ -22,6 +22,7 @@ details. */
#include <paths.h> #include <paths.h>
#include "dtable.h" #include "dtable.h"
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
extern BOOL allow_ntsec; extern BOOL allow_ntsec;

View File

@ -26,6 +26,7 @@ details. */
#include <lmcons.h> /* for UNLEN */ #include <lmcons.h> /* for UNLEN */
#include "dtable.h" #include "dtable.h"
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
extern BOOL allow_ntsec; extern BOOL allow_ntsec;

View File

@ -14,6 +14,7 @@ details. */
#include <time.h> #include <time.h>
#include <limits.h> #include <limits.h>
#include "dtable.h" #include "dtable.h"
#include "cygerrno.h"
/* sysconf: POSIX 4.8.1.1 */ /* sysconf: POSIX 4.8.1.1 */
/* Allows a portable app to determine quantities of resources or /* Allows a portable app to determine quantities of resources or

View File

@ -15,6 +15,7 @@ details. */
#include <stdarg.h> #include <stdarg.h>
#include <unistd.h> #include <unistd.h>
#include "dtable.h" #include "dtable.h"
#include "cygerrno.h"
/* FIXME: These should probably be in the registry. */ /* FIXME: These should probably be in the registry. */
/* FIXME: The Win95 path should be whatever slash is */ /* FIXME: The Win95 path should be whatever slash is */

View File

@ -14,6 +14,7 @@ details. */
#include "winsup.h" #include "winsup.h"
#include <errno.h> #include <errno.h>
#include "dtable.h" #include "dtable.h"
#include "cygerrno.h"
/* tcsendbreak: POSIX 7.2.2.1 */ /* tcsendbreak: POSIX 7.2.2.1 */
extern "C" extern "C"

View File

@ -17,6 +17,7 @@ details. */
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
#define FACTOR (0x19db1ded53ea710LL) #define FACTOR (0x19db1ded53ea710LL)
#define NSPERSEC 10000000LL #define NSPERSEC 10000000LL

View File

@ -16,6 +16,7 @@ details. */
#include <winuser.h> #include <winuser.h>
#include "dtable.h" #include "dtable.h"
#include "pinfo.h" #include "pinfo.h"
#include "cygerrno.h"
extern fhandler_tty_master *tty_master; extern fhandler_tty_master *tty_master;

View File

@ -12,6 +12,7 @@ details. */
#include <sys/wait.h> #include <sys/wait.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include "cygerrno.h"
/* This is called _wait and not wait because the real wait is defined /* This is called _wait and not wait because the real wait is defined
in libc/syscalls/syswait.c. It calls us. */ in libc/syscalls/syswait.c. It calls us. */

View File

@ -17,6 +17,7 @@ details. */
#include <limits.h> #include <limits.h>
#include <wingdi.h> #include <wingdi.h>
#include <winuser.h> #include <winuser.h>
#include "cygerrno.h"
static NO_COPY UINT timer_active = 0; static NO_COPY UINT timer_active = 0;
static NO_COPY struct itimerval itv; static NO_COPY struct itimerval itv;

View File

@ -466,31 +466,4 @@ extern "C" char __stdcall **cur_environ ();
extern char *old_title; extern char *old_title;
extern BOOL display_title; extern BOOL display_title;
/*************************** errno manipulation ******************************/
void seterrno_from_win_error (const char *file, int line, int code);
void seterrno (const char *, int line);
#define __seterrno() seterrno (__FILE__, __LINE__)
#define __seterrno_from_win_error(val) seterrno_from_win_error (__FILE__, __LINE__, val)
#define set_errno(val) (_impure_ptr->_errno = (val))
#define get_errno() (_impure_ptr->_errno)
extern "C" void __stdcall set_sig_errno (int e);
class save_errno
{
int saved;
public:
save_errno () {saved = get_errno ();}
save_errno (int what) {saved = get_errno (); set_errno (what); }
void set (int what) {set_errno (what); saved = what;}
void reset () {saved = get_errno ();}
~save_errno () {set_errno (saved);}
};
extern const char *__sp_fn;
extern int __sp_ln;
#endif /* defined __cplusplus */ #endif /* defined __cplusplus */