2000-10-27 17:50:33 +08:00
|
|
|
/* fhandler_socket.cc. See fhandler.h for a description of the fhandler classes.
|
|
|
|
|
2005-02-20 12:25:33 +08:00
|
|
|
Copyright 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
|
2000-10-27 17:50:33 +08:00
|
|
|
|
|
|
|
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. */
|
|
|
|
|
|
|
|
/* #define DEBUG_NEST_ON 1 */
|
|
|
|
|
|
|
|
#define __INSIDE_CYGWIN_NET__
|
|
|
|
|
|
|
|
#include "winsup.h"
|
|
|
|
#include <sys/socket.h>
|
2002-06-27 03:25:09 +08:00
|
|
|
#include <sys/un.h>
|
|
|
|
#include <sys/uio.h>
|
2001-05-15 16:42:15 +08:00
|
|
|
#include <asm/byteorder.h>
|
2006-02-01 19:10:53 +08:00
|
|
|
#include <iphlpapi.h>
|
2000-10-27 17:50:33 +08:00
|
|
|
|
2001-04-09 15:21:32 +08:00
|
|
|
#include <stdlib.h>
|
2001-03-21 03:50:28 +08:00
|
|
|
#define USE_SYS_TYPES_FD_SET
|
2000-10-27 17:50:33 +08:00
|
|
|
#include <winsock2.h>
|
|
|
|
#include "cygerrno.h"
|
2001-07-27 03:22:24 +08:00
|
|
|
#include "security.h"
|
2001-08-07 08:01:42 +08:00
|
|
|
#include "cygwin/version.h"
|
|
|
|
#include "perprocess.h"
|
2001-10-01 12:10:07 +08:00
|
|
|
#include "path.h"
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
#include "fhandler.h"
|
2000-10-27 17:50:33 +08:00
|
|
|
#include "dtable.h"
|
2001-04-19 05:10:15 +08:00
|
|
|
#include "cygheap.h"
|
2000-10-27 17:50:33 +08:00
|
|
|
#include "sigproc.h"
|
2003-06-03 01:52:16 +08:00
|
|
|
#include "cygthread.h"
|
2003-06-03 22:05:17 +08:00
|
|
|
#include "select.h"
|
2004-05-16 12:18:50 +08:00
|
|
|
#include "wininfo.h"
|
2002-10-21 09:00:58 +08:00
|
|
|
#include <unistd.h>
|
2005-02-20 04:03:18 +08:00
|
|
|
#include <sys/acl.h>
|
2005-07-03 10:40:30 +08:00
|
|
|
#include "cygtls.h"
|
2000-10-27 17:50:33 +08:00
|
|
|
|
2005-03-22 02:56:50 +08:00
|
|
|
#define ASYNC_MASK (FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT)
|
|
|
|
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
extern bool fdsock (cygheap_fdmanip& fd, const device *, SOCKET soc);
|
2002-06-27 03:25:09 +08:00
|
|
|
extern "C" {
|
|
|
|
int sscanf (const char *, const char *, ...);
|
|
|
|
} /* End of "C" section */
|
|
|
|
|
2001-09-06 12:41:59 +08:00
|
|
|
fhandler_dev_random* entropy_source;
|
2001-04-09 15:21:32 +08:00
|
|
|
|
2002-06-27 03:25:09 +08:00
|
|
|
/* cygwin internal: map sockaddr into internet domain address */
|
|
|
|
static int
|
|
|
|
get_inet_addr (const struct sockaddr *in, int inlen,
|
2005-04-07 02:50:13 +08:00
|
|
|
struct sockaddr_in *out, int *outlen,
|
|
|
|
int *type = NULL, int *secret = NULL)
|
2002-06-27 03:25:09 +08:00
|
|
|
{
|
|
|
|
int secret_buf [4];
|
|
|
|
int* secret_ptr = (secret ? : secret_buf);
|
|
|
|
|
|
|
|
if (in->sa_family == AF_INET)
|
|
|
|
{
|
2005-03-24 01:27:18 +08:00
|
|
|
*out = * (struct sockaddr_in *)in;
|
2002-06-27 03:25:09 +08:00
|
|
|
*outlen = inlen;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else if (in->sa_family == AF_LOCAL)
|
|
|
|
{
|
2003-03-01 23:28:24 +08:00
|
|
|
path_conv pc (in->sa_data, PC_SYM_FOLLOW);
|
|
|
|
if (pc.error)
|
2003-03-10 04:31:07 +08:00
|
|
|
{
|
2003-03-01 23:28:24 +08:00
|
|
|
set_errno (pc.error);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (!pc.exists ())
|
2003-03-10 04:31:07 +08:00
|
|
|
{
|
2003-03-01 23:28:24 +08:00
|
|
|
set_errno (ENOENT);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (!pc.issocket ())
|
2003-03-10 04:31:07 +08:00
|
|
|
{
|
2003-03-01 23:28:24 +08:00
|
|
|
set_errno (EBADF);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
HANDLE fh = CreateFile (pc, GENERIC_READ, wincap.shared (), &sec_none,
|
|
|
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
|
|
|
if (fh == INVALID_HANDLE_VALUE)
|
2003-03-10 04:31:07 +08:00
|
|
|
{
|
2003-03-01 23:28:24 +08:00
|
|
|
__seterrno ();
|
|
|
|
return 0;
|
|
|
|
}
|
2002-06-27 03:25:09 +08:00
|
|
|
int ret = 0;
|
2003-03-01 23:28:24 +08:00
|
|
|
DWORD len = 0;
|
2002-06-27 03:25:09 +08:00
|
|
|
char buf[128];
|
|
|
|
memset (buf, 0, sizeof buf);
|
2003-03-01 23:28:24 +08:00
|
|
|
if (ReadFile (fh, buf, 128, &len, 0))
|
2003-03-10 04:31:07 +08:00
|
|
|
{
|
2005-03-24 01:27:18 +08:00
|
|
|
struct sockaddr_in sin;
|
2005-04-07 02:50:13 +08:00
|
|
|
char ctype;
|
2002-09-30 23:17:44 +08:00
|
|
|
sin.sin_family = AF_INET;
|
2005-04-07 02:50:13 +08:00
|
|
|
sscanf (buf + strlen (SOCKET_COOKIE), "%hu %c %08x-%08x-%08x-%08x",
|
2002-09-30 23:17:44 +08:00
|
|
|
&sin.sin_port,
|
2005-04-07 02:50:13 +08:00
|
|
|
&ctype,
|
2002-09-30 23:17:44 +08:00
|
|
|
secret_ptr, secret_ptr + 1, secret_ptr + 2, secret_ptr + 3);
|
|
|
|
sin.sin_port = htons (sin.sin_port);
|
|
|
|
sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
|
|
|
|
*out = sin;
|
|
|
|
*outlen = sizeof sin;
|
2005-04-07 02:50:13 +08:00
|
|
|
if (type)
|
|
|
|
*type = (ctype == 's' ? SOCK_STREAM :
|
2005-05-02 11:50:11 +08:00
|
|
|
ctype == 'd' ? SOCK_DGRAM
|
|
|
|
: 0);
|
2002-09-30 23:17:44 +08:00
|
|
|
ret = 1;
|
|
|
|
}
|
2005-05-03 22:07:19 +08:00
|
|
|
else
|
2005-08-12 10:39:13 +08:00
|
|
|
__seterrno ();
|
2003-03-01 23:28:24 +08:00
|
|
|
CloseHandle (fh);
|
2002-06-27 03:25:09 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
set_errno (EAFNOSUPPORT);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-10-27 17:50:33 +08:00
|
|
|
/**********************************************************************/
|
|
|
|
/* fhandler_socket */
|
|
|
|
|
2004-04-09 16:43:29 +08:00
|
|
|
fhandler_socket::fhandler_socket () :
|
|
|
|
fhandler_base (),
|
|
|
|
sun_path (NULL),
|
2004-04-09 20:09:45 +08:00
|
|
|
status ()
|
2000-10-27 17:50:33 +08:00
|
|
|
{
|
2004-04-10 21:45:10 +08:00
|
|
|
need_fork_fixup (true);
|
2001-11-05 14:09:15 +08:00
|
|
|
prot_info_ptr = (LPWSAPROTOCOL_INFOA) cmalloc (HEAP_BUF,
|
2001-09-08 05:32:07 +08:00
|
|
|
sizeof (WSAPROTOCOL_INFOA));
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
#if 0
|
|
|
|
if (pc.is_fs_special ())
|
|
|
|
{
|
|
|
|
fhandler_socket * fhs = (fhandler_socket *) fh;
|
|
|
|
fhs->set_addr_family (AF_LOCAL);
|
|
|
|
fhs->set_sun_path (posix_path);
|
|
|
|
}
|
|
|
|
#endif
|
2000-10-27 17:50:33 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
fhandler_socket::~fhandler_socket ()
|
|
|
|
{
|
|
|
|
if (prot_info_ptr)
|
|
|
|
cfree (prot_info_ptr);
|
2002-01-02 00:25:31 +08:00
|
|
|
if (sun_path)
|
|
|
|
cfree (sun_path);
|
2000-10-27 17:50:33 +08:00
|
|
|
}
|
|
|
|
|
2005-03-24 22:04:06 +08:00
|
|
|
char *
|
|
|
|
fhandler_socket::get_proc_fd_name (char *buf)
|
|
|
|
{
|
|
|
|
__small_sprintf (buf, "socket:[%d]", get_socket ());
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_socket::open (int flags, mode_t mode)
|
|
|
|
{
|
|
|
|
set_errno (ENXIO);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-03-22 02:56:50 +08:00
|
|
|
void
|
2005-07-05 11:16:46 +08:00
|
|
|
fhandler_socket::af_local_set_sockpair_cred ()
|
2005-03-22 02:56:50 +08:00
|
|
|
{
|
|
|
|
sec_pid = sec_peer_pid = getpid ();
|
|
|
|
sec_uid = sec_peer_uid = geteuid32 ();
|
|
|
|
sec_gid = sec_peer_gid = getegid32 ();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2005-03-24 22:04:06 +08:00
|
|
|
fhandler_socket::af_local_setblocking (bool &async, bool &nonblocking)
|
2005-03-22 02:56:50 +08:00
|
|
|
{
|
|
|
|
async = async_io ();
|
|
|
|
nonblocking = is_nonblocking ();
|
|
|
|
if (async || nonblocking)
|
|
|
|
WSAAsyncSelect (get_socket (), winmsg, 0, 0);
|
|
|
|
unsigned long p = 0;
|
|
|
|
ioctlsocket (get_socket (), FIONBIO, &p);
|
|
|
|
set_nonblocking (false);
|
|
|
|
async_io (false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2005-03-24 22:04:06 +08:00
|
|
|
fhandler_socket::af_local_unsetblocking (bool async, bool nonblocking)
|
2005-03-22 02:56:50 +08:00
|
|
|
{
|
|
|
|
if (nonblocking)
|
|
|
|
{
|
|
|
|
unsigned long p = 1;
|
|
|
|
ioctlsocket (get_socket (), FIONBIO, &p);
|
|
|
|
set_nonblocking (true);
|
|
|
|
}
|
|
|
|
if (async)
|
|
|
|
{
|
|
|
|
WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO, ASYNC_MASK);
|
|
|
|
async_io (true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2005-07-05 11:16:46 +08:00
|
|
|
fhandler_socket::af_local_recv_secret ()
|
2005-03-24 22:04:06 +08:00
|
|
|
{
|
|
|
|
int out[4] = { 0, 0, 0, 0 };
|
|
|
|
int rest = sizeof out;
|
|
|
|
char *ptr = (char *) out;
|
|
|
|
while (rest > 0)
|
|
|
|
{
|
|
|
|
int ret = recvfrom (ptr, rest, 0, NULL, NULL);
|
|
|
|
if (ret <= 0)
|
|
|
|
break;
|
|
|
|
rest -= ret;
|
|
|
|
ptr += ret;
|
|
|
|
}
|
|
|
|
if (rest == 0)
|
|
|
|
{
|
|
|
|
debug_printf ("Received af_local secret: %08x-%08x-%08x-%08x",
|
|
|
|
out[0], out[1], out[2], out[3]);
|
|
|
|
if (out[0] != connect_secret[0] || out[1] != connect_secret[1]
|
2005-05-02 11:50:11 +08:00
|
|
|
|| out[2] != connect_secret[2] || out[3] != connect_secret[3])
|
2005-03-24 22:04:06 +08:00
|
|
|
{
|
|
|
|
debug_printf ("Receiving af_local secret mismatch");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
debug_printf ("Receiving af_local secret failed");
|
|
|
|
return rest == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2005-07-05 11:16:46 +08:00
|
|
|
fhandler_socket::af_local_send_secret ()
|
2005-03-24 22:04:06 +08:00
|
|
|
{
|
|
|
|
int rest = sizeof connect_secret;
|
|
|
|
char *ptr = (char *) connect_secret;
|
|
|
|
while (rest > 0)
|
|
|
|
{
|
|
|
|
int ret = sendto (ptr, rest, 0, NULL, 0);
|
|
|
|
if (ret <= 0)
|
|
|
|
break;
|
|
|
|
rest -= ret;
|
|
|
|
ptr += ret;
|
|
|
|
}
|
|
|
|
debug_printf ("Sending af_local secret %s", rest == 0 ? "succeeded"
|
|
|
|
: "failed");
|
|
|
|
return rest == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2005-07-05 11:16:46 +08:00
|
|
|
fhandler_socket::af_local_recv_cred ()
|
2005-03-22 02:56:50 +08:00
|
|
|
{
|
|
|
|
struct ucred out = { (pid_t) 0, (__uid32_t) -1, (__gid32_t) -1 };
|
|
|
|
int rest = sizeof out;
|
|
|
|
char *ptr = (char *) &out;
|
|
|
|
while (rest > 0)
|
|
|
|
{
|
|
|
|
int ret = recvfrom (ptr, rest, 0, NULL, NULL);
|
|
|
|
if (ret <= 0)
|
|
|
|
break;
|
|
|
|
rest -= ret;
|
|
|
|
ptr += ret;
|
|
|
|
}
|
|
|
|
if (rest == 0)
|
|
|
|
{
|
|
|
|
debug_printf ("Received eid credentials: pid: %d, uid: %d, gid: %d",
|
|
|
|
out.pid, out.uid, out.gid);
|
|
|
|
sec_peer_pid = out.pid;
|
|
|
|
sec_peer_uid = out.uid;
|
|
|
|
sec_peer_gid = out.gid;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
debug_printf ("Receiving eid credentials failed");
|
|
|
|
return rest == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2005-07-05 11:16:46 +08:00
|
|
|
fhandler_socket::af_local_send_cred ()
|
2005-03-22 02:56:50 +08:00
|
|
|
{
|
|
|
|
struct ucred in = { sec_pid, sec_uid, sec_gid };
|
|
|
|
int rest = sizeof in;
|
|
|
|
char *ptr = (char *) ∈
|
|
|
|
while (rest > 0)
|
|
|
|
{
|
|
|
|
int ret = sendto (ptr, rest, 0, NULL, 0);
|
|
|
|
if (ret <= 0)
|
|
|
|
break;
|
|
|
|
rest -= ret;
|
|
|
|
ptr += ret;
|
|
|
|
}
|
|
|
|
if (rest == 0)
|
|
|
|
debug_printf ("Sending eid credentials succeeded");
|
|
|
|
else
|
|
|
|
debug_printf ("Sending eid credentials failed");
|
|
|
|
return rest == 0;
|
|
|
|
}
|
|
|
|
|
2005-03-24 22:04:06 +08:00
|
|
|
int
|
2005-07-05 11:16:46 +08:00
|
|
|
fhandler_socket::af_local_connect ()
|
2005-03-22 02:56:50 +08:00
|
|
|
{
|
2005-03-24 22:04:06 +08:00
|
|
|
/* This keeps the test out of select. */
|
|
|
|
if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
debug_printf ("af_local_connect called");
|
2005-03-22 02:56:50 +08:00
|
|
|
bool orig_async_io, orig_is_nonblocking;
|
2005-03-24 22:04:06 +08:00
|
|
|
af_local_setblocking (orig_async_io, orig_is_nonblocking);
|
|
|
|
if (!af_local_send_secret () || !af_local_recv_secret ()
|
|
|
|
|| !af_local_send_cred () || !af_local_recv_cred ())
|
|
|
|
{
|
|
|
|
debug_printf ("accept from unauthorized server");
|
|
|
|
::shutdown (get_socket (), SD_BOTH);
|
|
|
|
WSASetLastError (WSAECONNREFUSED);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
af_local_unsetblocking (orig_async_io, orig_is_nonblocking);
|
|
|
|
return 0;
|
2005-03-22 02:56:50 +08:00
|
|
|
}
|
|
|
|
|
2005-03-24 22:04:06 +08:00
|
|
|
int
|
2005-07-05 11:16:46 +08:00
|
|
|
fhandler_socket::af_local_accept ()
|
2005-03-22 02:56:50 +08:00
|
|
|
{
|
2005-03-24 22:04:06 +08:00
|
|
|
debug_printf ("af_local_accept called");
|
2005-03-22 02:56:50 +08:00
|
|
|
bool orig_async_io, orig_is_nonblocking;
|
2005-03-24 22:04:06 +08:00
|
|
|
af_local_setblocking (orig_async_io, orig_is_nonblocking);
|
|
|
|
if (!af_local_recv_secret () || !af_local_send_secret ()
|
|
|
|
|| !af_local_recv_cred () || !af_local_send_cred ())
|
|
|
|
{
|
|
|
|
debug_printf ("connect from unauthorized client");
|
|
|
|
::shutdown (get_socket (), SD_BOTH);
|
|
|
|
::closesocket (get_socket ());
|
|
|
|
WSASetLastError (WSAECONNABORTED);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
af_local_unsetblocking (orig_async_io, orig_is_nonblocking);
|
|
|
|
return 0;
|
2005-03-22 02:56:50 +08:00
|
|
|
}
|
|
|
|
|
2005-03-24 22:04:06 +08:00
|
|
|
void
|
2005-07-05 11:16:46 +08:00
|
|
|
fhandler_socket::af_local_set_cred ()
|
2005-01-31 18:28:55 +08:00
|
|
|
{
|
2005-03-24 22:04:06 +08:00
|
|
|
sec_pid = getpid ();
|
|
|
|
sec_uid = geteuid32 ();
|
|
|
|
sec_gid = getegid32 ();
|
|
|
|
sec_peer_pid = (pid_t) 0;
|
|
|
|
sec_peer_uid = (__uid32_t) -1;
|
|
|
|
sec_peer_gid = (__gid32_t) -1;
|
2005-01-31 18:28:55 +08:00
|
|
|
}
|
|
|
|
|
2005-03-24 22:04:06 +08:00
|
|
|
void
|
|
|
|
fhandler_socket::af_local_copy (fhandler_socket *sock)
|
2005-02-01 23:11:47 +08:00
|
|
|
{
|
2005-03-24 22:04:06 +08:00
|
|
|
sock->connect_secret[0] = connect_secret[0];
|
|
|
|
sock->connect_secret[1] = connect_secret[1];
|
|
|
|
sock->connect_secret[2] = connect_secret[2];
|
|
|
|
sock->connect_secret[3] = connect_secret[3];
|
|
|
|
sock->sec_pid = sec_pid;
|
|
|
|
sock->sec_uid = sec_uid;
|
|
|
|
sock->sec_gid = sec_gid;
|
|
|
|
sock->sec_peer_pid = sec_peer_pid;
|
|
|
|
sock->sec_peer_uid = sec_peer_uid;
|
|
|
|
sock->sec_peer_gid = sec_peer_gid;
|
2005-02-01 23:11:47 +08:00
|
|
|
}
|
|
|
|
|
2001-04-09 15:21:32 +08:00
|
|
|
void
|
2005-03-24 22:04:06 +08:00
|
|
|
fhandler_socket::af_local_set_secret (char *buf)
|
2001-04-09 15:21:32 +08:00
|
|
|
{
|
2001-05-05 00:30:18 +08:00
|
|
|
if (!entropy_source)
|
|
|
|
{
|
|
|
|
void *buf = malloc (sizeof (fhandler_dev_random));
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
entropy_source = new (buf) fhandler_dev_random ();
|
|
|
|
entropy_source->dev () = *urandom_dev;
|
2001-05-05 00:30:18 +08:00
|
|
|
}
|
|
|
|
if (entropy_source &&
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
!entropy_source->open (O_RDONLY))
|
2001-05-05 00:30:18 +08:00
|
|
|
{
|
|
|
|
delete entropy_source;
|
|
|
|
entropy_source = NULL;
|
|
|
|
}
|
2003-05-20 23:22:09 +08:00
|
|
|
if (entropy_source)
|
2002-12-14 12:01:32 +08:00
|
|
|
{
|
|
|
|
size_t len = sizeof (connect_secret);
|
|
|
|
entropy_source->read (connect_secret, len);
|
|
|
|
if (len != sizeof (connect_secret))
|
|
|
|
bzero ((char*) connect_secret, sizeof (connect_secret));
|
|
|
|
}
|
2001-04-09 15:21:32 +08:00
|
|
|
__small_sprintf (buf, "%08x-%08x-%08x-%08x",
|
|
|
|
connect_secret [0], connect_secret [1],
|
|
|
|
connect_secret [2], connect_secret [3]);
|
|
|
|
}
|
|
|
|
|
2000-10-27 17:50:33 +08:00
|
|
|
void
|
|
|
|
fhandler_socket::fixup_before_fork_exec (DWORD win_proc_id)
|
|
|
|
{
|
2005-10-18 05:22:18 +08:00
|
|
|
if (!WSADuplicateSocketA (get_socket (), win_proc_id, prot_info_ptr))
|
2001-10-30 15:43:46 +08:00
|
|
|
debug_printf ("WSADuplicateSocket went fine, sock %p, win_proc_id %d, prot_info_ptr %p",
|
|
|
|
get_socket (), win_proc_id, prot_info_ptr);
|
2000-10-27 17:50:33 +08:00
|
|
|
else
|
|
|
|
{
|
2001-10-30 15:43:46 +08:00
|
|
|
debug_printf ("WSADuplicateSocket error, sock %p, win_proc_id %d, prot_info_ptr %p",
|
2001-11-05 14:09:15 +08:00
|
|
|
get_socket (), win_proc_id, prot_info_ptr);
|
2001-10-14 01:23:35 +08:00
|
|
|
set_winsock_errno ();
|
2000-10-27 17:50:33 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2002-06-10 19:07:44 +08:00
|
|
|
fhandler_socket::fixup_after_fork (HANDLE parent)
|
2000-10-27 17:50:33 +08:00
|
|
|
{
|
2001-10-14 01:23:35 +08:00
|
|
|
SOCKET new_sock;
|
2000-10-27 17:50:33 +08:00
|
|
|
|
|
|
|
debug_printf ("WSASocket begin, dwServiceFlags1=%d",
|
|
|
|
prot_info_ptr->dwServiceFlags1);
|
2001-10-14 01:23:35 +08:00
|
|
|
|
|
|
|
if ((new_sock = WSASocketA (FROM_PROTOCOL_INFO,
|
|
|
|
FROM_PROTOCOL_INFO,
|
|
|
|
FROM_PROTOCOL_INFO,
|
|
|
|
prot_info_ptr, 0, 0)) == INVALID_SOCKET)
|
2000-10-27 17:50:33 +08:00
|
|
|
{
|
|
|
|
debug_printf ("WSASocket error");
|
2003-03-11 21:05:36 +08:00
|
|
|
set_io_handle ((HANDLE)INVALID_SOCKET);
|
2000-10-27 17:50:33 +08:00
|
|
|
set_winsock_errno ();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-01-23 23:10:57 +08:00
|
|
|
debug_printf ("WSASocket went fine new_sock %p, old_sock %p", new_sock, get_socket ());
|
|
|
|
|
|
|
|
/* Go figure! Even though the original socket was not inheritable,
|
|
|
|
the duplicated socket is inheritable again. This can lead to all
|
|
|
|
sorts of trouble, apparently. Note that there's no way to prevent
|
|
|
|
this on 9x, not even by trying to reset socket inheritance using
|
|
|
|
DuplicateHandle and closing the original socket. */
|
|
|
|
if (wincap.has_set_handle_information ())
|
|
|
|
SetHandleInformation ((HANDLE) new_sock, HANDLE_FLAG_INHERIT, 0);
|
|
|
|
|
2001-10-14 01:23:35 +08:00
|
|
|
set_io_handle ((HANDLE) new_sock);
|
2000-10-27 17:50:33 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-09-20 19:29:48 +08:00
|
|
|
void
|
2004-02-03 05:00:07 +08:00
|
|
|
fhandler_socket::fixup_after_exec ()
|
2001-09-20 19:29:48 +08:00
|
|
|
{
|
2004-04-10 21:45:10 +08:00
|
|
|
if (!close_on_exec ())
|
2004-02-03 05:00:07 +08:00
|
|
|
fixup_after_fork (NULL);
|
2001-09-20 19:29:48 +08:00
|
|
|
}
|
|
|
|
|
2000-10-27 17:50:33 +08:00
|
|
|
int
|
2005-09-29 03:22:25 +08:00
|
|
|
fhandler_socket::dup (fhandler_base *child)
|
2000-10-27 17:50:33 +08:00
|
|
|
{
|
2005-02-28 21:11:50 +08:00
|
|
|
HANDLE nh;
|
|
|
|
|
2001-10-14 01:23:35 +08:00
|
|
|
debug_printf ("here");
|
2000-10-27 17:50:33 +08:00
|
|
|
fhandler_socket *fhs = (fhandler_socket *) child;
|
2001-04-09 15:21:32 +08:00
|
|
|
fhs->addr_family = addr_family;
|
2003-03-05 00:35:00 +08:00
|
|
|
fhs->set_socket_type (get_socket_type ());
|
2005-02-28 21:11:50 +08:00
|
|
|
if (get_addr_family () == AF_LOCAL)
|
|
|
|
{
|
|
|
|
fhs->set_sun_path (get_sun_path ());
|
|
|
|
if (get_socket_type () == SOCK_STREAM)
|
2005-05-02 11:50:11 +08:00
|
|
|
{
|
2005-02-28 21:11:50 +08:00
|
|
|
fhs->sec_pid = sec_pid;
|
|
|
|
fhs->sec_uid = sec_uid;
|
|
|
|
fhs->sec_gid = sec_gid;
|
|
|
|
fhs->sec_peer_pid = sec_peer_pid;
|
|
|
|
fhs->sec_peer_uid = sec_peer_uid;
|
|
|
|
fhs->sec_peer_gid = sec_peer_gid;
|
|
|
|
}
|
|
|
|
}
|
2004-04-10 21:45:10 +08:00
|
|
|
fhs->connect_state (connect_state ());
|
2001-10-30 15:43:46 +08:00
|
|
|
|
2005-10-18 05:22:18 +08:00
|
|
|
/* Since WSADuplicateSocket() fails on NT systems when the process
|
|
|
|
is currently impersonating a non-privileged account, we revert
|
|
|
|
to the original account before calling WSADuplicateSocket() and
|
|
|
|
switch back afterwards as it's also in fork().
|
|
|
|
If WSADuplicateSocket() still fails for some reason, we fall back
|
|
|
|
to DuplicateHandle(). */
|
|
|
|
WSASetLastError (0);
|
|
|
|
cygheap->user.deimpersonate ();
|
|
|
|
fhs->set_io_handle (get_io_handle ());
|
|
|
|
fhs->fixup_before_fork_exec (GetCurrentProcessId ());
|
|
|
|
cygheap->user.reimpersonate ();
|
|
|
|
if (!WSAGetLastError ())
|
2000-10-27 17:50:33 +08:00
|
|
|
{
|
2005-10-18 05:22:18 +08:00
|
|
|
fhs->fixup_after_fork (hMainProc);
|
|
|
|
if (fhs->get_io_handle() != (HANDLE) INVALID_SOCKET)
|
2003-05-30 00:16:59 +08:00
|
|
|
{
|
2005-10-18 05:22:18 +08:00
|
|
|
cygheap->fdtab.inc_need_fixup_before ();
|
|
|
|
return 0;
|
2003-05-30 00:16:59 +08:00
|
|
|
}
|
2000-10-27 17:50:33 +08:00
|
|
|
}
|
2005-10-18 05:22:18 +08:00
|
|
|
debug_printf ("WSADuplicateSocket failed, trying DuplicateHandle");
|
2003-05-27 15:50:00 +08:00
|
|
|
|
2004-10-27 05:13:50 +08:00
|
|
|
/* We don't call fhandler_base::dup here since that requires
|
|
|
|
having winsock called from fhandler_base and it creates only
|
2003-03-12 00:49:58 +08:00
|
|
|
inheritable sockets which is wrong for winsock2. */
|
2003-05-29 06:05:56 +08:00
|
|
|
|
2005-09-29 03:22:25 +08:00
|
|
|
if (!DuplicateHandle (hMainProc, get_io_handle (), hMainProc, &nh, 0,
|
2005-10-18 05:22:18 +08:00
|
|
|
FALSE, DUPLICATE_SAME_ACCESS))
|
2003-03-12 00:49:58 +08:00
|
|
|
{
|
2003-05-29 06:05:56 +08:00
|
|
|
system_printf ("!DuplicateHandle(%x) failed, %E", get_io_handle ());
|
2003-03-12 00:49:58 +08:00
|
|
|
__seterrno ();
|
|
|
|
return -1;
|
|
|
|
}
|
2004-01-24 07:05:33 +08:00
|
|
|
VerifyHandle (nh);
|
2003-05-30 00:16:59 +08:00
|
|
|
fhs->set_io_handle (nh);
|
2004-08-19 18:58:37 +08:00
|
|
|
cygheap->fdtab.inc_need_fixup_before ();
|
2003-03-12 00:49:58 +08:00
|
|
|
return 0;
|
2000-10-27 17:50:33 +08:00
|
|
|
}
|
|
|
|
|
2001-10-14 01:23:35 +08:00
|
|
|
int __stdcall
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
fhandler_socket::fstat (struct __stat64 *buf)
|
2001-10-14 01:23:35 +08:00
|
|
|
{
|
2005-02-20 04:03:18 +08:00
|
|
|
int res;
|
|
|
|
if (get_device () == FH_UNIX)
|
2002-06-24 10:23:14 +08:00
|
|
|
{
|
2005-02-20 04:03:18 +08:00
|
|
|
res = fhandler_base::fstat_fs (buf);
|
|
|
|
if (!res)
|
2005-05-02 11:50:11 +08:00
|
|
|
{
|
2005-02-20 04:03:18 +08:00
|
|
|
buf->st_mode = (buf->st_mode & ~S_IFMT) | S_IFSOCK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
res = fhandler_base::fstat (buf);
|
|
|
|
if (!res)
|
|
|
|
{
|
|
|
|
buf->st_dev = 0;
|
|
|
|
buf->st_ino = (__ino64_t) ((DWORD) get_handle ());
|
|
|
|
buf->st_mode = S_IFSOCK | S_IRWXU | S_IRWXG | S_IRWXO;
|
|
|
|
}
|
2002-06-24 10:23:14 +08:00
|
|
|
}
|
2002-06-08 09:24:58 +08:00
|
|
|
return res;
|
2001-10-14 01:23:35 +08:00
|
|
|
}
|
|
|
|
|
2005-02-20 04:03:18 +08:00
|
|
|
int
|
|
|
|
fhandler_socket::fchmod (mode_t mode)
|
|
|
|
{
|
|
|
|
if (get_device () == FH_UNIX)
|
|
|
|
{
|
2005-02-20 19:44:32 +08:00
|
|
|
fhandler_disk_file fh (pc);
|
2005-02-20 04:03:18 +08:00
|
|
|
fh.get_device () = FH_FS;
|
|
|
|
int ret = fh.fchmod (mode);
|
|
|
|
SetFileAttributes (pc, GetFileAttributes (pc) | FILE_ATTRIBUTE_SYSTEM);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_socket::fchown (__uid32_t uid, __gid32_t gid)
|
|
|
|
{
|
|
|
|
if (get_device () == FH_UNIX)
|
|
|
|
{
|
2005-02-20 19:44:32 +08:00
|
|
|
fhandler_disk_file fh (pc);
|
2005-02-20 04:03:18 +08:00
|
|
|
return fh.fchown (uid, gid);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_socket::facl (int cmd, int nentries, __aclent32_t *aclbufp)
|
|
|
|
{
|
|
|
|
if (get_device () == FH_UNIX)
|
|
|
|
{
|
2005-02-20 19:44:32 +08:00
|
|
|
fhandler_disk_file fh (pc);
|
2005-02-20 04:03:18 +08:00
|
|
|
return fh.facl (cmd, nentries, aclbufp);
|
|
|
|
}
|
|
|
|
return fhandler_base::facl (cmd, nentries, aclbufp);
|
|
|
|
}
|
|
|
|
|
2005-02-20 05:53:36 +08:00
|
|
|
int
|
|
|
|
fhandler_socket::link (const char *newpath)
|
|
|
|
{
|
|
|
|
if (get_device () == FH_UNIX)
|
|
|
|
{
|
2005-02-20 19:44:32 +08:00
|
|
|
fhandler_disk_file fh (pc);
|
2005-02-20 05:53:36 +08:00
|
|
|
return fh.link (newpath);
|
|
|
|
}
|
|
|
|
return fhandler_base::link (newpath);
|
|
|
|
}
|
|
|
|
|
2006-02-01 19:10:53 +08:00
|
|
|
static inline bool
|
|
|
|
address_in_use (struct sockaddr_in *addr)
|
|
|
|
{
|
|
|
|
PMIB_TCPTABLE tab;
|
|
|
|
PMIB_TCPROW entry;
|
|
|
|
DWORD size = 0, i;
|
|
|
|
|
|
|
|
if (GetTcpTable (NULL, &size, FALSE) == ERROR_INSUFFICIENT_BUFFER)
|
|
|
|
{
|
|
|
|
tab = (PMIB_TCPTABLE) alloca (size);
|
|
|
|
if (!GetTcpTable (tab, &size, FALSE))
|
|
|
|
{
|
|
|
|
for (i = tab->dwNumEntries, entry = tab->table; i > 0; --i, ++entry)
|
|
|
|
if (entry->dwLocalAddr == addr->sin_addr.s_addr
|
|
|
|
&& entry->dwLocalPort == addr->sin_port
|
|
|
|
&& entry->dwState >= MIB_TCP_STATE_LISTEN
|
|
|
|
&& entry->dwState <= MIB_TCP_STATE_LAST_ACK)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2002-06-27 03:25:09 +08:00
|
|
|
int
|
|
|
|
fhandler_socket::bind (const struct sockaddr *name, int namelen)
|
|
|
|
{
|
|
|
|
int res = -1;
|
|
|
|
|
|
|
|
if (name->sa_family == AF_LOCAL)
|
|
|
|
{
|
|
|
|
#define un_addr ((struct sockaddr_un *) name)
|
|
|
|
struct sockaddr_in sin;
|
2002-09-19 11:30:20 +08:00
|
|
|
int len = sizeof sin;
|
2002-06-27 03:25:09 +08:00
|
|
|
|
|
|
|
if (strlen (un_addr->sun_path) >= UNIX_PATH_LEN)
|
|
|
|
{
|
|
|
|
set_errno (ENAMETOOLONG);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
sin.sin_family = AF_INET;
|
|
|
|
sin.sin_port = 0;
|
|
|
|
sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
|
|
|
|
if (::bind (get_socket (), (sockaddr *) &sin, len))
|
|
|
|
{
|
|
|
|
syscall_printf ("AF_LOCAL: bind failed %d", get_errno ());
|
|
|
|
set_winsock_errno ();
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
if (::getsockname (get_socket (), (sockaddr *) &sin, &len))
|
|
|
|
{
|
|
|
|
syscall_printf ("AF_LOCAL: getsockname failed %d", get_errno ());
|
|
|
|
set_winsock_errno ();
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
sin.sin_port = ntohs (sin.sin_port);
|
|
|
|
debug_printf ("AF_LOCAL: socket bound to port %u", sin.sin_port);
|
|
|
|
|
2003-03-02 00:17:55 +08:00
|
|
|
path_conv pc (un_addr->sun_path, PC_SYM_FOLLOW);
|
|
|
|
if (pc.error)
|
2003-03-10 04:31:07 +08:00
|
|
|
{
|
|
|
|
set_errno (pc.error);
|
2002-06-27 03:25:09 +08:00
|
|
|
goto out;
|
|
|
|
}
|
2003-03-02 00:17:55 +08:00
|
|
|
if (pc.exists ())
|
2003-03-10 04:31:07 +08:00
|
|
|
{
|
2003-03-02 00:17:55 +08:00
|
|
|
set_errno (EADDRINUSE);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
mode_t mode = (S_IRWXU | S_IRWXG | S_IRWXO) & ~cygheap->umask;
|
|
|
|
DWORD attr = FILE_ATTRIBUTE_SYSTEM;
|
|
|
|
if (!(mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
|
2003-03-10 04:31:07 +08:00
|
|
|
attr |= FILE_ATTRIBUTE_READONLY;
|
2003-03-02 00:17:55 +08:00
|
|
|
SECURITY_ATTRIBUTES sa = sec_none;
|
2003-11-26 21:23:27 +08:00
|
|
|
security_descriptor sd;
|
2003-03-02 00:17:55 +08:00
|
|
|
if (allow_ntsec && pc.has_acls ())
|
2003-11-26 21:23:27 +08:00
|
|
|
set_security_attribute (mode, &sa, sd);
|
2003-03-02 00:17:55 +08:00
|
|
|
HANDLE fh = CreateFile (pc, GENERIC_WRITE, 0, &sa, CREATE_NEW, attr, 0);
|
|
|
|
if (fh == INVALID_HANDLE_VALUE)
|
2003-03-10 04:31:07 +08:00
|
|
|
{
|
2003-03-02 00:17:55 +08:00
|
|
|
if (GetLastError () == ERROR_ALREADY_EXISTS)
|
|
|
|
set_errno (EADDRINUSE);
|
|
|
|
else
|
|
|
|
__seterrno ();
|
|
|
|
}
|
2002-06-27 03:25:09 +08:00
|
|
|
|
|
|
|
char buf[sizeof (SOCKET_COOKIE) + 80];
|
2005-04-07 02:50:13 +08:00
|
|
|
__small_sprintf (buf, "%s%u %c ", SOCKET_COOKIE, sin.sin_port, get_socket_type () == SOCK_STREAM ? 's' : get_socket_type () == SOCK_DGRAM ? 'd' : '-');
|
2005-03-24 22:04:06 +08:00
|
|
|
af_local_set_secret (strchr (buf, '\0'));
|
2003-03-02 00:17:55 +08:00
|
|
|
DWORD blen = strlen (buf) + 1;
|
|
|
|
if (!WriteFile (fh, buf, blen, &blen, 0))
|
2003-03-10 04:31:07 +08:00
|
|
|
{
|
2003-03-02 00:17:55 +08:00
|
|
|
__seterrno ();
|
|
|
|
CloseHandle (fh);
|
|
|
|
DeleteFile (pc);
|
2002-06-27 03:25:09 +08:00
|
|
|
}
|
|
|
|
else
|
2003-03-10 04:31:07 +08:00
|
|
|
{
|
2003-03-02 00:17:55 +08:00
|
|
|
CloseHandle (fh);
|
2002-06-27 03:25:09 +08:00
|
|
|
set_sun_path (un_addr->sun_path);
|
|
|
|
res = 0;
|
|
|
|
}
|
|
|
|
#undef un_addr
|
|
|
|
}
|
|
|
|
else
|
2006-01-29 20:23:44 +08:00
|
|
|
{
|
|
|
|
/* If the application didn't explicitely call setsockopt (SO_REUSEADDR),
|
|
|
|
enforce exclusive local address use using the SO_EXCLUSIVEADDRUSE
|
|
|
|
socket option, to emulate POSIX socket behaviour more closely.
|
|
|
|
|
|
|
|
KB 870562: Note that this option is only available since NT4 SP4.
|
|
|
|
Also note that a bug in Win2K SP1-3 and XP up to SP1 only enables
|
|
|
|
this option for users in the local administrators group. */
|
|
|
|
if (wincap.has_exclusiveaddruse ())
|
|
|
|
{
|
|
|
|
if (!saw_reuseaddr ())
|
|
|
|
{
|
|
|
|
int on = 1;
|
|
|
|
int ret = ::setsockopt (get_socket (), SOL_SOCKET,
|
|
|
|
~(SO_REUSEADDR),
|
|
|
|
(const char *) &on, sizeof on);
|
|
|
|
debug_printf ("%d = setsockopt (SO_EXCLUSIVEADDRUSE), %E", ret);
|
|
|
|
}
|
|
|
|
else
|
2006-02-01 19:10:53 +08:00
|
|
|
{
|
|
|
|
debug_printf ("SO_REUSEADDR set");
|
|
|
|
/* There's a bug in SO_REUSEADDR handling in WinSock.
|
|
|
|
Per standards, we must not be able to reuse a complete
|
|
|
|
duplicate of a local TCP address (same IP, same port),
|
|
|
|
even if SO_REUSEADDR has been set. That's unfortunately
|
|
|
|
possible in WinSock. So we're testing here if the local
|
|
|
|
address is already in use and don't bind, if so. This
|
|
|
|
only works for OSes with IP Helper support. */
|
|
|
|
if (get_socket_type () == SOCK_STREAM
|
|
|
|
&& wincap.has_ip_helper_lib ()
|
|
|
|
&& address_in_use ((struct sockaddr_in *) name))
|
|
|
|
{
|
|
|
|
debug_printf ("Local address in use, don't bind");
|
|
|
|
set_errno (EADDRINUSE);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
2006-01-29 20:23:44 +08:00
|
|
|
}
|
|
|
|
if (::bind (get_socket (), name, namelen))
|
|
|
|
set_winsock_errno ();
|
|
|
|
else
|
|
|
|
res = 0;
|
|
|
|
}
|
2002-06-27 03:25:09 +08:00
|
|
|
|
|
|
|
out:
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_socket::connect (const struct sockaddr *name, int namelen)
|
|
|
|
{
|
|
|
|
int res = -1;
|
2003-12-08 06:37:12 +08:00
|
|
|
bool in_progress = false;
|
2005-03-24 01:27:18 +08:00
|
|
|
struct sockaddr_in sin;
|
2003-06-07 19:05:35 +08:00
|
|
|
DWORD err;
|
2005-04-07 02:50:13 +08:00
|
|
|
int type;
|
2002-06-27 03:25:09 +08:00
|
|
|
|
2005-04-07 02:50:13 +08:00
|
|
|
if (!get_inet_addr (name, namelen, &sin, &namelen, &type, connect_secret))
|
2002-06-27 03:25:09 +08:00
|
|
|
return -1;
|
|
|
|
|
2005-04-07 02:50:13 +08:00
|
|
|
if (get_addr_family () == AF_LOCAL && get_socket_type () != type)
|
|
|
|
{
|
|
|
|
WSASetLastError (WSAEPROTOTYPE);
|
|
|
|
set_winsock_errno ();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2005-10-22 23:11:49 +08:00
|
|
|
if (is_nonblocking ())
|
|
|
|
res = ::connect (get_socket (), (struct sockaddr *) &sin, namelen);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
HANDLE evt;
|
|
|
|
if (prepare (evt, FD_CONNECT))
|
|
|
|
{
|
|
|
|
res = ::connect (get_socket (), (struct sockaddr *) &sin, namelen);
|
|
|
|
if (res == SOCKET_ERROR
|
|
|
|
&& WSAGetLastError () == WSAEWOULDBLOCK)
|
2006-02-07 01:50:23 +08:00
|
|
|
res = wait (evt, 0, INFINITE);
|
2005-10-22 23:11:49 +08:00
|
|
|
release (evt);
|
|
|
|
}
|
|
|
|
}
|
2003-02-28 05:41:28 +08:00
|
|
|
|
2005-03-23 03:00:31 +08:00
|
|
|
if (!res)
|
|
|
|
err = 0;
|
|
|
|
else
|
2002-06-27 03:25:09 +08:00
|
|
|
{
|
2005-03-22 02:56:50 +08:00
|
|
|
err = WSAGetLastError ();
|
2002-06-27 03:25:09 +08:00
|
|
|
/* Special handling for connect to return the correct error code
|
|
|
|
when called on a non-blocking socket. */
|
2005-04-19 02:56:52 +08:00
|
|
|
if (is_nonblocking ())
|
2002-06-27 03:25:09 +08:00
|
|
|
{
|
|
|
|
if (err == WSAEWOULDBLOCK || err == WSAEALREADY)
|
2003-12-08 06:37:12 +08:00
|
|
|
in_progress = true;
|
2003-06-07 19:05:35 +08:00
|
|
|
|
|
|
|
if (err == WSAEWOULDBLOCK)
|
2005-03-22 02:56:50 +08:00
|
|
|
WSASetLastError (err = WSAEINPROGRESS);
|
2002-06-27 03:25:09 +08:00
|
|
|
}
|
2005-10-23 00:02:15 +08:00
|
|
|
if (err == WSAEINVAL)
|
|
|
|
WSASetLastError (err = WSAEISCONN);
|
2002-06-27 03:25:09 +08:00
|
|
|
set_winsock_errno ();
|
|
|
|
}
|
2005-03-17 19:56:30 +08:00
|
|
|
|
|
|
|
if (get_addr_family () == AF_LOCAL && (!res || in_progress))
|
|
|
|
set_sun_path (name->sa_data);
|
|
|
|
|
2002-06-27 03:25:09 +08:00
|
|
|
if (get_addr_family () == AF_LOCAL && get_socket_type () == SOCK_STREAM)
|
|
|
|
{
|
2005-03-24 22:04:06 +08:00
|
|
|
af_local_set_cred (); /* Don't move into af_local_connect since
|
|
|
|
af_local_connect is called from select,
|
|
|
|
possibly running under another identity. */
|
|
|
|
if (!res && af_local_connect ())
|
|
|
|
{
|
|
|
|
set_winsock_errno ();
|
|
|
|
return -1;
|
2005-02-28 21:11:50 +08:00
|
|
|
}
|
2002-06-27 03:25:09 +08:00
|
|
|
}
|
|
|
|
|
2003-06-07 19:05:35 +08:00
|
|
|
if (err == WSAEINPROGRESS || err == WSAEALREADY)
|
2004-04-10 21:45:10 +08:00
|
|
|
connect_state (connect_pending);
|
2005-04-19 02:56:52 +08:00
|
|
|
else if (err)
|
|
|
|
connect_state (connect_failed);
|
2002-07-06 19:16:07 +08:00
|
|
|
else
|
2004-04-10 21:45:10 +08:00
|
|
|
connect_state (connected);
|
2003-02-28 05:41:28 +08:00
|
|
|
|
2002-06-27 03:25:09 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_socket::listen (int backlog)
|
|
|
|
{
|
|
|
|
int res = ::listen (get_socket (), backlog);
|
|
|
|
if (res)
|
|
|
|
set_winsock_errno ();
|
2002-07-06 02:26:23 +08:00
|
|
|
else
|
2005-02-24 01:39:46 +08:00
|
|
|
{
|
|
|
|
if (get_addr_family () == AF_LOCAL && get_socket_type () == SOCK_STREAM)
|
2005-03-24 22:04:06 +08:00
|
|
|
af_local_set_cred ();
|
2005-02-24 01:39:46 +08:00
|
|
|
connect_state (connected);
|
|
|
|
}
|
2002-06-27 03:25:09 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_socket::accept (struct sockaddr *peer, int *len)
|
|
|
|
{
|
|
|
|
int res = -1;
|
|
|
|
|
|
|
|
/* Allows NULL peer and len parameters. */
|
|
|
|
struct sockaddr_in peer_dummy;
|
|
|
|
int len_dummy;
|
|
|
|
if (!peer)
|
|
|
|
peer = (struct sockaddr *) &peer_dummy;
|
|
|
|
if (!len)
|
|
|
|
{
|
|
|
|
len_dummy = sizeof (struct sockaddr_in);
|
|
|
|
len = &len_dummy;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* accept on NT fails if len < sizeof (sockaddr_in)
|
|
|
|
* some programs set len to
|
|
|
|
* sizeof (name.sun_family) + strlen (name.sun_path) for UNIX domain
|
|
|
|
*/
|
|
|
|
if (len && ((unsigned) *len < sizeof (struct sockaddr_in)))
|
|
|
|
*len = sizeof (struct sockaddr_in);
|
|
|
|
|
2005-10-23 00:02:15 +08:00
|
|
|
if (is_nonblocking ())
|
|
|
|
res = ::accept (get_socket (), peer, len);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
HANDLE evt;
|
|
|
|
if (prepare (evt, FD_ACCEPT))
|
|
|
|
{
|
|
|
|
res = wait (evt, 0, INFINITE);
|
|
|
|
if (res != -1
|
|
|
|
|| (WSAGetLastError () != WSAEINTR
|
|
|
|
&& WSAGetLastError () != WSAEFAULT))
|
|
|
|
res = ::accept (get_socket (), peer, len);
|
|
|
|
release (evt);
|
|
|
|
}
|
|
|
|
}
|
2002-06-27 03:25:09 +08:00
|
|
|
|
2005-03-24 22:04:06 +08:00
|
|
|
if (res == (int) INVALID_SOCKET)
|
2003-01-28 23:33:50 +08:00
|
|
|
set_winsock_errno ();
|
|
|
|
else
|
|
|
|
{
|
2003-02-20 22:14:37 +08:00
|
|
|
cygheap_fdnew res_fd;
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
if (res_fd >= 0 && fdsock (res_fd, &dev (), res))
|
2004-05-29 03:50:07 +08:00
|
|
|
{
|
2005-03-22 02:56:50 +08:00
|
|
|
fhandler_socket *sock = (fhandler_socket *) res_fd;
|
|
|
|
sock->set_addr_family (get_addr_family ());
|
|
|
|
sock->set_socket_type (get_socket_type ());
|
|
|
|
sock->async_io (async_io ());
|
|
|
|
sock->set_nonblocking (is_nonblocking ());
|
2005-02-24 01:39:46 +08:00
|
|
|
if (get_addr_family () == AF_LOCAL)
|
|
|
|
{
|
2005-03-22 02:56:50 +08:00
|
|
|
sock->set_sun_path (get_sun_path ());
|
2005-02-24 01:39:46 +08:00
|
|
|
if (get_socket_type () == SOCK_STREAM)
|
2005-05-02 11:50:11 +08:00
|
|
|
{
|
2005-03-22 02:56:50 +08:00
|
|
|
/* Don't forget to copy credentials from accepting
|
|
|
|
socket to accepted socket and start transaction
|
|
|
|
on accepted socket! */
|
2005-03-24 22:04:06 +08:00
|
|
|
af_local_copy (sock);
|
|
|
|
res = sock->af_local_accept ();
|
|
|
|
if (res == -1)
|
|
|
|
{
|
|
|
|
res_fd.release ();
|
|
|
|
set_winsock_errno ();
|
|
|
|
goto out;
|
|
|
|
}
|
2005-05-02 11:50:11 +08:00
|
|
|
}
|
2005-02-24 01:39:46 +08:00
|
|
|
}
|
2005-03-22 02:56:50 +08:00
|
|
|
sock->connect_state (connected);
|
2003-02-20 22:14:37 +08:00
|
|
|
res = res_fd;
|
|
|
|
}
|
|
|
|
else
|
2003-03-10 04:31:07 +08:00
|
|
|
{
|
2003-02-20 22:14:37 +08:00
|
|
|
closesocket (res);
|
|
|
|
res = -1;
|
|
|
|
}
|
2003-01-28 23:33:50 +08:00
|
|
|
}
|
2002-07-03 17:20:24 +08:00
|
|
|
|
2005-03-24 22:04:06 +08:00
|
|
|
out:
|
* devices.cc: New file.
* devices.gperf: New file.
* devices.shilka: New file.
* cygwin-gperf: New file.
* cygwin-shilka: New file.
* fhandler_fifo.cc: New file.
* fhandler_nodevice.cc : New file. Reorganize headers so that path.h precedes
fhandler.h throughout. Remove device argument and unit arguments from fhandler
constructors throughout. Remove pc arguments to fhandler functions and use
internal pc element instead, throughout. Use dev element in pc throughout.
Use major/minor elements rather than units and device numbers previously in
fhandler class. Use correct methods for fhandler file names rather than
directly accessing file name variables, throughout.
* Makefile.in (DLL_OFILES): Add devices.o, fhandler_fifo.o
* dcrt0.cc (dll_crt0_1): Call device::init.
* devices.h: Renumber devices based on more Linux-like major/minor numbers.
Add more devices. Declare standard device storage.
(device): Declare struct.
* dir.cc (opendir): Use new 'build_fh_name' to construct a fhandler_* type.
* dtable.cc (dtable::get_debugger_info): Ditto.
(cygwin_attach_handle_to_fd): Ditto.
(dtable::release): Remove special FH_SOCKET case in favor of generic
"need_fixup_before" test.
(dtable::init_std_file_from_handle): Use either build_fh_dev or build_fh_name
to build standard fhandler.
(dtable::build_fh_name): Renamed from dtable::build_fhandler_from_name. Move
out of dtable class. Don't accept a path_conv argument. Just build it here
and pass it to:
(build_fh_pc): Renamed from dtable::build_fhandler. Move out of dtable class.
Use intrinsic device type in path_conv to create new fhandler.
(build_fh_dev): Renamed from dtable::build_fhandler. Move out of dtable class.
Simplify arguments to just take new 'device' type and a name. Just return
pointer to fhandler rather than trying to insert into dtable.
(dtable::dup_worker): Accommodate above build_fh name changes.
(dtable::find_fifo): New (currently broken) function.
(handle_to_fn): Use strechr for efficiency.
* dtable.h: Reflect above build_fh name changes and argument differences.
(fhandler_base *&operator []): Return self rather than copy of self.
* fhandler.cc (fhandler_base::operator =): Use pc element to set normalized
path.
(fhandler_base::set_name): Ditto.
(fhandler_base::raw_read): Use method to access name.
(fhandler_base::write): Correctly use get_output_handle rather than get_handle.
(handler_base::device_access_denied): New function.
(fhandler_base::open): Eliminate pc argument and use pc element of
fhandler_base throughout.
(fhandler_base::fstat): Detect if device is based in filesystem and use
fstat_fs to calculate stat, if so.
(fhandler_base::fhandler_base): Eliminate handling of file names and, instead,
just free appropriate component from pc.
(fhandler_base::opendir): Remove path_conv parameter.
* fhandler.h: Remove all device flags.
(fhandler_base::pc): New element.
(fhandler_base::set_name): Change argument to path_conv.
(fhandler_base::error): New function.
(fhandler_base::exists): New function.
(fhandler_base::pc_binmode): New function.
(fhandler_base::dev): New function.
(fhandler_base::open_fs): New function.
(fhandler_base::fstat_fs): New function.
(fhandler_base::fstat_by_name): New function.
(fhandler_base::fstat_by_handle): New function.
(fhandler_base::isfifo): New function.
(fhandler_base::is_slow): New function.
(fhandler_base::is_auto_device): New function.
(fhandler_base::is_fs_special): New function.
(fhandler_base::device_access_denied): New function.
(fhandler_base::operator DWORD&): New operator.
(fhandler_base::get_name): Return normalized path from pc.
(fhandler_base::get_win32_name): Return windows path from pc.
(fhandler_base::isdevice): Renamed from is_device.
(fhandler_base::get_native_name): Return device format.
(fhandler_fifo): New class.
(fhandler_nodevice): New class.
(select_stuff::device_specific): Remove array.
(select_stuff::device_specific_pipe): New class element.
(select_stuff::device_specific_socket): New class element.
(select_stuff::device_specific_serial): New class element.
(select_stuff::select_stuff): Initialize new elements.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Move to base class
from fhandler_disk_file.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_base::fstat_by_name): Ditto.
(fhandler_disk_file::open): Move most functionality into
fhandler_base::open_fs.
(fhandler_base::open_fs): New function.
(fhandler_disk_file::close): Move most functionality into
fhandler_base::close_fs.
(fhandler_base::close_fs): New function.
* fhandler_mem.cc (fhandler_dev_mem::open): Use device name in debugging
output.
* fhandler_socket.cc (fhandler_socket::set_connect_secret): Copy standard
urandom device into appropriate place.
(fhandler_socket::accept): Reflect change in fdsock return value.
* fhandler_tty.cc: See "throughouts" above.
* net.cc: Accommodate fdsock change throughout.
(fdsock): Return success or failure, accept fd argument and device argument.
* path.cc (symlink_info::major): New element.
(symlink_info::minor): New element.
(symlink_info::parse_device): Declare new function.
(fs_info::update): Accommodate changes in path_conv class.
(path_conv::fillin): Ditto.
(path_conv::return_and_clear_normalized_path): Eliminate.
(path_conv::set_normalized_path): New function.
(path_conv::path_conv): Set info in dev element. Use path_conv methods Check
for FH_FS rather than FH_BAD to indicate when to fill in filesystem stuff.
where appropriate rather than direct access. Use set_normalized_path to set
normalized path.
(windows_device_names): Eliminate.
(get_dev): Ditto.
(get_raw_device_number): Ditto.
(get_device_number): Ditto.
(win32_device_name): Call new device name parser to do most of the heavy
lifting.
(mount_info::conv_to_win32_path): Fill in dev field as appropriate.
(symlink_worker): Handle new device files.
(symlink_info::check): Ditto.
(symlink_info::parse_device): Define new function.
* path.h (executable_states): Move here from fhandler.h.
(fs_info): Rename variables to *_storage and create methods for accessing same.
(path_conv): Add dev element, remove devn and unit and adjust inline methods to
accommodate.
(set_normalized_path): Declare new function.
* pinfo.cc (_pinfo::commune_recv): Add broken support for handling fifos.
(_pinfo::commune_send): Ditto.
* pipe.cc (fhandler_pipe::close): check for existence of handle before closing
it.
(handler_pipe::create): Rename from make_pipe. Change arguments to accept
fhandler_pipe array. Accommodate fifos.
(pipe): Rework to deal with fhandler_pipe::create changes.
(_pipe): Ditto.
* select.cc: Use individual device_specific types throughout rather than
indexing with obsolete device number.
(set_bits): Use is_socket call rather than checking device number.
* shared_info.h (CURR_MOUNT_MAGIC): Update.
(conv_to_win32_path): Reflect addition of device argument.
* syscalls.cc (mknod_worker): New function.
(open): Use build_fh_name to build fhandler.
(chown_worker): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(chmod_device): New function.
(chmod): Detect if this is an 'auto' device rather than an on-filesystem device
and handle appropriately. Use chmod_device to set mode of in-filesystem
devices.
(stat_worker): Eliminate path_conv argument. Call build_fh_name to construct
fhandler. Use fh->error() rather than pc->error to detect errors in fhandler
construction.
(access_worker): New function pulled from access. Accommodate in-filesystem
devices.
(access): Use access_worker.
(fpathconf): Detect if this is an 'auto' device rather than an on-filesystem
device and handle appropriately.
(mknod_worker): New function.
(mknod32): New function.
(chroot): Free normalized path -- assuming it was actually cmalloced.
* tty.cc (create_tty_master): Tweak for new device class.
(tty::common_init): Ditto.
* winsup.h (stat_worker): Remove.
(symlink_worker): Declare.
* exceptions.cc (set_process_mask): Just call sig_dispatch_pending and don't
worry about pending_signals since sig_dispatch_pending should always do the
right thing now.
(sig_handle): Reorganize SIGCONT handling to more closely conform to SUSv3.
* pinfo.h: Move __SIG enum to sigproc.h.
(PICOM_FIFO): New enum element.
(_pinfo): Remove 'thread2signal' stuff throughout class.
(_pinfo::commune_send): Make varargs.
(_pinfo::sigtodo): Eliminate.
(_pinfo::thread2signal): Ditto.
* signal.cc (kill_worker): Eliminate call to setthread2signal.
* sigproc.cc (local_sigtodo): Eliminate.
(getlocal_sigtodo): Ditto.
(sigelem): New class.
(pending_signals): New class.
(sigqueue): New variable, start of sigqueue linked list.
(sigcatch_nonmain): Eliminate.
(sigcatch_main): Eliminate.
(sigcatch_nosync): Eliminate.
(sigcomplete_nonmain): Eliminate.
(pending_signals): Eliminate.
(sig_clear): Call signal thread to clear pending signals, unless already in
signal thread.
(sigpending): Call signal thread to get pending signals.
(sig_dispatch_pending): Eliminate use of pending_signals and just check
sigqueue.
(sigproc_terminate): Eliminate all of the obsolete semaphore stuff. Close
signal pipe handle.
(sig_send): Eliminate all of the obsolete semaphore stuff and use pipe to send
signals.
(getevent): Eliminate.
(pending_signals::add): New function.
(pending_signals::del): New function.
(pending_signals::next): New function.
(wait_sig): Eliminate all of the obsolete semaphore stuff. Use pipe to
communicate and maintain a linked list of signals.
* sigproc.h: Move __SIG defines here. Add __SIGPENDING.
(sig_dispatch_pending): Remove "C" specifier.
(sig_handle): Accept a mask argument.
* thread.cc: Remove signal handling considerations throughout.
2003-09-25 08:37:18 +08:00
|
|
|
debug_printf ("res %d", res);
|
2002-06-27 03:25:09 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_socket::getsockname (struct sockaddr *name, int *namelen)
|
|
|
|
{
|
|
|
|
int res = -1;
|
|
|
|
|
|
|
|
if (get_addr_family () == AF_LOCAL)
|
|
|
|
{
|
|
|
|
struct sockaddr_un *sun = (struct sockaddr_un *) name;
|
|
|
|
memset (sun, 0, *namelen);
|
|
|
|
sun->sun_family = AF_LOCAL;
|
|
|
|
|
|
|
|
if (!get_sun_path ())
|
|
|
|
sun->sun_path[0] = '\0';
|
|
|
|
else
|
|
|
|
/* According to SUSv2 "If the actual length of the address is
|
|
|
|
greater than the length of the supplied sockaddr structure, the
|
|
|
|
stored address will be truncated." We play it save here so
|
|
|
|
that the path always has a trailing 0 even if it's truncated. */
|
|
|
|
strncpy (sun->sun_path, get_sun_path (),
|
|
|
|
*namelen - sizeof *sun + sizeof sun->sun_path - 1);
|
|
|
|
|
|
|
|
*namelen = sizeof *sun - sizeof sun->sun_path
|
|
|
|
+ strlen (sun->sun_path) + 1;
|
|
|
|
res = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
res = ::getsockname (get_socket (), name, namelen);
|
|
|
|
if (res)
|
|
|
|
set_winsock_errno ();
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_socket::getpeername (struct sockaddr *name, int *namelen)
|
|
|
|
{
|
|
|
|
int res = ::getpeername (get_socket (), name, namelen);
|
|
|
|
if (res)
|
|
|
|
set_winsock_errno ();
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2004-05-07 15:51:31 +08:00
|
|
|
bool
|
|
|
|
fhandler_socket::prepare (HANDLE &event, long event_mask)
|
|
|
|
{
|
|
|
|
WSASetLastError (0);
|
|
|
|
closed (false);
|
|
|
|
if ((event = WSACreateEvent ()) == WSA_INVALID_EVENT)
|
|
|
|
{
|
2004-09-03 09:53:12 +08:00
|
|
|
debug_printf ("WSACreateEvent, %E");
|
2004-05-07 15:51:31 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (WSAEventSelect (get_socket (), event, event_mask) == SOCKET_ERROR)
|
|
|
|
{
|
2006-01-20 18:22:38 +08:00
|
|
|
debug_printf ("WSAEventSelect(evt), %d", WSAGetLastError ());
|
2004-05-07 15:51:31 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2005-10-22 23:11:49 +08:00
|
|
|
fhandler_socket::wait (HANDLE event, int flags, DWORD timeout)
|
2004-05-07 15:51:31 +08:00
|
|
|
{
|
|
|
|
int ret = SOCKET_ERROR;
|
|
|
|
int wsa_err = 0;
|
|
|
|
WSAEVENT ev[2] = { event, signal_arrived };
|
|
|
|
WSANETWORKEVENTS evts;
|
|
|
|
|
2006-02-07 01:50:23 +08:00
|
|
|
/* If WSAWaitForMultipleEvents is interrupted by a signal, and the signal
|
|
|
|
has the SA_RESTART flag set, return to this label and... restart. */
|
|
|
|
sa_restart:
|
|
|
|
|
2005-10-22 23:11:49 +08:00
|
|
|
switch (WSAWaitForMultipleEvents (2, ev, FALSE, timeout, FALSE))
|
2004-05-07 15:51:31 +08:00
|
|
|
{
|
2004-05-10 23:21:01 +08:00
|
|
|
case WSA_WAIT_TIMEOUT:
|
2004-05-29 03:50:07 +08:00
|
|
|
ret = 0;
|
2004-05-10 23:21:01 +08:00
|
|
|
break;
|
2004-05-07 15:51:31 +08:00
|
|
|
case WSA_WAIT_EVENT_0:
|
|
|
|
if (!WSAEnumNetworkEvents (get_socket (), event, &evts))
|
|
|
|
{
|
|
|
|
if (!evts.lNetworkEvents)
|
|
|
|
{
|
2004-05-29 03:50:07 +08:00
|
|
|
ret = 0;
|
2004-05-07 15:51:31 +08:00
|
|
|
break;
|
|
|
|
}
|
2004-05-10 23:21:01 +08:00
|
|
|
if (evts.lNetworkEvents & FD_OOB)
|
|
|
|
{
|
|
|
|
if (evts.iErrorCode[FD_OOB_BIT])
|
|
|
|
wsa_err = evts.iErrorCode[FD_OOB_BIT];
|
|
|
|
else if (flags & MSG_OOB)
|
|
|
|
ret = 0;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
raise (SIGURG);
|
|
|
|
WSASetLastError (WSAEINTR);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2005-10-23 00:02:15 +08:00
|
|
|
if (evts.lNetworkEvents & FD_ACCEPT)
|
|
|
|
{
|
|
|
|
if (evts.iErrorCode[FD_ACCEPT_BIT])
|
|
|
|
wsa_err = evts.iErrorCode[FD_ACCEPT_BIT];
|
|
|
|
else
|
|
|
|
ret = 0;
|
|
|
|
}
|
2005-10-22 23:11:49 +08:00
|
|
|
if (evts.lNetworkEvents & FD_CONNECT)
|
|
|
|
{
|
|
|
|
if (evts.iErrorCode[FD_CONNECT_BIT])
|
|
|
|
wsa_err = evts.iErrorCode[FD_CONNECT_BIT];
|
|
|
|
else
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
else if (evts.lNetworkEvents & FD_READ)
|
2004-05-07 15:51:31 +08:00
|
|
|
{
|
|
|
|
if (evts.iErrorCode[FD_READ_BIT])
|
|
|
|
wsa_err = evts.iErrorCode[FD_READ_BIT];
|
|
|
|
else
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
else if (evts.lNetworkEvents & FD_WRITE)
|
|
|
|
{
|
|
|
|
if (evts.iErrorCode[FD_WRITE_BIT])
|
|
|
|
wsa_err = evts.iErrorCode[FD_WRITE_BIT];
|
|
|
|
else
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
if (evts.lNetworkEvents & FD_CLOSE)
|
|
|
|
{
|
|
|
|
closed (true);
|
|
|
|
if (!wsa_err)
|
|
|
|
{
|
|
|
|
if (evts.iErrorCode[FD_CLOSE_BIT])
|
|
|
|
wsa_err = evts.iErrorCode[FD_CLOSE_BIT];
|
|
|
|
else
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (wsa_err)
|
|
|
|
WSASetLastError (wsa_err);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WSA_WAIT_EVENT_0 + 1:
|
2004-05-29 03:50:07 +08:00
|
|
|
WSASetLastError (WSAEINTR);
|
2006-02-07 01:50:23 +08:00
|
|
|
if (_my_tls.call_signal_handler ())
|
|
|
|
{
|
|
|
|
sig_dispatch_pending ();
|
|
|
|
goto sa_restart;
|
|
|
|
}
|
2004-05-07 15:51:31 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
WSASetLastError (WSAEFAULT);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
fhandler_socket::release (HANDLE event)
|
|
|
|
{
|
|
|
|
int last_err = WSAGetLastError ();
|
|
|
|
/* KB 168349: NT4 fails if the event parameter is not NULL. */
|
2006-01-20 18:22:38 +08:00
|
|
|
if (WSAEventSelect (get_socket (), NULL, 0) == SOCKET_ERROR)
|
|
|
|
debug_printf ("WSAEventSelect(NULL), %d", WSAGetLastError ());
|
2004-06-23 15:36:21 +08:00
|
|
|
WSACloseEvent (event);
|
2004-05-07 15:51:31 +08:00
|
|
|
unsigned long non_block = 0;
|
|
|
|
if (ioctlsocket (get_socket (), FIONBIO, &non_block))
|
|
|
|
debug_printf ("return to blocking failed: %d", WSAGetLastError ());
|
|
|
|
else
|
|
|
|
WSASetLastError (last_err);
|
|
|
|
}
|
|
|
|
|
2002-09-04 17:39:35 +08:00
|
|
|
int
|
|
|
|
fhandler_socket::readv (const struct iovec *const iov, const int iovcnt,
|
|
|
|
ssize_t tot)
|
2002-02-09 18:40:48 +08:00
|
|
|
{
|
2002-09-04 17:39:35 +08:00
|
|
|
struct msghdr msg =
|
|
|
|
{
|
2002-11-28 08:41:02 +08:00
|
|
|
msg_name: NULL,
|
|
|
|
msg_namelen: 0,
|
|
|
|
msg_iov: (struct iovec *) iov, // const_cast
|
|
|
|
msg_iovlen: iovcnt,
|
2005-10-18 05:22:18 +08:00
|
|
|
msg_control: NULL,
|
|
|
|
msg_controllen: 0,
|
|
|
|
msg_flags: 0
|
2002-09-04 17:39:35 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
return recvmsg (&msg, 0, tot);
|
2002-02-09 18:40:48 +08:00
|
|
|
}
|
2002-02-08 19:54:10 +08:00
|
|
|
|
2002-06-27 03:25:09 +08:00
|
|
|
int
|
2002-08-26 17:57:27 +08:00
|
|
|
fhandler_socket::recvfrom (void *ptr, size_t len, int flags,
|
2002-06-27 03:25:09 +08:00
|
|
|
struct sockaddr *from, int *fromlen)
|
|
|
|
{
|
2004-05-07 15:51:31 +08:00
|
|
|
int res = SOCKET_ERROR;
|
2005-08-18 21:14:15 +08:00
|
|
|
DWORD ret = 0;
|
2002-06-27 03:25:09 +08:00
|
|
|
|
2005-10-18 05:22:18 +08:00
|
|
|
WSABUF wsabuf = { len, (char *) ptr };
|
|
|
|
|
|
|
|
if (is_nonblocking () || closed () || async_io ())
|
2005-12-08 18:13:57 +08:00
|
|
|
{
|
|
|
|
DWORD lflags = (DWORD) (flags & MSG_WINMASK);
|
|
|
|
res = WSARecvFrom (get_socket (), &wsabuf, 1, &ret,
|
|
|
|
&lflags, from, fromlen, NULL, NULL);
|
|
|
|
}
|
2002-06-27 03:25:09 +08:00
|
|
|
else
|
|
|
|
{
|
2005-10-18 05:22:18 +08:00
|
|
|
HANDLE evt;
|
|
|
|
if (prepare (evt, FD_CLOSE | FD_READ | (owner () ? FD_OOB : 0)))
|
2002-06-27 03:25:09 +08:00
|
|
|
{
|
2005-10-18 05:22:18 +08:00
|
|
|
do
|
2004-05-07 15:51:31 +08:00
|
|
|
{
|
2005-12-08 18:13:57 +08:00
|
|
|
DWORD lflags = (DWORD) (flags & MSG_WINMASK);
|
2005-10-18 05:22:18 +08:00
|
|
|
res = WSARecvFrom (get_socket (), &wsabuf, 1, &ret, &lflags,
|
|
|
|
from, fromlen, NULL, NULL);
|
2004-05-07 15:51:31 +08:00
|
|
|
}
|
2005-10-18 05:22:18 +08:00
|
|
|
while (res == SOCKET_ERROR
|
|
|
|
&& WSAGetLastError () == WSAEWOULDBLOCK
|
|
|
|
&& !closed ()
|
|
|
|
&& !(res = wait (evt, flags)));
|
|
|
|
release (evt);
|
2002-06-27 03:25:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-09-04 17:39:35 +08:00
|
|
|
if (res == SOCKET_ERROR)
|
|
|
|
{
|
2003-02-03 23:34:52 +08:00
|
|
|
/* According to SUSv3, errno isn't set in that case and no error
|
2003-03-10 04:31:07 +08:00
|
|
|
condition is returned. */
|
2003-02-03 23:34:52 +08:00
|
|
|
if (WSAGetLastError () == WSAEMSGSIZE)
|
2003-03-10 04:31:07 +08:00
|
|
|
return len;
|
2003-02-03 23:34:52 +08:00
|
|
|
|
2005-11-14 00:24:40 +08:00
|
|
|
/* ESHUTDOWN isn't defined for recv in SUSv3. Simply EOF is returned
|
2005-12-22 13:57:54 +08:00
|
|
|
in this case. */
|
2005-11-14 00:24:40 +08:00
|
|
|
if (WSAGetLastError () == WSAESHUTDOWN)
|
2005-12-22 13:57:54 +08:00
|
|
|
return 0;
|
2005-11-14 00:24:40 +08:00
|
|
|
|
2002-09-04 17:39:35 +08:00
|
|
|
set_winsock_errno ();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
res = ret;
|
|
|
|
|
2002-06-27 03:25:09 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2002-09-04 17:39:35 +08:00
|
|
|
fhandler_socket::recvmsg (struct msghdr *msg, int flags, ssize_t tot)
|
2002-06-27 03:25:09 +08:00
|
|
|
{
|
2005-10-18 05:22:18 +08:00
|
|
|
if (CYGWIN_VERSION_CHECK_FOR_USING_ANCIENT_MSGHDR)
|
|
|
|
((struct OLD_msghdr *) msg)->msg_accrightslen = 0;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
msg->msg_controllen = 0;
|
|
|
|
msg->msg_flags = 0;
|
|
|
|
}
|
2002-06-27 03:25:09 +08:00
|
|
|
if (get_addr_family () == AF_LOCAL)
|
|
|
|
{
|
|
|
|
/* On AF_LOCAL sockets the (fixed-size) name of the shared memory
|
|
|
|
area used for descriptor passing is transmitted first.
|
|
|
|
If this string is empty, no descriptors are passed and we can
|
|
|
|
go ahead recv'ing the normal data blocks. Otherwise start
|
|
|
|
special handling for descriptor passing. */
|
|
|
|
/*TODO*/
|
|
|
|
}
|
2002-09-04 17:39:35 +08:00
|
|
|
|
|
|
|
struct iovec *const iov = msg->msg_iov;
|
|
|
|
const int iovcnt = msg->msg_iovlen;
|
|
|
|
|
2002-11-06 00:49:58 +08:00
|
|
|
struct sockaddr *from = (struct sockaddr *) msg->msg_name;
|
|
|
|
int *fromlen = from ? &msg->msg_namelen : NULL;
|
|
|
|
|
2004-05-07 15:51:31 +08:00
|
|
|
int res = SOCKET_ERROR;
|
2002-09-04 17:39:35 +08:00
|
|
|
|
2005-10-18 05:22:18 +08:00
|
|
|
WSABUF wsabuf[iovcnt];
|
|
|
|
unsigned long len = 0L;
|
2002-09-04 17:39:35 +08:00
|
|
|
|
2005-10-18 05:22:18 +08:00
|
|
|
const struct iovec *iovptr = iov + iovcnt;
|
|
|
|
WSABUF *wsaptr = wsabuf + iovcnt;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
iovptr -= 1;
|
|
|
|
wsaptr -= 1;
|
|
|
|
len += wsaptr->len = iovptr->iov_len;
|
|
|
|
wsaptr->buf = (char *) iovptr->iov_base;
|
|
|
|
}
|
|
|
|
while (wsaptr != wsabuf);
|
2002-09-04 17:39:35 +08:00
|
|
|
|
2005-10-18 05:22:18 +08:00
|
|
|
DWORD ret = 0;
|
2002-09-04 17:39:35 +08:00
|
|
|
|
2005-10-18 05:22:18 +08:00
|
|
|
if (is_nonblocking () || closed () || async_io ())
|
2005-12-08 18:13:57 +08:00
|
|
|
{
|
|
|
|
DWORD lflags = (DWORD) (flags & MSG_WINMASK);
|
|
|
|
res = WSARecvFrom (get_socket (), wsabuf, iovcnt, &ret,
|
|
|
|
&lflags, from, fromlen, NULL, NULL);
|
|
|
|
}
|
2002-09-04 17:39:35 +08:00
|
|
|
else
|
2002-06-27 03:25:09 +08:00
|
|
|
{
|
2005-10-18 05:22:18 +08:00
|
|
|
HANDLE evt;
|
|
|
|
if (prepare (evt, FD_CLOSE | FD_READ | (owner () ? FD_OOB : 0)))
|
2002-09-04 17:39:35 +08:00
|
|
|
{
|
2005-10-18 05:22:18 +08:00
|
|
|
do
|
2004-05-07 15:51:31 +08:00
|
|
|
{
|
2005-12-08 18:13:57 +08:00
|
|
|
DWORD lflags = (DWORD) (flags & MSG_WINMASK);
|
2005-10-18 05:22:18 +08:00
|
|
|
res = WSARecvFrom (get_socket (), wsabuf, iovcnt, &ret,
|
|
|
|
&lflags, from, fromlen, NULL, NULL);
|
2004-05-07 15:51:31 +08:00
|
|
|
}
|
2005-10-18 05:22:18 +08:00
|
|
|
while (res == SOCKET_ERROR
|
|
|
|
&& WSAGetLastError () == WSAEWOULDBLOCK
|
|
|
|
&& !closed ()
|
|
|
|
&& !(res = wait (evt, flags)));
|
|
|
|
release (evt);
|
2002-09-04 17:39:35 +08:00
|
|
|
}
|
2005-10-18 05:22:18 +08:00
|
|
|
}
|
2002-09-04 17:39:35 +08:00
|
|
|
|
2005-10-18 05:22:18 +08:00
|
|
|
if (res == SOCKET_ERROR)
|
|
|
|
{
|
|
|
|
/* According to SUSv3, errno isn't set in that case and no error
|
|
|
|
condition is returned. */
|
|
|
|
if (WSAGetLastError () == WSAEMSGSIZE)
|
|
|
|
return len;
|
2003-02-03 23:34:52 +08:00
|
|
|
|
2005-11-14 00:24:40 +08:00
|
|
|
/* ESHUTDOWN isn't defined for recv in SUSv3. Simply EOF is returned
|
2005-12-22 13:57:54 +08:00
|
|
|
in this case. */
|
2005-11-14 00:24:40 +08:00
|
|
|
if (WSAGetLastError () == WSAESHUTDOWN)
|
2005-12-22 13:57:54 +08:00
|
|
|
return 0;
|
2005-11-14 00:24:40 +08:00
|
|
|
|
2005-10-18 05:22:18 +08:00
|
|
|
set_winsock_errno ();
|
2002-06-27 03:25:09 +08:00
|
|
|
}
|
2005-10-18 05:22:18 +08:00
|
|
|
else
|
|
|
|
res = ret;
|
2002-09-04 17:39:35 +08:00
|
|
|
|
2002-06-27 03:25:09 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2002-02-09 18:40:48 +08:00
|
|
|
int
|
2002-09-04 17:39:35 +08:00
|
|
|
fhandler_socket::writev (const struct iovec *const iov, const int iovcnt,
|
|
|
|
ssize_t tot)
|
2002-02-09 18:40:48 +08:00
|
|
|
{
|
2002-09-04 17:39:35 +08:00
|
|
|
struct msghdr msg =
|
|
|
|
{
|
|
|
|
msg_name: NULL,
|
|
|
|
msg_namelen: 0,
|
|
|
|
msg_iov: (struct iovec *) iov, // const_cast
|
|
|
|
msg_iovlen: iovcnt,
|
2005-10-18 05:22:18 +08:00
|
|
|
msg_control: NULL,
|
|
|
|
msg_controllen: 0,
|
|
|
|
msg_flags: 0
|
2002-09-04 17:39:35 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
return sendmsg (&msg, 0, tot);
|
2002-02-09 18:40:48 +08:00
|
|
|
}
|
|
|
|
|
2002-06-27 03:25:09 +08:00
|
|
|
int
|
2002-08-26 17:57:27 +08:00
|
|
|
fhandler_socket::sendto (const void *ptr, size_t len, int flags,
|
2002-06-27 03:25:09 +08:00
|
|
|
const struct sockaddr *to, int tolen)
|
|
|
|
{
|
2005-03-24 01:27:18 +08:00
|
|
|
struct sockaddr_in sin;
|
2002-06-27 03:25:09 +08:00
|
|
|
|
2002-08-12 21:54:12 +08:00
|
|
|
if (to && !get_inet_addr (to, tolen, &sin, &tolen))
|
2004-04-04 03:07:59 +08:00
|
|
|
return SOCKET_ERROR;
|
2002-06-27 03:25:09 +08:00
|
|
|
|
2004-05-07 15:51:31 +08:00
|
|
|
int res = SOCKET_ERROR;
|
2005-06-11 05:47:24 +08:00
|
|
|
DWORD ret = 0;
|
2002-09-04 17:39:35 +08:00
|
|
|
|
2005-10-18 05:22:18 +08:00
|
|
|
WSABUF wsabuf = { len, (char *) ptr };
|
|
|
|
|
|
|
|
if (is_nonblocking () || closed () || async_io ())
|
|
|
|
res = WSASendTo (get_socket (), &wsabuf, 1, &ret,
|
|
|
|
flags & MSG_WINMASK,
|
|
|
|
(to ? (const struct sockaddr *) &sin : NULL), tolen,
|
|
|
|
NULL, NULL);
|
2002-06-27 03:25:09 +08:00
|
|
|
else
|
|
|
|
{
|
2005-10-18 05:22:18 +08:00
|
|
|
HANDLE evt;
|
|
|
|
if (prepare (evt, FD_CLOSE | FD_WRITE | (owner () ? FD_OOB : 0)))
|
2002-06-27 03:25:09 +08:00
|
|
|
{
|
2005-10-18 05:22:18 +08:00
|
|
|
do
|
2004-05-07 15:51:31 +08:00
|
|
|
{
|
2005-10-18 05:22:18 +08:00
|
|
|
res = WSASendTo (get_socket (), &wsabuf, 1, &ret,
|
|
|
|
flags & MSG_WINMASK,
|
|
|
|
(to ? (const struct sockaddr *) &sin : NULL),
|
|
|
|
tolen, NULL, NULL);
|
2004-05-07 15:51:31 +08:00
|
|
|
}
|
2005-10-18 05:22:18 +08:00
|
|
|
while (res == SOCKET_ERROR
|
|
|
|
&& WSAGetLastError () == WSAEWOULDBLOCK
|
|
|
|
&& !(res = wait (evt, 0))
|
|
|
|
&& !closed ());
|
|
|
|
release (evt);
|
2002-06-27 03:25:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-09-04 17:39:35 +08:00
|
|
|
if (res == SOCKET_ERROR)
|
2004-03-31 17:13:54 +08:00
|
|
|
set_winsock_errno ();
|
2002-09-04 17:39:35 +08:00
|
|
|
else
|
|
|
|
res = ret;
|
|
|
|
|
2003-03-20 16:53:28 +08:00
|
|
|
/* Special handling for EPIPE and SIGPIPE.
|
2003-07-26 12:53:59 +08:00
|
|
|
|
2003-03-20 16:53:28 +08:00
|
|
|
EPIPE is generated if the local end has been shut down on a connection
|
|
|
|
oriented socket. In this case the process will also receive a SIGPIPE
|
|
|
|
unless MSG_NOSIGNAL is set. */
|
2004-03-31 17:13:54 +08:00
|
|
|
if (res == SOCKET_ERROR && get_errno () == ESHUTDOWN
|
2003-03-20 16:53:28 +08:00
|
|
|
&& get_socket_type () == SOCK_STREAM)
|
2002-08-28 18:18:20 +08:00
|
|
|
{
|
|
|
|
set_errno (EPIPE);
|
|
|
|
if (! (flags & MSG_NOSIGNAL))
|
2002-10-20 12:46:31 +08:00
|
|
|
raise (SIGPIPE);
|
2002-08-28 18:18:20 +08:00
|
|
|
}
|
2002-09-04 17:39:35 +08:00
|
|
|
|
2002-06-27 03:25:09 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2002-09-04 17:39:35 +08:00
|
|
|
fhandler_socket::sendmsg (const struct msghdr *msg, int flags, ssize_t tot)
|
2002-06-27 03:25:09 +08:00
|
|
|
{
|
2005-09-29 03:22:25 +08:00
|
|
|
if (get_addr_family () == AF_LOCAL)
|
2002-09-04 17:39:35 +08:00
|
|
|
{
|
2005-09-29 03:22:25 +08:00
|
|
|
/* For AF_LOCAL/AF_UNIX sockets, if descriptors are given, start
|
2002-09-04 17:39:35 +08:00
|
|
|
the special handling for descriptor passing. Otherwise just
|
|
|
|
transmit an empty string to tell the receiver that no
|
|
|
|
descriptor passing is done. */
|
2005-09-29 03:22:25 +08:00
|
|
|
/*TODO*/
|
2002-09-04 17:39:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
struct iovec *const iov = msg->msg_iov;
|
|
|
|
const int iovcnt = msg->msg_iovlen;
|
|
|
|
|
2004-05-07 15:51:31 +08:00
|
|
|
int res = SOCKET_ERROR;
|
2002-09-04 17:39:35 +08:00
|
|
|
|
2005-10-18 05:22:18 +08:00
|
|
|
WSABUF wsabuf[iovcnt];
|
2002-09-04 17:39:35 +08:00
|
|
|
|
2005-10-18 05:22:18 +08:00
|
|
|
const struct iovec *iovptr = iov + iovcnt;
|
|
|
|
WSABUF *wsaptr = wsabuf + iovcnt;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
iovptr -= 1;
|
|
|
|
wsaptr -= 1;
|
|
|
|
wsaptr->len = iovptr->iov_len;
|
|
|
|
wsaptr->buf = (char *) iovptr->iov_base;
|
|
|
|
}
|
|
|
|
while (wsaptr != wsabuf);
|
2002-09-04 17:39:35 +08:00
|
|
|
|
2005-10-18 05:22:18 +08:00
|
|
|
DWORD ret = 0;
|
2002-09-04 17:39:35 +08:00
|
|
|
|
2005-10-18 05:22:18 +08:00
|
|
|
if (is_nonblocking () || closed () || async_io ())
|
|
|
|
res = WSASendTo (get_socket (), wsabuf, iovcnt, &ret,
|
2005-12-08 18:13:57 +08:00
|
|
|
flags & MSG_WINMASK, (struct sockaddr *) msg->msg_name,
|
2005-10-18 05:22:18 +08:00
|
|
|
msg->msg_namelen, NULL, NULL);
|
2002-09-04 17:39:35 +08:00
|
|
|
else
|
|
|
|
{
|
2005-10-18 05:22:18 +08:00
|
|
|
HANDLE evt;
|
|
|
|
if (prepare (evt, FD_CLOSE | FD_WRITE | (owner () ? FD_OOB : 0)))
|
2002-09-04 17:39:35 +08:00
|
|
|
{
|
2005-10-18 05:22:18 +08:00
|
|
|
do
|
2004-05-07 15:51:31 +08:00
|
|
|
{
|
2005-10-18 05:22:18 +08:00
|
|
|
res = WSASendTo (get_socket (), wsabuf, iovcnt,
|
2005-12-08 18:13:57 +08:00
|
|
|
&ret, flags & MSG_WINMASK,
|
2005-10-18 05:22:18 +08:00
|
|
|
(struct sockaddr *) msg->msg_name,
|
|
|
|
msg->msg_namelen, NULL, NULL);
|
2004-05-07 15:51:31 +08:00
|
|
|
}
|
2005-10-18 05:22:18 +08:00
|
|
|
while (res == SOCKET_ERROR
|
|
|
|
&& WSAGetLastError () == WSAEWOULDBLOCK
|
|
|
|
&& !(res = wait (evt, 0))
|
|
|
|
&& !closed ());
|
|
|
|
release (evt);
|
2002-09-04 17:39:35 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-10-18 05:22:18 +08:00
|
|
|
if (res == SOCKET_ERROR)
|
|
|
|
set_winsock_errno ();
|
|
|
|
else
|
|
|
|
res = ret;
|
|
|
|
|
2005-09-29 03:22:25 +08:00
|
|
|
/* Special handling for EPIPE and SIGPIPE.
|
2005-09-29 03:02:53 +08:00
|
|
|
|
2005-09-29 03:22:25 +08:00
|
|
|
EPIPE is generated if the local end has been shut down on a connection
|
|
|
|
oriented socket. In this case the process will also receive a SIGPIPE
|
|
|
|
unless MSG_NOSIGNAL is set. */
|
|
|
|
if (res == SOCKET_ERROR && get_errno () == ESHUTDOWN
|
|
|
|
&& get_socket_type () == SOCK_STREAM)
|
|
|
|
{
|
|
|
|
set_errno (EPIPE);
|
|
|
|
if (! (flags & MSG_NOSIGNAL))
|
|
|
|
raise (SIGPIPE);
|
2004-03-31 18:10:59 +08:00
|
|
|
}
|
|
|
|
|
2002-09-04 17:39:35 +08:00
|
|
|
return res;
|
2002-06-27 03:25:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_socket::shutdown (int how)
|
|
|
|
{
|
|
|
|
int res = ::shutdown (get_socket (), how);
|
|
|
|
|
|
|
|
if (res)
|
|
|
|
set_winsock_errno ();
|
|
|
|
else
|
|
|
|
switch (how)
|
|
|
|
{
|
|
|
|
case SHUT_RD:
|
2004-04-10 21:45:10 +08:00
|
|
|
saw_shutdown_read (true);
|
2002-06-27 03:25:09 +08:00
|
|
|
break;
|
|
|
|
case SHUT_WR:
|
2004-04-10 21:45:10 +08:00
|
|
|
saw_shutdown_write (true);
|
2002-06-27 03:25:09 +08:00
|
|
|
break;
|
|
|
|
case SHUT_RDWR:
|
2004-04-10 21:45:10 +08:00
|
|
|
saw_shutdown_read (true);
|
|
|
|
saw_shutdown_write (true);
|
2002-06-27 03:25:09 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2000-10-27 17:50:33 +08:00
|
|
|
int
|
|
|
|
fhandler_socket::close ()
|
|
|
|
{
|
|
|
|
int res = 0;
|
2002-06-27 03:25:09 +08:00
|
|
|
|
2001-08-14 15:41:45 +08:00
|
|
|
/* HACK to allow a graceful shutdown even if shutdown() hasn't been
|
|
|
|
called by the application. Note that this isn't the ultimate
|
|
|
|
solution but it helps in many cases. */
|
|
|
|
struct linger linger;
|
|
|
|
linger.l_onoff = 1;
|
2003-11-20 02:50:23 +08:00
|
|
|
linger.l_linger = 240; /* secs. default 2MSL value according to MSDN. */
|
2001-08-14 15:41:45 +08:00
|
|
|
setsockopt (get_socket (), SOL_SOCKET, SO_LINGER,
|
|
|
|
(const char *)&linger, sizeof linger);
|
|
|
|
|
2002-03-06 02:02:53 +08:00
|
|
|
while ((res = closesocket (get_socket ())) != 0)
|
2001-10-30 19:48:36 +08:00
|
|
|
{
|
2002-03-06 02:02:53 +08:00
|
|
|
if (WSAGetLastError () != WSAEWOULDBLOCK)
|
|
|
|
{
|
|
|
|
set_winsock_errno ();
|
|
|
|
res = -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0)
|
|
|
|
{
|
|
|
|
set_errno (EINTR);
|
|
|
|
res = -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
WSASetLastError (0);
|
2001-10-30 19:48:36 +08:00
|
|
|
}
|
2000-10-27 17:50:33 +08:00
|
|
|
|
2001-08-14 15:41:45 +08:00
|
|
|
debug_printf ("%d = fhandler_socket::close()", res);
|
2000-10-27 17:50:33 +08:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_socket::ioctl (unsigned int cmd, void *p)
|
|
|
|
{
|
|
|
|
extern int get_ifconf (struct ifconf *ifc, int what); /* net.cc */
|
|
|
|
int res;
|
2001-02-08 06:50:50 +08:00
|
|
|
struct ifconf ifc, *ifcp;
|
|
|
|
struct ifreq *ifr, *ifrp;
|
2002-06-27 03:25:09 +08:00
|
|
|
|
2000-10-27 17:50:33 +08:00
|
|
|
switch (cmd)
|
|
|
|
{
|
|
|
|
case SIOCGIFCONF:
|
2001-02-08 06:50:50 +08:00
|
|
|
ifcp = (struct ifconf *) p;
|
|
|
|
if (!ifcp)
|
2000-10-27 17:50:33 +08:00
|
|
|
{
|
|
|
|
set_errno (EINVAL);
|
|
|
|
return -1;
|
|
|
|
}
|
2001-02-08 06:50:50 +08:00
|
|
|
res = get_ifconf (ifcp, cmd);
|
2000-10-27 17:50:33 +08:00
|
|
|
if (res)
|
2002-09-30 12:35:18 +08:00
|
|
|
debug_printf ("error in get_ifconf");
|
2000-10-27 17:50:33 +08:00
|
|
|
break;
|
|
|
|
case SIOCGIFFLAGS:
|
|
|
|
ifr = (struct ifreq *) p;
|
|
|
|
if (ifr == 0)
|
|
|
|
{
|
|
|
|
set_errno (EINVAL);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
ifr->ifr_flags = IFF_NOTRAILERS | IFF_UP | IFF_RUNNING;
|
2002-11-07 18:22:26 +08:00
|
|
|
if (!strncmp(ifr->ifr_name, "lo", 2)
|
2003-01-26 14:42:40 +08:00
|
|
|
|| ntohl (((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr)
|
2001-09-08 05:32:07 +08:00
|
|
|
== INADDR_LOOPBACK)
|
|
|
|
ifr->ifr_flags |= IFF_LOOPBACK;
|
2000-10-27 17:50:33 +08:00
|
|
|
else
|
2001-09-08 05:32:07 +08:00
|
|
|
ifr->ifr_flags |= IFF_BROADCAST;
|
2000-10-27 17:50:33 +08:00
|
|
|
res = 0;
|
|
|
|
break;
|
|
|
|
case SIOCGIFBRDADDR:
|
|
|
|
case SIOCGIFNETMASK:
|
|
|
|
case SIOCGIFADDR:
|
2001-02-08 06:50:50 +08:00
|
|
|
case SIOCGIFHWADDR:
|
|
|
|
case SIOCGIFMETRIC:
|
|
|
|
case SIOCGIFMTU:
|
2000-10-27 17:50:33 +08:00
|
|
|
{
|
2001-02-08 06:50:50 +08:00
|
|
|
ifc.ifc_len = 2048;
|
|
|
|
ifc.ifc_buf = (char *) alloca (2048);
|
2000-10-27 17:50:33 +08:00
|
|
|
|
2001-02-08 06:50:50 +08:00
|
|
|
ifr = (struct ifreq *) p;
|
2000-10-27 17:50:33 +08:00
|
|
|
if (ifr == 0)
|
|
|
|
{
|
2002-09-30 12:35:18 +08:00
|
|
|
debug_printf ("ifr == NULL");
|
2000-10-27 17:50:33 +08:00
|
|
|
set_errno (EINVAL);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
res = get_ifconf (&ifc, cmd);
|
|
|
|
if (res)
|
|
|
|
{
|
2002-09-30 12:35:18 +08:00
|
|
|
debug_printf ("error in get_ifconf");
|
2000-10-27 17:50:33 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2002-09-30 12:35:18 +08:00
|
|
|
debug_printf (" name: %s", ifr->ifr_name);
|
2000-10-27 17:50:33 +08:00
|
|
|
for (ifrp = ifc.ifc_req;
|
|
|
|
(caddr_t) ifrp < ifc.ifc_buf + ifc.ifc_len;
|
|
|
|
++ifrp)
|
|
|
|
{
|
2002-09-30 12:35:18 +08:00
|
|
|
debug_printf ("testname: %s", ifrp->ifr_name);
|
2000-10-27 17:50:33 +08:00
|
|
|
if (! strcmp (ifrp->ifr_name, ifr->ifr_name))
|
|
|
|
{
|
|
|
|
switch (cmd)
|
|
|
|
{
|
|
|
|
case SIOCGIFADDR:
|
|
|
|
ifr->ifr_addr = ifrp->ifr_addr;
|
|
|
|
break;
|
|
|
|
case SIOCGIFBRDADDR:
|
|
|
|
ifr->ifr_broadaddr = ifrp->ifr_broadaddr;
|
|
|
|
break;
|
|
|
|
case SIOCGIFNETMASK:
|
|
|
|
ifr->ifr_netmask = ifrp->ifr_netmask;
|
|
|
|
break;
|
2001-02-08 06:50:50 +08:00
|
|
|
case SIOCGIFHWADDR:
|
|
|
|
ifr->ifr_hwaddr = ifrp->ifr_hwaddr;
|
|
|
|
break;
|
|
|
|
case SIOCGIFMETRIC:
|
|
|
|
ifr->ifr_metric = ifrp->ifr_metric;
|
|
|
|
break;
|
|
|
|
case SIOCGIFMTU:
|
|
|
|
ifr->ifr_mtu = ifrp->ifr_mtu;
|
|
|
|
break;
|
2000-10-27 17:50:33 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((caddr_t) ifrp >= ifc.ifc_buf + ifc.ifc_len)
|
|
|
|
{
|
|
|
|
set_errno (EINVAL);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case FIOASYNC:
|
2004-05-16 12:18:50 +08:00
|
|
|
res = WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO,
|
2000-10-27 17:50:33 +08:00
|
|
|
*(int *) p ? ASYNC_MASK : 0);
|
|
|
|
syscall_printf ("Async I/O on socket %s",
|
|
|
|
*(int *) p ? "started" : "cancelled");
|
2004-04-10 21:45:10 +08:00
|
|
|
async_io (*(int *) p != 0);
|
2000-10-27 17:50:33 +08:00
|
|
|
break;
|
2004-02-09 19:30:57 +08:00
|
|
|
case FIONREAD:
|
|
|
|
res = ioctlsocket (get_socket (), FIONREAD, (unsigned long *) p);
|
|
|
|
if (res == SOCKET_ERROR)
|
2004-05-29 03:50:07 +08:00
|
|
|
set_winsock_errno ();
|
2004-02-09 19:30:57 +08:00
|
|
|
break;
|
2000-10-27 17:50:33 +08:00
|
|
|
default:
|
|
|
|
/* We must cancel WSAAsyncSelect (if any) before setting socket to
|
|
|
|
* blocking mode
|
|
|
|
*/
|
2006-01-20 18:22:38 +08:00
|
|
|
if (cmd == FIONBIO && *(int *) p == 0)
|
|
|
|
{
|
|
|
|
if (async_io ())
|
|
|
|
WSAAsyncSelect (get_socket (), winmsg, 0, 0);
|
|
|
|
if (WSAEventSelect (get_socket (), NULL, 0) == SOCKET_ERROR)
|
|
|
|
debug_printf ("WSAEventSelect(NULL), %d", WSAGetLastError ());
|
|
|
|
}
|
2000-10-27 17:50:33 +08:00
|
|
|
res = ioctlsocket (get_socket (), cmd, (unsigned long *) p);
|
|
|
|
if (res == SOCKET_ERROR)
|
|
|
|
set_winsock_errno ();
|
|
|
|
if (cmd == FIONBIO)
|
|
|
|
{
|
2006-01-20 18:22:38 +08:00
|
|
|
if (!res)
|
|
|
|
{
|
|
|
|
syscall_printf ("socket is now %sblocking",
|
|
|
|
*(int *) p ? "non" : "");
|
|
|
|
set_nonblocking (*(int *) p);
|
|
|
|
}
|
2000-10-27 17:50:33 +08:00
|
|
|
/* Start AsyncSelect if async socket unblocked */
|
2004-04-10 21:45:10 +08:00
|
|
|
if (*(int *) p && async_io ())
|
2004-05-16 12:18:50 +08:00
|
|
|
WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO, ASYNC_MASK);
|
2000-10-27 17:50:33 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
syscall_printf ("%d = ioctl_socket (%x, %x)", res, cmd, p);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_socket::fcntl (int cmd, void *arg)
|
|
|
|
{
|
|
|
|
int res = 0;
|
|
|
|
int request, current;
|
|
|
|
|
|
|
|
switch (cmd)
|
|
|
|
{
|
2004-05-10 23:21:01 +08:00
|
|
|
case F_SETOWN:
|
|
|
|
{
|
|
|
|
/* Urgh! Bad hack! */
|
|
|
|
pid_t pid = (pid_t) arg;
|
|
|
|
owner (pid == getpid ());
|
|
|
|
debug_printf ("owner set to %d", owner ());
|
|
|
|
}
|
|
|
|
break;
|
2000-10-27 17:50:33 +08:00
|
|
|
case F_SETFL:
|
|
|
|
{
|
2001-09-08 05:32:07 +08:00
|
|
|
/* Carefully test for the O_NONBLOCK or deprecated OLD_O_NDELAY flag.
|
2001-08-07 08:01:42 +08:00
|
|
|
Set only the flag that has been passed in. If both are set, just
|
|
|
|
record O_NONBLOCK. */
|
2001-08-14 15:41:45 +08:00
|
|
|
int new_flags = (int) arg & O_NONBLOCK_MASK;
|
2001-08-07 08:01:42 +08:00
|
|
|
if ((new_flags & OLD_O_NDELAY) && (new_flags & O_NONBLOCK))
|
|
|
|
new_flags = O_NONBLOCK;
|
2001-09-08 05:32:07 +08:00
|
|
|
current = get_flags () & O_NONBLOCK_MASK;
|
2001-08-14 15:41:45 +08:00
|
|
|
request = new_flags ? 1 : 0;
|
2001-09-08 05:32:07 +08:00
|
|
|
if (!!current != !!new_flags && (res = ioctl (FIONBIO, &request)))
|
|
|
|
break;
|
2001-08-14 15:41:45 +08:00
|
|
|
set_flags ((get_flags () & ~O_NONBLOCK_MASK) | new_flags);
|
2001-09-08 05:32:07 +08:00
|
|
|
break;
|
2000-10-27 17:50:33 +08:00
|
|
|
}
|
|
|
|
default:
|
|
|
|
res = fhandler_base::fcntl (cmd, arg);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2001-06-23 04:53:45 +08:00
|
|
|
void
|
2004-04-10 21:45:10 +08:00
|
|
|
fhandler_socket::set_close_on_exec (bool val)
|
2001-06-23 04:53:45 +08:00
|
|
|
{
|
2004-04-10 21:45:10 +08:00
|
|
|
close_on_exec (val);
|
2001-06-23 04:53:45 +08:00
|
|
|
debug_printf ("set close_on_exec for %s to %d", get_name (), val);
|
|
|
|
}
|
2002-01-02 00:25:31 +08:00
|
|
|
|
|
|
|
void
|
|
|
|
fhandler_socket::set_sun_path (const char *path)
|
|
|
|
{
|
2002-07-05 01:18:14 +08:00
|
|
|
sun_path = path ? cstrdup (path) : NULL;
|
2002-01-02 00:25:31 +08:00
|
|
|
}
|
2005-02-24 01:39:46 +08:00
|
|
|
|
|
|
|
int
|
|
|
|
fhandler_socket::getpeereid (pid_t *pid, __uid32_t *euid, __gid32_t *egid)
|
|
|
|
{
|
2005-03-22 02:56:50 +08:00
|
|
|
if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
|
|
|
|
{
|
|
|
|
set_errno (EINVAL);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (connect_state () != connected)
|
2005-02-24 01:39:46 +08:00
|
|
|
{
|
|
|
|
set_errno (ENOTCONN);
|
2005-03-22 02:56:50 +08:00
|
|
|
return -1;
|
2005-02-24 01:39:46 +08:00
|
|
|
}
|
2005-03-22 02:56:50 +08:00
|
|
|
if (sec_peer_pid == (pid_t) 0)
|
|
|
|
{
|
|
|
|
set_errno (ENOTCONN); /* Usually when calling getpeereid on
|
2005-05-02 11:50:11 +08:00
|
|
|
accepting (instead of accepted) socket. */
|
2005-03-22 02:56:50 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2005-07-03 10:40:30 +08:00
|
|
|
myfault efault;
|
|
|
|
if (efault.faulted (EFAULT))
|
|
|
|
return -1;
|
|
|
|
if (pid)
|
2005-03-22 02:56:50 +08:00
|
|
|
*pid = sec_peer_pid;
|
2005-07-03 10:40:30 +08:00
|
|
|
if (euid)
|
2005-03-22 02:56:50 +08:00
|
|
|
*euid = sec_peer_uid;
|
2005-07-03 10:40:30 +08:00
|
|
|
if (egid)
|
2005-03-22 02:56:50 +08:00
|
|
|
*egid = sec_peer_gid;
|
|
|
|
return 0;
|
2005-02-24 01:39:46 +08:00
|
|
|
}
|