void manager_free(Manager *m) { Machine *machine; assert(m); while ((machine = hashmap_first(m->machines))) machine_free(machine); hashmap_free(m->machines); hashmap_free(m->machine_units); if (m->bus) { dbus_connection_flush(m->bus); dbus_connection_close(m->bus); dbus_connection_unref(m->bus); } if (m->bus_fd >= 0) close_nointr_nofail(m->bus_fd); if (m->epoll_fd >= 0) close_nointr_nofail(m->epoll_fd); free(m); }
int main(int argc, char*argv[]) { DBusConnection *bus; int fd1, fd2; bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, NULL); assert(bus); print_inhibitors(bus); fd1 = inhibit(bus, "sleep"); assert(fd1 >= 0); print_inhibitors(bus); fd2 = inhibit(bus, "idle:shutdown"); assert(fd2 >= 0); print_inhibitors(bus); close_nointr_nofail(fd1); sleep(1); print_inhibitors(bus); close_nointr_nofail(fd2); sleep(1); print_inhibitors(bus); return 0; }
int server_open_kernel_seqnum(Server *s) { int fd; uint64_t *p; assert(s); /* We store the seqnum we last read in an mmaped file. That * way we can just use it like a variable, but it is * persistent and automatically flushed at reboot. */ fd = open("/run/systemd/journal/kernel-seqnum", O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644); if (fd < 0) { log_error("Failed to open /run/systemd/journal/kernel-seqnum, ignoring: %m"); return 0; } if (posix_fallocate(fd, 0, sizeof(uint64_t)) < 0) { log_error("Failed to allocate sequential number file, ignoring: %m"); close_nointr_nofail(fd); return 0; } p = mmap(NULL, sizeof(uint64_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (p == MAP_FAILED) { log_error("Failed to map sequential number file, ignoring: %m"); close_nointr_nofail(fd); return 0; } close_nointr_nofail(fd); s->kernel_seqnum = p; return 0; }
int button_open(Button *b) { char name[256], *p; struct epoll_event ev; int r; assert(b); if (b->fd >= 0) { close_nointr_nofail(b->fd); b->fd = -1; } p = strappend("/dev/input/", b->name); if (!p) return log_oom(); b->fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK); free(p); if (b->fd < 0) { log_warning("Failed to open %s: %m", b->name); return -errno; } if (ioctl(b->fd, EVIOCGNAME(sizeof(name)), name) < 0) { log_error("Failed to get input name: %m"); r = -errno; goto fail; } zero(ev); ev.events = EPOLLIN; ev.data.u32 = FD_OTHER_BASE + b->fd; if (epoll_ctl(b->manager->epoll_fd, EPOLL_CTL_ADD, b->fd, &ev) < 0) { log_error("Failed to add to epoll: %m"); r = -errno; goto fail; } r = hashmap_put(b->manager->button_fds, INT_TO_PTR(b->fd + 1), b); if (r < 0) { log_error("Failed to add to hash map: %s", strerror(-r)); assert_se(epoll_ctl(b->manager->epoll_fd, EPOLL_CTL_DEL, b->fd, NULL) == 0); goto fail; } log_info("Watching system buttons on /dev/input/%s (%s)", b->name, name); return 0; fail: close_nointr_nofail(b->fd); b->fd = -1; return r; }
int main(int argc, char *argv[]) { int r, fd = -1, saved_stderr = -1; log_parse_environment(); log_open(); r = parse_argv(argc, argv); if (r <= 0) goto finish; fd = sd_journal_stream_fd(arg_identifier, arg_priority, arg_level_prefix); if (fd < 0) { log_error("Failed to create stream fd: %s", strerror(-fd)); r = fd; goto finish; } saved_stderr = fcntl(STDERR_FILENO, F_DUPFD_CLOEXEC, 3); if (dup3(fd, STDOUT_FILENO, 0) < 0 || dup3(fd, STDERR_FILENO, 0) < 0) { log_error("Failed to duplicate fd: %m"); r = -errno; goto finish; } if (fd >= 3) close_nointr_nofail(fd); fd = -1; if (argc <= optind) execl("/bin/cat", "/bin/cat", NULL); else execvp(argv[optind], argv + optind); r = -errno; /* Let's try to restore a working stderr, so we can print the error message */ if (saved_stderr >= 0) dup3(saved_stderr, STDERR_FILENO, 0); log_error("Failed to execute process: %s", strerror(-r)); finish: if (fd >= 0) close_nointr_nofail(fd); if (saved_stderr >= 0) close_nointr_nofail(saved_stderr); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; }
static int generate(char id[34]) { int fd; char buf[16]; char *p, *q; ssize_t k; assert(id); /* First, try reading the D-Bus machine id, unless it is a symlink */ if ((fd = open("/var/lib/dbus/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW)) >= 0) { k = loop_read(fd, id, 33, false); close_nointr_nofail(fd); if (k >= 32) { id[32] = '\n'; id[33] = 0; log_info("Initializing machine ID from D-Bus machine ID."); return 0; } } /* If that didn't work, generate a random machine id */ if ((fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY)) < 0) { log_error("Failed to open /dev/urandom: %m"); return -errno; } k = loop_read(fd, buf, sizeof(buf), false); close_nointr_nofail(fd); if (k != sizeof(buf)) { log_error("Failed to read /dev/urandom: %s", strerror(k < 0 ? -k : EIO)); return k < 0 ? (int) k : -EIO; } for (p = buf, q = id; p < buf + sizeof(buf); p++, q += 2) { q[0] = hexchar(*p >> 4); q[1] = hexchar(*p & 15); } id[32] = '\n'; id[33] = 0; log_info("Initializing machine ID from random generator."); return 0; }
static void server_done(Server *s) { assert(s); if (s->epoll_fd >= 0) close_nointr_nofail(s->epoll_fd); if (s->kmsg_fd >= 0) close_nointr_nofail(s->kmsg_fd); if (s->signal_fd >= 0) close_nointr_nofail(s->signal_fd); if (s->syslog_fds) fdset_free(s->syslog_fds); }
static int client_stop(sd_dhcp_client *client, int error) { assert_return(client, -EINVAL); client->receive_message = sd_event_source_unref(client->receive_message); if (client->fd >= 0) close_nointr_nofail(client->fd); client->fd = -1; client->timeout_resend = sd_event_source_unref(client->timeout_resend); client->timeout_t1 = sd_event_source_unref(client->timeout_t1); client->timeout_t2 = sd_event_source_unref(client->timeout_t2); client->timeout_expire = sd_event_source_unref(client->timeout_expire); client->attempt = 1; client_notify(client, error); client->start_time = 0; client->secs = 0; client->state = DHCP_STATE_INIT; if (client->lease) client->lease = sd_dhcp_lease_unref(client->lease); log_dhcp_client(client, "STOPPED"); return 0; }
static int open_dev_autofs(Manager *m) { struct autofs_dev_ioctl param; assert(m); if (m->dev_autofs_fd >= 0) return m->dev_autofs_fd; label_fix("/dev/autofs", false, false); m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY); if (m->dev_autofs_fd < 0) { log_error("Failed to open /dev/autofs: %m"); return -errno; } init_autofs_dev_ioctl(¶m); if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, ¶m) < 0) { close_nointr_nofail(m->dev_autofs_fd); m->dev_autofs_fd = -1; return -errno; } log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor); return m->dev_autofs_fd; }
int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link) { int s, one = 1; assert(index > 0); assert(link); s = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, htons(ETH_P_IP)); if (s < 0) return -errno; link->ll.sll_family = AF_PACKET; link->ll.sll_protocol = htons(ETH_P_IP); link->ll.sll_ifindex = index; link->ll.sll_halen = ETH_ALEN; memset(link->ll.sll_addr, 0xff, ETH_ALEN); if (setsockopt (s, SOL_PACKET, PACKET_AUXDATA, &one, sizeof(one)) < 0) return -errno; if (bind(s, &link->sa, sizeof(link->ll)) < 0) { close_nointr_nofail(s); return -errno; } return s; }
ReadaheadShared *shared_get(void) { int fd; ReadaheadShared *m = NULL; #ifdef ANDROID mkdir(READAHEAD_DIR, 0755); #else mkdir("/run/systemd", 0755); mkdir("/run/systemd/readahead", 0755); #endif if ((fd = open(READAHEAD_DIR "/shared", O_CREAT|O_RDWR|O_CLOEXEC, 0644)) < 0) { log_error("Failed to create shared memory segment: %m"); goto finish; } if (ftruncate(fd, sizeof(ReadaheadShared)) < 0) { log_error("Failed to truncate shared memory segment: %m"); goto finish; } if ((m = mmap(NULL, sizeof(ReadaheadShared), PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { log_error("Failed to mmap shared memory segment: %m"); m = NULL; goto finish; } finish: if (fd >= 0) close_nointr_nofail(fd); return m; }
int dhcp_network_bind_udp_socket(int index, be32_t address, uint16_t port) { int s; union sockaddr_union src = { .in.sin_family = AF_INET, .in.sin_port = htobe16(port), .in.sin_addr.s_addr = address, }; s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); if (s < 0) return -errno; if (bind(s, &src.sa, sizeof(src.in)) < 0) { close_nointr_nofail(s); return -errno; } return s; } int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link, const void *packet, size_t len) { assert(link); assert(packet); assert(len); if (sendto(s, packet, len, 0, &link->sa, sizeof(link->ll)) < 0) return -errno; return 0; }
static void connection_free(Connection *c) { assert(c); if (c->context) set_remove(c->context->connections, c); sd_event_source_unref(c->server_event_source); sd_event_source_unref(c->client_event_source); if (c->server_fd >= 0) close_nointr_nofail(c->server_fd); if (c->client_fd >= 0) close_nointr_nofail(c->client_fd); close_pipe(c->server_to_client_buffer); close_pipe(c->client_to_server_buffer); free(c); }
static void remove_timeout(DBusTimeout *timeout, void *data) { EpollData _cleanup_free_ *e = NULL; assert(timeout); e = dbus_timeout_get_data(timeout); if (!e) return; assert_se(epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_DEL, e->fd, NULL) >= 0); close_nointr_nofail(e->fd); }
void log_close_console(void) { if (console_fd < 0) return; if (getpid() == 1) { if (console_fd >= 3) close_nointr_nofail(console_fd); console_fd = -1; } }
static void remove_watch(DBusWatch *watch, void *data) { EpollData _cleanup_free_ *e = NULL; assert(watch); e = dbus_watch_get_data(watch); if (!e) return; assert_se(epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_DEL, e->fd, NULL) >= 0); if (e->fd_is_dupped) close_nointr_nofail(e->fd); }
void button_free(Button *b) { assert(b); hashmap_remove(b->manager->buttons, b->name); if (b->fd >= 0) { hashmap_remove(b->manager->button_fds, INT_TO_PTR(b->fd + 1)); assert_se(epoll_ctl(b->manager->epoll_fd, EPOLL_CTL_DEL, b->fd, NULL) == 0); close_nointr_nofail(b->fd); } free(b->name); free(b->seat); free(b); }
static void server_done(Server *s) { assert(s); while (s->fifos) fifo_free(s->fifos); if (s->epoll_fd >= 0) close_nointr_nofail(s->epoll_fd); if (s->bus) { dbus_connection_flush(s->bus); dbus_connection_close(s->bus); dbus_connection_unref(s->bus); } }
int fdset_put_dup(FDSet *s, int fd) { int copy, r; assert(s); assert(fd >= 0); if ((copy = fcntl(fd, F_DUPFD_CLOEXEC, 3)) < 0) return -errno; if ((r = fdset_put(s, copy)) < 0) { close_nointr_nofail(copy); return r; } return copy; }
int server_open_dev_kmsg(Server *s) { int r; assert(s); s->dev_kmsg_fd = open("/dev/kmsg", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); if (s->dev_kmsg_fd < 0) { log_full(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, "Failed to open /dev/kmsg, ignoring: %m"); return 0; } r = sd_event_add_io(s->event, &s->dev_kmsg_event_source, s->dev_kmsg_fd, EPOLLIN, dispatch_dev_kmsg, s); if (r < 0) { /* This will fail with EPERM on older kernels where * /dev/kmsg is not readable. */ if (r == -EPERM) { r = 0; goto fail; } log_error("Failed to add /dev/kmsg fd to event loop: %s", strerror(-r)); goto fail; } r = sd_event_source_set_priority(s->dev_kmsg_event_source, SD_EVENT_PRIORITY_IMPORTANT+10); if (r < 0) { log_error("Failed to adjust priority of kmsg event source: %s", strerror(-r)); goto fail; } s->dev_kmsg_readable = true; return 0; fail: if (s->dev_kmsg_event_source) s->dev_kmsg_event_source = sd_event_source_unref(s->dev_kmsg_event_source); if (s->dev_kmsg_fd >= 0) { close_nointr_nofail(s->dev_kmsg_fd); s->dev_kmsg_fd = -1; } return r; }
int loopback_setup(void) { int r, if_loopback; union { struct sockaddr sa; struct sockaddr_nl nl; struct sockaddr_storage storage; } sa; unsigned requests = 0, i; int fd; errno = 0; if ((if_loopback = (int) if_nametoindex("lo")) <= 0) return errno ? -errno : -ENODEV; if ((fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0) return -errno; zero(sa); sa.nl.nl_family = AF_NETLINK; if (bind(fd, &sa.sa, sizeof(sa)) < 0) { r = -errno; goto finish; } if ((r = add_adresses(fd, if_loopback, &requests)) < 0) goto finish; if ((r = start_interface(fd, if_loopback, &requests)) < 0) goto finish; for (i = 0; i < requests; i++) { if ((r = read_response(fd, requests)) < 0) goto finish; } r = 0; finish: if (r < 0) log_warning("Failed to configure loopback device: %s", strerror(-r)); if (fd >= 0) close_nointr_nofail(fd); return r; }
int hwclock_set_time(const struct tm *tm) { int fd; int err = 0; assert(tm); fd = open("/dev/rtc", O_RDONLY|O_CLOEXEC); if (fd < 0) return -errno; if (ioctl(fd, RTC_SET_TIME, tm) < 0) err = -errno; close_nointr_nofail(fd); return err; }
int automount_send_ready(Automount *a, int status) { int ioctl_fd, r; unsigned token; assert(a); assert(status <= 0); if (set_isempty(a->tokens)) return 0; ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id); if (ioctl_fd < 0) { r = ioctl_fd; goto fail; } if (status) log_debug_unit(UNIT(a)->id, "Sending failure: %s", strerror(-status)); else log_debug_unit(UNIT(a)->id, "Sending success."); r = 0; /* Autofs thankfully does not hand out 0 as a token */ while ((token = PTR_TO_UINT(set_steal_first(a->tokens)))) { int k; /* Autofs fun fact II: * * if you pass a positive status code here, the kernel will * freeze! Yay! */ k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd, ioctl_fd, token, status); if (k < 0) r = k; } fail: if (ioctl_fd >= 0) close_nointr_nofail(ioctl_fd); return r; }
int bus_loop_open(DBusConnection *c) { int fd; assert(c); fd = epoll_create1(EPOLL_CLOEXEC); if (fd < 0) return -errno; if (!dbus_connection_set_watch_functions(c, add_watch, remove_watch, toggle_watch, INT_TO_PTR(fd), NULL) || !dbus_connection_set_timeout_functions(c, add_timeout, remove_timeout, toggle_timeout, INT_TO_PTR(fd), NULL)) { close_nointr_nofail(fd); return -ENOMEM; } return fd; }
static dbus_bool_t add_watch(DBusWatch *watch, void *data) { EpollData _cleanup_free_ *e = NULL; struct epoll_event ev; assert(watch); e = new0(EpollData, 1); if (!e) return FALSE; e->fd = dbus_watch_get_unix_fd(watch); e->object = watch; e->is_timeout = false; zero(ev); ev.events = bus_flags_to_events(watch); ev.data.ptr = e; if (epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_ADD, e->fd, &ev) < 0) { if (errno != EEXIST) return FALSE; /* Hmm, bloody D-Bus creates multiple watches on the * same fd. epoll() does not like that. As a dirty * hack we simply dup() the fd and hence get a second * one we can safely add to the epoll(). */ e->fd = dup(e->fd); if (e->fd < 0) return FALSE; if (epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_ADD, e->fd, &ev) < 0) { close_nointr_nofail(e->fd); return FALSE; } e->fd_is_dupped = true; } dbus_watch_set_data(watch, e, NULL); e = NULL; /* prevent freeing */ return TRUE; }
static void bit_toggle(const char *fn, uint64_t p) { uint8_t b; ssize_t r; int fd; fd = open(fn, O_RDWR|O_CLOEXEC); assert(fd >= 0); r = pread(fd, &b, 1, p/8); assert(r == 1); b ^= 1 << (p % 8); r = pwrite(fd, &b, 1, p/8); assert(r == 1); close_nointr_nofail(fd); }
static void fifo_free(Fifo *f) { assert(f); if (f->server) { assert(f->server->n_fifos > 0); f->server->n_fifos--; LIST_REMOVE(Fifo, fifo, f->server->fifos, f); } if (f->fd >= 0) { if (f->server) epoll_ctl(f->server->epoll_fd, EPOLL_CTL_DEL, f->fd, NULL); close_nointr_nofail(f->fd); } free(f); }
int open_inotify(void) { int fd; if ((fd = inotify_init1(IN_CLOEXEC|IN_NONBLOCK)) < 0) { log_error("Failed to create inotify handle: %m"); return -errno; } mkdir("/run/systemd", 0755); mkdir("/run/systemd/readahead", 0755); if (inotify_add_watch(fd, "/run/systemd/readahead", IN_CREATE) < 0) { log_error("Failed to watch /run/systemd/readahead: %m"); close_nointr_nofail(fd); return -errno; } return fd; }
static int ipv4ll_stop(sd_ipv4ll *ll, int event) { assert(ll); ll->receive_message = sd_event_source_unref(ll->receive_message); if (ll->fd >= 0) close_nointr_nofail(ll->fd); ll->fd = -1; ll->timer = sd_event_source_unref(ll->timer); ipv4ll_client_notify(ll, event); ll->claimed_address = 0; ipv4ll_set_state (ll, IPV4LL_STATE_INIT, 1); log_ipv4ll(ll, "STOPPED"); return 0; }
static void unmount_autofs(Automount *a) { assert(a); if (a->pipe_fd < 0) return; automount_send_ready(a, -EHOSTDOWN); a->pipe_event_source = sd_event_source_unref(a->pipe_event_source); close_nointr_nofail(a->pipe_fd); a->pipe_fd = -1; /* If we reload/reexecute things we keep the mount point * around */ if (a->where && (UNIT(a)->manager->exit_code != MANAGER_RELOAD && UNIT(a)->manager->exit_code != MANAGER_REEXECUTE)) repeat_unmount(a->where); }