syslogd: support "symlink to symlink" for /dev/log; reduce stack usage
authorDenis Vlasenko <vda.linux@googlemail.com>
Sat, 10 Nov 2007 01:28:19 +0000 (01:28 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Sat, 10 Nov 2007 01:28:19 +0000 (01:28 -0000)
function                                             old     new   delta
create_socket                                          -     134    +134
syslogd_main                                        1132     865    -267
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 0/1 up/down: 134/-267)         Total: -133 bytes
   text    data     bss     dec     hex filename
 775603     974    9420  785997   bfe4d busybox_old
 775445     974    9420  785839   bfdaf busybox_unstripped

libbb/xreadlink.c
sysklogd/syslogd.c

index 0b6eb05f3fae2f2a17b3bfa5d5baa5335827fa67..706a3d9fff98f5ac5ecc31f6108551646ae4e2cb 100644 (file)
@@ -65,7 +65,7 @@ char *xmalloc_follow_symlinks(const char *path)
 
                if (!--looping) {
                        free(linkpath);
-free_buf_ret_null:
+ free_buf_ret_null:
                        free(buf);
                        return NULL;
                }
index da63ced4261a25cca5d59fea09aadb38843845af..e3abcc7cbb938d51b143214cb7a9cc0f17ac88c9 100644 (file)
@@ -467,13 +467,39 @@ static void do_mark(int sig)
 }
 #endif
 
-static void do_syslogd(void) ATTRIBUTE_NORETURN;
-static void do_syslogd(void)
+/* Don't inline: prevent struct sockaddr_un to take up space on stack
+ * permanently */
+static NOINLINE int create_socket(void)
 {
        struct sockaddr_un sunx;
        int sock_fd;
        char *dev_log_name;
 
+       memset(&sunx, 0, sizeof(sunx));
+       sunx.sun_family = AF_UNIX;
+
+       /* Unlink old /dev/log or object it points to. */
+       /* (if it exists, bind will fail) */
+       strcpy(sunx.sun_path, "/dev/log");
+       dev_log_name = xmalloc_follow_symlinks("/dev/log");
+       if (dev_log_name) {
+               safe_strncpy(sunx.sun_path, dev_log_name, sizeof(sunx.sun_path));
+               free(dev_log_name);
+       }
+       unlink(sunx.sun_path);
+
+       sock_fd = xsocket(AF_UNIX, SOCK_DGRAM, 0);
+       xbind(sock_fd, (struct sockaddr *) &sunx, sizeof(sunx));
+       chmod("/dev/log", 0666);
+
+       return sock_fd;
+}
+
+static void do_syslogd(void) ATTRIBUTE_NORETURN;
+static void do_syslogd(void)
+{
+       int sock_fd;
+
        /* Set up signal handlers */
        signal(SIGINT, quit_signal);
        signal(SIGTERM, quit_signal);
@@ -487,36 +513,8 @@ static void do_syslogd(void)
        signal(SIGALRM, do_mark);
        alarm(G.markInterval);
 #endif
-       remove_pidfile("/var/run/syslogd.pid");
-
-       memset(&sunx, 0, sizeof(sunx));
-       sunx.sun_family = AF_UNIX;
-       strcpy(sunx.sun_path, "/dev/log");
+       sock_fd = create_socket();
 
-       /* Unlink old /dev/log or object it points to. */
-       /* (if it exists, bind will fail) */
-       logmode = LOGMODE_NONE;
-       dev_log_name = xmalloc_readlink_or_warn("/dev/log");
-       logmode = LOGMODE_STDIO;
-       if (dev_log_name) {
-               int fd = xopen(".", O_NONBLOCK);
-               xchdir("/dev");
-               /* we do not check whether this is a link also */
-               unlink(dev_log_name);
-               fchdir(fd);
-               close(fd);
-               safe_strncpy(sunx.sun_path, dev_log_name, sizeof(sunx.sun_path));
-               free(dev_log_name);
-       } else {
-               unlink("/dev/log");
-       }
-
-       sock_fd = xsocket(AF_UNIX, SOCK_DGRAM, 0);
-       xbind(sock_fd, (struct sockaddr *) &sunx, sizeof(sunx));
-
-       if (chmod("/dev/log", 0666) < 0) {
-               bb_perror_msg_and_die("cannot set permission on /dev/log");
-       }
        if (ENABLE_FEATURE_IPC_SYSLOG && (option_mask32 & OPT_circularlog)) {
                ipcsyslog_init();
        }