* cygwin.din: Export _getmode and getmode to allow querying of binary state of

an fd.
* external.cc (cygwin_internal): Add handling of perfile_table setting.
* fhandler.cc (perfile_table): New global.
(fhandler_base::get_default_fmode): New method to return a file's default mode
based on its name.
(fhandler_base::open): Use get_default_mode method to determine a file's mode.
Record file mode in file flags.
* fhandler.h (fhandler_base): Declare get_default_fmode
* syscalls.cc (getmode): New function.
* sys/cygwin.h (__cygwin_perfile): New structure.
(cygwin_getinfo_types): Move outside of WINVER conditional.
(per_process): Move inside of WINVER conditional.
This commit is contained in:
Christopher Faylor 2000-07-09 05:29:51 +00:00
parent 85219b356e
commit bd4ec49671
8 changed files with 125 additions and 54 deletions

View File

@ -1,3 +1,19 @@
Sun Jul 9 01:19:06 2000 Christopher Faylor <cgf@cygnus.com>
* cygwin.din: Export _getmode and getmode to allow querying of binary
state of an fd.
* external.cc (cygwin_internal): Add handling of perfile_table setting.
* fhandler.cc (perfile_table): New global.
(fhandler_base::get_default_fmode): New method to return a file's
default mode based on its name.
(fhandler_base::open): Use get_default_mode method to determine a
file's mode. Record file mode in file flags.
* fhandler.h (fhandler_base): Declare get_default_fmode
* syscalls.cc (getmode): New function.
* sys/cygwin.h (__cygwin_perfile): New structure.
(cygwin_getinfo_types): Move outside of WINVER conditional.
(per_process): Move inside of WINVER conditional.
Sat Jul 8 00:15:01 2000 Christopher Faylor <cgf@cygnus.com>
* external.cc (cygwin_internal): Export __cygwin_user_data.

View File

@ -335,6 +335,8 @@ getlogin
_getlogin = getlogin
getmntent
_getmntent = getmntent
getmode
_getmode = getmode
get_osfhandle
_get_osfhandle = get_osfhandle
getpagesize

View File

@ -103,6 +103,10 @@ cygwin_internal (cygwin_getinfo_types t, ...)
case CW_USER_DATA:
return (DWORD) &__cygwin_user_data;
case CW_PERFILE:
perfile_table = va_arg (arg, struct __cygwin_perfile *);
return 0;
default:
return (DWORD) -1;
}

View File

