示例#1
0
/* Set the state of FD to *TERMIOS_P.  */
int
tcsetattr (int fd, int optional_actions, const struct termios *termios_p)
{
  struct termios myt;

  if (optional_actions & TCSASOFT)
    {
      myt = *termios_p;
      myt.c_cflag |= CIGNORE;
      termios_p = &myt;
      optional_actions &= ~TCSASOFT;
    }

  switch (optional_actions)
    {
    case TCSANOW:
      return __ioctl (fd, TIOCSETA, termios_p);

    case TCSADRAIN:
      return __ioctl (fd, TIOCSETAW, termios_p);

    default:
      return __ioctl (fd, TIOCSETAF, termios_p);
    }
}
示例#2
0
/* Send zero bits on FD.  */
int
tcsendbreak (int fd, int duration)
{
  struct timeval delay;

  /* The break lasts 0.25 to 0.5 seconds if DURATION is zero,
     and an implementation-defined period if DURATION is nonzero.
     We define a positive DURATION to be number of microseconds to break.  */
  if (duration <= 0)
    duration = 400000;

  delay.tv_sec = 0;
  delay.tv_usec = duration;

  /* Starting sending break.  */
  if (__ioctl (fd, TIOCSBRK, (void *) NULL) < 0)
    return -1;

  /* Wait DURATION microseconds.  */
  (void) __select (0, (fd_set *) NULL, (fd_set *) NULL, (fd_set *) NULL,
		   &delay);

  /* Turn off the break.  */
  return __ioctl (fd, TIOCCBRK, (void *) NULL);
}
/* Wait for pending output to be written on FD.  */
int
__libc_tcdrain (int fd)
{
  /* The TIOCSETP control waits for pending output to be written before
     affecting its changes, so we use that without changing anything.  */
  struct sgttyb b;
  if (__ioctl (fd, TIOCGETP, (void *) &b) < 0 ||
      __ioctl (fd, TIOCSETP, (void *) &b) < 0)
    return -1;
  return 0;
}
示例#4
0
void
__ifreq (struct ifreq **ifreqs, int *num_ifs, int sockfd)
{
  int fd = sockfd;
  struct ifconf ifc;
  int rq_len;
  int nifs;
# define RQ_IFS	4

  if (fd < 0)
    fd = __opensock ();
  if (fd < 0)
    {
      *num_ifs = 0;
      *ifreqs = NULL;
      return;
    }

  ifc.ifc_buf = NULL;

  /* We may be able to get the needed buffer size directly, rather than
     guessing.  */
  ifc.ifc_buf = NULL;
  ifc.ifc_len = 0;
  if (__ioctl (fd, SIOCGIFCONF, &ifc) < 0 || ifc.ifc_len == 0)
    rq_len = RQ_IFS * sizeof (struct ifreq);
  else
    rq_len = ifc.ifc_len;

  /* Read all the interfaces out of the kernel.  */
  ifc.ifc_len = rq_len;
  void *newp = realloc (ifc.ifc_buf, ifc.ifc_len);
  if (newp == NULL
      || (ifc.ifc_buf = newp, __ioctl (fd, SIOCGIFCONF, &ifc)) < 0)
    {
      free (ifc.ifc_buf);

      if (fd != sockfd)
	__close (fd);

      *num_ifs = 0;
      *ifreqs = NULL;
      return;
    }

  nifs = ifc.ifc_len / sizeof (struct ifreq);

  if (fd != sockfd)
    __close (fd);

  *num_ifs = nifs;
  *ifreqs = realloc (ifc.ifc_buf, nifs * sizeof (struct ifreq));
}
示例#5
0
/*
 * don't use gethostbyname, which would invoke yellow pages
 *
 * Avoid loopback interfaces.  We return information from a loopback
 * interface only if there are no other possible interfaces.
 */
