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
This commit is contained in:
Denis Vlasenko 2007-11-10 01:28:19 +00:00
parent 9bd8d0c23e
commit d031b203c7
2 changed files with 30 additions and 32 deletions

View 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;
}

View 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");
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();
}