Read multiple times in a single named pipe - c

I got a school project and been searching for hours on how to prevent my program to terminate when it reads one "message" through pipe.
The goal is to have a 'server' waiting for requests from clients, and obviously clients that can send requests to this server.
I have 2 executables 1 for server, and 1 for clients (that can be executed multiple times if you want multiple requests at the same time)
Notice that when the server receives a request, it must creates a process (fork) that will do the necessary job, meanwhile the main process can still receive more requests
Everything works absolutely fine when I do a request, the problem is that it terminates the server execution, and I have no clue on how to prevent it.
Here is the code that receives the request from client from pipe, I removed a lot a things that are used for the calculations I got to do but it doesn't affect my problem
server.c :
if(read(**pipe**,buffer,REQUEST_LENGTH) != REQUEST_LENGTH){
perror("read");
exit(EXIT_FAILURE);
}
pid_t worker = fork();
if(worker == -1){
perror("fork");
exit(EXIT_FAILURE);
}
//SOME UNINTERESTING THINGS
exit(EXIT_SUCCESS);
}
}
On termination of server.c, perror says "Read : Success"

If, at any time after a reader has opened a FIFO successfully (meaning that there was a writer at that time), there are no writers left on the FIFO, then the reader gets EOF each time it reads from the FIFO (which can easily end up as a busy loop). If the reader closes the FIFO after receiving EOF and reopens it, it will hang in the open using no resources until another process opens the FIFO for writing.
There is some code available in my SOQ (Stack Overflow Questions) repository on GitHub as files fifo-*-41.[ch] in the src/so-4825-2451 sub-directory. The code was prepared as an answer to another question, but there was a simpler solution to that particular problem that someone else provided, so I never posted the code explicitly.
There are two programs:
fifo-rdr-41 which reads data from a FIFO.
fifo-wrt-41 which writes data to a FIFO.
You could run the reader in one terminal window and the writer in a second terminal window. If you simply run fifo-rdr-41, it will continue to try reading after getting an EOF, but there is a random delay of 250-750 ms between attempts. If you run fifo-rdr-41 -r, then it will reopen the FIFO after receiving EOF. If you run fifo-rdr-41 -w, then it will also open the FIFO for writing (and fifo-rdr-41 -r -w is legitimate too).
In the second terminal, run fifo-wrt-41 repeatedly to send data to the FIFO. You could arrange to run multiple copies in parallel if you wanted too. There are no controls; it writes a random number of blocks of random upper-case letters, with a 250-750 ms random delay between writes and another random delay before closing the FIFO.
Example 1 — Reader keeps FIFO open after receiving EOF
Terminal 1: fifo-rdr-41
fifo-rdr-41: 2022-12-31 21:43:18.965 - pid=71914: Creating FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:43:18.966 - pid=71914: Open FIFO './test-fifo' for reading
fifo-rdr-41: 2022-12-31 21:44:13.330 - pid=71914: FIFO './test-fifo' opened for reading
fifo-rdr-41: 2022-12-31 21:44:13.330 - pid=71914: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:13.915 - pid=71914: 893 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:13.915 - pid=71914: Data: [BRIJVUSAANMQOOEWDHXWQCQRVEZLVIPMSDSXHYVDTAGLXPPCUMAZMQLNYHWMWHRZRWHJWXOZYEMUCZXLYFDEFUBSPVICPYVMFWXMZIVZLKFWLFAJWTDBQDWZPEWHXKFXSFJJNUDRZGQQBZMFAQDBYCIUSKPQHQDIDRKIEHNELCSAVHPLYXXLALRJNNVNIVJZWVVPSISUEGTGIISUQZJYVHZLKSMIWTHPOWZJCMMDHMVCCQZPXXRTZOYVEJUIOCYBMRBPBVJYBFZNMZIJDUTVISHLXAGRYOGRYKKOHVONMHTOUSBNBJEYENWADHXYNNCIYEKGXGPPUYRLTNAZROBHWKLDMXHILZXVKRPKUIZXQOOTTKVRMZNDSBRYXGWRZBSQPRPXZSVERASKOLMQQGQFCAXCQMKEHVSRGVFROCQLCLZGNLDLSLQOSKMKWPLJUNCZNTPNXNLIABVBGGTNWGAKTNXZHVHMQAXXKKQWMATQGHIMQCWGGSXGSZDPMJOZMFUJGHPFQHGJTWICLHNKGQGDDZVYGLOBXKUPDXJSEILVVRHNCHKWNKGQMOHCIKXDMQNMSCNPZIXKWEUVOZZCCVCQMFGMUFJJNGSNUCBPDPREEJOCVRUHEILCASMATNJKLDHZWAIJMRBORJLWDUGBTAWKETBNFBZNYJZDKYAOQLERLGWMCNOGWLCYJAFIFCIOMFZEPVRPDAQOGFUAVQOAXPMRBDHBUXSEFRJWSWCEBDFISPGIZOUENNRIEEPBCULDCDMUOSBDQFJYJSAMXZNPZHEEMOLLMAUJDUXGMISSHVWPPFGBJTLDVZMKNYISUXMRQLCTPBPIXATAJFNOJSSAJMSUOQDFGFYBVONMTYQBEWLHGSOVCTWKPWMGAELQGTCZE]
fifo-rdr-41: 2022-12-31 21:44:13.915 - pid=71914: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:14.309 - pid=71914: 496 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:14.309 - pid=71914: Data: [CXDXBNJWJFGRHDNHQEEZSVQELRWCYXKGJVYYCVPFAUTKSNJUNPRVMSFSVXZLWZPMQEWEBXMTEYGUXHRDAJPUODMWUYRFFXFQTGACHSAPTTKBPPYNBXWSTSRXAHQTVEMJUSEKYUEMGMSDSRAUASZPSYKDCULMHYYKZJKXIBAYGPICTEUVQAIWWSDVGEYVOCPERGJTDPYKSGFKEGTJTUFVHUZWSSNONMKCPRBCCPVMKOPNPOIYATQRRCQPOJFRDTEOCPHNJTHLCZBLXPVCQPOWZPWWWEOHCZTYZPATCNQYRPRWXYTSGLJCHONDYZLVRLXMEMRZLUMKJLZXSTEVQGXJLFSLUMCCFAYLDIXLATVACDXVNEEVQSRUWWVWPYBNUHETWTRCHSIRGVCQZTQWWEAQSEKCSHGOJVOGURPVVIODYCEQBNXHBNMBGHHQBKQRRAZINNZUBJBQNPTXLPFVUNPJBRAITXPNJQHXAXMMATRKZNVMFRTT]
fifo-rdr-41: 2022-12-31 21:44:14.309 - pid=71914: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:14.935 - pid=71914: 0 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:14.935 - pid=71914: Napping 0.557 seconds
fifo-rdr-41: 2022-12-31 21:44:15.495 - pid=71914: Woke up 0.557 seconds later
fifo-rdr-41: 2022-12-31 21:44:15.495 - pid=71914: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:15.495 - pid=71914: 0 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:15.495 - pid=71914: Napping 0.499 seconds
fifo-rdr-41: 2022-12-31 21:44:15.996 - pid=71914: Woke up 0.499 seconds later
fifo-rdr-41: 2022-12-31 21:44:15.996 - pid=71914: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:15.996 - pid=71914: 0 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:15.996 - pid=71914: Napping 0.323 seconds
fifo-rdr-41: 2022-12-31 21:44:16.323 - pid=71914: Woke up 0.323 seconds later
fifo-rdr-41: 2022-12-31 21:44:16.323 - pid=71914: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:16.323 - pid=71914: 0 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:16.323 - pid=71914: Napping 0.408 seconds
fifo-rdr-41: 2022-12-31 21:44:16.734 - pid=71914: Woke up 0.408 seconds later
fifo-rdr-41: 2022-12-31 21:44:16.734 - pid=71914: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:16.734 - pid=71914: 0 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:16.734 - pid=71914: Napping 0.680 seconds
fifo-rdr-41: 2022-12-31 21:44:17.416 - pid=71914: Woke up 0.680 seconds later
fifo-rdr-41: 2022-12-31 21:44:17.416 - pid=71914: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:17.416 - pid=71914: 0 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:17.416 - pid=71914: Napping 0.522 seconds
fifo-rdr-41: 2022-12-31 21:44:17.941 - pid=71914: Woke up 0.522 seconds later
fifo-rdr-41: 2022-12-31 21:44:17.941 - pid=71914: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:17.941 - pid=71914: 0 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:17.941 - pid=71914: Napping 0.294 seconds
fifo-rdr-41: 2022-12-31 21:44:18.235 - pid=71914: Woke up 0.294 seconds later
fifo-rdr-41: 2022-12-31 21:44:18.235 - pid=71914: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:18.524 - pid=71914: 351 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:18.524 - pid=71914: Data: [OORFJGIYUKOWERSICRKHRQRSRDOYRWDLBQCGPPUPFMUTEDHLAJINRWUBYDCFLTDGIAXNPPDQDRCQPVZLEGNJSONSJUTXYEAQDMUXDYFKBUQDNWFCJNXGSLCJVJOCPCHKOERUOJAJUINWTBYOYVAKFOMJPBDCSCMDNVKKRRPJUJKCTCGVGGHIUXVXGAKQFCKVQIUXRNDMUEARVZWRXNOOLYPJHYCBVBMMJEDBKSLGEQFHXVZAUTCMDUFWWHKZNJWVBUCJDJJPWIFMWONIRVPQFTTVZWMVNXCLJOWUFZKUACZAPBJXAEGRJARZALSLWLEXUFEPMNIUTFISQUZNEXKLVCNZNUGVMWM]
fifo-rdr-41: 2022-12-31 21:44:18.524 - pid=71914: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:19.023 - pid=71914: 465 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:19.023 - pid=71914: Data: [DYZJOTBGVECGSGBNYNTCVPUSTQGIQQSYTMXWZOQLBUQMGFPILPRIRGTOZFKNHERVCXLFDPLDOKRUCNPNTMCKJXLBGHRIBHKUEKLUGSQBUITWSLQITKSXCLLWOFSVOQFKILJXDXFJILLTGOFHXBZEAQQDKIEZYXJJJDQVDVITLXOALMFQJQFFLTWTBFXCJPIAWQZUKYYECDUVZOVYWEWIZIFYQUDGHPLVUPOIBHYSSNNALTXMPCOKVUGWTVWXQHCCUECQSGNUOKASFNNMJAVDVINHHKKQNBFHWNLMMKNCHJGBQZXYQNDEIDWIORIIPGCOOANURPRNLFMQHXFLDUXHCQEDGTUFIZRLQLGVVDKMNXJQJOYWEGFUOYUBLPEOGZFHRZOYVGDNNQRLFSIMRWWZEQDWISILUXDYPQMPNHZEIFKZRAHSOXVKOTBICLAMOFPMOHDWGFZNMAMYEBRPT]
fifo-rdr-41: 2022-12-31 21:44:19.023 - pid=71914: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:19.653 - pid=71914: 1000 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:19.653 - pid=71914: Data: [PTKDVAKIAHVFJYYLAZVAHELKTIXNRTABXOHWUIYPIUBCBPQTVKPGZWNSDWZFWJTICZAPEOGVHAGNKXQOLBNBTGIJHXMXHCQIJZCMKCDRRNIDWXTQNQURUVQLEKTCIGPJHQELGMMJPCKYDQJKVYFTCTVLNVZGVHXFOSTLQENLBLOQZPVDERXYZSJPLIQPPTFRPLTLUNHVJGRLCODCNQXPAFVKOGADXNMPCBPXGLYKEPEXOYFKLBNFUDVAHLQPSNORZERDDJHZXSNFQLOIINVCJDQAUFZCNKNBJBDDYKAXOMTCUVHNIVIPTVDXMZKKSYEARHUNPTNKKKUQGFAKJWRKCGJKMURSSBYUNFFBFOSSUZGYVTLFUJKFDKUTUPUQHOHMJJVSMTRBRDIARHMTOBJZJGGLFTUYHCOHJFKJVRHXWTOVFTESXLHYHLVEOFIVMEJNXUTLOXEXESAKYHZUZXRPUNYFIRRMCSUICRMIULMWXKZZFNUCLVXLATYEIFQQERAJRPMMSXJVXMXADHVPCFOMQQGQGQKGMOQLNFNEDMQZOFXNQMRGEQMWLBBETLKLDYCSJXFKAVVBZNHYDWFNJGXFTQFBEVOGCBDQDULEKAUWSXJVSBHZNGTTURURGWDDGGLGGUJYCVQUWGBWJABAKPIFDMPCTBNMNLQBWZIVSPAYZSDPGOVFDBDMRWBQCTKQIHFGBWOXXPMSBIVHRGBJQBBPCILDQXRNFZTKMKQDRNAHTDJTJHAXSJTLLHMWNNPVMOZCPJKDOQECJHTBOMXFJDVNSUOHKERDCYLBZGJHOIJBNWTWLXHQYCRFPJKSNUSTIDGWBNTIKOPLFPFKKDJWZZJSDJLDTOKGUFAHOWTRCMLFRVOIQAARPROTAXKFHMEQYDBUXBHSXWJDSVOGHRRBESUGFPTIYBHHGIEIRAIIKELQZRNXEIRIHICVZNFOSOTQWCNRJDEPTKDFTAQWQXIQZFNYZFROJSOJKGHJJHNNNGAH]
fifo-rdr-41: 2022-12-31 21:44:19.653 - pid=71914: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:20.365 - pid=71914: 213 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:20.365 - pid=71914: Data: [FTBRVOCRNYSBMSVOXGXMXCQHPLDNCKSTGUQJYDSJOZVERBVWNZRUZXEMUGAOPPZCPJLWDPYPXIDRCNDUQNGSURYNTAGNYLKRABZATLXBXTBRQQRYZXDFNRQNMZMLQNHWASNEQUBYUNNNZPNERAHUQSVVCTRNANYRYXPLMMQUJXOSYSDFTUSOFRQRQNLFQBJTEBAGXKNEREVDPSDCZKPRV]
fifo-rdr-41: 2022-12-31 21:44:20.365 - pid=71914: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:20.665 - pid=71914: 0 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:44:20.665 - pid=71914: Napping 0.628 seconds
fifo-rdr-41: 2022-12-31 21:44:20.666 - pid=71914: Woke up 0.628 seconds later
fifo-rdr-41: 2022-12-31 21:44:20.666 - pid=71914: Interrupted by signal 15 (SIGTERM)
Terminal 2: fifo-wrt-41; sleep 3; fifo-wrt-41; kill 71914
Note that the reader was started and hung for about a minute while I futzed around typing the command. The PID was known from the logging output.
$ fifo-wrt-41; sleep 3; fifo-wrt-41; kill 71914
fifo-wrt-41: 2022-12-31 21:44:13.329 - pid=71927: Open FIFO './test-fifo' for writing
fifo-wrt-41: 2022-12-31 21:44:13.330 - pid=71927: FIFO './test-fifo' opened for writing
fifo-wrt-41: 2022-12-31 21:44:13.330 - pid=71927: Napping 0.583 seconds
fifo-wrt-41: 2022-12-31 21:44:13.915 - pid=71927: Woke up 0.583 seconds later
fifo-wrt-41: 2022-12-31 21:44:13.915 - pid=71927: Write to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:44:13.915 - pid=71927: 893 bytes written to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:44:13.915 - pid=71927: Data: [BRIJVUSAANMQOOEWDHXWQCQRVEZLVIPMSDSXHYVDTAGLXPPCUMAZMQLNYHWMWHRZRWHJWXOZYEMUCZXLYFDEFUBSPVICPYVMFWXMZIVZLKFWLFAJWTDBQDWZPEWHXKFXSFJJNUDRZGQQBZMFAQDBYCIUSKPQHQDIDRKIEHNELCSAVHPLYXXLALRJNNVNIVJZWVVPSISUEGTGIISUQZJYVHZLKSMIWTHPOWZJCMMDHMVCCQZPXXRTZOYVEJUIOCYBMRBPBVJYBFZNMZIJDUTVISHLXAGRYOGRYKKOHVONMHTOUSBNBJEYENWADHXYNNCIYEKGXGPPUYRLTNAZROBHWKLDMXHILZXVKRPKUIZXQOOTTKVRMZNDSBRYXGWRZBSQPRPXZSVERASKOLMQQGQFCAXCQMKEHVSRGVFROCQLCLZGNLDLSLQOSKMKWPLJUNCZNTPNXNLIABVBGGTNWGAKTNXZHVHMQAXXKKQWMATQGHIMQCWGGSXGSZDPMJOZMFUJGHPFQHGJTWICLHNKGQGDDZVYGLOBXKUPDXJSEILVVRHNCHKWNKGQMOHCIKXDMQNMSCNPZIXKWEUVOZZCCVCQMFGMUFJJNGSNUCBPDPREEJOCVRUHEILCASMATNJKLDHZWAIJMRBORJLWDUGBTAWKETBNFBZNYJZDKYAOQLERLGWMCNOGWLCYJAFIFCIOMFZEPVRPDAQOGFUAVQOAXPMRBDHBUXSEFRJWSWCEBDFISPGIZOUENNRIEEPBCULDCDMUOSBDQFJYJSAMXZNPZHEEMOLLMAUJDUXGMISSHVWPPFGBJTLDVZMKNYISUXMRQLCTPBPIXATAJFNOJSSAJMSUOQDFGFYBVONMTYQBEWLHGSOVCTWKPWMGAELQGTCZE]
fifo-wrt-41: 2022-12-31 21:44:13.915 - pid=71927: Napping 0.393 seconds
fifo-wrt-41: 2022-12-31 21:44:14.309 - pid=71927: Woke up 0.393 seconds later
fifo-wrt-41: 2022-12-31 21:44:14.309 - pid=71927: Write to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:44:14.309 - pid=71927: 496 bytes written to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:44:14.309 - pid=71927: Data: [CXDXBNJWJFGRHDNHQEEZSVQELRWCYXKGJVYYCVPFAUTKSNJUNPRVMSFSVXZLWZPMQEWEBXMTEYGUXHRDAJPUODMWUYRFFXFQTGACHSAPTTKBPPYNBXWSTSRXAHQTVEMJUSEKYUEMGMSDSRAUASZPSYKDCULMHYYKZJKXIBAYGPICTEUVQAIWWSDVGEYVOCPERGJTDPYKSGFKEGTJTUFVHUZWSSNONMKCPRBCCPVMKOPNPOIYATQRRCQPOJFRDTEOCPHNJTHLCZBLXPVCQPOWZPWWWEOHCZTYZPATCNQYRPRWXYTSGLJCHONDYZLVRLXMEMRZLUMKJLZXSTEVQGXJLFSLUMCCFAYLDIXLATVACDXVNEEVQSRUWWVWPYBNUHETWTRCHSIRGVCQZTQWWEAQSEKCSHGOJVOGURPVVIODYCEQBNXHBNMBGHHQBKQRRAZINNZUBJBQNPTXLPFVUNPJBRAITXPNJQHXAXMMATRKZNVMFRTT]
fifo-wrt-41: 2022-12-31 21:44:14.309 - pid=71927: Napping 0.621 seconds
fifo-wrt-41: 2022-12-31 21:44:14.934 - pid=71927: Woke up 0.621 seconds later
fifo-wrt-41: 2022-12-31 21:44:14.935 - pid=71927: Completed
fifo-wrt-41: 2022-12-31 21:44:18.094 - pid=71929: Open FIFO './test-fifo' for writing
fifo-wrt-41: 2022-12-31 21:44:18.095 - pid=71929: FIFO './test-fifo' opened for writing
fifo-wrt-41: 2022-12-31 21:44:18.095 - pid=71929: Napping 0.429 seconds
fifo-wrt-41: 2022-12-31 21:44:18.524 - pid=71929: Woke up 0.429 seconds later
fifo-wrt-41: 2022-12-31 21:44:18.524 - pid=71929: Write to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:44:18.524 - pid=71929: 351 bytes written to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:44:18.524 - pid=71929: Data: [OORFJGIYUKOWERSICRKHRQRSRDOYRWDLBQCGPPUPFMUTEDHLAJINRWUBYDCFLTDGIAXNPPDQDRCQPVZLEGNJSONSJUTXYEAQDMUXDYFKBUQDNWFCJNXGSLCJVJOCPCHKOERUOJAJUINWTBYOYVAKFOMJPBDCSCMDNVKKRRPJUJKCTCGVGGHIUXVXGAKQFCKVQIUXRNDMUEARVZWRXNOOLYPJHYCBVBMMJEDBKSLGEQFHXVZAUTCMDUFWWHKZNJWVBUCJDJJPWIFMWONIRVPQFTTVZWMVNXCLJOWUFZKUACZAPBJXAEGRJARZALSLWLEXUFEPMNIUTFISQUZNEXKLVCNZNUGVMWM]
fifo-wrt-41: 2022-12-31 21:44:18.524 - pid=71929: Napping 0.495 seconds
fifo-wrt-41: 2022-12-31 21:44:19.023 - pid=71929: Woke up 0.495 seconds later
fifo-wrt-41: 2022-12-31 21:44:19.023 - pid=71929: Write to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:44:19.023 - pid=71929: 465 bytes written to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:44:19.023 - pid=71929: Data: [DYZJOTBGVECGSGBNYNTCVPUSTQGIQQSYTMXWZOQLBUQMGFPILPRIRGTOZFKNHERVCXLFDPLDOKRUCNPNTMCKJXLBGHRIBHKUEKLUGSQBUITWSLQITKSXCLLWOFSVOQFKILJXDXFJILLTGOFHXBZEAQQDKIEZYXJJJDQVDVITLXOALMFQJQFFLTWTBFXCJPIAWQZUKYYECDUVZOVYWEWIZIFYQUDGHPLVUPOIBHYSSNNALTXMPCOKVUGWTVWXQHCCUECQSGNUOKASFNNMJAVDVINHHKKQNBFHWNLMMKNCHJGBQZXYQNDEIDWIORIIPGCOOANURPRNLFMQHXFLDUXHCQEDGTUFIZRLQLGVVDKMNXJQJOYWEGFUOYUBLPEOGZFHRZOYVGDNNQRLFSIMRWWZEQDWISILUXDYPQMPNHZEIFKZRAHSOXVKOTBICLAMOFPMOHDWGFZNMAMYEBRPT]
fifo-wrt-41: 2022-12-31 21:44:19.023 - pid=71929: Napping 0.626 seconds
fifo-wrt-41: 2022-12-31 21:44:19.653 - pid=71929: Woke up 0.626 seconds later
fifo-wrt-41: 2022-12-31 21:44:19.653 - pid=71929: Write to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:44:19.653 - pid=71929: 1000 bytes written to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:44:19.653 - pid=71929: Data: [PTKDVAKIAHVFJYYLAZVAHELKTIXNRTABXOHWUIYPIUBCBPQTVKPGZWNSDWZFWJTICZAPEOGVHAGNKXQOLBNBTGIJHXMXHCQIJZCMKCDRRNIDWXTQNQURUVQLEKTCIGPJHQELGMMJPCKYDQJKVYFTCTVLNVZGVHXFOSTLQENLBLOQZPVDERXYZSJPLIQPPTFRPLTLUNHVJGRLCODCNQXPAFVKOGADXNMPCBPXGLYKEPEXOYFKLBNFUDVAHLQPSNORZERDDJHZXSNFQLOIINVCJDQAUFZCNKNBJBDDYKAXOMTCUVHNIVIPTVDXMZKKSYEARHUNPTNKKKUQGFAKJWRKCGJKMURSSBYUNFFBFOSSUZGYVTLFUJKFDKUTUPUQHOHMJJVSMTRBRDIARHMTOBJZJGGLFTUYHCOHJFKJVRHXWTOVFTESXLHYHLVEOFIVMEJNXUTLOXEXESAKYHZUZXRPUNYFIRRMCSUICRMIULMWXKZZFNUCLVXLATYEIFQQERAJRPMMSXJVXMXADHVPCFOMQQGQGQKGMOQLNFNEDMQZOFXNQMRGEQMWLBBETLKLDYCSJXFKAVVBZNHYDWFNJGXFTQFBEVOGCBDQDULEKAUWSXJVSBHZNGTTURURGWDDGGLGGUJYCVQUWGBWJABAKPIFDMPCTBNMNLQBWZIVSPAYZSDPGOVFDBDMRWBQCTKQIHFGBWOXXPMSBIVHRGBJQBBPCILDQXRNFZTKMKQDRNAHTDJTJHAXSJTLLHMWNNPVMOZCPJKDOQECJHTBOMXFJDVNSUOHKERDCYLBZGJHOIJBNWTWLXHQYCRFPJKSNUSTIDGWBNTIKOPLFPFKKDJWZZJSDJLDTOKGUFAHOWTRCMLFRVOIQAARPROTAXKFHMEQYDBUXBHSXWJDSVOGHRRBESUGFPTIYBHHGIEIRAIIKELQZRNXEIRIHICVZNFOSOTQWCNRJDEPTKDFTAQWQXIQZFNYZFROJSOJKGHJJHNNNGAH]
fifo-wrt-41: 2022-12-31 21:44:19.653 - pid=71929: Napping 0.707 seconds
fifo-wrt-41: 2022-12-31 21:44:20.365 - pid=71929: Woke up 0.707 seconds later
fifo-wrt-41: 2022-12-31 21:44:20.365 - pid=71929: Write to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:44:20.365 - pid=71929: 213 bytes written to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:44:20.365 - pid=71929: Data: [FTBRVOCRNYSBMSVOXGXMXCQHPLDNCKSTGUQJYDSJOZVERBVWNZRUZXEMUGAOPPZCPJLWDPYPXIDRCNDUQNGSURYNTAGNYLKRABZATLXBXTBRQQRYZXDFNRQNMZMLQNHWASNEQUBYUNNNZPNERAHUQSVVCTRNANYRYXPLMMQUJXOSYSDFTUSOFRQRQNLFQBJTEBAGXKNEREVDPSDCZKPRV]
fifo-wrt-41: 2022-12-31 21:44:20.365 - pid=71929: Napping 0.296 seconds
fifo-wrt-41: 2022-12-31 21:44:20.665 - pid=71929: Woke up 0.296 seconds later
fifo-wrt-41: 2022-12-31 21:44:20.665 - pid=71929: Completed
$
Example 2 — Reader reopens file on EOF
Terminal 1: fifo-rdr-41 -r
fifo-rdr-41: 2022-12-31 21:49:10.754 - pid=72086: Open FIFO './test-fifo' for reading
fifo-rdr-41: 2022-12-31 21:49:29.581 - pid=72086: FIFO './test-fifo' opened for reading
fifo-rdr-41: 2022-12-31 21:49:29.581 - pid=72086: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:30.131 - pid=72086: 773 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:30.131 - pid=72086: Data: […omitted for lack of space…]
fifo-rdr-41: 2022-12-31 21:49:30.131 - pid=72086: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:30.430 - pid=72086: 496 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:30.430 - pid=72086: Data: […omitted for lack of space…]
fifo-rdr-41: 2022-12-31 21:49:30.430 - pid=72086: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:30.907 - pid=72086: 952 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:30.907 - pid=72086: Data: […omitted for lack of space…]
fifo-rdr-41: 2022-12-31 21:49:30.907 - pid=72086: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:31.271 - pid=72086: 0 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:31.271 - pid=72086: Close FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:31.271 - pid=72086: Open FIFO './test-fifo' for reading
fifo-rdr-41: 2022-12-31 21:49:34.293 - pid=72086: FIFO './test-fifo' opened for reading
fifo-rdr-41: 2022-12-31 21:49:34.293 - pid=72086: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:34.945 - pid=72086: 984 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:34.945 - pid=72086: Data: […omitted for lack of space…]
fifo-rdr-41: 2022-12-31 21:49:34.945 - pid=72086: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:35.513 - pid=72086: 880 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:35.513 - pid=72086: Data: […omitted for lack of space…]
fifo-rdr-41: 2022-12-31 21:49:35.513 - pid=72086: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:35.965 - pid=72086: 510 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:35.965 - pid=72086: Data: […omitted for lack of space…]
fifo-rdr-41: 2022-12-31 21:49:35.966 - pid=72086: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:36.571 - pid=72086: 900 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:36.571 - pid=72086: Data: […omitted for lack of space…]
fifo-rdr-41: 2022-12-31 21:49:36.571 - pid=72086: Read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:36.883 - pid=72086: 0 bytes read from FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:36.883 - pid=72086: Close FIFO './test-fifo'
fifo-rdr-41: 2022-12-31 21:49:36.884 - pid=72086: Open FIFO './test-fifo' for reading
fifo-rdr-41: 2022-12-31 21:49:36.885 - pid=72086: Interrupted by signal 15 (SIGTERM)
Terminal 2: fifo-wrt-41; sleep 3; fifo-wrt-41; kill 72086
fifo-wrt-41: 2022-12-31 21:49:29.580 - pid=72090: Open FIFO './test-fifo' for writing
fifo-wrt-41: 2022-12-31 21:49:29.581 - pid=72090: FIFO './test-fifo' opened for writing
fifo-wrt-41: 2022-12-31 21:49:29.581 - pid=72090: Napping 0.550 seconds
fifo-wrt-41: 2022-12-31 21:49:30.131 - pid=72090: Woke up 0.550 seconds later
fifo-wrt-41: 2022-12-31 21:49:30.131 - pid=72090: Write to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:49:30.131 - pid=72090: 773 bytes written to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:49:30.131 - pid=72090: Data: […omitted for lack of space…]
fifo-wrt-41: 2022-12-31 21:49:30.131 - pid=72090: Napping 0.294 seconds
fifo-wrt-41: 2022-12-31 21:49:30.429 - pid=72090: Woke up 0.294 seconds later
fifo-wrt-41: 2022-12-31 21:49:30.430 - pid=72090: Write to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:49:30.430 - pid=72090: 496 bytes written to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:49:30.430 - pid=72090: Data: […omitted for lack of space…]
fifo-wrt-41: 2022-12-31 21:49:30.430 - pid=72090: Napping 0.473 seconds
fifo-wrt-41: 2022-12-31 21:49:30.907 - pid=72090: Woke up 0.473 seconds later
fifo-wrt-41: 2022-12-31 21:49:30.907 - pid=72090: Write to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:49:30.907 - pid=72090: 952 bytes written to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:49:30.907 - pid=72090: Data: […omitted for lack of space…]
fifo-wrt-41: 2022-12-31 21:49:30.907 - pid=72090: Napping 0.361 seconds
fifo-wrt-41: 2022-12-31 21:49:31.270 - pid=72090: Woke up 0.361 seconds later
fifo-wrt-41: 2022-12-31 21:49:31.271 - pid=72090: Completed
fifo-wrt-41: 2022-12-31 21:49:34.293 - pid=72093: Open FIFO './test-fifo' for writing
fifo-wrt-41: 2022-12-31 21:49:34.293 - pid=72093: FIFO './test-fifo' opened for writing
fifo-wrt-41: 2022-12-31 21:49:34.293 - pid=72093: Napping 0.651 seconds
fifo-wrt-41: 2022-12-31 21:49:34.945 - pid=72093: Woke up 0.651 seconds later
fifo-wrt-41: 2022-12-31 21:49:34.945 - pid=72093: Write to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:49:34.945 - pid=72093: 984 bytes written to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:49:34.945 - pid=72093: Data: […omitted for lack of space…]
fifo-wrt-41: 2022-12-31 21:49:34.945 - pid=72093: Napping 0.568 seconds
fifo-wrt-41: 2022-12-31 21:49:35.513 - pid=72093: Woke up 0.568 seconds later
fifo-wrt-41: 2022-12-31 21:49:35.513 - pid=72093: Write to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:49:35.513 - pid=72093: 880 bytes written to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:49:35.513 - pid=72093: Data: […omitted for lack of space…]
fifo-wrt-41: 2022-12-31 21:49:35.513 - pid=72093: Napping 0.451 seconds
fifo-wrt-41: 2022-12-31 21:49:35.965 - pid=72093: Woke up 0.451 seconds later
fifo-wrt-41: 2022-12-31 21:49:35.965 - pid=72093: Write to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:49:35.965 - pid=72093: 510 bytes written to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:49:35.965 - pid=72093: Data: […omitted for lack of space…]
fifo-wrt-41: 2022-12-31 21:49:35.965 - pid=72093: Napping 0.602 seconds
fifo-wrt-41: 2022-12-31 21:49:36.571 - pid=72093: Woke up 0.602 seconds later
fifo-wrt-41: 2022-12-31 21:49:36.571 - pid=72093: Write to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:49:36.571 - pid=72093: 900 bytes written to FIFO './test-fifo'
fifo-wrt-41: 2022-12-31 21:49:36.571 - pid=72093: Data: […omitted for lack of space…]
fifo-wrt-41: 2022-12-31 21:49:36.571 - pid=72093: Napping 0.309 seconds
fifo-wrt-41: 2022-12-31 21:49:36.883 - pid=72093: Woke up 0.309 seconds later
fifo-wrt-41: 2022-12-31 21:49:36.883 - pid=72093: Completed