void
get_myaddress (struct sockaddr_in *addr)
{
  int s;
  char buf[BUFSIZ];
  struct ifconf ifc;
  struct ifreq ifreq, *ifr;
  int len, loopback = 0;

  if ((s = __socket (AF_INET, SOCK_DGRAM, 0)) < 0)
    {
      perror ("get_myaddress: socket");
      exit (1);
    }
  ifc.ifc_len = sizeof (buf);
  ifc.ifc_buf = buf;
  if (__ioctl (s, SIOCGIFCONF, (char *) &ifc) < 0)
    {
      perror (_("get_myaddress: ioctl (get interface configuration)"));
      exit (1);
    }

 again:
  ifr = ifc.ifc_req;
  for (len = ifc.ifc_len; len; len -= sizeof ifreq)
    {
      ifreq = *ifr;
      if (__ioctl (s, SIOCGIFFLAGS, (char *) &ifreq) < 0)
	{
          perror ("get_myaddress: ioctl");
          exit (1);
	}
      if ((ifreq.ifr_flags & IFF_UP) && (ifr->ifr_addr.sa_family == AF_INET)
	  && (!(ifreq.ifr_flags & IFF_LOOPBACK) ||
	      (loopback == 1 && (ifreq.ifr_flags & IFF_LOOPBACK))))
	{
	  *addr = *((struct sockaddr_in *) &ifr->ifr_addr);
	  addr->sin_port = htons (PMAPPORT);
	  __close (s);
	  return;
	}
      ifr++;
    }
  if (loopback == 0)
    {
      loopback = 1;
      goto again;
    }
  __close (s);
}
示例#6
0
static hp_timing_t
__get_clockfreq_via_dev_openprom (void)
{
  hp_timing_t result;
  int obp_dev_fd;

  result = 0;

  obp_dev_fd = __open ("/dev/openprom", O_RDONLY);
  if (obp_dev_fd != -1)
    {
      char obp_buf[8192];
      struct openpromio *obp_cmd = (struct openpromio *)obp_buf;
      int ret;

      obp_cmd->oprom_size =
	sizeof (obp_buf) - sizeof (unsigned int);
      set_obp_int (obp_cmd, 0);
      ret = __ioctl (obp_dev_fd, OPROMCHILD, (char *) obp_cmd);
      if (ret == 0)
	{
	  int cur_node = get_obp_int (obp_cmd);

	  while (cur_node != 0 && cur_node != -1)
	    {
	      obp_cmd->oprom_size = sizeof (obp_buf) - sizeof (unsigned int);
	      strcpy (obp_cmd->oprom_array, "device_type");
	      ret = __ioctl (obp_dev_fd, OPROMGETPROP, (char *) obp_cmd);
	      if (ret == 0
		  && strncmp (obp_cmd->oprom_array, "cpu", 3) == 0)
		{
		  obp_cmd->oprom_size = (sizeof (obp_buf)
					 - sizeof (unsigned int));
		  strcpy (obp_cmd->oprom_array, "clock-frequency");
		  ret = __ioctl (obp_dev_fd, OPROMGETPROP, (char *) obp_cmd);
		  if (ret == 0)
		    result = (hp_timing_t) get_obp_int (obp_cmd);
		}
	      obp_cmd->oprom_size = sizeof (obp_buf) - sizeof (unsigned int);
	      set_obp_int (obp_cmd, cur_node);
	      ret = __ioctl (obp_dev_fd, OPROMNEXT, (char *) obp_cmd);
	      if (ret < 0)
		break;
	      cur_node = get_obp_int (obp_cmd);
	    }
	}
    }

  return result;
}
示例#7
0
/* Wait for pending output to be written on FD.  */
int
__libc_tcdrain (int fd)
{
  if (SINGLE_THREAD_P)
    return __ioctl (fd, TIOCDRAIN);

  int oldtype = LIBC_CANCEL_ASYNC ();

  int result = __ioctl (fd, TIOCDRAIN);

  LIBC_CANCEL_RESET (oldtype);

  return result;
}
示例#8
0
文件: if_index.c 项目: AubrCool/glibc
char *
__if_indextoname (unsigned int ifindex, char *ifname)
{
  /* We may be able to do the conversion directly, rather than searching a
     list.  This ioctl is not present in kernels before version 2.1.50.  */
  struct ifreq ifr;
  int fd;
  int status;

  fd = __opensock ();

  if (fd < 0)
    return NULL;

  ifr.ifr_ifindex = ifindex;
  status = __ioctl (fd, SIOCGIFNAME, &ifr);

  close_not_cancel_no_status (fd);

  if (status  < 0)
    {
      if (errno == ENODEV)
	/* POSIX requires ENXIO.  */
	__set_errno (ENXIO);

      return NULL;
    }
  else
    return strncpy (ifname, ifr.ifr_name, IFNAMSIZ);
}
unsigned int
if_nametoindex (const char *ifname)
{
#ifndef SIOCGIFINDEX
  __set_errno (ENOSYS);
  return 0;
#else
  struct ifreq ifr;
  int fd = __opensock ();

  if (fd < 0)
    return 0;

  strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
  if (__ioctl (fd, SIOCGIFINDEX, &ifr) < 0)
    {
      int saved_errno = errno;
      close_not_cancel_no_status (fd);
      if (saved_errno == EINVAL)
	__set_errno (ENOSYS);
      return 0;
    }
  close_not_cancel_no_status (fd);
  return ifr.ifr_ifindex;
#endif
}
示例#10
0
void
__ifreq (struct ifreq **ifreqs, int *num_ifs, int sockfd)
{
  int fd = sockfd;
  struct ifconf ifc;
  int rq_len;
  int nifs;
# define RQ_IFS	4

  if (fd < 0)
    fd = __opensock ();
  if (fd < 0)
    {
      *num_ifs = 0;
      *ifreqs = NULL;
      return;
    }

  ifc.ifc_buf = NULL;
  rq_len = RQ_IFS * sizeof (struct ifreq) / 2; /* Doubled in the loop.  */
  do
    {
      ifc.ifc_len = rq_len *= 2;
      void *newp = realloc (ifc.ifc_buf, ifc.ifc_len);
      if (newp == NULL || __ioctl (fd, SIOCGIFCONF, &ifc) < 0)
	{
	  free (ifc.ifc_buf);

	  if (fd != sockfd)
	    __close (fd);
	  *num_ifs = 0;
	  *ifreqs = NULL;
	  return;
	}
      ifc.ifc_buf = newp;
    }
  while (rq_len < sizeof (struct ifreq) + ifc.ifc_len);

  if (fd != sockfd)
    __close (fd);

#ifdef _HAVE_SA_LEN
  struct ifreq *ifr = *ifreqs;
  nifs = 0;
  while ((char *) ifr < ifc.ifc_buf + ifc.ifc_len)
    {
      ++nifs;
      ifr = __if_nextreq (ifr);
      if (ifr == NULL)
	break;
    }
#else
  nifs = ifc.ifc_len / sizeof (struct ifreq);
#endif

  *num_ifs = nifs;
  *ifreqs = realloc (ifc.ifc_buf, nifs * sizeof (struct ifreq));
}
示例#11
0
TPCANStatus CAN_FilterMessages(TPCANHandle Channel, DWORD FromID, DWORD ToID,
		TPCANMode Mode) {

	PCAN_DESCRIPTOR *desc;
	TPCANStatus Result = PCAN_ERROR_OK;

	try {

		// logging
		char szLog[MAX_LOG];
		LOG_EnteringTo("CAN_FilterMessages");
		sprintf(szLog,
				"Channel: 0x%02X, FromID: 0x%08X, ToID: 0x%08X, Mode: 0x%08X",
				Channel, FromID, ToID, Mode);
		LOG_Parameters("CAN_FilterMessages", szLog);

		// descriptor
		if (ppDescriptors == NULL) {
			Result = PCAN_ERROR_INITIALIZE;
			goto leave;
		}
		if (ppDescriptors[Channel] == NULL) {
			Result = PCAN_ERROR_INITIALIZE;
			goto leave;
		}
		desc = ppDescriptors[Channel];

		// convert parameters
		TPMSGFILTER Filter;
		Filter.FromID = FromID;
		Filter.ToID = ToID;
		switch (Mode) {
		case PCAN_MESSAGE_STANDARD:
			Filter.MSGTYPE = MSGTYPE_STANDARD;
			break;
		case PCAN_MESSAGE_EXTENDED:
			Filter.MSGTYPE = MSGTYPE_EXTENDED;
			break;
		default:
			Filter.MSGTYPE = MSGTYPE_EXTENDED;
		}

		// set filter
		if (__ioctl(desc->nFileNo, PCAN_MSG_FILTER, &Filter) < 0) {
			Result = PCAN_ERROR_UNKNOWN;
			goto leave;
		}
		desc->nFilter = PCAN_FILTER_CUSTOM;

		leave: LOG_LeavingFrom("CAN_FilterMessages", Result);
		return Result;
	} catch (...) {
		Result = PCAN_ERROR_UNKNOWN;
		LOG_Exception("CAN_FilterMessages");
	}
	return Result;
}
示例#12
0
文件: fstat.c 项目: asb/frankenlibc
int
fstat(int fd, struct stat *st)
{
	int ret;
	struct freebsd_stat fst;

	ret = __fstat(fd, &fst);
	if (ret == -1) {
		errno = EBADF;
		return -1;
	}

	st->st_size = fst.st_size;

	switch (fst.st_mode & FREEBSD_S_IFMT) {
	case FREEBSD_S_IFBLK:
		__ioctl(fd, DIOCGMEDIASIZE, &fst.st_size);
		break;
	case FREEBSD_S_IFCHR:
		/* XXX only for tap device */
		ret = __ioctl(fd, SIOCGIFADDR, st->st_hwaddr);
		if (ret == 0) {
			/* say we are a "socket" ie network device */
			fst.st_mode = FREEBSD_S_IFSOCK;
			/* add to poll */
			__platform_pollfd[__platform_npoll].fd = fd;
			__platform_pollfd[__platform_npoll].events = POLLIN | POLLPRI;
			__platform_npoll++;
		}
		break;
	}

	st->st_mode = (FREEBSD_S_ISDIR (fst.st_mode) ? S_IFDIR  : 0) |
		      (FREEBSD_S_ISCHR (fst.st_mode) ? S_IFCHR  : 0) |
		      (FREEBSD_S_ISBLK (fst.st_mode) ? S_IFBLK  : 0) |
		      (FREEBSD_S_ISREG (fst.st_mode) ? S_IFREG  : 0) |
		      (FREEBSD_S_ISFIFO(fst.st_mode) ? S_IFIFO  : 0) |
		      (FREEBSD_S_ISLNK (fst.st_mode) ? S_IFLNK  : 0) |
		      (FREEBSD_S_ISSOCK(fst.st_mode) ? S_IFSOCK : 0);

	return 0;
}
示例#13
0
int WRAP(ioctl)(int fd, int request, ...)
{
    va_list ap;
    void * arg;

    va_start(ap, request);
    arg = va_arg(ap, void *);
    va_end(ap);

    return __ioctl(fd, mips_change_request(request), arg);
}
示例#14
0
int
__posix_openpt (int oflag)
{
  int fd = INLINE_SYSCALL (posix_openpt, 1, oflag);
  if (fd >= 0)
  {
      if (!(oflag & O_NOCTTY))
        __ioctl (fd, TIOCSCTTY, NULL);
  }
  return fd;
}
/* Send zero bits on FD.  */
int
tcsendbreak (int fd, int duration)
{
  /* The break lasts 0.25 to 0.5 seconds if DURATION is zero,
     and an implementation-defined period if DURATION is nonzero.
     We define a positive DURATION to be number of milliseconds to break.  */
  if (duration <= 0)
    return __ioctl (fd, TCSBRK, 0);

#ifdef TCSBRKP
  /* Probably Linux-specific: a positive third TCSBRKP ioctl argument is
     defined to be the number of 100ms units to break.  */
  return __ioctl (fd, TCSBRKP, (duration + 99) / 100);
#else
  /* ioctl can't send a break of any other duration for us.
     This could be changed to use trickery (e.g. lower speed and
     send a '\0') to send the break, but for now just return an error.  */
  __set_errno (EINVAL);
  return -1;
#endif
}
示例#16
0
TPCANStatus CAN_Reset(TPCANHandle Channel) {

	PCAN_DESCRIPTOR *desc;
	TPCANStatus Result = PCAN_ERROR_OK;

	try {

		// logging
		char szLog[MAX_LOG];
		LOG_EnteringTo("CAN_Reset");
		sprintf(szLog, "Channel: 0x%02X", Channel);
		LOG_Parameters("CAN_Reset", szLog);

		// descriptor
		if (ppDescriptors == NULL) {
			Result = PCAN_ERROR_INITIALIZE;
			goto leave;
		}
		if (ppDescriptors[Channel] == NULL) {
			Result = PCAN_ERROR_INITIALIZE;
			goto leave;
		}
		desc = ppDescriptors[Channel];

		// call init
		TPCANInit init;
		init.wBTR0BTR1 = desc->Btr0Btr1; // combined BTR0 and BTR1 register of the SJA100
		init.ucCANMsgType = MSGTYPE_EXTENDED; // 11 or 29 bits
		init.ucListenOnly = desc->nListenOnly; // listen only mode when != 0
		if (__ioctl(desc->nFileNo, PCAN_INIT, &init) < 0) {
			Result = PCAN_ERROR_UNKNOWN;
			goto leave;
		}

		leave: LOG_LeavingFrom("CAN_Reset", Result);
		return Result;
	} catch (...) {
		Result = PCAN_ERROR_UNKNOWN;
		LOG_Exception("CAN_Reset");
	}
	return Result;
}
/* Return the interface index corresponding to interface IFNAME.
   On error, return 0.  */
