#include #include #include #include #include #include #include #include #include #include #include #include #include #include "ldm.h" #include "ldmutils.h" /* * rc_files * * Run startup commands. */ void rc_files(char *action) { GPid rcpid; gchar *command; command = g_strjoin(" ", "/bin/sh", RC_DIR "/ldm-script", action, NULL); rcpid = ldm_spawn(command, NULL, NULL, NULL); ldm_wait(rcpid); g_free(command); } /* * get_ipaddr * Get ip address of host */ void get_ipaddr() { int numreqs = 10; struct ifconf ifc; struct ifreq *ifr; /* netdevice(7) */ struct ifreq info; struct sockaddr_in *sa; int skfd, n; skfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); if (skfd < 0) die("ldm","socket"); /* * Get a list of all the interfaces. */ ifc.ifc_buf = NULL; while (TRUE) { ifc.ifc_len = sizeof(struct ifreq) * numreqs; ifc.ifc_buf = (char *)realloc(ifc.ifc_buf, ifc.ifc_len); if (ifc.ifc_buf == NULL) die("ldm","out of memory"); if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) { log_entry("ldm",4,"SIOCGIFCONF"); goto out; } if (ifc.ifc_len == (int)sizeof(struct ifreq) * numreqs){ /* assume it overflowed and try again */ numreqs += 10; continue; } break; } /* * Look for the first interface that has an IP address, is not * loopback, and is up. */ ifr = ifc.ifc_req; for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) { if (ifr->ifr_addr.sa_family != AF_INET) continue; strcpy(info.ifr_name, ifr->ifr_name); if (ioctl(skfd, SIOCGIFFLAGS, &info) < 0) { log_entry("ldm",4,"SIOCGIFFLAGS"); goto out; } if (!(info.ifr_flags & IFF_LOOPBACK) && (info.ifr_flags & IFF_UP)) { sa = (struct sockaddr_in *) &ifr->ifr_addr; ldm.ipaddr = g_strdup(inet_ntoa(sa->sin_addr)); break; } ifr++; } out: if (ifc.ifc_buf) free(ifc.ifc_buf); if (n == ifc.ifc_len) die("ldm","no configured interface found"); } /* * ldm_spawn: * * Execute commands. Prints nice error message if failure. */ GPid ldm_spawn(gchar *command, gint *rfd, gint *wfd, GSpawnChildSetupFunc setup) { GPid pid; GError *error = NULL; GSpawnFlags flags = G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD; gint argc; gchar **argv = NULL; g_shell_parse_argv (command, &argc, &argv, NULL); if (!wfd) flags |= G_SPAWN_STDOUT_TO_DEV_NULL; g_spawn_async_with_pipes ( NULL, /* Working directory: inherit */ argv, /* Arguments, null term */ NULL, /* Environment, inherit from parent */ flags, /* Flags, set above */ setup, /* Child setup function: passed to us */ NULL, /* No user data */ &pid, /* child pid */ wfd, /* Pointer to in file descriptor */ rfd, /* Pointer to out file descriptor */ NULL, /* No stderr */ &error); /* GError handler */ g_strfreev(argv); if (error) { log_entry("ldm",3,"ldm_spawn failed to execute: %s", error->message); } else { log_entry("ldm",7,"ldm_spawn: pid = %d", pid); } return pid; } /* * handle_sigchld * * Handle sigchld's for ldm processes. Empty function, * since we wait for things to happen in order via * ldm_wait */ void handle_sigchld(int signo) { /* do nothing */ child_exited = TRUE; } /* * ldm_wait * * wait for child process */ void ldm_wait(GPid pid) { siginfo_t info; log_entry("ldm",7,"waiting for process: %d", pid); do { int res; res = waitid (P_PID, pid, &info, WEXITED | WSTOPPED); if (res == -1) { int temp; temp = errno; log_entry("ldm",4,"waitid returned an error: %s", strerror(errno)); if(temp == ECHILD) { break; } } else { if (info.si_pid == pid) { /* * The process we were waiting for exited, * so break out of the loop. */ break; } else { log_entry("ldm",4,"unexpected terminated process, pid: %d", info.si_pid); unexpected_child = TRUE; } } } while (TRUE); if (info.si_code == CLD_EXITED) { log_entry("ldm",7,"process %d exited with status %d", info.si_pid, WEXITSTATUS(info.si_status)); } else if (info.si_code == CLD_KILLED) { log_entry("ldm",7,"process %d killed by signal %d", info.si_pid, info.si_status); } } /* * close_wm * Close window manager by SIGKILL */ void close_wm() { if (!(ldm.wmpid)) { return; } log_entry("ldm",7,"closing window manager"); if (kill(ldm.wmpid, SIGKILL) < 0) { log_entry("ldm",3,"sending SIGKILL to window manager failed"); } ldm_wait(ldm.wmpid); ldm.wmpid = 0; }