Related

C FIFO crashes when writer goes faster than reader

I have a parent and child process using fork who communicate using a FIFO pipe. The program will sometimes work and other times it will crash when the writer process (parent) goes faster than the reader process (child).
The following code is what I currently have.
void writeprocess(char* text);
void readprocess(void);
#define FIFO_NAME "MYTESTFIFO"
#define MAX 200
int main(int argc, const char * argv[]) {
pid_t pid;
pid = fork();
if(pid==0){
printf("Started child process.\n");
mkfifo(FIFO_NAME, 0666);
readprocess();
printf("Child process finished.\n");
exit(EXIT_SUCCESS);
}
else{
printf("Started parent process.\n");
mkfifo(FIFO_NAME, 0666);
writeprocess("Message 1");
writeprocess("Message 2");
writeprocess("Message 3");
writeprocess("Message 4");
writeprocess("terminate");
printf("Waiting for child process to finish.\n");
int returnStatus;
waitpid(pid, &returnStatus, 0);
printf("Parent process also finished.\n");
exit(EXIT_SUCCESS);
}
}
void writeprocess(char* text){
FILE *fp;
char *send_buf;
fp = fopen(FIFO_NAME, "w");
asprintf( &send_buf, "%s\n", text);
if ( fputs( send_buf, fp ) == EOF )
{
fprintf( stderr, "Error writing data to fifo\n");
exit( EXIT_FAILURE );
}
printf("Message send: %s", send_buf);
free( send_buf );
fclose(fp);
}
void readprocess(){
sleep(1);
FILE *fp;
char *str_result = NULL;
char recv_buf[MAX];
int stringdifference = 1;
while (stringdifference)
{
fp = fopen(FIFO_NAME, "r");
str_result = fgets(recv_buf, MAX, fp);
if ( str_result != NULL )
{
printf("Message received: %s", recv_buf);
}
fclose( fp );
stringdifference = strncmp(str_result, "terminate", 9);
}
}
When the writer writes faster to the FIFO pipe than the reader can read, I get an exit error with the following message: "Terminated due to signal 13". How can I avoid this from happening while keeping my program run at full performance?
I do want the parent process to be able to end the process and I have to keep working using a FIFO pipe.
When the writer writes faster to the FIFO pipe than the reader can read, I get an exit error with the following message: "Terminated due to signal 13".
You have mischaracterized the nature of the problem. As your other answer already observes, signal 13 is SIGPIPE, which is delivered if you try to write to a pipe that has no readers.
There is normally some (limited) protection against entering that situation with FIFOs, in that opening one end of a FIFO blocks until the other end is opened as well. Therefore if a process opens a FIFO successfully, it knows that there is initially another process with the other end open. The one with the write end open can then expect a high likelihood of writing successfully (but not necessarily without blocking). As soon as the last reader closes the FIFO, however, further attempts to write to it will cause a SIGPIPE to be delivered to the writer. Of course, if the same or a new reader opens the FIFO, that permits writing to resume -- something that's possible with a FIFO, but not with an ordinary pipe.
So the problem is not that the reader does not keep up, but rather that it keeps opening and closing the FIFO. This creates a race condition, in that there are multiple intervals in which the writer will elicit a SIGPIPE if it tries to write. Since the writer also repeatedly opens and closes the FIFO, it follows that to receive a SIGPIPE, the writer must reopen the FIFO before the reader closes it after a previous message, but that doesn't mean the writer is outpacing the reader. The reader cannot finish reading a given message before the writer finishes writing it, so their behaviors are staggered. The writer does nothing else between closing the FIFO and reopening it, so it is not surprising that it sometimes reopens before the reader closes.
The solution is simple: have each process keep the pipe open continuously until it is done communicating with the other. There is no upside to opening and closing for each message, but plenty of downside. For your particular use, however, it may be beneficial to put the writer's stream in line-buffered mode (setvbuf(); default will be fully-buffered).
Signal 13 is SIGPIPE. This happens because nobody is reading from the FIFO.
You cannot write to a FIFO if there is no process that currently has that FIFO open for reading. If you try to do this, your process will get SIGPIPE (which can be ignored, which turns it into EPIPE... but either way, it fails).
One way to handle this correctly:
Create the FIFO in the parent.
Fork.
In the writer process, open it for writing. This will block until the reader has opened it. Keep it open.
In the reader process, open it for writing. This will block until the writer has opened it. Keep it open.