unsigned int
if_nametoindex (const char *ifname)
{
  struct ifreq ifr;
  int fd = __opensock ();

  if (fd < 0)
    return 0;

  strncpy (ifr.ifr_name, ifname, IFNAMSIZ);
  if (__ioctl (fd, SIOCGIFINDEX, &ifr) < 0)
    {
      int saved_errno = errno;
      __close (fd);
      if (saved_errno == EINVAL || saved_errno == ENOTTY)
        __set_errno (ENOSYS);
      return 0;
    }
  __close (fd);
  return ifr.ifr_ifindex;
}
示例#18
0
/* Unlock the slave pseudo terminal associated with the master pseudo
   terminal specified by FD.  */
int
unlockpt (int fd)
{
#ifdef TIOCSPTLCK
  int save_errno = errno;
  int unlock = 0;

  if (__ioctl (fd, TIOCSPTLCK, &unlock))
    {
      if (errno == EINVAL)
	{
	  __set_errno (save_errno);
	  return 0;
	}
      else
	return -1;
    }
#endif
  /* If we have no TIOCSPTLCK ioctl, all slave pseudo terminals are
     unlocked by default.  */
  return 0;
}
示例#19
0
/* Return the session ID of FD.  */
pid_t
tcgetsid (int fd)
{
  pid_t pgrp;
  pid_t sid;
#ifdef TIOCGSID
  static int tiocgsid_does_not_work;

  if (! tiocgsid_does_not_work)
    {
      int serrno = errno;
      int sid;

      if (__ioctl (fd, TIOCGSID, &sid) < 0)
	{
	  if (errno == EINVAL)
	    {
	      tiocgsid_does_not_work = 1;
	      __set_errno (serrno);
	    }
	  else
	    return (pid_t) -1;
	}
      else
	return (pid_t) sid;
    }
#endif

  pgrp = tcgetpgrp (fd);
  if (pgrp == -1)
    return (pid_t) -1;

  sid = getsid (pgrp);
  if (sid == -1 && errno == ESRCH)
    __set_errno (ENOTTY);

  return sid;
}
/* Store the name of the interface corresponding to index IFINDEX in
   IFNAME (which has space for at least IFNAMSIZ characters).  Return
   IFNAME, or NULL on error.  */
