コード例 #1
0
ファイル: serial.c プロジェクト: korneliuszo/shoehorn
/* open the serial port */
void serial_open(const char *dev)
{
	portfd = open(dev, O_RDWR | O_NOCTTY);
	if (portfd < 0)
		perror_exit(dev);

	/* save current port settings */
	if (tcgetattr(portfd, &oldtio) < 0)
		perror_exit("tcgetattr");

	/* set signal handlers before switching settings */
	signal(SIGHUP, handler1);
	signal(SIGINT, handler1);
	signal(SIGPIPE, handler1);
	signal(SIGTERM, handler1);

	/* configure new port settings: 9600 8N1 */
	memset(&newtio, 0, sizeof(newtio));
	newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
	newtio.c_iflag = IGNPAR;
	newtio.c_oflag = 0;
	/* set input mode (non-canonical, no echo,...) */
	newtio.c_lflag = 0;
	newtio.c_cc[VTIME] = 0;	/* inter-character timer unused */
	newtio.c_cc[VMIN] = 1;	/* blocking read until 1 char received */

	/* install new port settings */
	tcflush(portfd, TCIFLUSH);
	if (tcsetattr(portfd, TCSANOW, &newtio) < 0)
		perror_exit("tcsetattr");
}
コード例 #2
0
ファイル: i2c.c プロジェクト: useche/btstats
void i2c_init(struct plugin *p, struct plugin_set *__un1, struct plug_args *pa)
{
	char filename[FILENAME_MAX];
	struct i2c_data *i2c = p->data = g_new(struct i2c_data,1);

	i2c->is = g_tree_new(comp_int64);
	i2c->outstanding = 0;
	i2c->maxouts = 0;

	i2c->oio_f = NULL;
	if(pa->i2c_oio_f) {
		get_filename(filename, "i2c_oio", pa->i2c_oio_f, pa->end_range);
		i2c->oio_f = fopen(filename,"w");
		if(!i2c->oio_f) perror_exit("Opening I2C detail file");
	}

	i2c->oio_hist_f = NULL;
	if(pa->i2c_oio_hist_f) {
		get_filename(filename, "i2c_oio_hist", pa->i2c_oio_hist_f, pa->end_range);
		i2c->oio_hist_f = fopen(filename,"w");
		if(!i2c->oio_hist_f) perror_exit("Opening I2C detail file");
	}

	i2c->oio = NULL;
	i2c->oio_size = 0;
	i2c->oio_prev_time = UINT64_MAX;
}
コード例 #3
0
ファイル: dbg_mac.c プロジェクト: arv3/edbg
//-----------------------------------------------------------------------------
int dbg_dap_cmd(uint8_t *data, int size, int rsize)
{
  char cmd = data[0];
  int res;

  memset(hid_buffer, 0xff, report_size + 1);

  hid_buffer[0] = 0x00; // Report ID
  memcpy(&hid_buffer[1], data, rsize);

  res = hid_write(handle, hid_buffer, report_size + 1);
  if (res < 0)
  {
    printf("Error: %ls\n", hid_error(handle));
    perror_exit("debugger write()");
  }

  res = hid_read(handle, hid_buffer, report_size + 1);
  if (res < 0)
    perror_exit("debugger read()");

  check(res, "empty response received");

  check(hid_buffer[0] == cmd, "invalid response received");

  res--;
  memcpy(data, &hid_buffer[1], (size < res) ? size : res);

  return res;
}
コード例 #4
0
ファイル: edbg.c プロジェクト: arv3/edbg
//-----------------------------------------------------------------------------
int load_file(char *name, uint8_t *data, int size)
{
  struct stat stat;
  int fd, rsize;

  check(NULL != name, "input file name is not specified");

  fd = open(name, O_RDONLY | O_BINARY);

  if (fd < 0)
    perror_exit("open()");

  fstat(fd, &stat);

  check(stat.st_size <= size, "image is too big for the selected chip");

  rsize = read(fd, data, stat.st_size);

  if (rsize < 0)
    perror_exit("read()");

  check(rsize == stat.st_size, "cannot fully read file");

  close(fd);

  return rsize;
}
コード例 #5
0
void *connection_handler(void *arg){
    int err,length;
    char* directory;
    QNode* node;
    int newsock = ((information*)arg)->newsock;
    int queue_size = ((information*)arg)->queue_size;
    pthread_mutex_t *clientMutex = malloc(sizeof(pthread_mutex_t));
//---------------------------------------------
    if ( err = pthread_detach(pthread_self())){
        perror2("pthread_detach",err);
        exit(1);
    }
    pthread_mutex_init(clientMutex,NULL ) ; /* Initialize client mutex */

    if (read_all(newsock,&length,sizeof(int)) != sizeof(int) )
        perror_exit("read");
    directory = malloc(length);
    if (read_all(newsock,directory,length) != length)
        perror_exit("read");
    //print directory
    //printf("directory is: %s\n",directory);
    printf("[Thread: %ld]: About to scan directory Server\n",pthread_self());
    fflush(stdout);
    findFiles(directory,newsock,queue_size,clientMutex);
    //create ack
    node = createQNode();
    node->client_sock = newsock;
    node->buf = NULL;
    node->clientMutex = clientMutex;
    place(workQueue,node,queue_size);
    pthread_cond_broadcast(&cond_empty);
    pthread_exit(NULL);
}
コード例 #6
0
ファイル: sock_util.c プロジェクト: kevin4fly/network
/* sock_bind: create and bind a new socket with @port
 * @port: the port used to bind the socket
 *
 * */