After a pipe() and fork(), why does close(fd[1]) in the parent close the *child's* fd[1]?

In the parent process close(fd[1]);,
why it will skip the first fd[1] (replaced parent STD_OUT) and close fd[1] at child process ?
#define STD_INPUT 0
#define STD_OUTPUT 1
int fd[2];
pipe(fd[0]);
if(fork()!=0){
// parent process
close(fd[0]);
close(STD_OUTPUT);
dup(fd[1]);
close(fd[1]);
excel(process1, process1, 0);
}
else{
// child process
// ...
}
UPDATE
It will have 2 fd[1] after dup(fd[1];,
why the system closed the second fd[1](4. [write]) in the result? not first fd[1](2. [write])?
start fork
1. STD_IN
2. STD_OUT
3. [read]
4. [write]
result
1. STD_IN
2. [write]
3. -close-
4. -close-
It will have 2 fd[1] after dup(fd[1];,
No. The value of fd[1] never changes. If it was 4 before the call to dup, it's 4 after the call to dup.
why the system closed the second fd[1](4. [write]) in the result? not first fd[1](2. [write])?
If fd[1] is 4, then close(fd[1]); will close descriptor 4. It will not affect any other descriptors that happen to reference the same endpoint.
Before you call pipe, your process already has file descriptors 0, 1, and 2 as its standard input, standard output, and standard error. You then create two new descriptors for the pipe.
So this is what it looks like when you call fork, more or less:
...0...|....1....|.....2....|....fd[0]....|.....fd[1].....
stdin, stdout, stderr, pipe end, other pipe end
Then, in the parent, you close fd[0], so you have:
...0...|....1.....|.....2...|....fd[0]................|......fd[1].....
stdin, stdout, stderr, closed pipe end, open pipe end
Then you close stdout:
...0....|...1....|.....2.....|...fd[0]..|......fd[1].....
stdin, closed, stderr, closed, open pipe end
Then you dup the open pipe end:
...0....|..................1.............|.....2.....|..fd[0]..|.......fd[1].....
stdin, dup of open pipe end, stderr, closed, open pipe end
Then you close fd[1]:
...0....|....................1............|.....2...|...fd[0]..|..fd[1].....
stdin, dup of open pipe end, stderr, closed, closed
Or, more simply:
...0...|...................1...............|....2....
stdin, dup of open pipe end, stderr
So when you call execl, the new process will inherit the parent's standard input and standard error but will inherit a copy of one end of its pipe as its standard
output.

Why are my writes not blocking to this pipe?

I'm writing a little Linux fifo test program.
I created a pipe using mkfifo mpipe. The program should perform one write per argument sent to it. If no arguments are sent, then it performs one read from the pipe.
Here is my code
int main(int argc, char *argv[])
{
if (argc > 1)
{
int fd = open("./mpipe", O_WRONLY);
int i = 1;
for (i; i < argc; i++)
{
int bytes = write(fd, argv[i], strlen(argv[i]) + 1);
if (bytes <= 0)
{
printf("ERROR: write\n");
close(fd);
return 1;
}
printf("Wrote %d bytes: %s\n", bytes, argv[i]);
}
close(fd);
return 0;
}
/* Else perform one read */
char buf[64];
int bytes = 0;
int fd = open("./mpipe", O_RDONLY);
bytes = read(fd, buf, 64);
if (bytes <= 0)
{
printf("ERROR: read\n");
close(fd);
return 1;
}
else
{
printf("Read %d bytes: %s\n", bytes, buf);
}
close(fd);
return 0;
}
I would expect the behavior to be something like this...
I call ./pt hello i am the deepest guy, and I would expect it to block for 6 reads. Instead one read seems enough to trigger multiple writes. My output looks like
# Term 1 - writer
$: ./pt hello i am the deepest guy # this call blocks until a read, but then cascades.
Just wrote hello
Just wrote i
Just wrote am
Just wrote the # output ends here
# Term 2 - reader
$: ./pt
Read 6 bytes: hello
Could someone help explain this weird behavior? I thought that every read would have to match with a write with regards to pipe communication.
What is happening there is that the kernel blocks the writer process in the open(2) system call until you have a reader opening it for reading. (A fifo requires both ends connected to processes to work) Once the reader does the first read(2) call (either the writer or the reader blocks, who gets first for the system call) The kernel passes all the data from the writer to the reader, and awakens both processes (that's the reason of receiving only the first command line parameter, and not the first 16 bytes from the writer, you get only the six characters {'h', 'e', 'l', 'l', 'o', '\0' } from the blocking writer)
Finally, as the reader just closes the fifo, the writer gets killed with a SIGPIPE signal, as no more readers have the fifo open. If you install a signal handler on the writer process (or ignore the signal) you'll get an error from the write(2) syscall, telling you that no more readers were blocked on the fifo (EPIPE errno value) on the blocking write.
Just notice that this is a feature, and not a bug, a means of knowing that writes will not reach any reader until you close and reopen the fifo.
The kernel blocks the inode of the fifo for the whole read(2) or write(2) calls, so even another process doing another write(2) on the fifo will be blocked, and you'll not get the data on the reader from that second writer (should you have one). You can try if you like, to start two writers and see what happens.
$ pru I am the best &
[1] 271
$ pru
Read 2 bytes: I
Wrote 2 bytes: I
Wrote 3 bytes: am
[1]+ Broken pipe pru I am the best <<< this is the kill to the writer process, announced by the shell.
$ _

How to kill zombie processes?

I have two problems: a program I made am glitching out and making nearly unkillable processes, if either subproblem is solved I believe both problems will be easily resolved. I am running an early 2008 Macbook on OSX 10.6.8.
/Problem #1, coding:/
I've been playing around with the iRobot Create using termios.h I/O. I compile without warnings or errors and can run the program without a hitch. I am connecting to the robot by usb which explains the input "/dev/tty.usbserial".
gcc simple.c -o simple
./simple /dev/tty.usbserial
The program starts by checking the arguments given, then tries to connect with the given argument (char * device is /dev/tty.usbserial) with the biscConnect() function. It fails on my mac.
//in file simple.c:
int main(int argc, char *argv[]){
if(argc!=2){
printf("Put port... like /dev/tty.usbserial or something\n");
exit(EXIT_FAILURE);
}
printf("Starting...\n");
biscConnect(argv[1]);
}
void biscConnect(char *device){
struct termios tty;
// Try to open the device from the input
if((fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK))==-1){
fprintf(stderr, "Serial port at %s could not be opened: %s\n", device, strerror(errno));
exit(EXIT_FAILURE);
}
tcflush (fd, TCIOFLUSH);
tcgetattr(fd, &tty);
tty.c_iflag = IGNBRK | IGNPAR;
tty.c_lflag = 0;
tty.c_oflag = 0;
tty.c_cflag = CREAD | CS8 | CLOCAL;
cfsetispeed(&tty, B57600);
cfsetospeed(&tty, B57600);
tcsetattr(fd, TCSANOW, &tty);
//The code fails prior to this point
}
I would then send bytes to the robot to make it move if it didn't get stuck before then.
/Problem #2, unkillable processes:/
When I run the file, the terminal goes into a weird mode where the prompt is gone and I can type anything I want (usually signifying a process is running). I cannot exit using control-c. The only way I can seem to exit is closing the terminal window. This fails to kill the running process.
I can easily look up the pid but the Activity Monitor but the Force Quit fails to kill the process, kill -9 [pid] fails, killall [program name] fails etc. despite acknowledging the existence of the program. The only way to force terminate the process seems to be to physically close off the power from the computer and reboot it (ie shuting down doesn't work because it tries, and fails, to terminate the process(es)). I am wasting a terrible amount of time if to debug the program I need to power-cycle my laptop every run! I can continually create more process but am unable to delete them.
I think if I knew the parent process I might be able to kill these "zombie" processes but I don't know what the parent is.
Any ideas on how to get rid of these processes without power-cycling would be tremendous help, thanks!
On Mac OS X 10.8.4, I created a program zombie from zombie.c:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
pid_t pid;
if ((pid = fork()) >= 0)
{
if (pid == 0)
{
printf("%d: committing suicide (parent %d)\n", (int)getpid(), (int)getppid());
exit(0);
}
else
{
printf("%d: going to sleep for a while - child %d might die while I snooze\n",
(int)getpid(), (int)pid);
sleep(30);
printf("%d: awake\n", (int)getpid());
}
}
return 0;
}
When I ran it in one terminal window, the output was:
$ ./zombie
2443: going to sleep for a while - child 2444 might die while I snooze
2444: committing suicide (parent 2443)
2443: awake
$
In another terminal window, running ps -f produced:
UID PID PPID C STIME TTY TIME CMD
503 260 249 0 12:42PM ttys004 0:00.08 -bash
503 2443 260 0 5:11PM ttys004 0:00.00 ./zombie
503 2444 2443 0 5:11PM ttys004 0:00.00 (zombie)
The parenthesize (zombie) is the defunct process, and the name in parentheses is the original name of the process. When I copied the program to living-dead, the corresponding output was:
UID PID PPID C STIME TTY TIME CMD
503 260 249 0 12:42PM ttys004 0:00.09 -bash
503 2454 260 0 5:13PM ttys004 0:00.00 ./living-dead
503 2455 2454 0 5:13PM ttys004 0:00.00 (living-dead)
(On most systems, the defunct process is marked as <defunct> or something similar.)
Clearly, the value in the PPID column identifies the parent process of the zombie, and the various process IDs match the output from the programs themselves.
You can find out who birthed that undead process by running ps ef or using htop.
PID TTY STAT TIME COMMAND
21138 tty1 T 0:00 sudo /usr/bin/aura -Akax open_watcom openwatcom-extras-hg HOME=/home/hav3lock USER=hav3lock SHELL=/bin/zsh TERM=linux PATH=/usr/local/sbin:/u
21139 tty1 T 0:00 \_ /usr/bin/aura -Akax open_watcom openwatcom-extras-hg TERM=linux PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/
22111 tty1 Z 0:00 \_ [su] <defunct>`
In the above I have a zombie process who's momma is /usr/bin/aura, a process spawned by sudo /usr/bin/aura.
Running sudo kill -9 21138 will kill the parent, thereby subsequently killing its zombie spawn.
PID TTY STAT TIME COMMAND
23858 pts/9 S+ 0:00 sudo sudo ps ef LANG=en_US.utf8 DISPLAY=:0 SHLVL=3 LOGNAME=hav3lock XDG_VTNR=1 PWD=/home/hav3lock/sy.l/repos/pub_rel/slen/linux/src HG=/usr/b
23860 pts/9 S+ 0:00 \_ sudo ps ef LANG=en_US.utf8 DISPLAY=:0 LS_COLORS=no=0:fi=0:di=34:ln=00;96:or=91;4:mi=00;31;9:mh=01;37:pi=33;7:so=01;35:do=35:bd=01;33:cd=9
23861 pts/9 R+ 0:00 \_ ps ef LANG=en_US.utf8 DISPLAY=:0 LS_COLORS=no=0:fi=0:di=34:ln=00;96:or=91;4:mi=00;31;9:mh=01;37:pi=33;7:so=01;35:do=35:bd=01;33:cd=93
13405 tty2 S<sl+ 3:49 X :0 HOME=/home/hav3lock USER=hav3lock SHELL=/bin/zsh TERM=linux PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/ve`

Using named pipes in a single process

I am trying to use a named pipe for communication within a process.
Here is the code
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
void sigint(int num)
{
int fd = open("np", O_WRONLY);
write(fd, "y", 1);
close(fd);
}
main()
{
char ch[1];
int fd;
mkfifo("np", 0666);
signal(SIGINT, sigint);
fd = open("np", O_RDONLY);
read(fd, ch, 1);
close(fd);
printf("%c\n", ch[0]);
return;
}
What I want is for main to block till something is written to the pipe.
The problem is that the signal handler sigint() also blocks after opening the pipe. Is this supposed to happen given that the pipe is already opened for reading earlier in main() ?
You're blocking in open() , opening a fifo for reading blocks until someone opens it for writing.
And opening a fifo for writing blocks until someone opens it for reading.
the signal handler runs in the same thread as your main(), so you'll get a deadlock. Neither will be able to open the fifo.
You can check what's going on by running your program under strace.
From the man page:
Opening a FIFO for reading normally
blocks until some other process opens
the same FIFO for writing, and vice
versa.
and:
A process can open a FIFO in
non-blocking mode. In this case,
opening for read only will succeed
even if no-one has opened on the write
side yet; opening for write only will
fail with ENXIO (no such device or
address) unless the other end has
already been opened.
Under Linux, opening a FIFO for read
and write will succeed both in
blocking and non-blocking mode. POSIX
leaves this behaviour undefined. This
can be used to open a FIFO for writing
while there are no readers available.
A process that uses both ends of the
connection in order to communicate
with itself should be very careful to
avoid deadlocks.

Resources