* dtable.cc (dtable::vfork_parent_restore): Add debugging statement.
* exceptions.cc (try_to_debug): Spin only as long as we don't have a debugger attached. * fhandler.h (fhandler_base::set_nohandle): New method. (fhandler_base::get_nohandle): New method. * fhandler.cc (fhandler_base::dup): Avoid duplicating handle if there is no handle. * fhandler_disk_file.cc (fhandler_disk_file::opendir): Set nohandle flag on dummy fd. * Makefile.in: Make intermediate library for eventual inclusion in libcygwin.a * fhandler.h (fhandler_pipe::fhandler_pipe): Remove default argument setting since it is no longer used. * miscfuncs.cc (check_null_str): New function. (+check_null_str_errno): Ditto. * net.cc: Add defensive buffer checking throughout. (cygwin_sendto): Protect against invalid fd. (cygwin_recvfrom): Ditto. (cygwin_getpeername): Ditto. (cygwin_recv): Ditto. (cygwin_send): Ditto. * winsup.h: Declare a new function. * select.cc (set_bits): Fix conditional for setting fd in exceptfds. * dtable.cc (dtable::build_fhandler): Create fhandler_pipe using correct device type. * path.cc (get_devn): Set correct pipe device type from device name.
This commit is contained in:
		| @@ -1,3 +1,42 @@ | |||||||