@ -18,6 +18,8 @@ static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
static char fhandler_disk_dummy_name[] = "some disk file";
struct __cygwin_perfile *perfile_table = NULL;
DWORD binmode;
int
@ -249,6 +251,27 @@ fhandler_base::raw_write (const void *ptr, size_t len)
return bytes_written;
}
#define ACCFLAGS(x) (x & (O_RDONLY | O_WRONLY | O_RDWR))
int
fhandler_base::get_default_fmode (int flags)
{
if (perfile_table)
{
size_t nlen = strlen (get_name ());
unsigned accflags = ACCFLAGS (flags);
for (__cygwin_perfile *pf = perfile_table; pf->name; pf++)
{
size_t pflen = strlen (pf->name);
const char *stem = get_name () + nlen - pflen;
if (pflen > nlen || (stem != get_name () && !isdirsep (stem[-1])))
continue;
else if (strcasematch (stem, pf->name) && ACCFLAGS (pf->flags) == accflags)
return pf->flags & ~(O_RDONLY | O_WRONLY | O_RDWR);
}
}
return __fmode;
}
/* Open system call handler function.
Path is now already checked for symlinks */
int
@ -262,8 +285,6 @@ fhandler_base::open (int flags, mode_t mode)
syscall_printf ("(%s, %p)", get_win32_name (), flags);
set_flags (flags);
if (get_win32_name () == NULL)
{
set_errno (ENOENT);
@ -352,17 +373,23 @@ fhandler_base::open (int flags, mode_t mode)
rpos_ = 0;
rsize_ = -1;
int bin;
if (flags & (O_BINARY | O_TEXT))
bin = flags & O_TEXT ? 0 : O_BINARY;
else if (__fmode & O_BINARY)
int fmode;
if ((bin = flags & (O_BINARY | O_TEXT)))
/* nothing to do */;
else if ((fmode = get_default_fmode (flags)) & O_BINARY)
bin = O_BINARY;
else if (__fmode & O_TEXT)
else if (fmode & O_TEXT)
bin = O_TEXT;
else if (get_device () == FH_DISK)
bin = get_w_binary () || get_r_binary ();
else
bin = binmode || get_w_binary () || get_r_binary ();
if (bin & O_TEXT)
bin = 0;
set_flags (flags | (bin ? O_BINARY : O_TEXT));
set_r_binary (bin);
set_w_binary (bin);
syscall_printf ("filemode set to %s", bin ? "binary" : "text");

View File

@ -107,6 +107,7 @@ enum
#define FHSTATOFF 0
extern const char *windows_device_names[];
extern struct __cygwin_perfile *perfile_table;
#define __fmode (*(user_data->fmode_ptr))
class select_record;
@ -182,6 +183,8 @@ public:
void set_w_binary (int b) { FHCONDSETF (b, WBINARY); FHSETF (WBINSET); }
void set_r_binary (int b) { FHCONDSETF (b, RBINARY); FHSETF (RBINSET); }
int get_default_fmode (int flags);
int get_r_no_interrupt () { return FHISSETF (NOEINTR); }
void set_r_no_interrupt (int b) { FHCONDSETF (b, NOEINTR); }

View File

@ -114,6 +114,7 @@ details. */
23: Export new dll_crt0 interface and cygwin_user_data for use
with crt0 startup code.
24: Export poll and _poll.
25: Export getmode and _getmode.
*/
#define CYGWIN_VERSION_API_MAJOR 0

View File

@ -36,6 +36,59 @@ extern void cygwin_premain1 (int argc, char **argv);
extern void cygwin_premain2 (int argc, char **argv);
extern void cygwin_premain3 (int argc, char **argv);
struct __cygwin_perfile
{
char *name;
unsigned flags;
};
#ifdef _PATH_PASSWD
extern HANDLE cygwin_logon_user (const struct passwd *, const char *);
#endif
/* External interface stuff */
typedef enum
{
CW_LOCK_PINFO,
CW_UNLOCK_PINFO,
CW_GETTHREADNAME,
CW_GETPINFO,
CW_SETPINFO,
CW_SETTHREADNAME,
CW_GETVERSIONINFO,
CW_READ_V1_MOUNT_TABLES,
CW_USER_DATA,
CW_PERFILE
} cygwin_getinfo_types;
#define CW_NEXTPID 0x80000000 // or with pid to get next one
/* Flags associated with process_state */
enum
{
PID_NOT_IN_USE = 0x0000, // Free entry.
PID_IN_USE = 0x0001, // Entry in use.
PID_ZOMBIE = 0x0002, // Child exited: no parent wait.
PID_STOPPED = 0x0004, // Waiting for SIGCONT.
PID_TTYIN = 0x0008, // Waiting for terminal input.
PID_TTYOU = 0x0010, // Waiting for terminal output.
PID_ORPHANED = 0x0020, // Member of an orphaned process group.
PID_ACTIVE = 0x0040, // Pid accepts signals.
PID_CYGPARENT = 0x0080, // Set if parent was a cygwin app.
PID_SPLIT_HEAP = 0x0100, // Set if the heap has been split,
// which means we can't fork again.
PID_CLEAR = 0x0200, // Flag that pid should be cleared from parent's
// wait list
PID_SOCKETS_USED = 0x0400, // Set if process uses Winsock.
PID_INITIALIZING = 0x0800, // Set until ready to receive signals.
PID_USETTY = 0x1000, // Setting this enables or disables cygwin's
// tty support. This is inherited by
// all execed or forked processes.
PID_REPARENT = 0x2000 // child has execed
};
#ifdef WINVER
/* This lives in the app and is initialized before jumping into the DLL.
It should only contain stuff which the user's process needs to see, or
which is needed before the user pointer is initialized, or is needed to
@ -126,11 +179,6 @@ struct per_process
};
#define per_process_overwrite ((unsigned) &(((struct per_process *) NULL)->resourcelocks))
#ifdef _PATH_PASSWD
extern HANDLE cygwin_logon_user (const struct passwd *, const char *);
#endif
#ifdef WINVER
extern void cygwin_set_impersonation_token (const HANDLE);
/* included if <windows.h> is included */
@ -139,21 +187,6 @@ extern int cygwin_attach_handle_to_fd (char *, int, HANDLE, mode_t, DWORD);
#include <sys/resource.h>
/* External interface stuff */
typedef enum
{
CW_LOCK_PINFO,
CW_UNLOCK_PINFO,
CW_GETTHREADNAME,
CW_GETPINFO,
CW_SETPINFO,
CW_SETTHREADNAME,
CW_GETVERSIONINFO,
CW_READ_V1_MOUNT_TABLES,
CW_USER_DATA
} cygwin_getinfo_types;
struct external_pinfo
{
pid_t pid;
@ -182,32 +215,6 @@ struct external_pinfo
DWORD cygwin_internal (cygwin_getinfo_types, ...);
#endif /*WINVER*/
#define CW_NEXTPID 0x80000000 // or with pid to get next one
/* Flags associated with process_state */
enum
{
PID_NOT_IN_USE = 0x0000, // Free entry.
PID_IN_USE = 0x0001, // Entry in use.
PID_ZOMBIE = 0x0002, // Child exited: no parent wait.
PID_STOPPED = 0x0004, // Waiting for SIGCONT.
PID_TTYIN = 0x0008, // Waiting for terminal input.
PID_TTYOU = 0x0010, // Waiting for terminal output.
PID_ORPHANED = 0x0020, // Member of an orphaned process group.
PID_ACTIVE = 0x0040, // Pid accepts signals.
PID_CYGPARENT = 0x0080, // Set if parent was a cygwin app.
PID_SPLIT_HEAP = 0x0100, // Set if the heap has been split,
// which means we can't fork again.
PID_CLEAR = 0x0200, // Flag that pid should be cleared from parent's
// wait list
PID_SOCKETS_USED = 0x0400, // Set if process uses Winsock.
PID_INITIALIZING = 0x0800, // Set until ready to receive signals.
PID_USETTY = 0x1000, // Setting this enables or disables cygwin's
// tty support. This is inherited by
// all execed or forked processes.
PID_REPARENT = 0x2000 // child has execed
};
#ifdef __cplusplus
};
#endif

View File

@ -1494,11 +1494,22 @@ setmode_helper (FILE *f)
return 0;
}
extern "C" int
getmode (int fd)
{
if (dtable.not_open (fd))
{
set_errno (EBADF);
return -1;
}
return dtable[fd]->get_flags () & (O_BINARY | O_TEXT);
}
/* Set a file descriptor into text or binary mode, returning the
previous mode. */
extern "C"
int
extern "C" int
setmode (int fd, int mode)
{
if (dtable.not_open (fd))