char *
if_indextoname (unsigned int ifindex, char *ifname)
{
  struct ifreq ifr;
  int fd = __opensock ();

  if (fd < 0)
    return NULL;

  ifr.ifr_ifindex = ifindex;
  if (__ioctl (fd, SIOCGIFNAME, &ifr) < 0)
    {
      int saved_errno = errno;
      __close (fd);
      if (saved_errno == EINVAL || saved_errno == ENOTTY)
        __set_errno (ENOSYS);
      else if (saved_errno == ENODEV)
	__set_errno (ENXIO);
      return NULL;
    }
  __close (fd);
  return strncpy (ifname, ifr.ifr_name, IFNAMSIZ);
}
示例#21
0
/* Flush pending data on FD.  */
int
tcflush (int fd, int queue_selector)
{
  int arg;

  switch (queue_selector)
    {
    case TCIFLUSH:
      arg = FREAD;
      break;
    case TCOFLUSH:
      arg = FWRITE;
      break;
    case TCIOFLUSH:
      arg = FREAD | FWRITE;
      break;
    default:
      __set_errno (EINVAL);
      return -1;
    }

  return __ioctl (fd, TIOCFLUSH, (void *) &arg);
}
示例#22
0
/* Wait for pending output to be written on FD.  */
int
__libc_tcdrain (int fd)
{
  return __ioctl (fd, TIOCDRAIN);
}
示例#23
0
/* Set the foreground process group ID of FD set PGRP_ID.  */
int
tcsetpgrp (int fd, pid_t pgrp_id)
{
  return __ioctl (fd, TIOCSPGRP, &pgrp_id);
}
static struct if_nameindex *
if_nameindex_ioctl (void)
{
  int fd = __opensock ();
  struct ifconf ifc;
  unsigned int nifs, i;
  int rq_len;
  struct if_nameindex *idx = NULL;
# define RQ_IFS	4

  if (fd < 0)
    return NULL;

  ifc.ifc_buf = NULL;

  /* We may be able to get the needed buffer size directly, rather than
     guessing.  */
  if (! old_siocgifconf)
    {
      ifc.ifc_buf = NULL;
      ifc.ifc_len = 0;
      if (__ioctl (fd, SIOCGIFCONF, &ifc) < 0 || ifc.ifc_len == 0)
	{
# if __ASSUME_SIOCGIFNAME == 0
	  old_siocgifconf = 1;
# endif
	  rq_len = RQ_IFS * sizeof (struct ifreq);
	}
      else
	rq_len = ifc.ifc_len;
    }
  else
    rq_len = RQ_IFS * sizeof (struct ifreq);

  /* Read all the interfaces out of the kernel.  */
  ifc.ifc_buf = alloca (rq_len);
  ifc.ifc_len = rq_len;
  while (1)
    {
        if (__ioctl (fd, SIOCGIFCONF, &ifc) < 0)
	{
	  close_not_cancel_no_status (fd);
	  return NULL;
	}
      if (ifc.ifc_len < rq_len || ! old_siocgifconf)
	break;

      ifc.ifc_buf = extend_alloca (ifc.ifc_buf, rq_len, 2 * rq_len);
      ifc.ifc_len = rq_len;
    }

  nifs = ifc.ifc_len / sizeof (struct ifreq);

  idx = malloc ((nifs + 1) * sizeof (struct if_nameindex));
  if (idx == NULL)
    {
      close_not_cancel_no_status (fd);
      __set_errno (ENOBUFS);
      return NULL;
    }

  for (i = 0; i < nifs; ++i)
    {
      struct ifreq *ifr = &ifc.ifc_req[i];
      idx[i].if_name = __strdup (ifr->ifr_name);
      if (idx[i].if_name == NULL
	  || __ioctl (fd, SIOCGIFINDEX, ifr) < 0)
	{
	  int saved_errno = errno;
	  unsigned int j;

	  for (j =  0; j < i; ++j)
	    free (idx[j].if_name);
	  free (idx);
	  close_not_cancel_no_status (fd);
	  if (saved_errno == EINVAL)
	    saved_errno = ENOSYS;
	  else if (saved_errno == ENOMEM)
	    saved_errno = ENOBUFS;
	  __set_errno (saved_errno);
	  return NULL;
	}
      idx[i].if_index = ifr->ifr_ifindex;
    }

  idx[i].if_index = 0;
  idx[i].if_name = NULL;

  close_not_cancel_no_status (fd);
  return idx;
}
示例#25
0
/* Suspend or restart transmission on FD.  */
int
tcflow (int fd, int action)
{
  return __ioctl (fd, TCXONC, action);
}
示例#26
0
/*
 * Create a UDP based client handle.
 * If *sockp<0, *sockp is set to a newly created UPD socket.
 * If raddr->sin_port is 0 a binder on the remote machine
 * is consulted for the correct port number.
 * NB: It is the clients responsibility to close *sockp.
 * NB: The rpch->cl_auth is initialized to null authentication.
 *     Caller may wish to set this something more useful.
 *
 * wait is the amount of time used between retransmitting a call if
 * no response has been heard; retransmission occurs until the actual
 * rpc call times out.
 *
 * sendsz and recvsz are the maximum allowable packet sizes that can be
 * sent and received.
 */
