Elixir: Making Concurrent API Calls 
angelcool@fedora-laptop$
angelcool@fedora-laptop$date
Fri Apr 12 07:51:16 PM PDT 2024
angelcool@fedora-laptop$ls lib/
coolprogram.ex coordinator.ex worker.ex
angelcool@fedora-laptop$cat lib/coolprogram.ex
defmodule CoolProgram do
def temperature_of(cities) do
coordinator_pid = spawn(CoolProgram.Coordinator, :loop, [[], Enum.count(cities)])
cities |> Enum.each(fn city ->
worker_pid = spawn(CoolProgram.Worker, :loop, [])
send(worker_pid, {coordinator_pid, city})
end)
end
end
angelcool@fedora-laptop$cat lib/coordinator.ex
defmodule CoolProgram.Coordinator do

def loop(results \\ [], results_expected) do
receive do
{:ok, result} ->
new_results = [result|results]
if results_expected == Enum.count(new_results) do
send(self(), :exit)
end
loop(new_results, results_expected)
:exit ->
IO.puts(results |> Enum.sort |> Enum.join(", "))
_->
loop(results, results_expected)
end
end

end
angelcool@fedora-laptop$cat lib/worker.ex
defmodule CoolProgram.Worker do

def temperature_of(location) do
result = url_for(location)
|> HTTPoison.get
|> parse_response
case result do
{:ok, temp} ->
"#{location}: #{temp}° C"
:error ->
"#{location} not found"
end
end

defp url_for(location) do
location = URI.encode(location)
"http://api.openweathermap.org/data/2.5/weather?q=#{location}&appid=#{apikey()}"
end

defp parse_response({:ok, %HTTPoison.Response{body: body, status_code: 200}}) do
body
|> JSON.decode!
|> compute_temperature()
end

defp parse_response(_) do
:error
end

defp compute_temperature(json) do
try do
temp = (json["main"]["temp"]-273.15)
|> Float.round(1)
{:ok, temp}
rescue
_-> :error
end
end

defp apikey do
"XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
end

def loop do
receive do
{sender_pid, location}->
send(sender_pid, {:ok, temperature_of(location)})
_->
IO.puts "don't know how to process this message"
end
loop()
end
end
angelcool@fedora-laptop$
angelcool@fedora-laptop$iex --version
IEx 1.15.7 (compiled with Erlang/OTP 26)
angelcool@fedora-laptop$iex -S mix
Compiling 1 file (.ex)
Erlang/OTP 26 [erts-14.2.2] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

Interactive Elixir (1.15.7) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> cities=["San Diego", "Merida", "Singapore", "Los Angeles", "Mexico City", "Miami", "Temecula", "Buenos Aires", "Ojai" ]
["San Diego", "Merida", "Singapore", "Los Angeles", "Mexico City", "Miami",
"Temecula", "Buenos Aires", "Ojai"]
iex(2)> CoolProgram.temperature_of(cities)
:ok
Buenos Aires: 17.0° C, Los Angeles: 14.7° C, Merida: 25.0° C, Mexico City: 22.8° C, Miami: 22.0° C, Ojai: 14.2° C, San Diego: 15.2° C, Singapore: 30.8° C, Temecula: 13.1° C
iex(3)>


[ view entry ] ( 29 views )   |  print article
Elixir: Miscellaneous Notes 
# Filtering files in a directory by filename
angelcool@fedora-laptop$date
Fri Apr 12 12:02:42 PM PDT 2024
angelcool@fedora-laptop$iex
...
iex(90)> "/home/angelcool/Downloads" \
...(90)> |> Path.join("**/*.rpm") \
...(90)> |> Path.wildcard \
...(90)> |> Enum.filter(fn fname -> String.contains?(Path.basename(fname),"dbeaver") end)
["/home/angelcool/Downloads/dbeaver-ce-24.0.2-stable.x86_64.rpm"]


# Making an HTTP GET request
iex(18)> :inets.start()
:ok
iex(19)> :ssl.start()
:ok
iex(20)> :httpc.request(:get, {'https://www.angelcool.net', []}, [ssl: :httpc.ssl_verify_host_options(true)], [])
...


[ view entry ] ( 25 views )   |  print article
Elixir: Clustering Elixir Nodes - Updating Shared State. 