int bind_sock(int port)
{
    int listenfd;
    struct sockaddr_in socket_addr;

    /* create a new socket */
    if ((listenfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
    {
        perror_exit("socket error");
    }

    /* fill the socket address struct */
    memset(&socket_addr,0,sizeof(struct sockaddr_in));
    socket_addr.sin_family = AF_INET;
    socket_addr.sin_port = htons(port);
    socket_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    /* bind the socket */
    if (bind(listenfd,(struct sockaddr *)&socket_addr,sizeof(struct sockaddr_in)) < 0)
    {
        perror_exit("bind error");
    }

    return listenfd;
}
コード例 #7
0
ファイル: sock_util.c プロジェクト: kevin4fly/network
/* handle_connection: handle the connected clients
 * @listenfd: the socket used to accept connections
 *
 * */
void handle_connection(int listenfd)
{
    /* the number of readable fds in the pollfd array */
    int nready, i;

    /* receive buffer */
    buffer_t recvbuf;
    memset(&recvbuf,0,sizeof(buffer_t));

    /* set the listenfd to non-block */
    //setnonblock(listenfd);

    /* epollfd set to monitor the related events */
    int epollfd;
    if ( (epollfd = epoll_create(EPOLL_SIZE)) < 0 )
    {
        perror_exit("epoll create error");
    }

    /* epoll event array */
    struct epoll_event events[EPOLL_EVENTS];

    /* add the listen socket to epoll set */
    int state = EPOLLIN;
    add_epoll_event(epollfd,listenfd,state);

    while( 1 )
    {
        /* obtain the ready sockets from the epoll set */
        if ( (nready = epoll_wait(epollfd,events,EPOLL_EVENTS,INFTIM)) < 0)
        {
            perror_exit("epoll wait error");
        }

        /* traverse the ready sockets */
        for (i = 0; i < nready; ++i)
        {
            int fd = events[i].data.fd;

            /* listenfd is ready */
            if ( fd == listenfd && (events[i].events & EPOLLIN) )
            {
                do_accept(listenfd, epollfd);
            }

            /* connected sockets are ready */
            else if ( events[i].events & EPOLLIN )
            {
                do_read(fd,epollfd,&recvbuf);
            }

            /* read the data from the connected socket and echo it also */
            else if ( events[i].events & EPOLLOUT )
            {
                do_write(fd,epollfd,&recvbuf);
            }
        }
    }
}
コード例 #8
0
void *server(void *data)
{
	data_struct *info = data;
	int port = info->port;
	pthread_t thr_server;
	int sock, newsock,retValue =-1;
	int optval;
    struct sockaddr_in server, client;
    socklen_t clientlen;
    struct sockaddr *serverptr=(struct sockaddr *)&server;
    struct sockaddr *clientptr=(struct sockaddr *)&client;
    struct hostent *rem;
    
    /* Create socket */
    if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
        perror_exit("socket");
    server.sin_family = AF_INET;       /* Internet domain */
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(port);      /* The given port */
    
    optval = 1;//make the socket reuseable fast
	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
    
    /* Bind socket to address */
    if (bind(sock, serverptr, sizeof(server)) < 0)
        perror_exit("bind");
        
    /* Listen for connections */
    if (listen(sock, 5) < 0)
		perror_exit("listen");
    printf("Listening for connections to port %d\n", port);
    
    while (1)
    {	clientlen = sizeof(client);
        /* accept connection */
    	if ((newsock = accept(sock, clientptr, &clientlen)) < 0)
			perror_exit("accept");
	
    	printf("Accepted connection\n");
		
		info->socket = newsock;
		//thread pou tha eksyphrethsei thn aithsh
		retValue = pthread_create(&thr_server, NULL, thread_server, (void *)info);
		if(retValue == 1)
			perror2("pthread_create", retValue);
			

    	
    	//close(newsock); /* parent closes socket to client */
    }
}
コード例 #9
0
void join_thread(pthread_t thread)
{
  int ret = pthread_join(thread, NULL);
  if (ret == -1) {
      perror_exit("pthread_join failed");
  }
}
コード例 #10
0
ファイル: xmisc.c プロジェクト: zsaleeba/shellbox
struct passwd *xgetpwnam(char *name)
{
  struct passwd *up = getpwnam(name);

  if (!up) perror_exit("user '%s'", name);
  return up;
}
コード例 #11
0
ファイル: xmisc.c プロジェクト: zsaleeba/shellbox
struct group *xgetgrgid(gid_t gid)
{
  struct group *group = getgrgid(gid);

  if (!group) perror_exit("gid %ld", (long)gid);
  return group;
}
コード例 #12
0
ファイル: sock_util.c プロジェクト: kevin4fly/network
/* do_accept: establish the new connection
 * @listenfd: the listening fd
 * @epollfd: the epollfd used to monitor the listening fd and new connected fd
 *
 * */
void do_accept(int listenfd, int epollfd)
{
    int connfd;
    struct sockaddr_in clitaddr;
    socklen_t socklen;
    //while ( (connfd = accept(listenfd,(struct sockaddr *)&clitaddr,&socklen)) > 0 )
    //{
    connfd = accept(listenfd,(struct sockaddr *)&clitaddr,&socklen);
        /* show client info */
        show_peer_info(connfd);

        /* set the connfd to non-block socket */
        //setnonblock(connfd);

        /* set the connfd events to EPOLLIN | EPLLET(edge trigger) */
        //int state =  EPOLLIN | EPOLLET;
        int state = EPOLLIN;

        /* add connected fd to epoll set */
        add_epoll_event(epollfd,connfd,state);
    //}

    /* if accept error*/
    if (connfd < 0)
    {
        if (errno != EINTR)
        {
            perror_exit("accept error");
        }
    }
}
コード例 #13
0
ファイル: toys.c プロジェクト: benravago/spin-up-tools
int xconnect(char *host, char *port, int family, int socktype, int protocol, int flags)
{
  struct addrinfo info, *ai, *ai2;
  int fd;

  memset(&info, 0, sizeof(struct addrinfo));
  info.ai_family = family;
  info.ai_socktype = socktype;
  info.ai_protocol = protocol;
  info.ai_flags = flags;

  fd = getaddrinfo(host, port, &info, &ai);
  if (fd || !ai)
    error_exit("Connect '%s%s%s': %s", host, port ? ":" : "", port ? port : "",
      fd ? gai_strerror(fd) : "not found");

  // Try all the returned addresses. Report errors if last entry can't connect.
  for (ai2 = ai; ai; ai = ai->ai_next) {
    fd = (ai->ai_next ? socket : xsocket)(ai->ai_family, ai->ai_socktype,
      ai->ai_protocol);
    if (!connect(fd, ai->ai_addr, ai->ai_addrlen)) break;
    else if (!ai2->ai_next) perror_exit("connect");
    close(fd);
  }
  freeaddrinfo(ai2);

  return fd;
}
コード例 #14
0
ファイル: sock_util.c プロジェクト: kevin4fly/network
/* setnonblock: set the non-blocking @fd
 * @fd: the fd to be set
 *
 * */
void setnonblock(int fd)
{
    int opt;
    /* get the orignal option */
    if ( (opt = fcntl(fd,F_GETFD)) < 0 )
    {
        perror_exit("fctl error");
    }

    /* set non-block option */
    opt |= O_NONBLOCK;
    if ( (opt = fcntl(fd,F_SETFD)) < 0 )
    {
        perror_exit("fcntl error");
    }
}
コード例 #15
0
ファイル: sock_util.c プロジェクト: kevin4fly/network
/* sock_listen: listen the @listenfd socket
 * @listenfd: the socket used for listening
 *
 * */
void listen_sock(int listenfd)
{
    if (listen(listenfd,LISTENQ) < 0)
    {
        perror_exit("listen error");
    }
}
コード例 #16
0
ファイル: sock_util.c プロジェクト: kevin4fly/network
void do_read(int fd, int epollfd, buffer_t *recvbuf)
{
    int space = buffer_hasspace(recvbuf);
    if (space > 0)
    {
        int nread = read(fd,recvbuf->buffer + recvbuf->in,space);

        /* read error */
        if (nread < 0)
        {
            perror_exit("read error");
        }

        /* read "FIN" from client */
        else if (nread == 0)
        {
            delete_epoll_event(epollfd,fd,EPOLLIN);
            close(fd);
        }

        else
        {
            recvbuf->in += nread;

            /* data is ready for writing */
            modify_epoll_event(epollfd,fd,EPOLLOUT);
        }
    }
}
コード例 #17
0
ファイル: main.c プロジェクト: OoOverflow/toybox
// Full init needed by multiplexer or reentrant calls, calls singleinit at end
void toy_init(struct toy_list *which, char *argv[])
{
  void *oldwhich = toys.which;

  // Drop permissions for non-suid commands.

  if (CFG_TOYBOX_SUID) {
    if (!toys.which) toys.which = toy_list;

    uid_t uid = getuid(), euid = geteuid();

    if (!(which->flags & TOYFLAG_STAYROOT)) {
      if (uid != euid) {
        if (setuid(uid)) perror_exit("setuid %d->%d", euid, uid); // drop root
        euid = uid;
        toys.wasroot++;
      }
    } else if (CFG_TOYBOX_DEBUG && uid && which != toy_list)
      error_msg("Not installed suid root");

    if ((which->flags & TOYFLAG_NEEDROOT) && euid) help_exit("Not root");
  }

  // Free old toys contents (to be reentrant), but leave rebound if any
  // don't blank old optargs if our new argc lives in the old optargs.
  if (argv<toys.optargs || argv>toys.optargs+toys.optc) free(toys.optargs);
  memset(&toys, 0, offsetof(struct toy_context, rebound));
  if (oldwhich) memset(&this, 0, sizeof(this));

  // Continue to portion of init needed by standalone commands
  toy_singleinit(which, argv);
}
コード例 #18
0
ファイル: insmod.c プロジェクト: drinkcat/toybox
void insmod_main(void)
{
  int fd = !strcmp(*toys.optargs, "-") ? 0 : xopen(*toys.optargs, O_RDONLY);
  int i, rc;

  i = 1;
  while (toys.optargs[i] &&
    strlen(toybuf) + strlen(toys.optargs[i]) + 2 < sizeof(toybuf))
  {
    strcat(toybuf, toys.optargs[i++]);
    strcat(toybuf, " ");
  }

  // finit_module was new in Linux 3.8, and doesn't work on stdin,
  // so we fall back to init_module if necessary.
  rc = finit_module(fd, toybuf, 0);
  if (rc && (fd == 0 || errno == ENOSYS)) {
    off_t len = 0;
    char *path = !strcmp(*toys.optargs, "-") ? "/dev/stdin" : *toys.optargs;
    char *buf = readfileat(AT_FDCWD, path, NULL, &len);

    rc = init_module(buf, len, toybuf);
    if (CFG_TOYBOX_FREE) free(buf);
  }

  if (rc) perror_exit("failed to load %s", toys.optargs[0]);

  if (CFG_TOYBOX_FREE) close(fd);
}
コード例 #19
0
ファイル: tcpa2a.c プロジェクト: oraccha/tcpbench
int
recv_handler(struct request *req)
{
    int cc;
    int base = req->rank * req->len;

    set_sock_blocking(req->fd, 0);
    while (req->count < req->len) {
	cc = read(req->fd, &recvbuf[base + req->count],
		  req->len - req->count);
	nr_read++;

	if (cc < 0) {
	    if (errno == EAGAIN || errno == EWOULDBLOCK)
		return 0;
	    else
		perror_exit("read", 1);
	} else if (cc == 0) {
	    fprintf(stderr, "recv: connection closed\n");
	    exit(1);
	}
	req->count += cc;
	rcnt += cc;
    }

    return 0;
}
コード例 #20
0
ファイル: id.c プロジェクト: luckboy/toybox
void do_id(char *username)
{
  int flags, i, ngroups, cmd_groups = toys.which->name[0] == 'g';
  struct passwd *pw;
  struct group *grp;
  uid_t uid = getuid(), euid = geteuid();
  gid_t gid = getgid(), egid = getegid(), *groups;

  if (cmd_groups)
      toys.optflags |= FLAG_G | FLAG_n;

  flags = toys.optflags;

  // check if a username is given
  if (username) {
    pw = xgetpwnam(username);
    uid = euid = pw->pw_uid;
    gid = egid = pw->pw_gid;
    if (cmd_groups) printf("%s : ", pw->pw_name);
  }

  i = flags & FLAG_r;
  pw = xgetpwuid(i ? uid : euid);
  if (flags & FLAG_u) s_or_u(pw->pw_name, pw->pw_uid, 1);

  grp = xgetgrgid(i ? gid : egid);
  if (flags & FLAG_g) s_or_u(grp->gr_name, grp->gr_gid, 1);

  if (!(flags & FLAG_G)) {
    showid("uid=", pw->pw_uid, pw->pw_name);
    showid(" gid=", grp->gr_gid, grp->gr_name);

    if (!i) {
      if (uid != euid) {
        pw = xgetpwuid(euid);
        showid(" euid=", pw->pw_uid, pw->pw_name);
      }
      if (gid != egid) {
        grp = xgetgrgid(egid);
        showid(" egid=", grp->gr_gid, grp->gr_name);
      }
    }

    showid(" groups=", grp->gr_gid, grp->gr_name);
  }

  groups = (gid_t *)toybuf;
  i = sizeof(toybuf)/sizeof(gid_t);
  ngroups = username ? getgrouplist(username, gid, groups, &i)
    : getgroups(i, groups);
  if (ngroups<0) perror_exit(0);

  for (i = 0; i<ngroups; i++) {
    if (i) xputc(' ');
    if (!(grp = getgrgid(groups[i]))) perror_msg(0);
    else if (flags & FLAG_G) s_or_u(grp->gr_name, grp->gr_gid, 0);
    else if (grp->gr_gid != egid) showid("", grp->gr_gid, grp->gr_name);
  }
  xputc('\n');
}
コード例 #21
0
ファイル: dbg_mac.c プロジェクト: arv3/edbg
//-----------------------------------------------------------------------------
void dbg_open(debugger_t *debugger)
{
  handle = hid_open(debugger->vid, debugger->pid, debugger->wserial);

  if (!handle)
    perror_exit("unable to open device");
}
コード例 #22
0
ファイル: xmisc.c プロジェクト: zsaleeba/shellbox
struct group *xgetgrnam(char *name)
{
  struct group *gr = getgrnam(name);

  if (!gr) perror_exit("group '%s'", name);
  return gr;
}
コード例 #23
0
ファイル: sem.c プロジェクト: AllenDowney/ThinkOS
Semaphore *make_semaphore(int value)
{
  Semaphore *sem = check_malloc(sizeof(Semaphore));
  int n = sem_init(sem, 0, value);
  if (n != 0) perror_exit("sem_init failed");
  return sem;
}
コード例 #24
0
MutexWrapper *make_mutex ()
{
  MutexWrapper *my_mutex = check_malloc (sizeof(MutexWrapper));
  int n = pthread_mutex_init (&(my_mutex->mutex), NULL);
  if (n != 0) perror_exit ("make_lock failed"); 
  return my_mutex;
}
コード例 #25
0
ファイル: semaphore.c プロジェクト: jgibson5/Olin
Mutex *make_mutex ()
{
  Mutex *mutex = check_malloc (sizeof(Mutex));
  int n = pthread_mutex_init (mutex, NULL);
  if (n != 0) perror_exit ("make_lock failed"); 
  return mutex;
}
コード例 #26
0
ファイル: counter.c プロジェクト: hhansson/SoftwareSystems
Semaphore *make_semaphore (int n)
{
  Semaphore *sem = check_malloc (sizeof(Semaphore));
  int ret = sem_init(sem, 0, n);
  if (ret == -1) perror_exit ("sem_init failed");
  return sem;
}
コード例 #27
0
ファイル: net.c プロジェクト: 0x6e3078/toybox
int xsocket(int domain, int type, int protocol)
{
  int fd = socket(domain, type, protocol);

  if (fd < 0) perror_exit("socket %x %x", type, protocol);
  return fd;
}
コード例 #28
0
void vconfig_main(void)
{
  struct vlan_ioctl_args request;
  char *cmd;
  int fd;

  fd = xsocket(AF_INET, SOCK_STREAM, 0);
  memset(&request, 0, sizeof(struct vlan_ioctl_args));
  cmd = toys.optargs[0];

  if (!strcmp(cmd, "set_name_type")) {
    char *types[] = {"VLAN_PLUS_VID", "DEV_PLUS_VID", "VLAN_PLUS_VID_NO_PAD",
                     "DEV_PLUS_VID_NO_PAD"};
    int i, j = sizeof(types)/sizeof(*types);

    for (i=0; i<j; i++) if (!strcmp(toys.optargs[1], types[i])) break;
    if (i == j) {
      for (i=0; i<j; i++) puts(types[i]);
      error_exit("%s: unknown '%s'", cmd, toys.optargs[1]);
    }

    request.u.name_type = i;
    request.cmd = SET_VLAN_NAME_TYPE_CMD;
    xioctl(fd, SIOCSIFVLAN, &request);
    return;
  }

  // Store interface name
  xstrncpy(request.device1, toys.optargs[1], 16);

  if (!strcmp(cmd, "add")) {
    request.cmd = ADD_VLAN_CMD;
    if (toys.optargs[2]) request.u.VID = atolx_range(toys.optargs[2], 0, 4094);
    if (request.u.VID == 1)
      xprintf("WARNING: VLAN 1 does not work with many switches.\n");
  } else if (!strcmp(cmd, "rem")) request.cmd = DEL_VLAN_CMD;
  else if (!strcmp(cmd, "set_flag")) {
    request.cmd = SET_VLAN_FLAG_CMD;
    if (toys.optargs[2]) request.u.flag = atolx_range(toys.optargs[2], 0, 1);
    if (toys.optargs[3]) request.vlan_qos = atolx_range(toys.optargs[3], 0, 7);
  } else if(strcmp(cmd, "set_egress_map") == 0) {
    request.cmd = SET_VLAN_EGRESS_PRIORITY_CMD;
    if (toys.optargs[2])
      request.u.skb_priority = atolx_range(toys.optargs[2], 0, INT_MAX);
    if (toys.optargs[3]) request.vlan_qos = atolx_range(toys.optargs[3], 0, 7);
  } else if(strcmp(cmd, "set_ingress_map") == 0) {
    request.cmd = SET_VLAN_INGRESS_PRIORITY_CMD;
    if (toys.optargs[2])
      request.u.skb_priority = atolx_range(toys.optargs[2], 0, INT_MAX);
    //To set flag we must have to set vlan_qos
    if (toys.optargs[3]) request.vlan_qos = atolx_range(toys.optargs[3], 0, 7);
  } else {
    xclose(fd);
    perror_exit("Unknown command %s", cmd);
  }

  xioctl(fd, SIOCSIFVLAN, &request);
  xprintf("Successful %s on device %s\n", cmd, toys.optargs[1]);
}
コード例 #29
0
pid_t xfork(void)
{
  pid_t pid = fork();

  if (pid < 0) perror_exit("fork");

  return pid;
}
コード例 #30
0
ファイル: net.c プロジェクト: emaste/toybox
void xsendto(int sockfd, void *buf, size_t len, struct sockaddr *dest)
{
  int rc = sendto(sockfd, buf, len, 0, dest,
    dest->sa_family == AF_INET ? sizeof(struct sockaddr_in) :
      sizeof(struct sockaddr_in6));

  if (rc != len) perror_exit("sendto");
}