static GAtIO *create_io(GIOChannel *channel, GIOFlags flags) { GAtIO *io; if (channel == NULL) return NULL; io = g_try_new0(GAtIO, 1); if (io == NULL) return io; io->ref_count = 1; io->debugf = NULL; if (flags & G_IO_FLAG_NONBLOCK) { io->max_read_attempts = 3; io->use_write_watch = TRUE; } else { io->max_read_attempts = 1; io->use_write_watch = FALSE; } io->buf = ring_buffer_new(8192); if (!io->buf) goto error; if (!g_at_util_setup_io(channel, flags)) goto error; io->channel = channel; io->read_watch = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, received_data, io, read_watcher_destroy_notify); return io; error: if (io->buf) ring_buffer_free(io->buf); g_free(io); return NULL; }
struct ppp_net *ppp_net_new(GAtPPP *ppp, int fd) { struct ppp_net *net; GIOChannel *channel = NULL; struct ifreq ifr; int err; net = g_try_new0(struct ppp_net, 1); if (net == NULL) goto badalloc; net->ppp_packet = ppp_packet_new(MAX_PACKET, PPP_IP_PROTO); if (net->ppp_packet == NULL) goto error; /* * If the fd value is still the default one, * open the tun interface and configure it. */ memset(&ifr, 0, sizeof(ifr)); if (fd < 0) { /* open a tun interface */ fd = open("/dev/net/tun", O_RDWR); if (fd < 0) goto error; ifr.ifr_flags = IFF_TUN | IFF_NO_PI; strcpy(ifr.ifr_name, "ppp%d"); err = ioctl(fd, TUNSETIFF, (void *) &ifr); if (err < 0) goto error; } else { err = ioctl(fd, TUNGETIFF, (void *) &ifr); if (err < 0) goto error; } net->if_name = strdup(ifr.ifr_name); /* create a channel for reading and writing to this interface */ channel = g_io_channel_unix_new(fd); if (channel == NULL) goto error; if (!g_at_util_setup_io(channel, 0)) goto error; g_io_channel_set_buffered(channel, FALSE); net->channel = channel; net->watch = g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, ppp_net_callback, net); net->ppp = ppp; net->mtu = MAX_PACKET; return net; error: if (channel) g_io_channel_unref(channel); g_free(net->if_name); g_free(net->ppp_packet); g_free(net); badalloc: if (fd >= 0) close(fd); return NULL; }