angelcool@fedora-laptop$ # Let's get the date and versions used
angelcool@fedora-laptop$date
Sat Apr 6 11:51:08 AM PDT 2024
angelcool@fedora-laptop$iex --version
IEx 1.15.7 (compiled with Erlang/OTP 26)
angelcool@fedora-laptop$mix --version
Erlang/OTP 26 [erts-14.2.2] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

Mix 1.15.7 (compiled with Erlang/OTP 26)
angelcool@fedora-laptop$mix phx.new --version
Phoenix installer v1.7.11
angelcool@fedora-laptop$
angelcool@fedora-laptop$
angelcool@fedora-laptop$
angelcool@fedora-laptop$ # The gist of this post...
angelcool@fedora-laptop$
angelcool@fedora-laptop$ # Terminal 1
angelcool@fedora-laptop$ iex --name a@127.0.0.1
iex(a@127.0.0.1)1>

angelcool@fedora-laptop$ #Terminal 2
angelcool@fedora-laptop$ iex --name b@127.0.0.1
Erlang/OTP 26 [erts-14.2.2] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

Interactive Elixir (1.15.7) - press Ctrl+C to exit (type h() ENTER for help)
iex(b@127.0.0.1)1> Node.connect :"a@127.0.0.1"
true
iex(b@127.0.0.1)2> Node.list
[:"a@127.0.0.1"]
iex(b@127.0.0.1)3>

# Terminal 1
iex(a@127.0.0.1)> Agent.start(
fn -> %{hello: "world"} end,
name: {:global, GlobalAgent}
)
{:ok, #PID<0.116.0>}

# Terminal 2
iex(b@127.0.0.1)4> Agent.get {:global,GlobalAgent}, &(&1)
%{hello: "world"}

# Terminal 2 - Update state
iex(b@127.0.0.1)5> Agent.update {:global, GlobalAgent}, fn _ -> %{hello: "everyone!"} end
:ok
iex(b@127.0.0.1)6>

# Terminal 2 - Get new state
iex(b@127.0.0.1)6> Agent.get {:global,GlobalAgent}, &(&1)
%{hello: "everyone!"}

# Terminal 1 - Get new state
iex(a@127.0.0.1)2> Agent.get {:global,GlobalAgent}, &(&1)
%{hello: "everyone!"}


[ view entry ] ( 35 views )   |  print article
Elixir: Processes Talking Amongst Themselves 
angelcool@fedora-laptop$date
Tue Apr 2 11:31:57 AM PDT 2024
angelcool@fedora-laptop$mix new process-demo --app process_a
* creating README.md
* creating .formatter.exs
* creating .gitignore
* creating mix.exs
* creating lib
* creating lib/process_a.ex
* creating test
* creating test/test_helper.exs
* creating test/process_a_test.exs

Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:

cd process-demo
mix test

Run "mix help" for more commands.
angelcool@fedora-laptop$
angelcool@fedora-laptop$cd process-demo/
angelcool@fedora-laptop$ls -l
total 8
drwxr-xr-x. 1 angelcool angelcool 24 Apr 2 11:31 lib
-rw-r--r--. 1 angelcool angelcool 575 Apr 2 11:31 mix.exs
-rw-r--r--. 1 angelcool angelcool 476 Apr 2 11:31 README.md
drwxr-xr-x. 1 angelcool angelcool 66 Apr 2 11:31 test
angelcool@fedora-laptop$
angelcool@fedora-laptop$cat lib/process_a.ex
defmodule ProcessA do
def receiverA(count) do
receive do
{from, message} -> send(from, {"Greetings from ProcessA!.", message})
receiverA(count+1)
end
end
end
angelcool@fedora-laptop$cat lib/process_b.ex
defmodule ProcessB do
def initialize do
pid_A = spawn(ProcessA, :receiverA, [1])
recieverB(pid_A)
end

def recieverB(pid_A) do
receive do
{message} ->
send(pid_A, {self(), message})
recieverB(pid_A)
{response, originalmessage} ->
IO.puts("Response: #{response}")
IO.puts("Original Message: #{originalmessage}")
recieverB(pid_A)
end
end
end
angelcool@fedora-laptop$
angelcool@fedora-laptop$iex --version
IEx 1.15.7 (compiled with Erlang/OTP 26)
angelcool@fedora-laptop$
angelcool@fedora-laptop$mix phx.new --version
Phoenix installer v1.7.11
angelcool@fedora-laptop$
angelcool@fedora-laptop$iex -S mix
Compiling 2 files (.ex)
Generated process_a app
Erlang/OTP 26 [erts-14.2.2] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

Interactive Elixir (1.15.7) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> pid_B = spawn(ProcessB, :initialize, [])
#PID<0.166.0>
iex(2)> send(pid_B, {"Hi! This is a message from process B!"})
Response: Greetings from ProcessA!.
{"Hi! This is a message from process B!"}
Original Message: Hi! This is a message from process B!
iex(3)>


[ view entry ] ( 39 views )   |  print article
Iperf - 1000BASE-LX SMF LC/LC Fiber Link Speed Test 
HOST A - SERVER

angelcool@2603-8000-6a00-5748-xxxx-xxxx-xxxx-xxxx:~$ date
Sun Mar 3 02:04:35 PM PST 2024

#IPv4
angelcool@2603-8000-6a00-5748-xxxx-xxxx-xxxx-xxxx:~$ iperf -s
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 128 KByte (default)
------------------------------------------------------------
[ 1] local 192.168.1.184 port 5001 connected with 192.168.1.192 port 57642 (icwnd/mss/irtt=14/1448/515)
[ ID] Interval Transfer Bandwidth
[ 1] 0.00-10.01 sec 1.10 GBytes 941 Mbits/sec
angelcool@2603-8000-6a00-5748-xxxx-xxxx-xxxx-xxxx:~$
angelcool@2603-8000-6a00-5748-xxxx-xxxx-xxxx-xxxx:~$

# IPv6
angelcool@2603-8000-6a00-5748-xxxx-xxxx-xxxx-xxxx:~$ iperf -s -V
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 128 KByte (default)
------------------------------------------------------------
[ 1] local 2603:8000:6a00:5748:xxxx:xxxx:xxxx:xxxx port 5001 connected with 2603:8000:6a00:5748:xxxx:xxxx:xxxx:xxxx port 56868 (icwnd/mss/irtt=13/1428/460)
[ ID] Interval Transfer Bandwidth
[ 1] 0.00-10.02 sec 1.08 GBytes 928 Mbits/sec
angelcool@2603-8000-6a00-5748-xxxx-xxxx-xxxx-xxxx:~$


HOST B - CLIENT

acool@localhost ~]$
# IPv4
[acool@localhost ~]$ iperf -c 192.168.1.184
------------------------------------------------------------
Client connecting to 192.168.1.184, TCP port 5001
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[ 1] local 192.168.1.192 port 57642 connected with 192.168.1.184 port 5001 (icwnd/mss/irtt=14/1448/731)
[ ID] Interval Transfer Bandwidth
[ 1] 0.00-10.02 sec 1.10 GBytes 940 Mbits/sec

