私は特別なLinux環境を持っています。すべてのファイルとフォルダは読み取り専用で、G++がインストールされています。もう走れませんsudo
。 C++ プログラムを実行できます。別のC ++コードをコンパイルしたいので、次のようなコードを書いています。
#include<iostream>
#include<string>
#include<cassert>
#include<unistd.h>
#include<wait.h>
#include<sys/mman.h>
constexpr char GPPPATH[]="/bin/g++";
int compile(std::string const& program){
int exefid=memfd_create("exe",0);
int subpid=fork();
assert(subpid!=-1);
if (subpid==0){
int pid=getpid();
int programfid=memfd_create("program",0);
write(programfid,program.c_str(),program.size());
std::string const programPath="/proc/"+std::to_string(pid)+"/fd/"+std::to_string(programfid);
std::string const ExePath="/proc/"+std::to_string(pid)+"/fd/"+std::to_string(exefid);
dup2(fileno(stdout),fileno(stderr));
execl(GPPPATH,GPPPATH,"-xc++",programPath.c_str(),"-o",ExePath.c_str(),NULL);
throw;
}else{
int status;
waitpid(subpid,&status,0);
if (!WIFEXITED(status)) throw;
}
return exefid;
}
int main(int argc,char** argv,char** envp){
int fid=compile("""#include<bits/stdc++.h>\nint main(){std::cout<<\"IAKIOI\";}""");
fexecve(fid,argv,envp);
}
私が使用した出力ファイルを保存するのはmemfd_create
もちろん動作しませんでした。 G ++はディスクに一時ファイルを作成しようとしましたが、失敗しました。ディスク書き込みなしでg ++でC ++をコンパイルする方法はありますか?
また、試してみました-pipe
が、まだ一時ファイルが生成されていることがわかりました。
╭─ /tmp 21:12:45
╰─❯ cat tmp.cpp
#include<bits/stdc++.h>
int main(){std::cout<<114514;}
╭─ /tmp 21:12:48
╰─❯ strace g++ -pipe tmp.cpp -o tmp 2>&1 | grep "/tmp"
getcwd("/tmp", 1024) = 5
readlink("/tmp/tmp.cpp", 0x7ffc1ec38d50, 1023) = -1 EINVAL (无效的参数)
getcwd("/tmp", 1024) = 5
readlink("/tmp/tmp", 0x7ffc1ec38d50, 1023) = -1 EINVAL (无效的参数)
access("/tmp", R_OK|W_OK|X_OK) = 0
newfstatat(AT_FDCWD, "/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=20504576, ...}, 0) = 0
openat(AT_FDCWD, "/tmp/ccolfqPz.o", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
openat(AT_FDCWD, "/tmp/cckzgSEX.res", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
newfstatat(AT_FDCWD, "/tmp/cckzgSEX.res", {st_mode=S_IFREG|0600, st_size=0, ...}, 0) = 0
unlink("/tmp/cckzgSEX.res") = 0
newfstatat(AT_FDCWD, "/tmp/ccolfqPz.o", {st_mode=S_IFREG|0600, st_size=2064, ...}, 0) = 0
unlink("/tmp/ccolfqPz.o") = 0
私のマウントは/proc/mounts
/dev/vda1 /etc/passwd ext4 ro,nosuid,relatime,errors=remount-ro 0 0
/dev/vda1 /etc/terminfo ext4 ro,nosuid,relatime,errors=remount-ro 0 0
/dev/vda1 /usr/lib/locale/locale-archive ext4 ro,nosuid,relatime,errors=remount-ro 0 0
proc /proc proc ro,nosuid,relatime 0 0
udev /dev devtmpfs ro,nosuid,relatime,size=11892204k,nr_inodes=2973051,mode=755 0 0
/dev/vda1 /nix ext4 ro,nosuid,relatime,errors=remount-ro 0 0
/dev/vda1 /tmp/exec_ir9g3uq9 ext4 ro,nosuid,relatime,errors=remount-ro 0 0
none /proc proc rw,nosuid,noexec,relatime,hidepid=invisible 0 0
none /proc/sys tmpfs ro,nosuid,relatime,size=0k 0 0
答え1
もちろん、TMPDIR
呼び出しgcc
(またはg++
他のGCCコンパイラ)の前に環境変数を設定してください。インストールパスに設定しますtmpfs
。あなた/tmp
の、またはすでに/run
その/run/user/$(id -u)/
ようなtmpfsマウントがあるかもしれません! (mount
たとえば、このクラスの出力を確認してくださいmount | grep tmpfs
。)
そのようなマウントを作成する必要がある場合、
sudo mount -t tmpfs -o size=10M tmpfs /path/to/empty/directory