+static int wait_for_write(int fd, int timeout) {
+ fd_set rfds;
+ struct timeval tv;
+ int result;
+
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+
+ result = select(fd + 1, &rfds, NULL, NULL, &tv);
+ if (result < 0) {
+ perror("select");
+ return 0;
+ }
+ if (result == 0) {
+ /* Timeout. */
+ return 0;
+ }
+
+ /* Got more data to read. */
+ return 1;
+}
+
+#ifdef USE_UTMPX
+static void drop_privileges(void) {
+ uid_t uid, ruid, euid, suid;
+ gid_t gid, rgid, egid, sgid;
+
+ uid = getuid();
+ gid = getgid();
+
+ /* Drop all privileges. */
+ if (setresgid(gid, gid, gid) != 0) {
+ perror("setresgid");
+ exit(EXIT_FAILURE);
+ }
+ if (setresuid(uid, uid, uid) != 0) {
+ perror("setresuid");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Verify all privileges were dropped. */
+ if (getresuid(&ruid, &euid, &suid) != 0) {
+ perror("getresuid");
+ exit(EXIT_FAILURE);
+ }
+ if (getresgid(&rgid, &egid, &sgid) != 0) {
+ perror("getresgid");
+ exit(EXIT_FAILURE);
+ }
+ if (uid == ruid && uid == euid && uid == suid
+ && gid == rgid && gid == egid && gid == sgid) {
+ /* Everything fine. */
+ return;
+ }
+
+ fprintf(stderr, "failed to drop privileges, aborting\n");
+ exit(EXIT_FAILURE);
+}
+#endif
+