# IPv6
[acool@localhost ~]$ iperf -c 2603:8000:6a00:xxxx:xxxx:xxxx:xxxx
------------------------------------------------------------
Client connecting to 2603:8000:6a00:xxxx:xxxx:xxxx:xxxx, TCP port 5001
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[ 1] local 2603:8000:6a00:5748:: port 56868 connected with 2603:8000:6a00:5748:xxxx:xxxx:xxxx:xxxx port 5001 (icwnd/mss/irtt=13/1428/783)
[ ID] Interval Transfer Bandwidth
[ 1] 0.00-10.02 sec 1.08 GBytes 928 Mbits/sec
[acool@localhost ~]$


[ view entry ] ( 44 views )   |  print article
SSL/TLS: Wildcard certificate 
Tested and working on 11/15/2023 !

# Create root CA
[acool@localhost tls]$openssl req --x509 --nodes --days 3650 --newkey rsa:2048 --keyout ENT-CA.key --out ENT-CA.crt

# Crate new key and signing request (Tip: remove --aes256 to remove passphrase requirement... I think)
Passphrase: mypassphrase
[acool@localhost tls]$openssl genrsa --out star-dev-localhost.key --aes256 2048
[acool@localhost tls]$openssl req --new --key star-dev-localhost.key --out star-dev-localhost.csr

# Sign request
[acool@localhost tls]$openssl x509 --req --in star-dev-localhost.csr --CA ENT-CA.crt --CAkey ENT-CA.key --CAcreateserial --days 3650 --sha256 --extfile star-dev-localhost.cnf --out star-dev-localhost.crt

