diff -up autofs-5.0.1/modules/mount_changer.c.fd-close-on-exec-mutex autofs-5.0.1/modules/mount_changer.c --- autofs-5.0.1/modules/mount_changer.c.fd-close-on-exec-mutex 2007-02-20 13:59:13.000000000 +0900 +++ autofs-5.0.1/modules/mount_changer.c 2007-12-18 11:47:58.000000000 +0900 @@ -34,6 +34,8 @@ #define MODPREFIX "mount(changer): " +extern pthread_mutex_t fd_mutex; + int mount_version = AUTOFS_MOUNT_VERSION; /* Required by protocol */ int swapCD(const char *device, const char *slotName); @@ -158,11 +160,18 @@ int swapCD(const char *device, const cha slot = atoi(slotName) - 1; + status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); + /* open device */ fd = open(device, O_RDONLY | O_NONBLOCK); if (fd < 0) { error(LOGOPT_ANY, MODPREFIX "Opening device %s failed : %s", device, strerror(errno)); + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); return 1; } @@ -171,6 +180,10 @@ int swapCD(const char *device, const cha fcntl(fd, F_SETFD, cl_flags); } + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + /* Check CD player status */ total_slots_available = ioctl(fd, CDROM_CHANGER_NSLOTS); if (total_slots_available <= 1) { diff -up autofs-5.0.1/modules/replicated.c.fd-close-on-exec-mutex autofs-5.0.1/modules/replicated.c --- autofs-5.0.1/modules/replicated.c.fd-close-on-exec-mutex 2007-12-18 11:13:48.000000000 +0900 +++ autofs-5.0.1/modules/replicated.c 2007-12-18 11:49:55.000000000 +0900 @@ -76,6 +76,8 @@ extern unsigned int random_selection; +extern pthread_mutex_t fd_mutex; + void seed_random(void) { int fd; @@ -104,7 +106,7 @@ static unsigned int get_proximity(const char tmp[20], buf[MAX_ERR_BUF], *ptr; struct ifconf ifc; struct ifreq *ifr, nmptr; - int sock, cl_flags, ret, i; + int sock, cl_flags, ret, i, status; uint32_t mask, ha, ia; memcpy(tmp, host_addr, addr_len); @@ -112,10 +114,17 @@ static unsigned int get_proximity(const ha = ntohl((uint32_t) hst_addr->s_addr); + status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); + sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { char *estr = strerror_r(errno, buf, MAX_ERR_BUF); error(LOGOPT_ANY, "socket creation failed: %s", estr); + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); return PROXIMITY_ERROR; } @@ -124,6 +133,10 @@ static unsigned int get_proximity(const fcntl(sock, F_SETFD, cl_flags); } + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + ifc.ifc_len = sizeof(buf); ifc.ifc_req = (struct ifreq *) buf; ret = ioctl(sock, SIOCGIFCONF, &ifc); diff -up autofs-5.0.1/modules/lookup_file.c.fd-close-on-exec-mutex autofs-5.0.1/modules/lookup_file.c --- autofs-5.0.1/modules/lookup_file.c.fd-close-on-exec-mutex 2007-12-18 11:13:48.000000000 +0900 +++ autofs-5.0.1/modules/lookup_file.c 2007-12-18 11:46:30.000000000 +0900 @@ -36,6 +36,8 @@ #define MAX_INCLUDE_DEPTH 16 +extern pthread_mutex_t fd_mutex; + typedef enum { st_begin, st_compare, st_star, st_badent, st_entspc, st_getent } LOOKUP_STATE; @@ -394,7 +396,7 @@ int lookup_read_master(struct master *ma char *ent; struct stat st; FILE *f; - int fd, cl_flags; + int fd, cl_flags, status; unsigned int path_len, ent_len; int entry, cur_state; @@ -422,11 +424,18 @@ int lookup_read_master(struct master *ma return NSS_STATUS_UNAVAIL; } + status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); + f = fopen(ctxt->mapname, "r"); if (!f) { error(LOGOPT_ANY, MODPREFIX "could not open master map file %s", ctxt->mapname); + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); return NSS_STATUS_UNAVAIL; } @@ -437,6 +446,10 @@ int lookup_read_master(struct master *ma fcntl(fd, F_SETFD, cl_flags); } + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + while(1) { entry = read_one(f, path, &path_len, ent, &ent_len); if (!entry) { @@ -631,7 +644,7 @@ int lookup_read_map(struct autofs_point char *mapent; struct stat st; FILE *f; - int fd, cl_flags; + int fd, cl_flags, status; unsigned int k_len, m_len; int entry; @@ -664,10 +677,17 @@ int lookup_read_map(struct autofs_point return NSS_STATUS_UNAVAIL; } + status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); + f = fopen(ctxt->mapname, "r"); if (!f) { error(ap->logopt, MODPREFIX "could not open map file %s", ctxt->mapname); + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); return NSS_STATUS_UNAVAIL; } @@ -678,6 +698,10 @@ int lookup_read_map(struct autofs_point fcntl(fd, F_SETFD, cl_flags); } + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + while(1) { entry = read_one(f, key, &k_len, mapent, &m_len); if (!entry) { @@ -756,7 +780,7 @@ static int lookup_one(struct autofs_poin char mapent[MAPENT_MAX_LEN + 1]; time_t age = time(NULL); FILE *f; - int fd, cl_flags; + int fd, cl_flags, status; unsigned int k_len, m_len; int entry, ret; @@ -766,10 +790,17 @@ static int lookup_one(struct autofs_poin mc = source->mc; + status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); + f = fopen(ctxt->mapname, "r"); if (!f) { error(ap->logopt, MODPREFIX "could not open map file %s", ctxt->mapname); + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); return CHE_FAIL; } @@ -780,6 +811,10 @@ static int lookup_one(struct autofs_poin fcntl(fd, F_SETFD, cl_flags); } + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + while(1) { entry = read_one(f, mkey, &k_len, mapent, &m_len); if (entry) { @@ -863,7 +898,7 @@ static int lookup_wild(struct autofs_poi char mapent[MAPENT_MAX_LEN + 1]; time_t age = time(NULL); FILE *f; - int fd, cl_flags; + int fd, cl_flags, status; unsigned int k_len, m_len; int entry, ret; @@ -873,10 +908,17 @@ static int lookup_wild(struct autofs_poi mc = source->mc; + status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); + f = fopen(ctxt->mapname, "r"); if (!f) { error(ap->logopt, MODPREFIX "could not open map file %s", ctxt->mapname); + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); return CHE_FAIL; } @@ -887,6 +929,10 @@ static int lookup_wild(struct autofs_poi fcntl(fd, F_SETFD, cl_flags); } + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + while(1) { entry = read_one(f, mkey, &k_len, mapent, &m_len); if (entry) { diff -up autofs-5.0.1/daemon/indirect.c.fd-close-on-exec-mutex autofs-5.0.1/daemon/indirect.c --- autofs-5.0.1/daemon/indirect.c.fd-close-on-exec-mutex 2007-12-18 11:13:48.000000000 +0900 +++ autofs-5.0.1/daemon/indirect.c 2007-12-18 11:31:27.000000000 +0900 @@ -43,9 +43,11 @@ extern pthread_attr_t thread_attr; static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER; +extern pthread_mutex_t fd_mutex; + static int autofs_init_indirect(struct autofs_point *ap) { - int pipefd[2], cl_flags; + int pipefd[2], cl_flags, status; if ((ap->state != ST_INIT)) { /* This can happen if an autofs process is already running*/ @@ -55,12 +57,19 @@ static int autofs_init_indirect(struct a ap->pipefd = ap->kpipefd = ap->ioctlfd = -1; + status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); + /* Pipe for kernel communications */ if (pipe(pipefd) < 0) { crit(ap->logopt, "failed to create commumication pipe for autofs path %s", ap->path); free(ap->path); + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); return -1; } @@ -84,6 +93,9 @@ static int autofs_init_indirect(struct a close(ap->pipefd); close(ap->kpipefd); /* Close kernel pipe end */ free(ap->path); + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); return -1; } @@ -97,6 +109,10 @@ static int autofs_init_indirect(struct a fcntl(ap->state_pipe[1], F_SETFD, cl_flags); } + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + return 0; } @@ -150,7 +166,7 @@ static int do_mount_autofs_indirect(stru const char *type, *map_name = NULL; struct stat st; struct mnt_list *mnts; - int cl_flags, ret; + int cl_flags, ret, status; mnts = get_mnt_list(_PROC_MOUNTS, ap->path, 1); if (mnts) { @@ -204,11 +220,18 @@ static int do_mount_autofs_indirect(stru options = NULL; + status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); + /* Root directory for ioctl()'s */ ap->ioctlfd = open(ap->path, O_RDONLY); if (ap->ioctlfd < 0) { crit(ap->logopt, "failed to create ioctl fd for autofs path %s", ap->path); + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); goto out_umount; } @@ -217,6 +240,10 @@ static int do_mount_autofs_indirect(stru fcntl(ap->ioctlfd, F_SETFD, cl_flags); } + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; ioctl(ap->ioctlfd, AUTOFS_IOC_SETTIMEOUT, &timeout); diff -up autofs-5.0.1/daemon/spawn.c.fd-close-on-exec-mutex autofs-5.0.1/daemon/spawn.c --- autofs-5.0.1/daemon/spawn.c.fd-close-on-exec-mutex 2007-12-18 11:13:48.000000000 +0900 +++ autofs-5.0.1/daemon/spawn.c 2007-12-18 11:14:39.000000000 +0900 @@ -28,6 +28,7 @@ #include "automount.h" +pthread_mutex_t fd_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t spawn_mutex = PTHREAD_MUTEX_INITIALIZER; #define SPAWN_OPT_NONE 0x0000 @@ -122,6 +123,10 @@ static int do_spawn(logger *log, unsigne egid = tsv->gid; } + status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); + f = fork(); if (f == 0) { reset_signals(); @@ -130,6 +135,10 @@ static int do_spawn(logger *log, unsigne dup2(pipefd[1], STDERR_FILENO); close(pipefd[1]); + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + /* Bind mount - check target exists */ if (use_access) { char **pargv = (char **) argv; @@ -165,6 +174,10 @@ static int do_spawn(logger *log, unsigne } else { tmpsig = oldsig; + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + sigaddset(&tmpsig, SIGCHLD); pthread_sigmask(SIG_SETMASK, &tmpsig, NULL); diff -up autofs-5.0.1/daemon/automount.c.fd-close-on-exec-mutex autofs-5.0.1/daemon/automount.c --- autofs-5.0.1/daemon/automount.c.fd-close-on-exec-mutex 2007-12-18 11:13:48.000000000 +0900 +++ autofs-5.0.1/daemon/automount.c 2007-12-18 11:14:39.000000000 +0900 @@ -81,6 +81,7 @@ static int umount_all(struct autofs_poin extern pthread_mutex_t master_mutex; extern struct master *master_list; +extern pthread_mutex_t fd_mutex; static int do_mkdir(const char *parent, const char *path, mode_t mode) { @@ -756,6 +757,10 @@ static int mount_autofs(struct autofs_po ap->state = ST_READY; + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + return 0; } diff -up autofs-5.0.1/daemon/direct.c.fd-close-on-exec-mutex autofs-5.0.1/daemon/direct.c --- autofs-5.0.1/daemon/direct.c.fd-close-on-exec-mutex 2007-12-18 11:13:48.000000000 +0900 +++ autofs-5.0.1/daemon/direct.c 2007-12-18 11:26:52.000000000 +0900 @@ -53,6 +53,8 @@ pthread_once_t key_mnt_params_once = PTH static pthread_mutex_t ma_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER; +extern pthread_mutex_t fd_mutex; + static void key_mnt_params_destroy(void *arg) { struct mnt_params *mp; @@ -88,7 +90,7 @@ static void mnts_cleanup(void *arg) static int autofs_init_direct(struct autofs_point *ap) { - int pipefd[2], cl_flags; + int pipefd[2], cl_flags, status; if ((ap->state != ST_INIT)) { /* This can happen if an autofs process is already running*/ @@ -98,11 +100,18 @@ static int autofs_init_direct(struct aut ap->pipefd = ap->kpipefd = ap->ioctlfd = -1; + status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); + /* Pipe for kernel communications */ if (pipe(pipefd) < 0) { crit(ap->logopt, "failed to create commumication pipe for autofs path %s", ap->path); + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); return -1; } @@ -125,6 +134,9 @@ static int autofs_init_direct(struct aut ap->path); close(ap->pipefd); close(ap->kpipefd); + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); return -1; } @@ -138,6 +150,10 @@ static int autofs_init_direct(struct aut fcntl(ap->state_pipe[1], F_SETFD, cl_flags); } + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + return 0; } @@ -162,7 +178,11 @@ int do_umount_autofs_direct(struct autof } ioctlfd = me->ioctlfd; } else { - int cl_flags; + int cl_flags, status; + + status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); ioctlfd = open(me->key, O_RDONLY); if (ioctlfd != -1) { @@ -171,6 +191,10 @@ int do_umount_autofs_direct(struct autof fcntl(ioctlfd, F_SETFD, cl_flags); } } + + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); } @@ -364,11 +388,15 @@ int do_mount_autofs_direct(struct autofs if (tree_get_mnt_list(mnts, &list, me->key, 1)) { if (ap->state == ST_READMAP) { time_t tout = ap->exp_timeout; - int save_ioctlfd, ioctlfd; + int save_ioctlfd, ioctlfd, status; save_ioctlfd = ioctlfd = me->ioctlfd; if (ioctlfd == -1) { + status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); + ioctlfd = open(me->key, O_RDONLY); if (ioctlfd != -1) { cl_flags = fcntl(ioctlfd, F_GETFD, 0); @@ -377,6 +405,11 @@ int do_mount_autofs_direct(struct autofs fcntl(ioctlfd, F_SETFD, cl_flags); } } + + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + } if (ioctlfd < 0) { @@ -457,10 +490,17 @@ int do_mount_autofs_direct(struct autofs goto out_err; } + status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); + /* Root directory for ioctl()'s */ ioctlfd = open(me->key, O_RDONLY); if (ioctlfd < 0) { crit(ap->logopt, "failed to create ioctl fd for %s", me->key); + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); goto out_umount; } @@ -469,6 +509,10 @@ int do_mount_autofs_direct(struct autofs fcntl(ioctlfd, F_SETFD, cl_flags); } + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + /* Calculate the timeouts */ ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; @@ -604,6 +648,8 @@ int umount_autofs_offset(struct autofs_p } ioctlfd = me->ioctlfd; } else { + int status; + /* offset isn't mounted, return success and try to recover */ if (!is_mounted(_PROC_MOUNTS, me->key, MNTS_AUTOFS)) { debug(ap->logopt, @@ -612,6 +658,10 @@ int umount_autofs_offset(struct autofs_p return 0; } + status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); + ioctlfd = open(me->key, O_RDONLY); if (ioctlfd != -1) { if ((cl_flags = fcntl(ioctlfd, F_GETFD, 0)) != -1) { @@ -619,6 +669,10 @@ int umount_autofs_offset(struct autofs_p fcntl(ioctlfd, F_SETFD, cl_flags); } } + + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); } if (ioctlfd >= 0) { @@ -816,10 +870,17 @@ int mount_autofs_offset(struct autofs_po goto out_err; } + status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); + /* Root directory for ioctl()'s */ ioctlfd = open(me->key, O_RDONLY); if (ioctlfd < 0) { crit(ap->logopt, "failed to create ioctl fd for %s", me->key); + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); goto out_umount; } @@ -828,6 +889,10 @@ int mount_autofs_offset(struct autofs_po fcntl(ioctlfd, F_SETFD, cl_flags); } + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + ioctl(ioctlfd, AUTOFS_IOC_SETTIMEOUT, &timeout); ret = fstat(ioctlfd, &st); @@ -1511,6 +1576,10 @@ int handle_packet_missing_direct(struct return 1; } + status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); + if (me->ioctlfd != -1) { /* Maybe someone did a manual umount, clean up ! */ ioctlfd = me->ioctlfd; @@ -1520,6 +1589,9 @@ int handle_packet_missing_direct(struct if (ioctlfd == -1) { cache_unlock(mc); + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); pthread_setcancelstate(state, NULL); crit(ap->logopt, "failed to create ioctl fd for %s", me->key); /* TODO: how do we clear wait q in kernel ?? */ @@ -1531,6 +1603,10 @@ int handle_packet_missing_direct(struct fcntl(ioctlfd, F_SETFD, cl_flags); } + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + debug(ap->logopt, "token %ld, name %s, request pid %u", (unsigned long) pkt->wait_queue_token, me->key, pkt->pid); diff -up autofs-5.0.1/lib/nss_parse.y.fd-close-on-exec-mutex autofs-5.0.1/lib/nss_parse.y --- autofs-5.0.1/lib/nss_parse.y.fd-close-on-exec-mutex 2007-12-18 11:13:48.000000000 +0900 +++ autofs-5.0.1/lib/nss_parse.y 2007-12-18 11:38:47.000000000 +0900 @@ -33,6 +33,7 @@ #include "nss_parse.tab.h" static pthread_mutex_t parse_mutex = PTHREAD_MUTEX_INITIALIZER; +extern pthread_mutex_t fd_mutex; static struct list_head *nss_list; static struct nss_source *src; @@ -165,16 +166,24 @@ static void parse_close_nsswitch(void *a int nsswitch_parse(struct list_head *list) { FILE *nsswitch; - int fd, cl_flags, status; + int fd, cl_flags, status, cur_state; + + status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); nsswitch = fopen(NSSWITCH_FILE, "r"); if (!nsswitch) { error(LOGOPT_ANY, "couldn't open %s\n", NSSWITCH_FILE); + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + pthread_setcancelstate(cur_state, NULL); return 1; } - pthread_cleanup_push(parse_close_nsswitch, nsswitch); - fd = fileno(nsswitch); if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { @@ -182,9 +191,16 @@ int nsswitch_parse(struct list_head *lis fcntl(fd, F_SETFD, cl_flags); } + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + parse_mutex_lock(); + pthread_cleanup_push(parse_close_nsswitch, nsswitch); pthread_cleanup_push(parse_mutex_unlock, NULL); + pthread_setcancelstate(cur_state, NULL); + nss_in = nsswitch; nss_automount_found = 0; diff -up autofs-5.0.1/lib/rpc_subs.c.fd-close-on-exec-mutex autofs-5.0.1/lib/rpc_subs.c --- autofs-5.0.1/lib/rpc_subs.c.fd-close-on-exec-mutex 2007-12-18 11:13:48.000000000 +0900 +++ autofs-5.0.1/lib/rpc_subs.c 2007-12-18 11:14:39.000000000 +0900 @@ -57,6 +57,8 @@ static char *domain = NULL; inline void dump_core(void); static pthread_mutex_t networks_mutex = PTHREAD_MUTEX_INITIALIZER; +extern pthread_mutex_t fd_mutex; + /* * Create a UDP RPC client */ @@ -108,20 +110,31 @@ got_addr: raddr.sin_port = htons(info->port); if (!info->client) { + int status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); /* * bind to any unused port. If we left this up to the rpc * layer, it would bind to a reserved port, which has been shown * to exhaust the reserved port range in some situations. */ fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (fd < 0) + if (fd < 0) { + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); return NULL; + } if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { cl_flags |= FD_CLOEXEC; fcntl(fd, F_SETFD, cl_flags); } + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + laddr.sin_family = AF_INET; laddr.sin_port = 0; laddr.sin_addr.s_addr = htonl(INADDR_ANY); @@ -317,15 +330,27 @@ got_addr: addr.sin_port = htons(info->port); if (!info->client) { + int status = pthread_mutex_lock(&fd_mutex); + if (status) + fatal(status); + fd = socket(PF_INET, SOCK_STREAM, info->proto->p_proto); - if (fd < 0) + if (fd < 0) { + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); return NULL; + } if ((cl_flags = fcntl(fd, F_GETFD, 0)) != -1) { cl_flags |= FD_CLOEXEC; fcntl(fd, F_SETFD, cl_flags); } + status = pthread_mutex_unlock(&fd_mutex); + if (status) + fatal(status); + ret = connect_nb(fd, &addr, &info->timeout); if (ret < 0) goto out_close;