CLIENT *
__libc_clntudp_bufcreate (struct sockaddr_in *raddr, u_long program,
			  u_long version, struct timeval wait, int *sockp,
			  u_int sendsz, u_int recvsz, int flags)
{
  CLIENT *cl;
  struct cu_data *cu = NULL;
  struct rpc_msg call_msg;

  cl = (CLIENT *) mem_alloc (sizeof (CLIENT));
  sendsz = ((sendsz + 3) / 4) * 4;
  recvsz = ((recvsz + 3) / 4) * 4;
  cu = (struct cu_data *) mem_alloc (sizeof (*cu) + sendsz + recvsz);
  if (cl == NULL || cu == NULL)
    {
      struct rpc_createerr *ce = &get_rpc_createerr ();
      (void) __fxprintf (NULL, "%s: %s",
			 "clntudp_create", _("out of memory\n"));
      ce->cf_stat = RPC_SYSTEMERROR;
      ce->cf_error.re_errno = ENOMEM;
      goto fooy;
    }
  cu->cu_outbuf = &cu->cu_inbuf[recvsz];

  if (raddr->sin_port == 0)
    {
      u_short port;
      if ((port =
	   pmap_getport (raddr, program, version, IPPROTO_UDP)) == 0)
	{
	  goto fooy;
	}
      raddr->sin_port = htons (port);
    }
  cl->cl_ops = (struct clnt_ops *) &udp_ops;
  cl->cl_private = (caddr_t) cu;
  cu->cu_raddr = *raddr;
  cu->cu_rlen = sizeof (cu->cu_raddr);
  cu->cu_wait = wait;
  cu->cu_total.tv_sec = -1;
  cu->cu_total.tv_usec = -1;
  cu->cu_sendsz = sendsz;
  cu->cu_recvsz = recvsz;
  call_msg.rm_xid = _create_xid ();
  call_msg.rm_direction = CALL;
  call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
  call_msg.rm_call.cb_prog = program;
  call_msg.rm_call.cb_vers = version;
  xdrmem_create (&(cu->cu_outxdrs), cu->cu_outbuf, sendsz, XDR_ENCODE);
  if (!xdr_callhdr (&(cu->cu_outxdrs), &call_msg))
    {
      goto fooy;
    }
  cu->cu_xdrpos = XDR_GETPOS (&(cu->cu_outxdrs));
  if (*sockp < 0)
    {
#ifdef SOCK_NONBLOCK
# ifndef __ASSUME_SOCK_CLOEXEC
      if (__have_sock_cloexec >= 0)
# endif
	{
	  *sockp = __socket (AF_INET, SOCK_DGRAM|SOCK_NONBLOCK|flags,
			     IPPROTO_UDP);
# ifndef __ASSUME_SOCK_CLOEXEC
	  if (__have_sock_cloexec == 0)
	    __have_sock_cloexec = *sockp >= 0 || errno != EINVAL ? 1 : -1;
# endif
	}
#endif
#ifndef __ASSUME_SOCK_CLOEXEC
# ifdef SOCK_CLOEXEC
      if (__have_sock_cloexec < 0)
# endif
	{
	  *sockp = __socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
# ifdef SOCK_CLOEXEC
	  if (flags & SOCK_CLOEXEC)
	    __fcntl (*sockp, F_SETFD, FD_CLOEXEC);
# endif
	}
#endif
      if (__builtin_expect (*sockp < 0, 0))
	{
	  struct rpc_createerr *ce = &get_rpc_createerr ();
	  ce->cf_stat = RPC_SYSTEMERROR;
	  ce->cf_error.re_errno = errno;
	  goto fooy;
	}
      /* attempt to bind to prov port */
      (void) bindresvport (*sockp, (struct sockaddr_in *) 0);
#ifndef __ASSUME_SOCK_CLOEXEC
# ifdef SOCK_CLOEXEC
      if (__have_sock_cloexec < 0)
# endif
	{
	  /* the sockets rpc controls are non-blocking */
	  int dontblock = 1;
	  (void) __ioctl (*sockp, FIONBIO, (char *) &dontblock);
	}
#endif
#ifdef IP_RECVERR
      {
	int on = 1;
	__setsockopt (*sockp, SOL_IP, IP_RECVERR, &on, sizeof(on));
      }
#endif
      cu->cu_closeit = TRUE;
    }
  else
    {
      cu->cu_closeit = FALSE;
    }
  cu->cu_sock = *sockp;
  cl->cl_auth = authnone_create ();
  return cl;
fooy:
  if (cu)
    mem_free ((caddr_t) cu, sizeof (*cu) + sendsz + recvsz);
  if (cl)
    mem_free ((caddr_t) cl, sizeof (CLIENT));
  return (CLIENT *) NULL;
}
/* Return an array of if_nameindex structures, one for each network
   interface present, plus one indicating the end of the array.  On
   error, return NULL.  */