# remove passphrase
[acool@localhost tls]$openssl rsa --in star-dev-localhost.key --out star-dev-localhost-nopassphrase.key

[acool@localhost tls]$ cat star-dev-localhost.cnf
authorityKeyIdentifier = keyid,issuer
basicConstraints = CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.dev.localhost
[acool@localhost tls]$
[acool@localhost tls]


# finally, import ENT-CA.crt certificate in Chrome
# chrome://settings/certificates


Configure Nginx:
...
listen 443 ssl;
ssl_certificate /etc/ssl/certs/star-dev-localhost.crt;
ssl_certificate_key /etc/ssl/certs/star-dev-localhost-nopassphrase.key;
...


[ view entry ] ( 143 views )   |  print article
C 101: Foreach loop macro 
[acool@localhost ~]$ 
[acool@localhost ~]$ date
Mon Apr 3 11:17:50 AM PDT 2023
[acool@localhost ~]$
[acool@localhost ~]$ cat c-foreach-macro.c
#include <stdio.h>

#define foreach(item, array) \
for(int keep = 1, \
count = 0,\
size = sizeof (array) / sizeof *(array); \
keep && count != size; \
keep = !keep, count++) \
for(item = (array) + count; keep; keep = !keep)

int main()
{
int mynumbers[] = {5,20,35,62,8,74,89};

char mygreeting[] = {"Hello world!"};

float myfloats[] = {1.6,6.9,5.8,43.5,1.1,0.9};

foreach(int *v, mynumbers) {
printf("value: %d\n", *v);
}

foreach(char *v, mygreeting) {
printf("value: %c\n", *v);
}

foreach(float *v, myfloats) {
printf("value: %.2f\n", *v);
}

return 0;
}
[acool@localhost ~]$
[acool@localhost ~]$ gcc c-foreach-macro.c -o c-foreach-macro
[acool@localhost ~]$
[acool@localhost ~]$ ./c-foreach-macro
value: 5
value: 20
value: 35
value: 62
value: 8
value: 74
value: 89
value: H
value: e
value: l
value: l
value: o
value:
value: w
value: o
value: r
value: l
value: d
value: !
value:
value: 1.60
value: 6.90
value: 5.80
value: 43.50
value: 1.10
value: 0.90
[acool@localhost ~]$


Bonus - dumping output from preprocessor.
[acool@localhost ~]$ 
[acool@localhost ~]$ gcc c-foreach-macro.c -E -o c-macro.preprocessed
[acool@localhost ~]$
[acool@localhost ~]$ cat c-macro.preprocessed
...
int main()
{
int mynumbers[] = {5,20,35,62,8,74,89};

char mygreeting[] = {"Hello world!"};

float myfloats[] = {1.6,6.9,5.8,43.5,1.1,0.9};

for(int keep = 1, count = 0, size = sizeof (mynumbers) / sizeof *(mynumbers); keep && count != size; keep = !keep, count++) for(int *v = (mynumbers) + count; keep; keep = !keep) {
printf("value: %d\n", *v);
}

for(int keep = 1, count = 0, size = sizeof (mygreeting) / sizeof *(mygreeting); keep && count != size; keep = !keep, count++) for(char *v = (mygreeting) + count; keep; keep = !keep) {
printf("value: %c\n", *v);
}

for(int keep = 1, count = 0, size = sizeof (myfloats) / sizeof *(myfloats); keep && count != size; keep = !keep, count++) for(float *v = (myfloats) + count; keep; keep = !keep) {
printf("value: %.2f\n", *v);
}

return 0;
}
[acool@localhost ~]$


[ view entry ] ( 183 views )   |  print article
C 101: Creating Child Processes With A Loop 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

void child( int seconds );

int children = 15;

int main(void)
{
printf("Parent ID %d, Main ID %d \n", getppid(), getpid());

for(int i=0;i<children;i++)
{
if(fork()==0)
{
child(children-i); // pass seconds to sleep
}
else
{
wait(NULL);
}
}
}

void child(int seconds)
{
printf("Parent ID %d, Child ID %d, Sleeping %d seconds.\n", getppid(), getpid(), seconds);
sleep(seconds);
exit(0);
}

