From d031b203c7ea7f5fe7ba8dfb16693bc91b3feaea Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Sat, 10 Nov 2007 01:28:19 +0000 Subject: [PATCH] syslogd: support "symlink to symlink" for /dev/log; reduce stack usage 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 | 2 +- sysklogd/syslogd.c | 60 ++++++++++++++++++++++------------------------ 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c index 0b6eb05f3..706a3d9ff 100644 --- a/libbb/xreadlink.c +++ b/libbb/xreadlink.c @@ -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; } diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index da63ced42..e3abcc7cb 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -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"); + sock_fd = create_socket(); - memset(&sunx, 0, sizeof(sunx)); - sunx.sun_family = AF_UNIX; - strcpy(sunx.sun_path, "/dev/log"); - - /* 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(); }