struct if_nameindex *
if_nameindex (void)
{
  error_t err = 0;
  char data[2048];
  file_t server;
  int fd = __opensock ();
  struct ifconf ifc;
  unsigned int nifs, i;
  struct if_nameindex *idx = NULL;

  ifc.ifc_buf = data;

  if (fd < 0)
    return NULL;

  server = _hurd_socket_server (PF_INET, 0);
  if (server == MACH_PORT_NULL)
    nifs = 0;
  else
    {
      size_t len = sizeof data;
      err = __pfinet_siocgifconf (server, -1, &ifc.ifc_buf, &len);
      if (err == MACH_SEND_INVALID_DEST || err == MIG_SERVER_DIED)
	{
	  /* On the first use of the socket server during the operation,
	     allow for the old server port dying.  */
	  server = _hurd_socket_server (PF_INET, 1);
	  if (server == MACH_PORT_NULL)
	    goto out;
	  err = __pfinet_siocgifconf (server, -1, &ifc.ifc_buf, &len);
	}
      if (err)
	goto out;

      ifc.ifc_len = len;
      nifs = len / sizeof (struct ifreq);
    }

  idx = malloc ((nifs + 1) * sizeof (struct if_nameindex));
  if (idx == NULL)
    {
      err = ENOBUFS;
      goto out;
    }

  for (i = 0; i < nifs; ++i)
    {
      struct ifreq *ifr = &ifc.ifc_req[i];
      idx[i].if_name = __strdup (ifr->ifr_name);
      if (idx[i].if_name == NULL
          || __ioctl (fd, SIOCGIFINDEX, ifr) < 0)
        {
          unsigned int j;
          err = errno;

          for (j =  0; j < i; ++j)
            free (idx[j].if_name);
          free (idx);
	  idx = NULL;

          if (err == EINVAL)
            err = ENOSYS;
          else if (err == ENOMEM)
            err = ENOBUFS;
          goto out;
        }
      idx[i].if_index = ifr->ifr_ifindex;
    }

  idx[i].if_index = 0;
  idx[i].if_name = NULL;

 out:
  __close (fd);
  if (data != ifc.ifc_buf)
    __vm_deallocate (__mach_task_self (), (vm_address_t) ifc.ifc_buf,
		     ifc.ifc_len);
  __set_errno (err);
  return idx;
}
char *
if_indextoname (unsigned int ifindex, char *ifname)
{
#if !defined SIOCGIFINDEX && __ASSUME_SIOCGIFNAME == 0
  __set_errno (ENOSYS);
  return NULL;
#else
# if __ASSUME_SIOCGIFNAME == 0
  struct if_nameindex *idx;
  struct if_nameindex *p;
  char *result = NULL;
# endif

# if defined SIOCGIFNAME || __ASSUME_SIOCGIFNAME > 0
  /* We may be able to do the conversion directly, rather than searching a
     list.  This ioctl is not present in kernels before version 2.1.50.  */
  struct ifreq ifr;
  int fd;
#  if __ASSUME_SIOCGIFNAME == 0
  static int siocgifname_works_not;

  if (!siocgifname_works_not)
#  endif
    {
#  if __ASSUME_SIOCGIFNAME == 0
      int serrno = errno;
#  endif
      int status;

      fd = __opensock ();

      if (fd < 0)
	return NULL;

      ifr.ifr_ifindex = ifindex;
      status = __ioctl (fd, SIOCGIFNAME, &ifr);

      close_not_cancel_no_status (fd);

      if (status  < 0)
	{
#  if __ASSUME_SIOCGIFNAME == 0
	  if (errno == EINVAL)
	    siocgifname_works_not = 1; /* Don't make the same mistake twice. */
	  else
#  endif
	    {
	      if (errno == ENODEV)
		/* POSIX requires ENXIO.  */
		__set_errno (ENXIO);

	      return NULL;
	    }
	}
      else
	return strncpy (ifname, ifr.ifr_name, IFNAMSIZ);

#  if __ASSUME_SIOCGIFNAME == 0
      __set_errno (serrno);
#  endif
    }
# endif

# if __ASSUME_SIOCGIFNAME == 0
  idx = if_nameindex ();

  if (idx != NULL)
    {
      for (p = idx; p->if_index || p->if_name; ++p)
	if (p->if_index == ifindex)
	  {
	    result = strncpy (ifname, p->if_name, IFNAMSIZ);
	    break;
	  }

      if_freenameindex (idx);

      if (result == NULL)
	__set_errno (ENXIO);
    }
  return result;
# endif
#endif
}
示例#29
0
/* Set the terminal parameters associated with FD to *PARAMS.  */
int
stty (int fd, const struct sgttyb *params)
{
  return __ioctl (fd, TIOCSETP, (void *) params);
}
void
internal_function
__protocol_available (int *have_inet, int *have_inet6)
{
  int fd = __opensock ();
  unsigned int nifs;
  int rq_len;
  struct ifconf ifc;
# define RQ_IFS	4

  /* Wirst case assumption.  */
  *have_inet = 0;
  *have_inet6 = 0;

  if (fd < 0)
    /* We cannot open the socket.  No networking at all?  */
    return;

  /* We may be able to get the needed buffer size directly, rather than
     guessing.  */
  if (! old_siocgifconf)
    {
      ifc.ifc_buf = NULL;
      ifc.ifc_len = 0;
      if (__ioctl (fd, SIOCGIFCONF, &ifc) < 0 || ifc.ifc_len == 0)
	{
# if __ASSUME_SIOCGIFNAME == 0
	  old_siocgifconf = 1;
# endif
	  rq_len = RQ_IFS * sizeof (struct ifreq);
	}
      else
	rq_len = ifc.ifc_len;
    }
  else
    rq_len = RQ_IFS * sizeof (struct ifreq);

  /* Read all the interfaces out of the kernel.  */
  do
    {
      ifc.ifc_buf = alloca (ifc.ifc_len = rq_len);
      if (__ioctl (fd, SIOCGIFCONF, &ifc) < 0)
	{
	  close_not_cancel_no_status (fd);
	  return;
	}
      rq_len *= 2;
    }
  while (ifc.ifc_len == rq_len && old_siocgifconf);

  nifs = ifc.ifc_len / sizeof (struct ifreq);

  /* Go through all the interfaces and get the address.  */
  while (nifs-- > 0)
    if (__ioctl (fd, SIOCGIFADDR, &ifc.ifc_req[nifs]) >= 0)
      {
	/* We successfully got information about this interface.  Now
	   test whether it is an IPv4 or IPv6 address.  */
	if (ifc.ifc_req[nifs].ifr_addr.sa_family == AF_INET)
	  *have_inet = 1;
	else if (ifc.ifc_req[nifs].ifr_addr.sa_family == AF_INET6)
	  *have_inet6 = 1;

	/* Note, this is & not &&.  It works since the values are always
	   0 or 1.  */
	if (*have_inet & *have_inet6)
	  /* We can stop early.  */
	  break;
      }

  close_not_cancel_no_status (fd);
}