[acool@localhost C-Exercises]$ date
Sun Oct 23 04:14:24 PM PDT 2022
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$ gcc parent_children.c
[acool@localhost C-Exercises]$ ./a.out
Parent ID 4298, Main ID 10357
Parent ID 10357, Child ID 10358, Sleeping 15 seconds.
Parent ID 10357, Child ID 10394, Sleeping 14 seconds.
Parent ID 10357, Child ID 10436, Sleeping 13 seconds.
Parent ID 10357, Child ID 10475, Sleeping 12 seconds.
Parent ID 10357, Child ID 10510, Sleeping 11 seconds.
Parent ID 10357, Child ID 10532, Sleeping 10 seconds.
Parent ID 10357, Child ID 10546, Sleeping 9 seconds.
Parent ID 10357, Child ID 10558, Sleeping 8 seconds.
Parent ID 10357, Child ID 10581, Sleeping 7 seconds.
Parent ID 10357, Child ID 10598, Sleeping 6 seconds.
Parent ID 10357, Child ID 10607, Sleeping 5 seconds.
Parent ID 10357, Child ID 10613, Sleeping 4 seconds.
Parent ID 10357, Child ID 10647, Sleeping 3 seconds.
Parent ID 10357, Child ID 10732, Sleeping 2 seconds.
Parent ID 10357, Child ID 10815, Sleeping 1 seconds.
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$ ps -A |grep a.out
10357 pts/0 00:00:00 a.out
10394 pts/0 00:00:00 a.out
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$ pstree -p 10357
a.out(10357)───a.out(10436)
[acool@localhost C-Exercises]$

Slightly different version, in this version we don't wait() for each child individually.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

void child( int seconds );

int children = 15;

int main(void)
{
printf("Parent ID %d, Main ID %d \n", getppid(), getpid());

for(int i=0;i<children;i++)
{
if(fork()==0)
{
child(children-i); // pass seconds to sleep
}
}

while (wait(NULL) > 0); // wait for all children to finish
}

void child(int seconds)
{
printf("Parent ID %d, Child ID %d, Sleeping %d seconds.\n", getppid(), getpid(), seconds);
sleep(seconds);
exit(0);
}

[acool@localhost C-Exercises]$ 
[acool@localhost C-Exercises]$ gcc parent_children.c
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$ ./a.out
Parent ID 4298, Main ID 14322
Parent ID 14322, Child ID 14323, Sleeping 15 seconds.
Parent ID 14322, Child ID 14324, Sleeping 14 seconds.
Parent ID 14322, Child ID 14325, Sleeping 13 seconds.
Parent ID 14322, Child ID 14326, Sleeping 12 seconds.
Parent ID 14322, Child ID 14327, Sleeping 11 seconds.
Parent ID 14322, Child ID 14328, Sleeping 10 seconds.
Parent ID 14322, Child ID 14329, Sleeping 9 seconds.
Parent ID 14322, Child ID 14330, Sleeping 8 seconds.
Parent ID 14322, Child ID 14331, Sleeping 7 seconds.
Parent ID 14322, Child ID 14332, Sleeping 6 seconds.
Parent ID 14322, Child ID 14333, Sleeping 5 seconds.
Parent ID 14322, Child ID 14334, Sleeping 4 seconds.
Parent ID 14322, Child ID 14335, Sleeping 3 seconds.
Parent ID 14322, Child ID 14336, Sleeping 2 seconds.
Parent ID 14322, Child ID 14337, Sleeping 1 seconds.
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$ pstree -p 14322
a.out(14322)─┬─a.out(14323)
├─a.out(14324)
├─a.out(14325)
├─a.out(14326)
├─a.out(14327)
├─a.out(14328)
├─a.out(14329)
├─a.out(14330)
├─a.out(14331)
├─a.out(14332)
├─a.out(14333)
├─a.out(14334)
└─a.out(14335)
[acool@localhost C-Exercises]$ ps -A |grep a.out
14322 pts/0 00:00:00 a.out
14323 pts/0 00:00:00 a.out
14324 pts/0 00:00:00 a.out
14325 pts/0 00:00:00 a.out
14326 pts/0 00:00:00 a.out
14327 pts/0 00:00:00 a.out
14328 pts/0 00:00:00 a.out
14329 pts/0 00:00:00 a.out
14330 pts/0 00:00:00 a.out
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$ pstree -p 14322
a.out(14322)─┬─a.out(14323)
├─a.out(14324)
├─a.out(14325)
├─a.out(14326)
├─a.out(14327)
└─a.out(14328)
[acool@localhost C-Exercises]$
[acool@localhost C-Exercises]$