|  | 2001-11-23  Christopher Faylor  <cgf@redhat.com> | ||||||
|  |  | ||||||
|  | 	* dtable.cc (dtable::vfork_parent_restore): Add debugging statement. | ||||||
|  |  | ||||||
|  | 	* exceptions.cc (try_to_debug): Spin only as long as we don't have a | ||||||
|  | 	debugger attached. | ||||||
|  |  | ||||||
|  | 	* fhandler.h (fhandler_base::set_nohandle): New method. | ||||||
|  | 	(fhandler_base::get_nohandle): New method. | ||||||
|  | 	* fhandler.cc (fhandler_base::dup): Avoid duplicating handle if there | ||||||
|  | 	is no handle. | ||||||
|  | 	* fhandler_disk_file.cc (fhandler_disk_file::opendir): Set nohandle | ||||||
|  | 	flag on dummy fd. | ||||||
|  |  | ||||||
|  | 2001-11-23  Christopher Faylor  <cgf@redhat.com> | ||||||
|  |  | ||||||
|  | 	* Makefile.in: Make intermediate library for eventual inclusion in | ||||||
|  | 	libcygwin.a | ||||||
|  |  | ||||||
|  | 	* fhandler.h (fhandler_pipe::fhandler_pipe): Remove default argument | ||||||
|  | 	setting since it is no longer used. | ||||||
|  |  | ||||||
|  | 	* miscfuncs.cc (check_null_str): New function. | ||||||
|  | 	(+check_null_str_errno): Ditto. | ||||||
|  | 	* net.cc: Add defensive buffer checking throughout. | ||||||
|  | 	(cygwin_sendto): Protect against invalid fd. | ||||||
|  | 	(cygwin_recvfrom): Ditto. | ||||||
|  | 	(cygwin_getpeername): Ditto. | ||||||
|  | 	(cygwin_recv): Ditto. | ||||||
|  | 	(cygwin_send): Ditto. | ||||||
|  | 	* winsup.h: Declare a new function. | ||||||
|  |  | ||||||
|  | 2001-11-23  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
|  | 	* select.cc (set_bits): Fix conditional for setting fd in exceptfds. | ||||||
|  | 	* dtable.cc (dtable::build_fhandler): Create fhandler_pipe using | ||||||
|  | 	correct device type. | ||||||
|  | 	* path.cc (get_devn): Set correct pipe device type from device name. | ||||||
|  |  | ||||||
| 2001-11-22  Christopher Faylor  <cgf@redhat.com> | 2001-11-22  Christopher Faylor  <cgf@redhat.com> | ||||||
|  |  | ||||||
| 	* path.cc (conv_path_list): Fix wild indexing into path due to | 	* path.cc (conv_path_list): Fix wild indexing into path due to | ||||||
|   | |||||||
| @@ -191,14 +191,14 @@ new-$(LIB_NAME): $(LIB_NAME) | |||||||
| # Rule to build cygwin.dll | # Rule to build cygwin.dll | ||||||
|  |  | ||||||
| new-$(DLL_NAME): $(LDSCRIPT) $(DLL_OFILES) $(DEF_FILE) $(DLL_IMPORTS) $(LIBC) $(LIBM) Makefile winver_stamp | new-$(DLL_NAME): $(LDSCRIPT) $(DLL_OFILES) $(DEF_FILE) $(DLL_IMPORTS) $(LIBC) $(LIBM) Makefile winver_stamp | ||||||
| 	$(CXX) $(CXXFLAGS) -nostdlib -Wl,-T$(firstword $^) -Wl,--out-implib,$(LIB_NAME) -shared -o $@ \ | 	$(CXX) $(CXXFLAGS) -nostdlib -Wl,-T$(firstword $^) -Wl,--out-implib,cygdll.a -shared -o $@ \ | ||||||
| 	-e $(DLL_ENTRY) $(DEF_FILE) $(DLL_OFILES) version.o winver.o \ | 	-e $(DLL_ENTRY) $(DEF_FILE) $(DLL_OFILES) version.o winver.o \ | ||||||
| 	$(DLL_IMPORTS) $(MALLOC_OBJ) $(LIBM) $(LIBC) \ | 	$(DLL_IMPORTS) $(MALLOC_OBJ) $(LIBM) $(LIBC) \ | ||||||
| 	-lstdc++ -lgcc -lshell32 -luuid | 	-lstdc++ -lgcc -lshell32 -luuid | ||||||
| 	@rm -f stamp-cygwin-lib | 	@rm -f stamp-cygwin-lib | ||||||
|  |  | ||||||
| $(LIB_NAME): new-$(DLL_NAME) $(LIBCOS) stamp-cygwin-lib | $(LIB_NAME): new-$(DLL_NAME) $(LIBCOS) stamp-cygwin-lib | ||||||
| 	$(AR) rcv $(LIB_NAME) $(LIBCOS) | 	$(AR) rcv $(LIB_NAME) $(LIBCOS) cygdll.a | ||||||
|  |  | ||||||
| stamp-cygwin-lib: | stamp-cygwin-lib: | ||||||
| 	@touch stamp-cygwin-lib | 	@touch stamp-cygwin-lib | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ details. */ | |||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <fcntl.h> | #include <fcntl.h> | ||||||
| #include <sys/cygwin.h> | #include <sys/cygwin.h> | ||||||
|  | #include <assert.h> | ||||||
|  |  | ||||||
| #define USE_SYS_TYPES_FD_SET | #define USE_SYS_TYPES_FD_SET | ||||||
| #include <winsock.h> | #include <winsock.h> | ||||||
| @@ -292,7 +293,7 @@ dtable::build_fhandler (int fd, DWORD dev, const char *name, int unit) | |||||||
|       case FH_PIPE: |       case FH_PIPE: | ||||||
|       case FH_PIPER: |       case FH_PIPER: | ||||||
|       case FH_PIPEW: |       case FH_PIPEW: | ||||||
| 	fh = cnew (fhandler_pipe) (); | 	fh = cnew (fhandler_pipe) (dev); | ||||||
| 	break; | 	break; | ||||||
|       case FH_SOCKET: |       case FH_SOCKET: | ||||||
| 	if ((fh = cnew (fhandler_socket) ())) | 	if ((fh = cnew (fhandler_socket) ())) | ||||||
| @@ -591,6 +592,7 @@ dtable::vfork_parent_restore () | |||||||
|  |  | ||||||
|   close_all_files (); |   close_all_files (); | ||||||
|   fhandler_base **deleteme = fds; |   fhandler_base **deleteme = fds; | ||||||
|  |   assert (fds_on_hold != NULL); | ||||||
|   fds = fds_on_hold; |   fds = fds_on_hold; | ||||||
|   fds_on_hold = NULL; |   fds_on_hold = NULL; | ||||||
|   cfree (deleteme); |   cfree (deleteme); | ||||||
|   | |||||||
| @@ -383,19 +383,19 @@ try_to_debug (bool waitloop) | |||||||
| 		       &si, | 		       &si, | ||||||
| 		       &pi); | 		       &pi); | ||||||
|  |  | ||||||
|   static int NO_COPY keep_looping = 0; |   if (!dbg) | ||||||
|  |     system_printf ("Failed to start debugger: %E"); | ||||||
|   if (dbg) |   else | ||||||
|     { |     { | ||||||
|       if (!waitloop) |       if (!waitloop) | ||||||
| 	return 1; | 	return 1; | ||||||
|       SetThreadPriority (hMainThread, THREAD_PRIORITY_IDLE); |       SetThreadPriority (hMainThread, THREAD_PRIORITY_IDLE); | ||||||
|       while (keep_looping) |       while (!IsDebuggerPresent ()) | ||||||
| 	/* spin */; | 	/* spin */; | ||||||
|  |       Sleep (4000); | ||||||
|  |       small_printf ("*** continuing from debugger call\n"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|   system_printf ("Failed to start debugger: %E"); |  | ||||||
|   /* FIXME: need to know handles of all running threads to |   /* FIXME: need to know handles of all running threads to | ||||||
|     resume_all_threads_except (current_thread_id); |     resume_all_threads_except (current_thread_id); | ||||||
|   */ |   */ | ||||||
|   | |||||||
| @@ -916,7 +916,9 @@ fhandler_base::dup (fhandler_base *child) | |||||||
|   debug_printf ("in fhandler_base dup"); |   debug_printf ("in fhandler_base dup"); | ||||||
|  |  | ||||||
|   HANDLE nh; |   HANDLE nh; | ||||||
|   if (!DuplicateHandle (hMainProc, get_handle(), hMainProc, &nh, 0, TRUE, |   if (get_nohandle ()) | ||||||
|  |     nh = NULL; | ||||||
|  |   else if (!DuplicateHandle (hMainProc, get_handle(), hMainProc, &nh, 0, TRUE, | ||||||
| 			DUPLICATE_SAME_ACCESS)) | 			DUPLICATE_SAME_ACCESS)) | ||||||
|     { |     { | ||||||
|       system_printf ("dup(%s) failed, handle %x, %E", |       system_printf ("dup(%s) failed, handle %x, %E", | ||||||
| @@ -1151,7 +1153,7 @@ fhandler_base::fixup_after_fork (HANDLE parent) | |||||||
|   fork_fixup (parent, io_handle, "io_handle"); |   fork_fixup (parent, io_handle, "io_handle"); | ||||||
| } | } | ||||||
|  |  | ||||||
| int | bool | ||||||
| fhandler_base::is_nonblocking () | fhandler_base::is_nonblocking () | ||||||
| { | { | ||||||
|   return (openflags & O_NONBLOCK_MASK) != 0; |   return (openflags & O_NONBLOCK_MASK) != 0; | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ enum | |||||||
|   FH_W95LSBUG	= 0x00400000,	/* set when lseek is called as a flag that |   FH_W95LSBUG	= 0x00400000,	/* set when lseek is called as a flag that | ||||||
| 				 * _write should check if we've moved beyond | 				 * _write should check if we've moved beyond | ||||||
| 				 * EOF, zero filling if so. */ | 				 * EOF, zero filling if so. */ | ||||||
|   FH_UNUSED	= 0x00800000,	/* currently unused. */ |   FH_NOHANDLE	= 0x00800000,	/* No handle associated with fhandler. */ | ||||||
|   FH_NOEINTR	= 0x01000000,	/* Set if I/O should be uninterruptible. */ |   FH_NOEINTR	= 0x01000000,	/* Set if I/O should be uninterruptible. */ | ||||||
|   FH_FFIXUP	= 0x02000000,	/* Set if need to fixup after fork. */ |   FH_FFIXUP	= 0x02000000,	/* Set if need to fixup after fork. */ | ||||||
|   FH_LOCAL	= 0x04000000,	/* File is unix domain socket */ |   FH_LOCAL	= 0x04000000,	/* File is unix domain socket */ | ||||||
| @@ -167,25 +167,29 @@ class fhandler_base | |||||||
|   int get_access () { return access; } |   int get_access () { return access; } | ||||||
|   void set_access (int x) { access = x; } |   void set_access (int x) { access = x; } | ||||||
|  |  | ||||||
|   int get_async () { return FHISSETF (ASYNC); } |   bool get_async () { return FHISSETF (ASYNC); } | ||||||
|   void set_async (int x) { FHCONDSETF (x, ASYNC); } |   void set_async (int x) { FHCONDSETF (x, ASYNC); } | ||||||
|  |  | ||||||
|   int get_flags () { return openflags; } |   int get_flags () { return openflags; } | ||||||
|   void set_flags (int x) { openflags = x; } |   void set_flags (int x) { openflags = x; } | ||||||
|  |  | ||||||
|   int is_nonblocking (); |   bool is_nonblocking (); | ||||||
|   void set_nonblocking (int yes); |   void set_nonblocking (int yes); | ||||||
|  |  | ||||||
|   int get_w_binary () { return FHISSETF (WBINARY); } |   bool get_w_binary () { return FHISSETF (WBINARY); } | ||||||
|   int get_r_binary () { return FHISSETF (RBINARY); } |   bool get_r_binary () { return FHISSETF (RBINARY); } | ||||||
|  |  | ||||||
|   int get_w_binset () { return FHISSETF (WBINSET); } |   bool get_w_binset () { return FHISSETF (WBINSET); } | ||||||
|   int get_r_binset () { return FHISSETF (RBINSET); } |   bool get_r_binset () { return FHISSETF (RBINSET); } | ||||||
|  |  | ||||||
|   void set_w_binary (int b) { FHCONDSETF (b, WBINARY); FHSETF (WBINSET); } |   void set_w_binary (int b) { FHCONDSETF (b, WBINARY); FHSETF (WBINSET); } | ||||||
|   void set_r_binary (int b) { FHCONDSETF (b, RBINARY); FHSETF (RBINSET); } |   void set_r_binary (int b) { FHCONDSETF (b, RBINARY); FHSETF (RBINSET); } | ||||||
|   void clear_w_binary () {FHCLEARF (WBINARY); FHCLEARF (WBINSET); } |   void clear_w_binary () {FHCLEARF (WBINARY); FHCLEARF (WBINSET); } | ||||||
|   void clear_r_binary () {FHCLEARF (RBINARY); FHCLEARF (RBINSET); } |   void clear_r_binary () {FHCLEARF (RBINARY); FHCLEARF (RBINSET); } | ||||||
|  |  | ||||||
|  |   bool get_nohandle () { return FHISSETF (NOHANDLE); } | ||||||
|  |   void set_nohandle (int x) { FHCONDSETF (x, NOHANDLE); } | ||||||
|  |  | ||||||
|   void set_open_status () {open_status = status;} |   void set_open_status () {open_status = status;} | ||||||
|   DWORD get_open_status () {return open_status;} |   DWORD get_open_status () {return open_status;} | ||||||
|   void reset_to_open_binmode () |   void reset_to_open_binmode () | ||||||
| @@ -197,10 +201,10 @@ class fhandler_base | |||||||
|  |  | ||||||
|   int get_default_fmode (int flags); |   int get_default_fmode (int flags); | ||||||
|  |  | ||||||
|   int get_r_no_interrupt () { return FHISSETF (NOEINTR); } |   bool get_r_no_interrupt () { return FHISSETF (NOEINTR); } | ||||||
|   void set_r_no_interrupt (int b) { FHCONDSETF (b, NOEINTR); } |   void set_r_no_interrupt (int b) { FHCONDSETF (b, NOEINTR); } | ||||||
|  |  | ||||||
|   int get_close_on_exec () { return FHISSETF (CLOEXEC); } |   bool get_close_on_exec () { return FHISSETF (CLOEXEC); } | ||||||
|   int set_close_on_exec_flag (int b) { return FHCONDSETF (b, CLOEXEC); } |   int set_close_on_exec_flag (int b) { return FHCONDSETF (b, CLOEXEC); } | ||||||
|  |  | ||||||
|   LPSECURITY_ATTRIBUTES get_inheritance (bool all = 0) |   LPSECURITY_ATTRIBUTES get_inheritance (bool all = 0) | ||||||
| @@ -212,9 +216,9 @@ class fhandler_base | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   void set_check_win95_lseek_bug (int b = 1) { FHCONDSETF (b, W95LSBUG); } |   void set_check_win95_lseek_bug (int b = 1) { FHCONDSETF (b, W95LSBUG); } | ||||||
|   int get_check_win95_lseek_bug () { return FHISSETF (W95LSBUG); } |   bool get_check_win95_lseek_bug () { return FHISSETF (W95LSBUG); } | ||||||
|  |  | ||||||
|   int get_need_fork_fixup () { return FHISSETF (FFIXUP); } |   bool get_need_fork_fixup () { return FHISSETF (FFIXUP); } | ||||||
|   void set_need_fork_fixup () { FHSETF (FFIXUP); } |   void set_need_fork_fixup () { FHSETF (FFIXUP); } | ||||||
|  |  | ||||||
|   virtual void set_close_on_exec (int val); |   virtual void set_close_on_exec (int val); | ||||||
| @@ -223,31 +227,31 @@ class fhandler_base | |||||||
|   virtual void fixup_after_fork (HANDLE); |   virtual void fixup_after_fork (HANDLE); | ||||||
|   virtual void fixup_after_exec (HANDLE) {} |   virtual void fixup_after_exec (HANDLE) {} | ||||||
|  |  | ||||||
|   int get_symlink_p () { return FHISSETF (SYMLINK); } |   bool get_symlink_p () { return FHISSETF (SYMLINK); } | ||||||
|   void set_symlink_p (int val) { FHCONDSETF (val, SYMLINK); } |   void set_symlink_p (int val) { FHCONDSETF (val, SYMLINK); } | ||||||
|   void set_symlink_p () { FHSETF (SYMLINK); } |   void set_symlink_p () { FHSETF (SYMLINK); } | ||||||
|  |  | ||||||
|   int get_socket_p () { return FHISSETF (LOCAL); } |   bool get_socket_p () { return FHISSETF (LOCAL); } | ||||||
|   void set_socket_p (int val) { FHCONDSETF (val, LOCAL); } |   void set_socket_p (int val) { FHCONDSETF (val, LOCAL); } | ||||||
|   void set_socket_p () { FHSETF (LOCAL); } |   void set_socket_p () { FHSETF (LOCAL); } | ||||||
|  |  | ||||||
|   int get_execable_p () { return FHISSETF (EXECABL); } |   bool get_execable_p () { return FHISSETF (EXECABL); } | ||||||
|   void set_execable_p (executable_states val) |   void set_execable_p (executable_states val) | ||||||
|   { |   { | ||||||
|     FHCONDSETF (val == is_executable, EXECABL); |     FHCONDSETF (val == is_executable, EXECABL); | ||||||
|     FHCONDSETF (val == dont_care_if_executable, DCEXEC); |     FHCONDSETF (val == dont_care_if_executable, DCEXEC); | ||||||
|   } |   } | ||||||
|   void set_execable_p () { FHSETF (EXECABL); } |   void set_execable_p () { FHSETF (EXECABL); } | ||||||
|   int dont_care_if_execable () { return FHISSETF (DCEXEC); } |   bool dont_care_if_execable () { return FHISSETF (DCEXEC); } | ||||||
|  |  | ||||||
|   int get_append_p () { return FHISSETF (APPEND); } |   bool get_append_p () { return FHISSETF (APPEND); } | ||||||
|   void set_append_p (int val) { FHCONDSETF (val, APPEND); } |   void set_append_p (int val) { FHCONDSETF (val, APPEND); } | ||||||
|   void set_append_p () { FHSETF (APPEND); } |   void set_append_p () { FHSETF (APPEND); } | ||||||
|  |  | ||||||
|   int get_query_open () { return FHISSETF (QUERYOPEN); } |   bool get_query_open () { return FHISSETF (QUERYOPEN); } | ||||||
|   void set_query_open (int val) { FHCONDSETF (val, QUERYOPEN); } |   void set_query_open (int val) { FHCONDSETF (val, QUERYOPEN); } | ||||||
|  |  | ||||||
|   int get_readahead_valid () { return raixget < ralen; } |   bool get_readahead_valid () { return raixget < ralen; } | ||||||
|   int puts_readahead (const char *s, size_t len = (size_t) -1); |   int puts_readahead (const char *s, size_t len = (size_t) -1); | ||||||
|   int put_readahead (char value); |   int put_readahead (char value); | ||||||
|  |  | ||||||
| @@ -260,10 +264,10 @@ class fhandler_base | |||||||
|  |  | ||||||
|   int get_readahead_into_buffer (char *buf, size_t buflen); |   int get_readahead_into_buffer (char *buf, size_t buflen); | ||||||
|  |  | ||||||
|   int has_acls () { return FHISSETF (HASACLS); } |   bool has_acls () { return FHISSETF (HASACLS); } | ||||||
|   void set_has_acls (int val) { FHCONDSETF (val, HASACLS); } |   void set_has_acls (int val) { FHCONDSETF (val, HASACLS); } | ||||||
|  |  | ||||||
|   int isremote () { return FHISSETF (ISREMOTE); } |   bool isremote () { return FHISSETF (ISREMOTE); } | ||||||
|   void set_isremote (int val) { FHCONDSETF (val, ISREMOTE); } |   void set_isremote (int val) { FHCONDSETF (val, ISREMOTE); } | ||||||
|  |  | ||||||
|   const char *get_name () { return unix_path_name; } |   const char *get_name () { return unix_path_name; } | ||||||
| @@ -405,7 +409,7 @@ class fhandler_pipe: public fhandler_base | |||||||
|   DWORD orig_pid; |   DWORD orig_pid; | ||||||
|   unsigned id; |   unsigned id; | ||||||
|  public: |  public: | ||||||
|   fhandler_pipe (DWORD devtype = FH_PIPE); |   fhandler_pipe (DWORD devtype); | ||||||
|   off_t lseek (off_t offset, int whence); |   off_t lseek (off_t offset, int whence); | ||||||
|   select_record *select_read (select_record *s); |   select_record *select_read (select_record *s); | ||||||
|   select_record *select_write (select_record *s); |   select_record *select_write (select_record *s); | ||||||
|   | |||||||
| @@ -599,6 +599,7 @@ fhandler_disk_file::opendir (path_conv& real_name) | |||||||
|       dir->__d_dirent->d_version = __DIRENT_VERSION; |       dir->__d_dirent->d_version = __DIRENT_VERSION; | ||||||
|       cygheap_fdnew fd; |       cygheap_fdnew fd; | ||||||
|       fd = this; |       fd = this; | ||||||
|  |       fd->set_nohandle (true); | ||||||
|       dir->__d_dirent->d_fd = fd; |       dir->__d_dirent->d_fd = fd; | ||||||
|       dir->__d_u.__d_data.__fh = this; |       dir->__d_u.__d_data.__fh = this; | ||||||
|       /* FindFirstFile doesn't seem to like duplicate /'s. */ |       /* FindFirstFile doesn't seem to like duplicate /'s. */ | ||||||
|   | |||||||
| @@ -115,6 +115,15 @@ strcasestr (const char *searchee, const char *lookfor) | |||||||
|   return NULL; |   return NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int __stdcall | ||||||
|  | check_null_str (const char *name) | ||||||
|  | { | ||||||
|  |   if (name && !IsBadStringPtr (name, MAX_PATH)) | ||||||
|  |     return 0; | ||||||
|  |  | ||||||
|  |   return EFAULT; | ||||||
|  | } | ||||||
|  |  | ||||||
| int __stdcall | int __stdcall | ||||||
| check_null_empty_str (const char *name) | check_null_empty_str (const char *name) | ||||||
| { | { | ||||||
| @@ -133,6 +142,15 @@ check_null_empty_str_errno (const char *name) | |||||||
|   return __err; |   return __err; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int __stdcall | ||||||
|  | check_null_str_errno (const char *name) | ||||||
|  | { | ||||||
|  |   int __err; | ||||||
|  |   if ((__err = check_null_str (name))) | ||||||
|  |     set_errno (__err); | ||||||
|  |   return __err; | ||||||
|  | } | ||||||
|  |  | ||||||
| int __stdcall | int __stdcall | ||||||
| __check_null_invalid_struct (const void *s, unsigned sz) | __check_null_invalid_struct (const void *s, unsigned sz) | ||||||
| { | { | ||||||
|   | |||||||
| @@ -117,6 +117,17 @@ wsock_event::wait (int socket, LPDWORD flags) | |||||||
|  |  | ||||||
| WSADATA wsadata; | WSADATA wsadata; | ||||||
|  |  | ||||||
|  | /* Cygwin internal */ | ||||||
|  | static fhandler_socket * | ||||||
|  | get (int fd) | ||||||
|  | { | ||||||
|  |   cygheap_fdget cfd (fd); | ||||||
|  |   if (cfd < 0) | ||||||
|  |     return 0; | ||||||
|  |  | ||||||
|  |   return cfd->is_socket (); | ||||||
|  | } | ||||||
|  |  | ||||||
| /* Cygwin internal */ | /* Cygwin internal */ | ||||||
| static SOCKET __stdcall | static SOCKET __stdcall | ||||||
| set_socket_inheritance (SOCKET sock) | set_socket_inheritance (SOCKET sock) | ||||||
| @@ -205,6 +216,9 @@ cygwin_inet_addr (const char *cp) | |||||||
| extern "C" int | extern "C" int | ||||||
| cygwin_inet_aton (const char *cp, struct in_addr *inp) | cygwin_inet_aton (const char *cp, struct in_addr *inp) | ||||||
| { | { | ||||||
|  |   if (check_null_str_errno (cp) || check_null_invalid_struct_errno (inp)) | ||||||
|  |     return 0; | ||||||
|  |  | ||||||
|   unsigned long res = inet_addr (cp); |   unsigned long res = inet_addr (cp); | ||||||
|   if (res == INADDR_NONE && strcmp (cp, "255.255.255.255")) |   if (res == INADDR_NONE && strcmp (cp, "255.255.255.255")) | ||||||
|     return 0; |     return 0; | ||||||
| @@ -219,6 +233,8 @@ extern "C" unsigned int	WINAPI inet_network (const char *); | |||||||
| extern "C" unsigned int | extern "C" unsigned int | ||||||
| cygwin_inet_network (const char *cp) | cygwin_inet_network (const char *cp) | ||||||
| { | { | ||||||
|  |   if (check_null_str_errno (cp)) | ||||||
|  |     return 0; | ||||||
|   unsigned int res = inet_network (cp); |   unsigned int res = inet_network (cp); | ||||||
|   return res; |   return res; | ||||||
| } | } | ||||||
| @@ -232,7 +248,6 @@ inet_netof (struct in_addr in) | |||||||
| { | { | ||||||
|   unsigned long i, res; |   unsigned long i, res; | ||||||
|  |  | ||||||
|  |  | ||||||
|   i = ntohl (in.s_addr); |   i = ntohl (in.s_addr); | ||||||
|   if (IN_CLASSA (i)) |   if (IN_CLASSA (i)) | ||||||
|     res = (i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT; |     res = (i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT; | ||||||
| @@ -253,8 +268,7 @@ extern "C" struct in_addr | |||||||
| inet_makeaddr (int net, int lna) | inet_makeaddr (int net, int lna) | ||||||
| { | { | ||||||
|   unsigned long i; |   unsigned long i; | ||||||
|   struct in_addr in; |   static struct in_addr in;	/* Note -- not thread safe! */ | ||||||
|  |  | ||||||
|  |  | ||||||
|   if (net < IN_CLASSA_MAX) |   if (net < IN_CLASSA_MAX) | ||||||
|     i = (net << IN_CLASSA_NSHIFT) | (lna & IN_CLASSA_HOST); |     i = (net << IN_CLASSA_NSHIFT) | (lna & IN_CLASSA_HOST); | ||||||
| @@ -473,6 +487,8 @@ out: | |||||||
| extern "C" struct protoent * | extern "C" struct protoent * | ||||||
| cygwin_getprotobyname (const char *p) | cygwin_getprotobyname (const char *p) | ||||||
| { | { | ||||||
|  |   if (check_null_str_errno (p)) | ||||||
|  |     return NULL; | ||||||
|   free_protoent_ptr (protoent_buf); |   free_protoent_ptr (protoent_buf); | ||||||
|   protoent_buf = dup_protoent_ptr (getprotobyname (p)); |   protoent_buf = dup_protoent_ptr (getprotobyname (p)); | ||||||
|   if (!protoent_buf) |   if (!protoent_buf) | ||||||
| @@ -604,37 +620,45 @@ cygwin_sendto (int fd, | |||||||
|   int res; |   int res; | ||||||
|   wsock_event wsock_evt; |   wsock_event wsock_evt; | ||||||
|   LPWSAOVERLAPPED ovr; |   LPWSAOVERLAPPED ovr; | ||||||
|   fhandler_socket *h = (fhandler_socket *) cygheap->fdtab[fd]; |   fhandler_socket *h = get (fd); | ||||||
|   sockaddr_in sin; |  | ||||||
|   sigframe thisframe (mainthread); |  | ||||||
|  |  | ||||||
|   if (get_inet_addr (to, tolen, &sin, &tolen) == 0) |   if ((len && __check_invalid_read_ptr_errno (buf, (unsigned) len)) | ||||||
|     return -1; |       || __check_null_invalid_struct_errno (to, tolen) | ||||||
|  |       || !h) | ||||||
|   if (h->is_nonblocking () || !(ovr = wsock_evt.prepare ())) |     res = -1; | ||||||
|     { |  | ||||||
|       debug_printf ("Fallback to winsock 1 sendto call"); |  | ||||||
|       if ((res = sendto (h->get_socket (), (const char *) buf, len, flags, |  | ||||||
| 			 (sockaddr *) &sin, tolen)) == SOCKET_ERROR) |  | ||||||
| 	{ |  | ||||||
| 	  set_winsock_errno (); |  | ||||||
| 	  res = -1; |  | ||||||
| 	} |  | ||||||
|     } |  | ||||||
|   else |   else | ||||||
|     { |     { | ||||||
|       WSABUF wsabuf = { len, (char *) buf }; |       sockaddr_in sin; | ||||||
|       DWORD ret = 0; |       sigframe thisframe (mainthread); | ||||||
|       if (WSASendTo (h->get_socket (), &wsabuf, 1, &ret, (DWORD)flags, |  | ||||||
| 		     (sockaddr *) &sin, tolen, ovr, NULL) != SOCKET_ERROR) |       if (get_inet_addr (to, tolen, &sin, &tolen) == 0) | ||||||
| 	res = ret; | 	return -1; | ||||||
|       else if ((res = WSAGetLastError ()) != WSA_IO_PENDING) |  | ||||||
|  |       if (h->is_nonblocking () || !(ovr = wsock_evt.prepare ())) | ||||||
| 	{ | 	{ | ||||||
| 	  set_winsock_errno (); | 	  debug_printf ("Fallback to winsock 1 sendto call"); | ||||||
| 	  res = -1; | 	  if ((res = sendto (h->get_socket (), (const char *) buf, len, flags, | ||||||
|  | 			     (sockaddr *) &sin, tolen)) == SOCKET_ERROR) | ||||||
|  | 	    { | ||||||
|  | 	      set_winsock_errno (); | ||||||
|  | 	      res = -1; | ||||||
|  | 	    } | ||||||
|  | 	} | ||||||
|  |       else | ||||||
|  | 	{ | ||||||
|  | 	  WSABUF wsabuf = { len, (char *) buf }; | ||||||
|  | 	  DWORD ret = 0; | ||||||
|  | 	  if (WSASendTo (h->get_socket (), &wsabuf, 1, &ret, (DWORD)flags, | ||||||
|  | 			 (sockaddr *) &sin, tolen, ovr, NULL) != SOCKET_ERROR) | ||||||
|  | 	    res = ret; | ||||||
|  | 	  else if ((res = WSAGetLastError ()) != WSA_IO_PENDING) | ||||||
|  | 	    { | ||||||
|  | 	      set_winsock_errno (); | ||||||
|  | 	      res = -1; | ||||||
|  | 	    } | ||||||
|  | 	  else if ((res = wsock_evt.wait (h->get_socket (), (DWORD *)&flags)) == -1) | ||||||
|  | 	    set_winsock_errno (); | ||||||
| 	} | 	} | ||||||
|       else if ((res = wsock_evt.wait (h->get_socket (), (DWORD *)&flags)) == -1) |  | ||||||
| 	set_winsock_errno (); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   syscall_printf ("%d = sendto (%d, %x, %x, %x)", res, fd, buf, len, flags); |   syscall_printf ("%d = sendto (%d, %x, %x, %x)", res, fd, buf, len, flags); | ||||||
| @@ -654,33 +678,42 @@ cygwin_recvfrom (int fd, | |||||||
|   int res; |   int res; | ||||||
|   wsock_event wsock_evt; |   wsock_event wsock_evt; | ||||||
|   LPWSAOVERLAPPED ovr; |   LPWSAOVERLAPPED ovr; | ||||||
|   fhandler_socket *h = (fhandler_socket *) cygheap->fdtab[fd]; |   fhandler_socket *h = get (fd); | ||||||
|   sigframe thisframe (mainthread); |  | ||||||
|  |  | ||||||
|   if (h->is_nonblocking () ||!(ovr = wsock_evt.prepare ())) |   if (__check_null_invalid_struct_errno (buf, (unsigned) len) | ||||||
|     { |       || check_null_invalid_struct_errno (fromlen) | ||||||
|       debug_printf ("Fallback to winsock 1 recvfrom call"); |       || __check_null_invalid_struct_errno (from, (unsigned) *fromlen) | ||||||
|       if ((res = recvfrom (h->get_socket (), buf, len, flags, from, fromlen)) |       || !h) | ||||||
| 	  == SOCKET_ERROR) |     res = -1; | ||||||
| 	{ |  | ||||||
| 	  set_winsock_errno (); |  | ||||||
| 	  res = -1; |  | ||||||
| 	} |  | ||||||
|     } |  | ||||||
|   else |   else | ||||||
|     { |     { | ||||||
|       WSABUF wsabuf = { len, (char *) buf }; |       sigframe thisframe (mainthread); | ||||||
|       DWORD ret = 0; |  | ||||||
|       if (WSARecvFrom (h->get_socket (), &wsabuf, 1, &ret, (DWORD *)&flags, |       if (h->is_nonblocking () ||!(ovr = wsock_evt.prepare ())) | ||||||
| 		       from, fromlen, ovr, NULL) != SOCKET_ERROR) |  | ||||||
| 	res = ret; |  | ||||||
|       else if ((res = WSAGetLastError ()) != WSA_IO_PENDING) |  | ||||||
| 	{ | 	{ | ||||||
| 	  set_winsock_errno (); | 	  debug_printf ("Fallback to winsock 1 recvfrom call"); | ||||||
| 	  res = -1; | 	  if ((res = recvfrom (h->get_socket (), buf, len, flags, from, fromlen)) | ||||||
|  | 	      == SOCKET_ERROR) | ||||||
|  | 	    { | ||||||
|  | 	      set_winsock_errno (); | ||||||
|  | 	      res = -1; | ||||||
|  | 	    } | ||||||
|  | 	} | ||||||
|  |       else | ||||||
|  | 	{ | ||||||
|  | 	  WSABUF wsabuf = { len, (char *) buf }; | ||||||
|  | 	  DWORD ret = 0; | ||||||
|  | 	  if (WSARecvFrom (h->get_socket (), &wsabuf, 1, &ret, (DWORD *)&flags, | ||||||
|  | 			   from, fromlen, ovr, NULL) != SOCKET_ERROR) | ||||||
|  | 	    res = ret; | ||||||
|  | 	  else if ((res = WSAGetLastError ()) != WSA_IO_PENDING) | ||||||
|  | 	    { | ||||||
|  | 	      set_winsock_errno (); | ||||||
|  | 	      res = -1; | ||||||
|  | 	    } | ||||||
|  | 	  else if ((res = wsock_evt.wait (h->get_socket (), (DWORD *)&flags)) == -1) | ||||||
|  | 	    set_winsock_errno (); | ||||||
| 	} | 	} | ||||||
|       else if ((res = wsock_evt.wait (h->get_socket (), (DWORD *)&flags)) == -1) |  | ||||||
| 	set_winsock_errno (); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   syscall_printf ("%d = recvfrom (%d, %x, %x, %x)", res, fd, buf, len, flags); |   syscall_printf ("%d = recvfrom (%d, %x, %x, %x)", res, fd, buf, len, flags); | ||||||
| @@ -688,17 +721,6 @@ cygwin_recvfrom (int fd, | |||||||
|   return res; |   return res; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Cygwin internal */ |  | ||||||
| fhandler_socket * |  | ||||||
| get (int fd) |  | ||||||
| { |  | ||||||
|   cygheap_fdget cfd (fd); |  | ||||||
|   if (cfd < 0) |  | ||||||
|     return 0; |  | ||||||
|  |  | ||||||
|   return cfd->is_socket (); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /* exported as setsockopt: standards? */ | /* exported as setsockopt: standards? */ | ||||||
| extern "C" int | extern "C" int | ||||||
| cygwin_setsockopt (int fd, | cygwin_setsockopt (int fd, | ||||||
| @@ -711,7 +733,7 @@ cygwin_setsockopt (int fd, | |||||||
|   int res = -1; |   int res = -1; | ||||||
|   const char *name = "error"; |   const char *name = "error"; | ||||||
|  |  | ||||||
|   if (h) |   if (!__check_invalid_read_ptr_errno (optval, optlen) && h) | ||||||
|     { |     { | ||||||
|       /* For the following debug_printf */ |       /* For the following debug_printf */ | ||||||
|       switch (optname) |       switch (optname) | ||||||
| @@ -774,7 +796,9 @@ cygwin_getsockopt (int fd, | |||||||
|   fhandler_socket *h = get (fd); |   fhandler_socket *h = get (fd); | ||||||
|   int res = -1; |   int res = -1; | ||||||
|   const char *name = "error"; |   const char *name = "error"; | ||||||
|   if (h) |   if (!check_null_invalid_struct_errno (optlen) | ||||||
|  |       && !__check_null_invalid_struct_errno (optval, (unsigned) optlen) | ||||||
|  |       && h) | ||||||
|     { |     { | ||||||
|       /* For the following debug_printf */ |       /* For the following debug_printf */ | ||||||
|       switch (optname) |       switch (optname) | ||||||
| @@ -843,13 +867,14 @@ cygwin_connect (int fd, | |||||||
|   int secret [4]; |   int secret [4]; | ||||||
|   sigframe thisframe (mainthread); |   sigframe thisframe (mainthread); | ||||||
|  |  | ||||||
|  |   if (__check_invalid_read_ptr_errno (name, namelen)) | ||||||
|  |     return -1; | ||||||
|  |  | ||||||
|   if (get_inet_addr (name, namelen, &sin, &namelen, secret) == 0) |   if (get_inet_addr (name, namelen, &sin, &namelen, secret) == 0) | ||||||
|     return -1; |     return -1; | ||||||
|  |  | ||||||
|   if (!sock) |   if (!sock) | ||||||
|     { |     res = -1; | ||||||
|       res = -1; |  | ||||||
|     } |  | ||||||
|   else |   else | ||||||
|     { |     { | ||||||
|       res = connect (sock->get_socket (), (sockaddr *) &sin, namelen); |       res = connect (sock->get_socket (), (sockaddr *) &sin, namelen); | ||||||
| @@ -975,6 +1000,10 @@ out: | |||||||
| extern "C" struct servent * | extern "C" struct servent * | ||||||
| cygwin_getservbyname (const char *name, const char *proto) | cygwin_getservbyname (const char *name, const char *proto) | ||||||
| { | { | ||||||
|  |   if (check_null_str_errno (name) | ||||||
|  |       || (proto != NULL && check_null_str_errno (proto))) | ||||||
|  |     return NULL; | ||||||
|  |  | ||||||
|   free_servent_ptr (servent_buf); |   free_servent_ptr (servent_buf); | ||||||
|   servent_buf = dup_servent_ptr (getservbyname (name, proto)); |   servent_buf = dup_servent_ptr (getservbyname (name, proto)); | ||||||
|   if (!servent_buf) |   if (!servent_buf) | ||||||
| @@ -988,6 +1017,9 @@ cygwin_getservbyname (const char *name, const char *proto) | |||||||
| extern "C" struct servent * | extern "C" struct servent * | ||||||
| cygwin_getservbyport (int port, const char *proto) | cygwin_getservbyport (int port, const char *proto) | ||||||
| { | { | ||||||
|  |   if (proto != NULL && check_null_str_errno (proto)) | ||||||
|  |     return NULL; | ||||||
|  |  | ||||||
|   free_servent_ptr (servent_buf); |   free_servent_ptr (servent_buf); | ||||||
|   servent_buf = dup_servent_ptr (getservbyport (port, proto)); |   servent_buf = dup_servent_ptr (getservbyport (port, proto)); | ||||||
|   if (!servent_buf) |   if (!servent_buf) | ||||||
| @@ -1002,6 +1034,9 @@ cygwin_gethostname (char *name, size_t len) | |||||||
| { | { | ||||||
|   int PASCAL win32_gethostname (char*, int); |   int PASCAL win32_gethostname (char*, int); | ||||||
|  |  | ||||||
|  |   if (__check_null_invalid_struct_errno (name, len)) | ||||||
|  |     return -1; | ||||||
|  |  | ||||||
|   if (wsock32_handle == NULL || |   if (wsock32_handle == NULL || | ||||||
|       win32_gethostname (name, len) == SOCKET_ERROR) |       win32_gethostname (name, len) == SOCKET_ERROR) | ||||||
|     { |     { | ||||||
| @@ -1080,6 +1115,9 @@ cygwin_gethostbyname (const char *name) | |||||||
|   static char *tmp_addr_list[2]; |   static char *tmp_addr_list[2]; | ||||||
|   static int a, b, c, d; |   static int a, b, c, d; | ||||||
|  |  | ||||||
|  |   if (check_null_str_errno (name)) | ||||||
|  |     return NULL; | ||||||
|  |  | ||||||
|   if (sscanf (name, "%d.%d.%d.%d", &a, &b, &c, &d) == 4) |   if (sscanf (name, "%d.%d.%d.%d", &a, &b, &c, &d) == 4) | ||||||
|     { |     { | ||||||
|       /* In case you don't have DNS, at least x.x.x.x still works */ |       /* In case you don't have DNS, at least x.x.x.x still works */ | ||||||
| @@ -1116,6 +1154,9 @@ cygwin_gethostbyname (const char *name) | |||||||
| extern "C" struct hostent * | extern "C" struct hostent * | ||||||
| cygwin_gethostbyaddr (const char *addr, int len, int type) | cygwin_gethostbyaddr (const char *addr, int len, int type) | ||||||
| { | { | ||||||
|  |   if (__check_null_invalid_struct_errno (addr, len)) | ||||||
|  |     return NULL; | ||||||
|  |  | ||||||
|   free_hostent_ptr (hostent_buf); |   free_hostent_ptr (hostent_buf); | ||||||
|   hostent_buf = dup_hostent_ptr (gethostbyaddr (addr, len, type)); |   hostent_buf = dup_hostent_ptr (gethostbyaddr (addr, len, type)); | ||||||
|   if (!hostent_buf) |   if (!hostent_buf) | ||||||
| @@ -1135,6 +1176,11 @@ cygwin_gethostbyaddr (const char *addr, int len, int type) | |||||||
| extern "C" int | extern "C" int | ||||||
| cygwin_accept (int fd, struct sockaddr *peer, int *len) | cygwin_accept (int fd, struct sockaddr *peer, int *len) | ||||||
| { | { | ||||||
|  |   if (peer != NULL | ||||||
|  |       && (check_null_invalid_struct_errno (len) | ||||||
|  | 	  || __check_null_invalid_struct_errno (peer, (unsigned) *len))) | ||||||
|  |     return -1; | ||||||
|  |  | ||||||
|   int res = -1; |   int res = -1; | ||||||
|   BOOL secret_check_failed = FALSE; |   BOOL secret_check_failed = FALSE; | ||||||
|   BOOL in_progress = FALSE; |   BOOL in_progress = FALSE; | ||||||
| @@ -1220,6 +1266,9 @@ cygwin_accept (int fd, struct sockaddr *peer, int *len) | |||||||
| extern "C" int | extern "C" int | ||||||
| cygwin_bind (int fd, const struct sockaddr *my_addr, int addrlen) | cygwin_bind (int fd, const struct sockaddr *my_addr, int addrlen) | ||||||
| { | { | ||||||
|  |   if (__check_null_invalid_struct_errno (my_addr, addrlen)) | ||||||
|  |     return -1; | ||||||
|  |  | ||||||
|   int res = -1; |   int res = -1; | ||||||
|  |  | ||||||
|   fhandler_socket *sock = get (fd); |   fhandler_socket *sock = get (fd); | ||||||
| @@ -1306,6 +1355,10 @@ out: | |||||||
| extern "C" int | extern "C" int | ||||||
| cygwin_getsockname (int fd, struct sockaddr *addr, int *namelen) | cygwin_getsockname (int fd, struct sockaddr *addr, int *namelen) | ||||||
| { | { | ||||||
|  |   if (check_null_invalid_struct_errno (namelen) | ||||||
|  |       || __check_null_invalid_struct_errno (addr, (unsigned) *namelen)) | ||||||
|  |     return -1; | ||||||
|  |  | ||||||
|   int res = -1; |   int res = -1; | ||||||
|  |  | ||||||
|   fhandler_socket *sock = get (fd); |   fhandler_socket *sock = get (fd); | ||||||
| @@ -1419,12 +1472,21 @@ cygwin_herror (const char *s) | |||||||
| extern "C" int | extern "C" int | ||||||
| cygwin_getpeername (int fd, struct sockaddr *name, int *len) | cygwin_getpeername (int fd, struct sockaddr *name, int *len) | ||||||
| { | { | ||||||
|   fhandler_socket *h = (fhandler_socket *) cygheap->fdtab[fd]; |   int res; | ||||||
|  |   if (check_null_invalid_struct_errno (len) | ||||||
|  |       || __check_null_invalid_struct_errno (name, (unsigned) *len)) | ||||||
|  |     return -1; | ||||||
|  |  | ||||||
|   debug_printf ("getpeername %d", h->get_socket ()); |   fhandler_socket *h = get (fd); | ||||||
|   int res = getpeername (h->get_socket (), name, len); |  | ||||||
|   if (res) |   if (!h) | ||||||
|     set_winsock_errno (); |     res = -1; | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       res = getpeername (h->get_socket (), name, len); | ||||||
|  |       if (res) | ||||||
|  | 	set_winsock_errno (); | ||||||
|  |     } | ||||||
|  |  | ||||||
|   debug_printf ("%d = getpeername %d", res, h->get_socket ()); |   debug_printf ("%d = getpeername %d", res, h->get_socket ()); | ||||||
|   return res; |   return res; | ||||||
| @@ -1437,33 +1499,39 @@ cygwin_recv (int fd, void *buf, int len, unsigned int flags) | |||||||
|   int res; |   int res; | ||||||
|   wsock_event wsock_evt; |   wsock_event wsock_evt; | ||||||
|   LPWSAOVERLAPPED ovr; |   LPWSAOVERLAPPED ovr; | ||||||
|   fhandler_socket *h = (fhandler_socket *) cygheap->fdtab[fd]; |   fhandler_socket *h = get (fd); | ||||||
|   sigframe thisframe (mainthread); |  | ||||||
|  |  | ||||||
|   if (h->is_nonblocking () || !(ovr = wsock_evt.prepare ())) |   if (__check_null_invalid_struct_errno (buf, len) || !h) | ||||||
|     { |     res = -1; | ||||||
|       debug_printf ("Fallback to winsock 1 recv call"); |  | ||||||
|       if ((res = recv (h->get_socket (), (char *) buf, len, flags)) |  | ||||||
| 	  == SOCKET_ERROR) |  | ||||||
| 	{ |  | ||||||
| 	  set_winsock_errno (); |  | ||||||
| 	  res = -1; |  | ||||||
| 	} |  | ||||||
|     } |  | ||||||
|   else |   else | ||||||
|     { |     { | ||||||
|       WSABUF wsabuf = { len, (char *) buf }; |       sigframe thisframe (mainthread); | ||||||
|       DWORD ret = 0; |  | ||||||
|       if (WSARecv (h->get_socket (), &wsabuf, 1, &ret, (DWORD *)&flags, |       if (h->is_nonblocking () || !(ovr = wsock_evt.prepare ())) | ||||||
| 		   ovr, NULL) != SOCKET_ERROR) |  | ||||||
| 	res = ret; |  | ||||||
|       else if ((res = WSAGetLastError ()) != WSA_IO_PENDING) |  | ||||||
| 	{ | 	{ | ||||||
| 	  set_winsock_errno (); | 	  debug_printf ("Fallback to winsock 1 recv call"); | ||||||
| 	  res = -1; | 	  if ((res = recv (h->get_socket (), (char *) buf, len, flags)) | ||||||
|  | 	      == SOCKET_ERROR) | ||||||
|  | 	    { | ||||||
|  | 	      set_winsock_errno (); | ||||||
|  | 	      res = -1; | ||||||
|  | 	    } | ||||||
|  | 	} | ||||||
|  |       else | ||||||
|  | 	{ | ||||||
|  | 	  WSABUF wsabuf = { len, (char *) buf }; | ||||||
|  | 	  DWORD ret = 0; | ||||||
|  | 	  if (WSARecv (h->get_socket (), &wsabuf, 1, &ret, (DWORD *)&flags, | ||||||
|  | 		       ovr, NULL) != SOCKET_ERROR) | ||||||
|  | 	    res = ret; | ||||||
|  | 	  else if ((res = WSAGetLastError ()) != WSA_IO_PENDING) | ||||||
|  | 	    { | ||||||
|  | 	      set_winsock_errno (); | ||||||
|  | 	      res = -1; | ||||||
|  | 	    } | ||||||
|  | 	  else if ((res = wsock_evt.wait (h->get_socket (), (DWORD *)&flags)) == -1) | ||||||
|  | 	    set_winsock_errno (); | ||||||
| 	} | 	} | ||||||
|       else if ((res = wsock_evt.wait (h->get_socket (), (DWORD *)&flags)) == -1) |  | ||||||
| 	set_winsock_errno (); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   syscall_printf ("%d = recv (%d, %x, %x, %x)", res, fd, buf, len, flags); |   syscall_printf ("%d = recv (%d, %x, %x, %x)", res, fd, buf, len, flags); | ||||||
| @@ -1478,33 +1546,39 @@ cygwin_send (int fd, const void *buf, int len, unsigned int flags) | |||||||
|   int res; |   int res; | ||||||
|   wsock_event wsock_evt; |   wsock_event wsock_evt; | ||||||
|   LPWSAOVERLAPPED ovr; |   LPWSAOVERLAPPED ovr; | ||||||
|   fhandler_socket *h = (fhandler_socket *) cygheap->fdtab[fd]; |   fhandler_socket *h = get (fd); | ||||||
|   sigframe thisframe (mainthread); |  | ||||||
|  |  | ||||||
|   if (h->is_nonblocking () || !(ovr = wsock_evt.prepare ())) |   if (__check_invalid_read_ptr_errno (buf, len) || !h) | ||||||
|     { |     res = -1; | ||||||
|       debug_printf ("Fallback to winsock 1 send call"); |  | ||||||
|       if ((res = send (h->get_socket (), (const char *) buf, len, flags)) |  | ||||||
| 	  == SOCKET_ERROR) |  | ||||||
| 	{ |  | ||||||
| 	  set_winsock_errno (); |  | ||||||
| 	  res = -1; |  | ||||||
| 	} |  | ||||||
|     } |  | ||||||
|   else |   else | ||||||
|     { |     { | ||||||
|       WSABUF wsabuf = { len, (char *) buf }; |       sigframe thisframe (mainthread); | ||||||
|       DWORD ret = 0; |  | ||||||
|       if (WSASend (h->get_socket (), &wsabuf, 1, &ret, (DWORD)flags, |       if (h->is_nonblocking () || !(ovr = wsock_evt.prepare ())) | ||||||
| 		   ovr, NULL) != SOCKET_ERROR) |  | ||||||
| 	res = ret; |  | ||||||
|       else if ((res = WSAGetLastError ()) != WSA_IO_PENDING) |  | ||||||
| 	{ | 	{ | ||||||
| 	  set_winsock_errno (); | 	  debug_printf ("Fallback to winsock 1 send call"); | ||||||
| 	  res = -1; | 	  if ((res = send (h->get_socket (), (const char *) buf, len, flags)) | ||||||
|  | 	      == SOCKET_ERROR) | ||||||
|  | 	    { | ||||||
|  | 	      set_winsock_errno (); | ||||||
|  | 	      res = -1; | ||||||
|  | 	    } | ||||||
|  | 	} | ||||||
|  |       else | ||||||
|  | 	{ | ||||||
|  | 	  WSABUF wsabuf = { len, (char *) buf }; | ||||||
|  | 	  DWORD ret = 0; | ||||||
|  | 	  if (WSASend (h->get_socket (), &wsabuf, 1, &ret, (DWORD)flags, | ||||||
|  | 		       ovr, NULL) != SOCKET_ERROR) | ||||||
|  | 	    res = ret; | ||||||
|  | 	  else if ((res = WSAGetLastError ()) != WSA_IO_PENDING) | ||||||
|  | 	    { | ||||||
|  | 	      set_winsock_errno (); | ||||||
|  | 	      res = -1; | ||||||
|  | 	    } | ||||||
|  | 	  else if ((res = wsock_evt.wait (h->get_socket (), (DWORD *)&flags)) == -1) | ||||||
|  | 	    set_winsock_errno (); | ||||||
| 	} | 	} | ||||||
|       else if ((res = wsock_evt.wait (h->get_socket (), (DWORD *)&flags)) == -1) |  | ||||||
| 	set_winsock_errno (); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   syscall_printf ("%d = send (%d, %x, %d, %x)", res, fd, buf, len, flags); |   syscall_printf ("%d = send (%d, %x, %d, %x)", res, fd, buf, len, flags); | ||||||
| @@ -1523,6 +1597,9 @@ getdomainname (char *domain, int len) | |||||||
|    * in use and include paths for the Domain name in each ? |    * in use and include paths for the Domain name in each ? | ||||||
|    * Punt for now and assume MS-TCP on Win95. |    * Punt for now and assume MS-TCP on Win95. | ||||||
|    */ |    */ | ||||||
|  |   if (__check_null_invalid_struct_errno (domain, len)) | ||||||
|  |     return -1; | ||||||
|  |  | ||||||
|   reg_key r (HKEY_LOCAL_MACHINE, KEY_READ, |   reg_key r (HKEY_LOCAL_MACHINE, KEY_READ, | ||||||
| 	     (!wincap.is_winnt ()) ? "System" : "SYSTEM", | 	     (!wincap.is_winnt ()) ? "System" : "SYSTEM", | ||||||
| 	     "CurrentControlSet", "Services", | 	     "CurrentControlSet", "Services", | ||||||
| @@ -2039,6 +2116,9 @@ get_ifconf (struct ifconf *ifc, int what) | |||||||
|   unsigned long lip, lnp; |   unsigned long lip, lnp; | ||||||
|   struct sockaddr_in *sa; |   struct sockaddr_in *sa; | ||||||
|  |  | ||||||
|  |   if (check_null_invalid_struct_errno (ifc)) | ||||||
|  |     return -1; | ||||||
|  |  | ||||||
|   /* Union maps buffer to correct struct */ |   /* Union maps buffer to correct struct */ | ||||||
|   struct ifreq *ifr = ifc->ifc_req; |   struct ifreq *ifr = ifc->ifc_req; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -857,8 +857,12 @@ get_devn (const char *name, int &unit) | |||||||
|       devn = FH_SERIAL; |       devn = FH_SERIAL; | ||||||
|       unit++; |       unit++; | ||||||
|     } |     } | ||||||
|   else if (deveq ("pipe") || deveq ("piper") || deveq ("pipew")) |   else if (deveq ("pipe")) | ||||||
|     devn = FH_PIPE; |     devn = FH_PIPE; | ||||||
|  |   else if (deveq ("piper")) | ||||||
|  |     devn = FH_PIPER; | ||||||
|  |   else if (deveq ("pipew")) | ||||||
|  |     devn = FH_PIPEW; | ||||||
|   else if (deveq ("tcp") || deveq ("udp") || deveq ("streamsocket") |   else if (deveq ("tcp") || deveq ("udp") || deveq ("streamsocket") | ||||||
| 	   || deveq ("dgsocket")) | 	   || deveq ("dgsocket")) | ||||||
|     devn = FH_SOCKET; |     devn = FH_SOCKET; | ||||||
|   | |||||||
| @@ -339,7 +339,7 @@ set_bits (select_record *me, fd_set *readfds, fd_set *writefds, | |||||||
|       UNIX_FD_SET (me->fd, writefds); |       UNIX_FD_SET (me->fd, writefds); | ||||||
|       ready++; |       ready++; | ||||||
|     } |     } | ||||||
|   if (me->except_ready && me->except_ready) |   if (me->except_selected && me->except_ready) | ||||||
|     { |     { | ||||||
|       UNIX_FD_SET (me->fd, exceptfds); |       UNIX_FD_SET (me->fd, exceptfds); | ||||||
|       ready++; |       ready++; | ||||||
|   | |||||||
| @@ -190,6 +190,7 @@ void set_console_handler (); | |||||||
|  |  | ||||||
| int __stdcall check_null_empty_str (const char *name) __attribute__ ((regparm(1))); | int __stdcall check_null_empty_str (const char *name) __attribute__ ((regparm(1))); | ||||||
| int __stdcall check_null_empty_str_errno (const char *name) __attribute__ ((regparm(1))); | int __stdcall check_null_empty_str_errno (const char *name) __attribute__ ((regparm(1))); | ||||||
|  | int __stdcall check_null_str_errno (const char *name) __attribute__ ((regparm(1))); | ||||||
| int __stdcall __check_null_invalid_struct (const void *s, unsigned sz) __attribute__ ((regparm(2))); | int __stdcall __check_null_invalid_struct (const void *s, unsigned sz) __attribute__ ((regparm(2))); | ||||||
| int __stdcall __check_null_invalid_struct_errno (const void *s, unsigned sz) __attribute__ ((regparm(2))); | int __stdcall __check_null_invalid_struct_errno (const void *s, unsigned sz) __attribute__ ((regparm(2))); | ||||||
| int __stdcall __check_invalid_read_ptr_errno (const void *s, unsigned sz) __attribute__ ((regparm(2))); | int __stdcall __check_invalid_read_ptr_errno (const void *s, unsigned sz) __attribute__ ((regparm(2))); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user