Witam czy w Linux jest jakaś funkcja systemowa która pozwoli mi odnaleźć binarke danego procesu. Chodzi o to że jak używam fork() to najpierw zwracam pid dziecka i dopisuje go do mapy, następnie jest druga instancja pid == 0 i temu dziecku podmieniam binarke na taką jaką potrzebuje. Ale tu pojawia się problem bo jak execl nie wykona się poprawnie to mam rodzica a w mapie mam tak naprawdę klon rodzica. Dlatego chce poszukiwać później mapę i porównywać binarki. Gdzieś słyszałem ze jest w linux funkcja systemowa do tego, ale nie chodzi mi o readlink.
Masz zapisany w rodzicu pid potomka.
W potomku wołasz exec, który failuje.
Co chcesz zrobić jak ten exec się wysypie?
EDIT:
jeżeli chcesz powiązać wprost PID z binarką... kombinowałeś już z zawartością /proc/pid_dziecka
?
#include <unistd.h>
#include <iostream>
#include <string>
#include <cstdio>
#include <map>
#include <cstdlib>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sstream>
#include <fstream>
#include <iostream>
using namespace std;
std::string pathToChildBinary[1] = {
// "/home/edmaatn/testfork/loop1"
};
int array[1];
int startProcess(std::string name);
string pathToBinaryProcess(int pid);
int main(int argc, char *argv[]) {
string pathToParrentBinary = pathToBinaryProcess(getpid());
cout << "path to parrent binary : " << pathToParrentBinary << endl;
for (int index = 0; index < 1; ++index)
{
array[index] = startProcess( pathToChildBinary[index] );
}
usleep(500);
cout << "childPid: " << array[0] << " getppid() " << getppid() << endl;
string pathToChildBinary = pathToBinaryProcess(/*childPid*/array[0]);
cout << "path to child binary : " << pathToChildBinary << endl;
cout << "path to parrent binary : " << pathToParrentBinary << endl;
if (pathToParrentBinary == pathToChildBinary)
printf("nie\n");
if (pathToParrentBinary != pathToChildBinary)
printf("ok\n");
// }
return 0;
}
int startProcess(std::string name) {
pid_t pid = fork();
cout << "startProcess: pid: " << pid << " getpid(): " << getpid() << endl;
cout << "path to binary getpid(): " << pathToBinaryProcess(getpid()) << endl;
if (pid == -1) {
exit(0);
} else if (pid == 0) {
execl(name.c_str(),name.c_str(),NULL);
cerr << "failed load binary " << name << endl;
exit(0);
}
return pid;
}
string pathToBinaryProcess(int pid) {
stringstream processCmdline;
processCmdline << "/proc/" << pid << "/cmdline";
string pathToProcessBinary;
ifstream myfile(processCmdline.str().c_str());
if (myfile.is_open())
getline(myfile, pathToProcessBinary);
else
cerr << "error open file: " << pathToProcessBinary << endl;
return pathToProcessBinary;
}
a to jest output:
path to parrent binary : ./main
startProcess: pid: 22060 getpid(): 22059
path to binary getpid(): ./main
startProcess: pid: 0 getpid(): 22060
path to binary getpid(): ./main
childPid: 22060 getppid() 30504
path to child binary : ./main
path to parrent binary : ./main
nie
chodzi o to ze zwsze jest porównany rodzic do klona i jest nie ok a dopiero później jest podmieniana binarka. Słyszałem że jest jakaś funkcja systemowa która porównuje processy
chyba chodziło o scieżki do binarki
Tu masz pętle for - to całkiem nieźle gmatwa sprawę:
https://stackoverflow.com/questions/26793402/visually-what-happens-to-fork-in-a-for-loop
To swoją drogą. Ale Bogiem a prawdą to póki się binarka nie podmieni to co Ty chcesz sprawdzać skoro to ciągle odpala się jeden i ten sam program?
Inaczej: co Ty kombinujesz i do czego Ci to potrzebne dokładnie?
BTW, po forkach wołaj wait
albo podobne funkcje...
Co dostaje execl jako nazwę binarki do uruchomienia?
std::string pathToChildBinary[1] = {
// "/home/edmaatn/testfork/loop1"
};
Jak zrobić wiat() po fork(). A przypadkiem nie jest tak że wait() czeka na skończenie sie procesu potomnego?
Jest taki magiczny plik /proc/pid/exe
, który można wykonać.
@enedil ale póki nie exec się nie wykona nic mu to nie da.
To może tak, czy jest jakiś sposób, żeby po fork() zamiast od razu wykonać proces rodzica to wykonał by się proces dziecka. Albo by poczekał i dopiero, wtedy gdy rodzic czeka to wykonuje się proces dziecka. I nie mówię tu o funkcji wait(), dlatego że tak funkcja czeka aż proces dziecka się zakończy a ja chce by te procesy działały jednakowo.
Nie bezpośrednio. Możesz co najwyżej synchronizować program(y) w pewnych punktach korzystając z semaforów lub podobnych struktur. Na problem XY mi to wygląda. Co dokładnie starasz się zrobić?
Mam taki problem, startuje sobie powiedzmu jakiś proces główny i on ma w sobie liste nazw procesów które powinnien wystartować. I tu mam pętelke po ilości tych procesów, każdy iteracja wykonuje fork i w porcesie dziecka podmienia binarke. I praktycznie jest ok, nawet sam nigdy nie dostrzegłęm problemu ktoś mi dopiero pokazał. Wystarczyło podmienić nazwe procesu i sie wykrzaczyło, a statło sie to ze maiłem dwa procesu głowne i zaczeły później razem wywoływać dalsze procesu i wszystko sie popsuło. Teraz mam taki problem, bo chce by proces rodzica jednak poczekal az dziecko podmieni binarke. Wtedy mogę od razu spradzić czy te dwa procesu maja róźne binarki. W programi jest jeszcze ustawienie zmiennych środowiskowych ale nie wiem czy to ma coś z tym wspólnego. Wiem że funkcja systemowa wait() nic nie da bo ona czeka aż proces się zakończy a moje mają chodzi równolegle, nie czekam na ich zakończenie.
fork() może być nieintuicyjny.
Może zamiast niego spróbuj Boost::Process?
Kilka opcji na szybko (niekoniecznie dobrych, do przemyślenia):
jeżeli exec się wyłoży to potomek powiadamia rodzica, w przeciwnym przypadku rodzic zakłada, że działa okej.
użycie fukcji "system" lub podobnej.
Myślałem o użyciu inotify
na /proc
ale wg dokumentacji to jest ograniczone albo wcale nie działa.
EDIT: boost też się nada. Chyba nawet najlepiej.
Mam pytanie bo szukam wykorzystania system z execl ale nie moge znaleźć.
Zarejestruj się i dołącz do największej społeczności programistów w Polsce.
Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.