[ view entry ] ( 221 views )   |  print article
C101: Printing Emojis 
#include <stdio.h>
#include <wchar.h>
#include <locale.h>

// multibyte array, each character is 4 bytes long
wchar_t mystring[] = L"Angel Cool á 🤪 😁 ა";

// [acool@localhost other]$ gcc -Wall -ggdb emoji-multibyte-array.c -o emoji-multibyte-array
int main()
{
setlocale(LC_ALL,"");

// print total number of characters in string
wprintf(L"wcslen of wchar_t mystring[]: %ld\n", wcslen(mystring));

// output string
wprintf(L"%ls\n",mystring);

// print one character
wprintf(L"Emoji : %lc\n", mystring[13]);

// print all
for (int j = 0; j < wcslen(mystring); ++j)
{
wprintf(L"%lc,", mystring[j]);
}

wprintf(L"\n");

// size in bytes of string, it also includes 4 bytes for the null (\0) characters at the end it seems
wprintf(L"Size in bytes of mystring[]: %d\n", sizeof(mystring));

// print size of wchar_t data type
wprintf(L"wchar_t is %d bytes long!\n", sizeof(wchar_t));

return 0;
}

[acool@localhost other]$ date
Sat Oct 22 12:05:24 PM PDT 2022
[acool@localhost other]$ gcc emoji-multibyte-array.c
[acool@localhost other]$ ./a.out
wcslen of wchar_t mystring[]: 18
Angel Cool á 🤪 😁 ა
Emoji : 🤪
A,n,g,e,l, ,C,o,o,l, ,á, ,🤪, ,😁, ,ა,
Size in bytes of mystring[]: 76
wchar_t is 4 bytes long!
[acool@localhost other]$


[ view entry ] ( 190 views )   |  print article
C 101: Preventing Zombie Processes  
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
pid_t pid;
int status;

pid = fork();

if(pid<0)
{
printf("Error: fork() returned %u.\n", pid);
return 1;
}

if(pid == 0)
{
printf("Child: PID is %u. Parent's PID is %u\n", getpid(), getppid());
sleep(10);
puts("Child: about to exit.\n");
return 33;
}
else
{
printf("Parent: PID is %u. Child's PID is %u\n", getpid(), pid);

while((pid=waitpid(-1,&status,WNOHANG)) == 0)
{
printf("Parent: No child has terminated.");
printf("Parent: Going to sleep for 1 second.\n");
sleep(1);
}
}

printf("Parent: child with PID %u ", pid);

if(WIFEXITED(status)!=0)
{
printf("exited with status %u\n",WIFEXITED(status));
}
else
{
printf("exited abnormally\n");
}

return 0;
}

Preventing Zombie Processes Using waitpid()
Listing 19.5 -Teach Yourself C For Linux Programming
[acool@localhost C-practice]$ gcc -Wall fork.c
[acool@localhost C-practice]$
[acool@localhost C-practice]$ ./a.out
Parent: PID is 57544. Child's PID is 57545
Parent: No child has terminated.Parent: Going to sleep for 1 second.
Child: PID is 57545. Parent's PID is 57544
Parent: No child has terminated.Parent: Going to sleep for 1 second.
Parent: No child has terminated.Parent: Going to sleep for 1 second.
Parent: No child has terminated.Parent: Going to sleep for 1 second.
Parent: No child has terminated.Parent: Going to sleep for 1 second.
Parent: No child has terminated.Parent: Going to sleep for 1 second.
Parent: No child has terminated.Parent: Going to sleep for 1 second.
Parent: No child has terminated.Parent: Going to sleep for 1 second.
Parent: No child has terminated.Parent: Going to sleep for 1 second.
Parent: No child has terminated.Parent: Going to sleep for 1 second.
Child: about to exit.

Parent: child with PID 57545 exited with status 1
[acool@localhost C-practice]$
[acool@localhost C-practice]$


[ view entry ] ( 218 views )   |  print article

| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Next> Last>>


2024 By Angel Cool