diff --git a/src/fdlib.c b/src/fdlib.c index 9a1c57256aa9cf5c224a6de53c21afbf10f202d6..10c3af68caab7d9f9cc291f74a1c53a1ad2b8486 100644 --- a/src/fdlib.c +++ b/src/fdlib.c @@ -306,7 +306,7 @@ PMOD_EXPORT HANDLE CheckValidHandle(HANDLE h) #endif /* Used by signal_handler.c:get_inheritable_handle(). */ -int fd_to_handle(int fd, int *type, HANDLE *handle) +int fd_to_handle(int fd, int *type, HANDLE *handle, int exclusive) { int ret = -1; @@ -314,7 +314,7 @@ int fd_to_handle(int fd, int *type, HANDLE *handle) if (fd >= FD_NO_MORE_FREE) { mt_lock(&fd_mutex); - while (fd_busy[fd]) { + while ((fd_busy[fd] < 0) || (exclusive && fd_busy[fd])) { FDDEBUG(fprintf(stderr, "fd %d is busy; waiting...\n", fd)); co_wait(&fd_cond, &fd_mutex); } @@ -322,7 +322,11 @@ int fd_to_handle(int fd, int *type, HANDLE *handle) FDDEBUG(fprintf(stderr, "fd %d is valid.\n", fd)); if (type) *type = fd_type[fd]; if (handle) *handle = da_handle[fd]; - fd_busy[fd] = 1; + if (exclusive) { + fd_busy[fd] = -1; + } else { + fd_busy[fd]++; + } ret = 0; FDDEBUG(fprintf(stderr, "fd %d ==> handle: %ld (%d)\n", fd, (long)da_handle[fd], fd_type[fd])); @@ -339,7 +343,7 @@ int fd_to_handle(int fd, int *type, HANDLE *handle) return ret; } -static int fd_to_socket(int fd, SOCKET *socket) +static int fd_to_socket(int fd, SOCKET *socket, int exclusive) { int ret = -1; @@ -347,14 +351,18 @@ static int fd_to_socket(int fd, SOCKET *socket) if (fd >= FD_NO_MORE_FREE) { mt_lock(&fd_mutex); - while (fd_busy[fd]) { + while ((fd_busy[fd] < 0) || (exclusive && fd_busy[fd])) { FDDEBUG(fprintf(stderr, "fd %d is busy; waiting...\n", fd)); co_wait(&fd_cond, &fd_mutex); } if (fd_type[fd] == FD_SOCKET) { FDDEBUG(fprintf(stderr, "fd %d is a valid socket.\n", fd)); if (socket) *socket = (SOCKET)da_handle[fd]; - fd_busy[fd] = 1; + if (exclusive) { + fd_busy[fd] = -1; + } else { + fd_busy[fd]++; + } ret = 0; } else if (fd_type[fd] < 0) { FDDEBUG(fprintf(stderr, "fd %d is not a socket.\n", fd)); @@ -394,7 +402,7 @@ static int allocate_fd(int type, HANDLE handle) first_free_handle = fd_type[fd]; fd_type[fd] = type; da_handle[fd] = handle; - fd_busy[fd] = 1; + fd_busy[fd] = -1; } else { FDDEBUG(fprintf(stderr, "All fds are allocated.\n")); errno = EMFILE; @@ -470,7 +478,7 @@ static int reallocate_fd(int fd, int type, HANDLE handle) FDDEBUG(fprintf(stderr, "Allocating fd %d.\n", fd)); fd_type[fd] = type; da_handle[fd] = handle; - fd_busy[fd] = 1; + fd_busy[fd] = -1; mt_unlock(&fd_mutex); return fd; } @@ -488,7 +496,11 @@ void release_fd(int fd) assert(fd_busy[fd]); - fd_busy[fd] = 0; + if (fd_busy[fd] < 0) { + fd_busy[fd] = 0; + } else { + fd_busy[fd]--; + } FDDEBUG(fprintf(stderr, "Broadcasting now that fd %d is no longer busy.\n", fd)); @@ -507,7 +519,7 @@ static void free_fd(int fd) FDDEBUG(fprintf(stderr, "Freeing fd %d. Busy: %d\n", fd, fd_busy[fd])); if (fd_type[fd] < FD_NO_MORE_FREE) { - assert(fd_busy[fd]); + assert(fd_busy[fd] < 0); fd_type[fd] = first_free_handle; first_free_handle = fd; @@ -530,7 +542,7 @@ static void set_fd_handle(int fd, HANDLE handle) } mt_lock(&fd_mutex); - assert(fd_busy[fd]); + assert(fd_busy[fd] < 0); da_handle[fd] = handle; mt_unlock(&fd_mutex); @@ -560,7 +572,7 @@ PMOD_EXPORT int debug_fd_query_properties(int fd, int guess) FDDEBUG(fprintf(stderr, "fd_query_properties(%d, %d)...\n", fd, guess)); - if (fd_to_handle(fd, &type, NULL) < 0) return 0; + if (fd_to_handle(fd, &type, NULL, 0) < 0) return 0; release_fd(fd); switch(type) @@ -1850,7 +1862,7 @@ PMOD_EXPORT FD debug_fd_accept(FD fd, struct sockaddr *addr, FDDEBUG(fprintf(stderr, "fd_accept(%d, %p, %p)...\n", fd, addr, addrlen)); - if (fd_to_socket(fd, &s) < 0) return -1; + if (fd_to_socket(fd, &s, 0) < 0) return -1; FDDEBUG(fprintf(stderr,"Accept on %d (%ld)..\n", fd, PTRDIFF_T_TO_LONG((ptrdiff_t)s))); @@ -1889,7 +1901,7 @@ PMOD_EXPORT int PIKE_CONCAT(debug_fd_,NAME) X1 { \ SOCKET s; \ int ret; \ FDDEBUG(fprintf(stderr, "fd_" #NAME "(%d, ...)...\n", fd)); \ - if (fd_to_socket(fd, &s) < 0) return -1; \ + if (fd_to_socket(fd, &s, 0) < 0) return -1; \ FDDEBUG(fprintf(stderr, #NAME " on %d (%ld)\n", \ fd, (long)(ptrdiff_t)s)); \ ret = NAME X2; \ @@ -1936,7 +1948,7 @@ PMOD_EXPORT int debug_fd_connect (FD fd, struct sockaddr *a, int len) FDDEBUG(fprintf(stderr, "fd_connect(%d, %p, %d)...\n", fd, a, len)); - if (fd_to_socket(fd, &ret) < 0) return -1; + if (fd_to_socket(fd, &ret, 0) < 0) return -1; FDDEBUG(fprintf(stderr, "connect on %d (%ld)\n", fd, PTRDIFF_T_TO_LONG((ptrdiff_t)ret)); @@ -1964,7 +1976,7 @@ PMOD_EXPORT int debug_fd_close(FD fd) FDDEBUG(fprintf(stderr, "fd_close(%d)...\n", fd)); - if (fd_to_handle(fd, &type, &h) < 0) return -1; + if (fd_to_handle(fd, &type, &h, 1) < 0) return -1; FDDEBUG(fprintf(stderr, "Closing %d (%ld)\n", fd, PTRDIFF_T_TO_LONG(h))); @@ -2004,7 +2016,7 @@ PMOD_EXPORT ptrdiff_t debug_fd_write(FD fd, void *buf, ptrdiff_t len) FDDEBUG(fprintf(stderr, "fd_write(%d, %p, %ld)...\n", fd, buf, (long)len)); - if (fd_to_handle(fd, &kind, &handle) < 0) return -1; + if (fd_to_handle(fd, &kind, &handle, 0) < 0) return -1; FDDEBUG(fprintf(stderr, "Writing %d bytes to %d (%d)\n", len, fd, (long)(ptrdiff_t)handle)); @@ -2066,7 +2078,7 @@ PMOD_EXPORT ptrdiff_t debug_fd_read(FD fd, void *to, ptrdiff_t len) FDDEBUG(fprintf("fd_read(%d, %p, %ld)...\n", fd, to, (long)len)); - if (fd_to_handle(fd, &type, &handle) < 0) return -1; + if (fd_to_handle(fd, &type, &handle, 0) < 0) return -1; FDDEBUG(fprintf(stderr,"Reading %d bytes from %d (%d) to %lx\n", len, fd, (long)(ptrdiff_t)h, @@ -2144,7 +2156,7 @@ PMOD_EXPORT PIKE_OFF_T debug_fd_lseek(FD fd, PIKE_OFF_T pos, int where) FDDEBUG(fprintf(stderr, "fd_lseek(%d)...\n", fd)); - if (fd_to_handle(fd, &type, &h) < 0) return -1; + if (fd_to_handle(fd, &type, &h, 0) < 0) return -1; if(type != FD_FILE) { release_fd(fd); @@ -2214,7 +2226,7 @@ PMOD_EXPORT int debug_fd_ftruncate(FD fd, PIKE_OFF_T len) FDDEBUG(fprintf(stderr, "fd_ftruncate(%d)...\n", fd)); - if (fd_to_handle(fd, &type, &h) < 0) return -1; + if (fd_to_handle(fd, &type, &h, 0) < 0) return -1; if(type != FD_FILE) { release_fd(fd); @@ -2278,7 +2290,7 @@ PMOD_EXPORT int debug_fd_flock(FD fd, int oper) FDDEBUG(fprintf(stderr, "fd_flock(%d)...\n", fd)); - if (fd_to_handle(fd, &type, &h) < 0) return -1; + if (fd_to_handle(fd, &type, &h, 0) < 0) return -1; if(type != FD_FILE) { release_fd(fd); @@ -2337,7 +2349,7 @@ PMOD_EXPORT int debug_fd_fstat(FD fd, PIKE_STAT_T *s) FDDEBUG(fprintf(stderr, "fd_fstat(%d, %p)\n", fd, s)); - if (fd_to_handle(fd, &type, &h) < 0) return -1; + if (fd_to_handle(fd, &type, &h, 0) < 0) return -1; if (type != FD_FILE) { release_fd(fd); @@ -2472,7 +2484,7 @@ PMOD_EXPORT int debug_fd_ioctl(FD fd, int cmd, void *data) FDDEBUG(fprintf(stderr, "fd_ioctl(%d, %d, %p)...\n", fd, cmd, data)); - if (fd_to_socket(fd, &s) < 0) return -1; + if (fd_to_socket(fd, &s, 0) < 0) return -1; FDDEBUG(fprintf(stderr,"ioctl(%d (%ld,%d,%p)\n", fd, (long)(ptrdiff_t)s, cmd, data)); @@ -2501,7 +2513,7 @@ PMOD_EXPORT FD debug_fd_dup(FD from) FDDEBUG(fprintf(stderr, "fd_dup(%d)...\n", from)); - if (fd_to_handle(from, &type, &h) < 0) return -1; + if (fd_to_handle(from, &type, &h, 0) < 0) return -1; fd = allocate_fd(type, (type == FD_SOCKET)? @@ -2539,7 +2551,7 @@ PMOD_EXPORT FD debug_fd_dup2(FD from, FD to) FDDEBUG(fprintf(stderr, "fd_dup2(%d, %d)...\n", from, to)); - if (fd_to_handle(from, &type, &h) < 0) return -1; + if (fd_to_handle(from, &type, &h, 0) < 0) return -1; if(!DuplicateHandle(p, h, p, &x, 0, 0, DUPLICATE_SAME_ACCESS)) { diff --git a/src/fdlib.h b/src/fdlib.h index 076de7d8e4ea3ae826847f40bb73113f88b439db..1e1bd98333dd45fce1a1cd5f3d74968b8848ec4d 100644 --- a/src/fdlib.h +++ b/src/fdlib.h @@ -124,7 +124,7 @@ typedef off_t PIKE_OFF_T; /* Prototypes begin here */ PMOD_EXPORT void set_errno_from_win32_error (unsigned long err); -int fd_to_handle(int fd, int *type, HANDLE *handle); +int fd_to_handle(int fd, int *type, HANDLE *handle, int exclusive); void release_fd(int fd); PMOD_EXPORT char *debug_fd_info(int fd); PMOD_EXPORT int debug_fd_query_properties(int fd, int guess); diff --git a/src/signal_handler.c b/src/signal_handler.c index be4afeba58e458d5038bd29a2b2aaedbaffc56b9..7997a35f5ff6bcd8de83a7f1114c1f8c2aa0ae40 100644 --- a/src/signal_handler.c +++ b/src/signal_handler.c @@ -2155,7 +2155,7 @@ static HANDLE get_inheritable_handle(struct mapping *optional, fd=fd_from_object(Pike_sp[-1].u.object); } - if(fd_to_handle(fd, NULL, &h) < 0) + if(fd_to_handle(fd, NULL, &h, 0) < 0) Pike_error("File for %s is not open.\n",name); if(!DuplicateHandle(GetCurrentProcess(), /* Source process */