示例#1
0
int sock_bind(net_sock_t *nsock, char *address, int port)
{
  network_sock_t *sock = (network_sock_t *)nsock;   

  if (sock == NULL) return(1);

  sock->fd = fd_bind(address, port);
  if (sock->fd < 0) return(1);

  return(0);
}
示例#2
0
文件: socket.c 项目: pikelang/Pike
/*! @decl int bind_unix(string path, void|function accept_callback)
 *!
 *! Opens a Unix domain socket at the given path in the file system.
 *! If the second argument is present, the socket is set to
 *! nonblocking and the callback funcition is called whenever
 *! something connects to it. The callback will receive the id for
 *! this port as argument and should typically call @[accept] to
 *! establish a connection.
 *!
 *! @returns
 *!   1 is returned on success, zero on failure. @[errno] provides
 *!   further details about the error in the latter case.
 *!
 *! @note
 *!   This function is only available on systems that support Unix domain
 *!   sockets.
 *!
 *! @note
 *!   @[path] had a quite restrictive length limit (~100 characters)
 *!   prior to Pike 7.8.334.
 *!
 *! @seealso
 *!   @[accept], @[set_id]
 */
static void bind_unix(INT32 args)
{
  struct port *p = THIS;
  struct sockaddr_un *addr;
  struct pike_string *path;
  struct svalue *cb = NULL;
  int addr_len,fd,tmp;

  do_close(p);

  get_all_args(NULL, args, "%n.%*", &path, &cb);

  /* NOTE: Some operating systems (eg Linux 2.6) do not support
   *       paths longer than what fits into a plain struct sockaddr_un.
   */
  addr_len = sizeof(struct sockaddr_un) + path->len + 1 -
    sizeof(addr->sun_path);
  addr = xalloc(addr_len);

  strcpy(addr->sun_path, path->str);
  addr->sun_family = AF_UNIX;
#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
  /* Length including NUL. */
  addr->sun_len = path->len + 1;
#endif

  fd=fd_socket(AF_UNIX, SOCK_STREAM, 0);

  if(fd < 0)
  {
    free(addr);
    p->my_errno=errno;
    pop_n_elems(args);
    push_int(0);
    return;
  }

#ifndef __NT__
  {
    int o=1;
    do {
      tmp = fd_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
			  (char *)&o, sizeof(int));
    } while ((tmp < 0) && (errno == EINTR));
  }
#endif

  my_set_close_on_exec(fd,1);

  THREADS_ALLOW_UID();
  do {
    tmp = fd_bind(fd, (struct sockaddr *)addr, addr_len);
  } while ((tmp < 0) && (errno == EINTR));
  if (tmp >= 0) {
    do {
      tmp = fd_listen(fd, 16384);
    } while ((tmp < 0) && (errno == EINTR));
  }
  THREADS_DISALLOW_UID();

  free(addr);

  if(!Pike_fp->current_object->prog)
  {
    if (fd >= 0)
      while (fd_close(fd) && errno == EINTR) {}
    Pike_error("Object destructed in Stdio.Port->bind_unix()\n");
  }

  if(tmp < 0)
  {
    p->my_errno=errno;
    while (fd_close(fd) && errno == EINTR) {}
    errno = p->my_errno;
    pop_n_elems(args);
    push_int(0);
    return;
  }

  change_fd_for_box (&p->box, fd);
  if (cb) assign_accept_cb (p, cb);
  p->my_errno=0;
  pop_n_elems(args);
  push_int(1);
}
示例#3
0
struct glfs_fd *
glfs_h_opendir (struct glfs *fs, struct glfs_object *object)
{
	int              ret = -1;
	struct glfs_fd  *glfd = NULL;
	xlator_t        *subvol = NULL;
	inode_t         *inode = NULL;
	loc_t            loc = {0, };

	/* validate in args */
	if ((fs == NULL) || (object == NULL)) {
		errno = EINVAL;
		return NULL;
	}

	__glfs_entry_fs (fs);

	/* get the active volume */
	subvol = glfs_active_subvol (fs);
	if (!subvol) {
		ret = -1;
		errno = EIO;
		goto out;
	}

	/* get/refresh the in arg objects inode in correlation to the xlator */
	inode = glfs_resolve_inode (fs, subvol, object);
	if (!inode) {
		errno = ESTALE;
		goto out;
	}

	if (!IA_ISDIR (inode->ia_type)) {
		ret = -1;
		errno = ENOTDIR;
		goto out;
	}

	glfd = glfs_fd_new (fs);
	if (!glfd)
		goto out;

	INIT_LIST_HEAD (&glfd->entries);

	glfd->fd = fd_create (inode, getpid());
	if (!glfd->fd) {
		ret = -1;
		errno = ENOMEM;
		goto out;
	}

	GLFS_LOC_FILL_INODE (inode, loc, out);

	/* fop/op */
	ret = syncop_opendir (subvol, &loc, glfd->fd);
        DECODE_SYNCOP_ERR (ret);

out:
	loc_wipe (&loc);

	if (inode)
		inode_unref (inode);

	if (ret && glfd) {
		glfs_fd_destroy (glfd);
		glfd = NULL;
	} else {
		fd_bind (glfd->fd);
		glfs_fd_bind (glfd);
	}

	glfs_subvol_done (fs, subvol);

	return glfd;
}
示例#4
0
文件: socket.c 项目: pikelang/Pike
/*! @decl int bind(int|string port, void|function accept_callback, @
 *!                void|string ip, void|string reuse_port)
 *!
 *! Opens a socket and binds it to port number on the local machine.
 *! If the second argument is present, the socket is set to
 *! nonblocking and the callback funcition is called whenever
 *! something connects to it. The callback will receive the id for
 *! this port as argument and should typically call @[accept] to
 *! establish a connection.
 *!
 *! If the optional argument @[ip] is given, @[bind] will try to bind
 *! to an interface with that host name or IP number. Omitting this
 *! will bind to all available IPv4 addresses; specifying "::" will
 *! bind to all IPv4 and IPv6 addresses.
 *!
 *! If the OS supports TCP_FASTOPEN it is enabled automatically.
 *!
 *! If the OS supports SO_REUSEPORT it is enabled if the fourth argument is true.
 *!
 *! @returns
 *!   1 is returned on success, zero on failure. @[errno] provides
 *!   further details about the error in the latter case.
 *!
 *! @seealso
 *!   @[accept], @[set_id]
 */
