Skip to content

Commit 3a19279

Browse files
committed
librc: fix unnecessary copying parent memory page table
posix_spawn() is a more lightweight and modern alternative to fork()/exec(), which are used inside popen(). The main advantage of posix_spawn is that it can create a new process without completely duplicating the address space of the parent process. References: - https://blog.famzah.net/2018/12/19/posix_spawn-performance-benchmarks-and-usage-examples/ - https://lobste.rs/s/smbsd5/fork_road - https://www.reddit.com/r/C_Programming/comments/1lvdhp2/fork_vs_posix_spawn/
1 parent 584444d commit 3a19279

1 file changed

Lines changed: 20 additions & 2 deletions

File tree

src/librc/librc-depend.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <sys/stat.h>
2828
#include <time.h>
2929
#include <unistd.h>
30+
#include <spawn.h>
3031

3132
#include "queue.h"
3233
#include "librc.h"
@@ -35,6 +36,8 @@
3536

3637
#define GENDEP RC_LIBEXECDIR "/sh/gendepends.sh"
3738

39+
extern char **environ;
40+
3841
static const char *bootlevel = NULL;
3942

4043
static char *
@@ -791,12 +794,27 @@ rc_deptree_update(void)
791794
bool retval = true;
792795
const char *sys = rc_sys();
793796
int serrno;
797+
pid_t pid;
798+
char *argv[] = { "sh", "-c", GENDEP, NULL };
799+
int pipe_fd[2];
794800

795801
/* Phase 1 - source all init scripts and print dependencies */
796802
setup_environment();
797-
if (!(fp = popen(GENDEP, "r")))
803+
if (pipe(pipe_fd) == -1)
798804
return false;
799805

806+
if (posix_spawnp(&pid, argv[0], NULL, NULL, argv, environ) != 0) {
807+
close(pipe_fd[0]);
808+
close(pipe_fd[1]);
809+
return false;
810+
}
811+
close(pipe_fd[1]);
812+
fp = fdopen(pipe_fd[0], "r");
813+
if (!fp) {
814+
close(pipe_fd[0]);
815+
return false;
816+
}
817+
800818
config = rc_stringlist_new();
801819

802820
deptree = make_deptree();
@@ -876,7 +894,7 @@ rc_deptree_update(void)
876894
}
877895
}
878896
free(line);
879-
pclose(fp);
897+
fclose(fp);
880898

881899
/* Phase 2 - if we're a special system, remove services that don't
882900
* work for them. This doesn't stop them from being run directly. */

0 commit comments

Comments
 (0)