static void port_bind(INT32 args)
{
  struct port *p = THIS;
  PIKE_SOCKADDR addr;
  int addr_len,fd,tmp;

  do_close(p);

  if(args < 1)
    SIMPLE_WRONG_NUM_ARGS_ERROR("bind", 1);

  if(TYPEOF(Pike_sp[-args]) != PIKE_T_INT &&
     (TYPEOF(Pike_sp[-args]) != PIKE_T_STRING ||
      Pike_sp[-args].u.string->size_shift))
    SIMPLE_ARG_TYPE_ERROR("bind", 1, "int|string(8bit)");

  addr_len = get_inet_addr(&addr,
                           (args > 2 && TYPEOF(Pike_sp[2-args])==PIKE_T_STRING?
                            Pike_sp[2-args].u.string->str : NULL),
                           (TYPEOF(Pike_sp[-args]) == PIKE_T_STRING?
                            Pike_sp[-args].u.string->str : NULL),
			   (TYPEOF(Pike_sp[-args]) == PIKE_T_INT?
			    Pike_sp[-args].u.integer : -1), 0);
  INVALIDATE_CURRENT_TIME();

  fd=fd_socket(SOCKADDR_FAMILY(addr), SOCK_STREAM, 0);

  if(fd < 0)
  {
    p->my_errno=errno;
    pop_n_elems(args);
    push_int(0);
    return;
  }
#ifdef SO_REUSEPORT
  if( args > 3 && Pike_sp[3-args].u.integer )
  {
    /* FreeBSD 7.x wants this to reuse portnumbers.
     * Linux 2.6.x seems to have reserved a slot for the option, but not
     * enabled it. Survive libc's with the option on kernels without.
     *
     * The emulated Linux runtime on MS Windows 10 fails this with EINVAL.
     */
    int o=1;
    if((fd_setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (char *)&o, sizeof(int)) < 0)
#ifdef ENOPROTOOPT
       && (errno != ENOPROTOOPT)
#endif
#ifdef EINVAL
       && (errno != EINVAL)
#endif
#ifdef WSAENOPROTOOPT
       && (errno != WSAENOPROTOOPT)
#endif
       ){
      p->my_errno=errno;
      while (fd_close(fd) && errno == EINTR) {}
      errno = p->my_errno;
      pop_n_elems(args);
      push_int(0);
      return;
    }
  }
#endif
#ifndef __NT__
  {
    int o=1;
    if(fd_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&o, sizeof(int)) < 0)
    {
      p->my_errno=errno;
      while (fd_close(fd) && errno == EINTR) {}
      errno = p->my_errno;
      pop_n_elems(args);
      push_int(0);
      return;
    }
  }
#endif

#if defined(IPV6_V6ONLY) && defined(IPPROTO_IPV6)
  if (SOCKADDR_FAMILY(addr) == AF_INET6) {
    /* Attempt to enable dual-stack (ie mapped IPv4 adresses).
     * Needed on WIN32.
     * cf http://msdn.microsoft.com/en-us/library/windows/desktop/bb513665(v=vs.85).aspx
     */
    int o = 0;
    fd_setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&o, sizeof(int));
  }
#endif

  my_set_close_on_exec(fd,1);

  THREADS_ALLOW_UID();
  if( !(tmp=fd_bind(fd, (struct sockaddr *)&addr, addr_len) < 0) )
#ifdef TCP_FASTOPEN
      tmp = 256,
      setsockopt(fd,SOL_TCP, TCP_FASTOPEN, &tmp, sizeof(tmp)),
#endif
      (tmp =  fd_listen(fd, 16384) < 0);
  THREADS_DISALLOW_UID();

  if(!Pike_fp->current_object->prog)
  {
    if (fd >= 0)
      while (fd_close(fd) && errno == EINTR) {}
    Pike_error("Object destructed in Stdio.Port->bind()\n");
  }

  if(tmp)
  {
    p->my_errno=errno;
    while (fd_close(fd) && errno == EINTR) {}
    errno = p->my_errno;
    pop_n_elems(args);
    push_int(0);
    return;
  }

  change_fd_for_box (&p->box, fd);
  if(args > 1) assign_accept_cb (p, Pike_sp+1-args);
  p->my_errno=0;
  pop_n_elems(args);
  push_int(1);
}