├── .DS_Store ├── Chapter01 ├── Makefile ├── TO_ADD.txt ├── first_script.sh ├── hello.cpp └── open_file.c ├── Chapter02 ├── atomic │ └── atomic.cpp ├── concurrency │ ├── concurrency_01.cpp │ ├── concurrency_02.cpp │ ├── concurrency_03.cpp │ └── concurrency_04.cpp ├── filesystem │ ├── filesystem_01.cpp │ └── filesystem_02.cpp ├── lambda │ ├── lambda_01.cpp │ └── lambda_02.cpp ├── moveSemantics │ ├── move_01.cpp │ ├── move_02.cpp │ └── move_03.cpp ├── primitiveTypes │ └── primitives.cpp └── smartPointer │ ├── shared_ptr.cpp │ ├── unique_ptr_01.cpp │ └── unique_ptr_02.cpp ├── Chapter03 ├── daemon_01.cpp ├── process_01.cpp ├── process_02.cpp ├── process_03.cpp ├── process_04.cpp └── thread_01.cpp ├── Chapter04 ├── alignedStorage.cpp ├── alignedStorage2.cpp ├── allocators.cpp ├── automatic.cpp ├── automaticDynamic.cpp ├── dynamic.cpp ├── isAligned.cpp ├── mmap_allocate.cpp ├── mmap_read.cpp ├── mmap_write.cpp ├── shared_ptr.cpp ├── shared_ptr2.cpp ├── unique_ptr.cpp └── unique_ptr2.cpp ├── Chapter05 ├── conditionVariable.cpp ├── lock_guard.cpp ├── posixMutex.cpp ├── posixSemaphore.cpp ├── producerConsumer.cpp ├── promiseFuture.cpp └── unique_lock.cpp ├── Chapter06 ├── fifo_chat_user1.c ├── fifo_chat_user2.c ├── mq_chat_user_1.c ├── mq_chat_user_2.c ├── pipe.c ├── shm_chat_user1.c └── shm_chat_user2.c ├── Chapter07 ├── clientTCP.cpp ├── clientUDP.cpp ├── serverTCP.cpp └── serverUDP.cpp ├── Chapter08 ├── console_01.cpp ├── console_02.cpp ├── console_03.cpp ├── console_04.cpp ├── console_05.cpp ├── console_06.cpp ├── console_07.cpp ├── file_01.cpp ├── file_01.txt ├── file_02.cpp ├── file_03.cpp ├── file_03.txt └── file_console_05.txt ├── Chapter09 ├── chrono_01.cpp ├── linux_time_01.cpp └── sleep.cpp ├── Chapter10 ├── signal_ignore.cpp ├── signal_send.cpp ├── signal_trap.cpp ├── signal_uncatchable.cpp └── signal_uncathable.cpp ├── Chapter11 ├── schedAffinity.cpp ├── schedGetInterval.cpp ├── schedNice.cpp ├── schedParameters.cpp └── schedYield.cpp ├── LICENSE └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/C-System-Programming-Cookbook/381ec1760ffec27b5cc2224bd201d7cd11d07b97/.DS_Store -------------------------------------------------------------------------------- /Chapter01/Makefile: -------------------------------------------------------------------------------- 1 | CC = g++ 2 | 3 | all: hello 4 | 5 | hello: hello.o 6 | ${CC} -o hello hello.o 7 | 8 | hello.o: hello.cpp 9 | ${CC} -c hello.cpp 10 | 11 | clean: 12 | rm hello.o hello 13 | -------------------------------------------------------------------------------- /Chapter01/TO_ADD.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/C-System-Programming-Cookbook/381ec1760ffec27b5cc2224bd201d7cd11d07b97/Chapter01/TO_ADD.txt -------------------------------------------------------------------------------- /Chapter01/first_script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cat does_not_exists.txt 3 | if [ $? -eq 0 ] 4 | then 5 | echo "All good, does_not_exists.txt exists!" 6 | exit 0 7 | else 8 | echo "does_not_exists.txt really DOES NOT exists!!" >&2 9 | exit 11 10 | fi 11 | 12 | -------------------------------------------------------------------------------- /Chapter01/hello.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int main() 3 | { 4 | std::cout << "Hello World!" << std::endl; 5 | return 0; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /Chapter01/open_file.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | int main(int argc, char *argv[]) 7 | { 8 | int fileDesc = open("myFile.txt", O_RDONLY); 9 | if (fileDesc == -1) 10 | { 11 | fprintf(stderr, "Cannot open myFile.txt .. error: %d\n", fileDesc); 12 | fprintf(stderr, "errno code = %d\n", errno); 13 | fprintf(stderr, "errno meaningn = %s\n", strerror(errno)); 14 | exit(1); 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /Chapter02/atomic/atomic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct MyArray { int z[50]; }; 6 | struct MyStr { int a, b; }; 7 | 8 | int main() 9 | { 10 | std::atomic myArray; 11 | std::atomic myStr; 12 | std::cout << std::boolalpha 13 | << "std::atomic is lock free? " 14 | << std::atomic_is_lock_free(&myArray) << std::endl 15 | << "std::atomic is lock free? " 16 | << std::atomic_is_lock_free(&myStr) << std::endl; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /Chapter02/concurrency/concurrency_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | void threadFunction1 (); 6 | int main() 7 | { 8 | std::thread t1 {threadFunction1}; 9 | 10 | t1.join(); 11 | return 0; 12 | } 13 | 14 | void threadFunction1 () 15 | { 16 | std::cout << "starting thread 1 ... " << std::endl; 17 | std::cout << "end thread 1 ... " << std::endl; 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /Chapter02/concurrency/concurrency_02.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void threadFunction (std::vector &speeds, int& res); 7 | int main() 8 | { 9 | std::vector speeds = {1, 2, 3, 4, 5}; 10 | int result = 0; 11 | std::thread t1 (threadFunction, std::ref(speeds), std::ref(result)); 12 | 13 | t1.join(); 14 | std::cout << "Result = " << result << std::endl; 15 | return 0; 16 | } 17 | 18 | void threadFunction (std::vector &speeds, int& res) 19 | { 20 | std::cout << "starting thread 1 ... " << std::endl; 21 | for_each(begin(speeds), end(speeds), [](int speed) { 22 | 23 | std::cout << "speed is " << speed << std::endl; 24 | 25 | }); 26 | res = 10; 27 | std::cout << "end thread 1 ... " << std::endl; 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /Chapter02/concurrency/concurrency_03.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int asyncFunction (); 5 | 6 | int main() 7 | { 8 | std::future fut = std::async(asyncFunction); 9 | std::cout << "max = " << fut.get() << std::endl; 10 | return 0; 11 | } 12 | 13 | int asyncFunction() 14 | { 15 | std::cout << "starting asyncFunction ... " << std::endl; 16 | int max = 0; 17 | for (int i = 0; i < 100000; ++i) 18 | { 19 | max += i; 20 | } 21 | std::cout << " Finished asyncFunction ..." << std::endl; 22 | return max; 23 | } 24 | 25 | 26 | -------------------------------------------------------------------------------- /Chapter02/concurrency/concurrency_04.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void asyncProducer(std::promise &prom); 5 | void asyncConsumer(std::future &fut); 6 | 7 | int main() 8 | { 9 | std::promise prom; 10 | std::future fut = prom.get_future(); 11 | 12 | std::async(asyncProducer, std::ref(prom)); 13 | std::async(asyncConsumer, std::ref(fut)); 14 | 15 | std::cout << "Async Producer-Consumer ended!" << std::endl; 16 | return 0; 17 | } 18 | void asyncConsumer(std::future &fut) 19 | { 20 | std::cout << "Got " << fut.get() << " from the producer ... " << std::endl; 21 | } 22 | 23 | void asyncProducer(std::promise &prom) 24 | { 25 | std::cout << " sending 5 to the consumer ... " << std::endl; 26 | prom.set_value (5); 27 | } 28 | 29 | 30 | -------------------------------------------------------------------------------- /Chapter02/filesystem/filesystem_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | for(auto& p: std::filesystem::directory_iterator("/")) 7 | std::cout << p << std::endl; 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /Chapter02/filesystem/filesystem_02.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::filesystem::create_directories("test/src/config"); 8 | std::ofstream("test/src/file.txt") << "This is an example!" << std::endl; 9 | } 10 | 11 | 12 | -------------------------------------------------------------------------------- /Chapter02/lambda/lambda_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main () 6 | { 7 | std::vector v {1, 2, 3, 4, 5, 6}; 8 | for_each (begin(v), end(v), [](int x) {std::cout << x << std::endl;}); 9 | return 0; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /Chapter02/lambda/lambda_02.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main () 6 | { 7 | std::vector v {1, 2, 3, 4, 5, 6}; 8 | std::string prefix ("0"); 9 | for_each (begin(v), end(v), [&prefix](int x) {std::cout << prefix << x << std::endl;}); 10 | return 0; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /Chapter02/moveSemantics/move_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main () { 5 | std::vector a = {1, 2, 3, 4, 5}; 6 | auto b = std::move(a); 7 | std::cout << "a: " << a.size() << std::endl; 8 | std::cout << "b: " << b.size() << std::endl; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /Chapter02/moveSemantics/move_02.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void print (std::string &&s) 5 | { 6 | std::cout << "print (std::string &&s)" << std::endl; 7 | std::string str (std::move(s)); 8 | std::cout << "universal reference ==> str = " << str << std::endl; 9 | std::cout << "universal reference ==> s = " << s << std::endl; 10 | } 11 | 12 | void print (std::string &s) 13 | { 14 | std::cout << "print (std::string &s)" << std::endl; 15 | } 16 | 17 | int main() 18 | { 19 | std::string str ("this is a string"); 20 | print (str); 21 | std::cout << "==> str = " << str << std::endl; 22 | return 0; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /Chapter02/moveSemantics/move_03.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void print (std::string &&s) 4 | { 5 | std::cout << "print (std::string &&s)" << std::endl; 6 | std::string str (std::move(s)); 7 | std::cout << "universal reference ==> str = " << str << std::endl; 8 | std::cout << "universal reference ==> s = " << s << std::endl; 9 | } 10 | 11 | void print (std::string &s) 12 | { 13 | std::cout << "print (std::string &s)" << std::endl; 14 | } 15 | 16 | int main() 17 | { 18 | print ("this is a string"); 19 | return 0; 20 | } 21 | 22 | 23 | -------------------------------------------------------------------------------- /Chapter02/primitiveTypes/primitives.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main () 5 | { 6 | // integral types section 7 | std::cout << "char " << int(std::numeric_limits::min()) 8 | << "-" << int(std::numeric_limits::max()) 9 | << " size (Byte) =" << sizeof (char) << std::endl; 10 | std::cout << "wchar_t " << std::numeric_limits::min() 11 | << "-" << std::numeric_limits::max() 12 | << " size (Byte) =" 13 | << sizeof (wchar_t) << std::endl; 14 | std::cout << "int " << std::numeric_limits::min() << "-" 15 | << std::numeric_limits::max() << " size (Byte) =" 16 | << sizeof (int) << std::endl; 17 | std::cout << "bool " << std::numeric_limits::min() << "-" 18 | << std::numeric_limits::max() << " size (Byte) =" 19 | << sizeof (bool) << std::endl; 20 | 21 | // floating point types 22 | std::cout << "float " << std::numeric_limits::min() << "-" 23 | << std::numeric_limits::max() << " size (Byte) =" 24 | << sizeof (float) << std::endl; 25 | std::cout << "double " << std::numeric_limits::min() << "-" 26 | << std::numeric_limits::max() << " size (Byte) =" 27 | << sizeof (double) << std::endl; 28 | 29 | return 0; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /Chapter02/smartPointer/shared_ptr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class CruiseControl 5 | { 6 | public: 7 | CruiseControl() 8 | { 9 | std::cout << "CruiseControl object created" << std::endl; 10 | }; 11 | ~CruiseControl() 12 | { 13 | std::cout << "CruiseControl object destroyed" << std::endl; 14 | } 15 | void increaseSpeedTo(int speed) 16 | { 17 | std::cout << "Speed at " << speed << std::endl; 18 | }; 19 | }; 20 | 21 | int main () 22 | { 23 | std::cout << "shared_ptr test started" << std::endl; 24 | 25 | std::shared_ptr cruiseControlMaster(nullptr); 26 | { 27 | std::shared_ptr cruiseControlSlave = std::make_shared(); 28 | cruiseControlMaster = cruiseControlSlave; 29 | } 30 | std::cout << "shared_ptr test finished" << std::endl; 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /Chapter02/smartPointer/unique_ptr_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class CruiseControl 5 | { 6 | public: 7 | CruiseControl() 8 | { 9 | std::cout << "CruiseControl object created" << std::endl; 10 | }; 11 | ~CruiseControl() 12 | { 13 | std::cout << "CruiseControl object destroyed" << std::endl; 14 | } 15 | void increaseSpeedTo(int speed) 16 | { 17 | std::cout << "Speed at " << speed << std::endl; 18 | }; 19 | }; 20 | 21 | int main () 22 | { 23 | std::cout << "unique_ptr test started" << std::endl; 24 | 25 | std::unique_ptr cruiseControl = std::make_unique(); 26 | cruiseControl->increaseSpeedTo(12); 27 | 28 | std::cout << "unique_ptr test finished" << std::endl; 29 | } 30 | 31 | 32 | -------------------------------------------------------------------------------- /Chapter02/smartPointer/unique_ptr_02.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class CruiseControl 5 | { 6 | public: 7 | CruiseControl() 8 | { 9 | std::cout << "CruiseControl object created" << std::endl; 10 | }; 11 | ~CruiseControl() 12 | { 13 | std::cout << "CruiseControl object destroyed" << std::endl; 14 | } 15 | void increaseSpeedTo(int speed) 16 | { 17 | std::cout << "Speed at " << speed << std::endl; 18 | }; 19 | }; 20 | 21 | int main () 22 | { 23 | std::cout << "unique_ptr test started" << std::endl; 24 | 25 | std::unique_ptr cruiseControl = std::make_unique(3); 26 | cruiseControl[1].increaseSpeedTo(12); 27 | 28 | std::cout << "unique_ptr test finished" << std::endl; 29 | } 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Chapter03/daemon_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(void) 6 | { 7 | pid_t child; 8 | int status; 9 | std::cout << "I am the parent, my PID is " << getpid() << std::endl; 10 | std::cout << "I am going to create a new daemon process..." << std::endl; 11 | 12 | // clear file creation mask 13 | umask(0); 14 | 15 | child = fork(); 16 | if (child == -1) 17 | { 18 | std::cout << "fork() failed." << std::endl; 19 | return (-1); 20 | } 21 | else if (child == 0) 22 | { 23 | setsid(); 24 | if (chdir("/") < 0) 25 | std::cout << "Couldn't change directory" << std::endl; 26 | 27 | // Attach here the daemon specific long running tasks ... sleep for now. 28 | sleep (10); 29 | } 30 | return (0); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /Chapter03/process_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main(void) 9 | { 10 | pid_t child; 11 | int status; 12 | std::cout << "I am the parent, my PID is " << getpid() << std::endl; 13 | std::cout << "My parent's PID is " << getppid() << std::endl; 14 | std::cout << "I am going to create a new process..." << std::endl; 15 | child = fork(); 16 | if (child == -1) 17 | { 18 | // fork() returns -1 on failure 19 | std::cout << "fork() failed." << std::endl; 20 | return (-1); 21 | } 22 | else if (child == 0) 23 | { 24 | // fork() returns 0 to the child process 25 | std::cout << "I am the child, my PID is " << getpid() << std::endl; 26 | std::cout << "My parent's PID is " << getppid() << std::endl; 27 | } 28 | else 29 | { 30 | // fork() returns the PID of the child to the parent 31 | wait(&status); // wait for the child process to finish... 32 | std::cout << "I am the parent, my PID is still " << getpid() << std::endl; 33 | } 34 | return (0); 35 | } 36 | 37 | -------------------------------------------------------------------------------- /Chapter03/process_02.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int main(void) 10 | { 11 | pid_t child; 12 | int status; 13 | std::cout << "I am the parent, my PID is " << getpid() << std::endl; 14 | std::cout << "My parent's PID is " << getppid() << std::endl; 15 | std::cout << "I am going to create a new process..." << std::endl; 16 | child = fork(); 17 | if (child == -1) 18 | { 19 | // fork() returns -1 on failure 20 | std::cout << "fork() failed." << std::endl; 21 | return 1; 22 | } 23 | else if (child == 0) 24 | { 25 | if (execl("/usr/bin/ls", "ls", "-l", NULL) < 0) { 26 | std::cout << "execl failed!" << std::endl; 27 | return 2; 28 | } 29 | std::cout << "I am the child, my PID is " << getpid() << std::endl; 30 | std::cout << "My parent's PID is " << getppid() << std::endl; 31 | } 32 | else 33 | { 34 | wait(&status); // wait for the child process to finish... 35 | } 36 | return (0); 37 | } 38 | 39 | -------------------------------------------------------------------------------- /Chapter03/process_03.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int main(void) 10 | { 11 | pid_t child; 12 | int status; 13 | std::cout << "I am the parent, my PID is " << getpid() << std::endl; 14 | child = fork(); 15 | std::cout << "Forked a child process with PID = " << child << std::endl; 16 | if (child == -1) 17 | { 18 | std::cout << "fork() failed." << std::endl; 19 | return 1; 20 | } 21 | else if (child == 0) 22 | { 23 | std::cout << "About to run the child process with PID = " << child << std::endl; 24 | if (execl("./child.out", "child.out", NULL) < 0) 25 | { 26 | std::cout << "error in executing child proceess " << std::endl; 27 | return 2; 28 | } 29 | } 30 | else 31 | { 32 | std::cout << "killing the child process with PID = " << child << std::endl; 33 | int status = kill (child, 9); 34 | if (status == 0) 35 | std::cout << "child process killed ...." << std::endl; 36 | else 37 | std::cout << "there was a problem killing the process with PID = " << child << std::endl; 38 | } 39 | return (0); 40 | } 41 | 42 | -------------------------------------------------------------------------------- /Chapter03/process_04.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int main(void) 10 | { 11 | std::cout << "Running child ..." << std::endl; 12 | while (true) 13 | ; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Chapter03/thread_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void threadFunction (std::vector &speeds, int start, int end, int& res); 7 | 8 | int main() 9 | { 10 | std::vector speeds (100000); 11 | std::generate(begin(speeds), end(speeds), [] () { return rand() % 10 ; }); 12 | 13 | int th1Result = 0; 14 | std::thread t1 (threadFunction, std::ref(speeds), 0, 49999, std::ref(th1Result)); 15 | 16 | int th2Result = 0; 17 | std::thread t2 (threadFunction, std::ref(speeds), 50000, 99999, std::ref(th2Result)); 18 | 19 | t1.join(); 20 | t2.join(); 21 | std::cout << "Result = " << th1Result + th2Result << std::endl; 22 | return 0; 23 | } 24 | 25 | void threadFunction (std::vector &speeds, int start, int end, int& res) 26 | { 27 | std::cout << "starting thread ... " << std::endl; 28 | for (int i = start; i <= end; ++i) 29 | res += speeds[i]; 30 | std::cout << "end thread ... " << std::endl; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /Chapter04/alignedStorage.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | std::cout << "int alignment = " << std::alignment_of::value << std::endl; 7 | std::cout << "double alignment = " << std::alignment_of::value << std::endl; 8 | 9 | return (0); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /Chapter04/alignedStorage2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef std::aligned_storage::type intAligned; 5 | 6 | int main() 7 | { 8 | intAligned i, j; 9 | new (&i) int(); 10 | new (&j) int(); 11 | int* iu = &reinterpret_cast(i); 12 | *iu = 12; 13 | 14 | int* ju = &reinterpret_cast(j); 15 | *ju = 13; 16 | 17 | std::cout << "alignment = " << std::alignment_of::value << std::endl; 18 | std::cout << "value = " << *iu << std::endl; 19 | std::cout << "value2 = " << reinterpret_cast(i) << std::endl; 20 | return (0); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /Chapter04/allocators.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | template 6 | class mmap_allocator 7 | { 8 | public: 9 | 10 | using value_type = T; 11 | template struct rebind { 12 | using alloc = mmap_allocator; 13 | }; 14 | 15 | public: 16 | 17 | mmap_allocator() {}; 18 | 19 | template 20 | mmap_allocator(const mmap_allocator &alloc) noexcept 21 | { 22 | (void) alloc; 23 | }; 24 | 25 | T* allocate(std::size_t n) 26 | { 27 | std::cout << "allocating ... n = " << n << std::endl; 28 | auto* mapPtr = static_cast (mmap(0, sizeof(T) * n, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); 29 | if (mapPtr != MAP_FAILED) 30 | return static_cast(mapPtr); 31 | throw std::bad_alloc(); 32 | }; 33 | 34 | void deallocate(T* p, std::size_t n) 35 | { 36 | std::cout << "deallocating ... n = " << n << std::endl; 37 | munmap(p, sizeof(T) * n); 38 | }; 39 | }; 40 | 41 | int main () 42 | { 43 | std::vector> mmap_vector = {1, 2, 3, 4, 5}; 44 | 45 | for (auto i : mmap_vector) 46 | std::cout << i << std::endl; 47 | 48 | return 0; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /Chapter04/automatic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class User 4 | { 5 | public: 6 | User(){}; 7 | 8 | ~User(){}; 9 | 10 | void cheers() {std::cout << " hello!" << std::endl;}; 11 | }; 12 | 13 | int main() 14 | { 15 | std::cout << "Start ... " << std::endl; 16 | { 17 | User developer; 18 | developer.cheers(); 19 | } 20 | std::cout << "End ... " << std::endl; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /Chapter04/automaticDynamic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class User 4 | { 5 | public: 6 | User(){}; 7 | 8 | ~User(){}; 9 | 10 | void cheers() {std::cout << " hello!" << std::endl;}; 11 | }; 12 | 13 | int main() 14 | { 15 | std::cout << "Start ... " << std::endl; 16 | { 17 | User developer; 18 | developer.cheers(); 19 | } 20 | std::cout << "End ... " << std::endl; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /Chapter04/dynamic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class User 4 | { 5 | public: 6 | User(){}; 7 | 8 | ~User(){}; 9 | 10 | void cheers() {std::cout << " hello!" << std::endl;}; 11 | }; 12 | 13 | int main() 14 | { 15 | std::cout << "Start ... " << std::endl; 16 | { 17 | User* developer = new User(); 18 | developer->cheers(); 19 | delete developer; 20 | } 21 | std::cout << "End ... " << std::endl; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /Chapter04/isAligned.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using intAligned8 = std::aligned_storage::type; 5 | using intAligned4 = std::aligned_storage::type; 6 | 7 | int main() 8 | { 9 | intAligned8 i; new (&i) int(); 10 | intAligned4 j; new (&j) int(); 11 | int* iu = &reinterpret_cast(i); 12 | *iu = 12; 13 | 14 | int* ju = &reinterpret_cast(j); 15 | *ju = 13; 16 | 17 | if (reinterpret_cast(iu) % 8 == 0) 18 | std::cout << "memory pointed by the variable aligned to 8 byte" << std::endl; 19 | else 20 | std::cout << "memory pointed by the variable NOT aligned to 8 bytes" << std::endl; 21 | if (reinterpret_cast(ju) % 8 == 0) 22 | std::cout << "memory pointed by the variable aligned to 8 bytes" << std::endl; 23 | else 24 | std::cout << "memory pointed by the variable NOT aligned to 8 bytes" << std::endl; 25 | 26 | return (0); 27 | } 28 | 29 | -------------------------------------------------------------------------------- /Chapter04/mmap_allocate.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | constexpr auto SIZE = 1024; 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | auto* mapPtr = (char*) mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 10 | if (mapPtr == MAP_FAILED) 11 | { 12 | std::cout << "Error mapping memory " << std::endl; 13 | return 1; 14 | } 15 | std::cout << "memory allocated available from: " << mapPtr << std::endl; 16 | 17 | strcpy (mapPtr, "this is a string!"); 18 | std::cout << "mapPtr val = " << mapPtr << std::endl; 19 | 20 | if (munmap(mapPtr, SIZE) == -1) 21 | std::cout << "Error un-mapping" << std::endl; 22 | 23 | return 0; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /Chapter04/mmap_read.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define FILEPATH "mmapped.txt" 9 | #define NUM_OF_ITEMS_IN_FILE (1000) 10 | #define FILESIZE (NUM_OF_ITEMS_IN_FILE * sizeof(int)) 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | int fd = open(FILEPATH, O_RDONLY); 15 | if (fd == -1) 16 | { 17 | std::cout << "Error opening file " << FILEPATH << std::endl; 18 | return 1; 19 | } 20 | 21 | int* map = (int*) mmap(0, FILESIZE, PROT_READ, MAP_SHARED, fd, 0); 22 | if (map == MAP_FAILED) 23 | { 24 | close(fd); 25 | std::cout << "Error mapping the file " << std::endl; 26 | return 4; 27 | } 28 | 29 | for (int i = 1; i <= NUM_OF_ITEMS_IN_FILE; ++i) 30 | std::cout << "i = " << map[i] << std::endl; 31 | 32 | if (munmap(map, FILESIZE) == -1) { 33 | std::cout << "Error un-mapping" << std::endl; 34 | } 35 | 36 | close(fd); 37 | return 0; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /Chapter04/mmap_write.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define FILEPATH "mmapped.txt" 9 | #define NUM_OF_ITEMS_IN_FILE (1000) 10 | #define FILESIZE (NUM_OF_ITEMS_IN_FILE * sizeof(int)) 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | int fd = open(FILEPATH, O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600); 15 | if (fd == -1) 16 | { 17 | std::cout << "Error opening file " << FILEPATH << std::endl; 18 | return 1; 19 | } 20 | 21 | int result = lseek(fd, FILESIZE-1, SEEK_SET); 22 | if (result == -1) 23 | { 24 | close(fd); 25 | std::cout << "Error calling lseek " << std::endl; 26 | return 2; 27 | } 28 | 29 | result = write(fd, "", 1); 30 | if (result != 1) 31 | { 32 | close(fd); 33 | std::cout << "Error writing into the file " << std::endl; 34 | return 3; 35 | } 36 | 37 | int* map = (int*) mmap(0, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 38 | if (map == MAP_FAILED) 39 | { 40 | close(fd); 41 | std::cout << "Error mapping the file " << std::endl; 42 | return 4; 43 | } 44 | 45 | for (int i = 1; i <=NUM_OF_ITEMS_IN_FILE; ++i) 46 | map[i] = 2 * i; 47 | 48 | if (munmap(map, FILESIZE) == -1) 49 | std::cout << "Error un-mapping" << std::endl; 50 | 51 | close(fd); 52 | return 0; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /Chapter04/shared_ptr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class User 5 | { 6 | public: 7 | User(){ 8 | std::cout << "User Constructor" << std::endl; 9 | }; 10 | 11 | ~User(){ 12 | std::cout << "User Destructor" << std::endl; 13 | }; 14 | 15 | void cheers() {std::cout << " hello!" << std::endl;}; 16 | }; 17 | 18 | int main() 19 | { 20 | std::cout << "Start ... " << std::endl; 21 | auto shared1 = std::make_shared(); 22 | { 23 | auto shared2 = shared1; 24 | shared2->cheers(); std::cout << " from shared2" << std::endl; 25 | shared1->cheers(); std::cout << " from shared1" << std::endl; 26 | } 27 | std::cout << "End ... " << std::endl; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /Chapter04/shared_ptr2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class User 5 | { 6 | public: 7 | User(){ 8 | std::cout << "User Constructor" << std::endl; 9 | }; 10 | 11 | ~User(){ 12 | std::cout << "User Destructor" << std::endl; 13 | }; 14 | 15 | void cheers() {std::cout << " hello!" << std::endl;}; 16 | }; 17 | 18 | int main() 19 | { 20 | std::cout << "Start ... " << std::endl; 21 | auto shared1 = std::make_shared(); 22 | { 23 | auto shared2 = shared1; 24 | User* newAllocation = new User(); 25 | auto uniqueAllocation = std::make_unique(); 26 | 27 | std::cout << "shared2 size = " << sizeof (shared2) << std::endl; 28 | std::cout << "newAllocation size = " << sizeof (newAllocation) << std::endl; 29 | std::cout << "uniqueAllocation size = " << sizeof (uniqueAllocation) << std::endl; 30 | delete newAllocation; 31 | } 32 | std::cout << "End ... " << std::endl; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /Chapter04/unique_ptr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class User 5 | { 6 | public: 7 | User() 8 | { 9 | std::cout << "User costructor" << std::endl; 10 | }; 11 | ~User() 12 | { 13 | std::cout << "User Destructor" << std::endl; 14 | }; 15 | 16 | void cheers() 17 | { 18 | std::cout << " hello!" << std::endl; 19 | }; 20 | }; 21 | 22 | int main() 23 | { 24 | std::cout << "Start ... " << std::endl; 25 | { 26 | auto developer = std::make_unique(); 27 | developer->cheers(); 28 | } 29 | std::cout << "End ... " << std::endl; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /Chapter04/unique_ptr2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class User 5 | { 6 | public: 7 | User(){ 8 | std::cout << "User Constructor" << std::endl; 9 | }; 10 | 11 | ~User(){ 12 | std::cout << "User Destructor" << std::endl; 13 | }; 14 | 15 | void cheers() {std::cout << " hello!" << std::endl;}; 16 | }; 17 | 18 | int main() 19 | { 20 | std::cout << "Start ... " << std::endl; 21 | { 22 | auto developer = std::make_unique(); 23 | User* developer2 = new User(); 24 | std::cout << "developer size = " << sizeof (developer) << std::endl; 25 | std::cout << "developer2 size = " << sizeof (developer2) << std::endl; 26 | delete developer2; 27 | } 28 | std::cout << "End ... " << std::endl; 29 | } 30 | 31 | -------------------------------------------------------------------------------- /Chapter05/conditionVariable.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | struct Item 7 | { 8 | int age; 9 | std::string name; 10 | std::string surname; 11 | }; 12 | 13 | std::queue queue; 14 | std::condition_variable cond; 15 | std::mutex mut; 16 | 17 | void producer(); 18 | void consumer(); 19 | 20 | int main() 21 | { 22 | std::thread t1 (producer); 23 | std::thread t2 (consumer); 24 | 25 | t1.join(); 26 | t2.join(); 27 | 28 | return 0; 29 | } 30 | 31 | void consumer() 32 | { 33 | std::cout << "Consumer ... " << std::endl; 34 | while(true) 35 | { 36 | std::unique_lock lck{mut}; 37 | std::cout << "Consumer ... loop ... START" << std::endl; 38 | cond.wait(lck); 39 | // cond.wait(lck, []{ return !queue.empty();}); 40 | auto item = queue.front(); 41 | queue.pop(); 42 | std::cout << "Age = " << item.age << " Name = " << item.name << " Surname = " << item.surname << std::endl; 43 | std::cout << "Queue Size = " << queue.size() << std::endl; 44 | std::cout << "Consumer ... loop ... END" << std::endl; 45 | lck.unlock(); 46 | } 47 | } 48 | 49 | void producer() 50 | { 51 | std::cout << "Producer ... " << std::endl; 52 | while(true) 53 | { 54 | Item item; 55 | item.age = 35; 56 | item.name = "Jack"; 57 | item.surname = "Sparrow"; 58 | std::lock_guard lock {mut}; 59 | std::cout << "Producer ... loop ... START" << std::endl; 60 | queue.push(item); 61 | cond.notify_one(); 62 | std::cout << "Producer ... loop ... END" << std::endl; 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /Chapter05/lock_guard.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct ThreadInfo 6 | { 7 | std::mutex mutex; 8 | int counter; 9 | }; 10 | 11 | void increment(ThreadInfo &info) 12 | { 13 | std::lock_guard lock(info.mutex); 14 | std::cout << "Thread Started ... " << std::endl; 15 | 16 | for (int i = 0; i < 100000; ++i) 17 | info.counter++; 18 | 19 | std::cout << "Thread Finished ... " << std::endl; 20 | } 21 | 22 | int main() 23 | { 24 | ThreadInfo thInfo; 25 | 26 | std::thread t1 (increment, std::ref(thInfo)); 27 | std::thread t2 (increment, std::ref(thInfo)); 28 | 29 | t1.join(); 30 | t2.join(); 31 | 32 | std::cout << "lock_guard:: Threads elaboration finished. Counter = " << thInfo.counter << std::endl; 33 | return 0; 34 | } 35 | 36 | -------------------------------------------------------------------------------- /Chapter05/posixMutex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct ThreadInfo 5 | { 6 | pthread_mutex_t lock; 7 | int counter; 8 | }; 9 | 10 | void* increment(void *arg) 11 | { 12 | ThreadInfo* info = static_cast(arg); 13 | pthread_mutex_lock(&info->lock); 14 | 15 | std::cout << "Thread Started ... " << std::endl; 16 | 17 | for (int i = 0; i < 100000; ++i) 18 | info->counter++; 19 | 20 | std::cout << "Thread Finished ... " << std::endl; 21 | pthread_mutex_unlock(&info->lock); 22 | return nullptr; 23 | } 24 | 25 | int main() 26 | { 27 | ThreadInfo thInfo; 28 | thInfo.counter = 0; 29 | if (pthread_mutex_init(&thInfo.lock, nullptr) != 0) 30 | { 31 | std::cout << "pthread_mutex_init failed!" << std::endl; 32 | return 1; 33 | } 34 | 35 | pthread_t t1; 36 | if (pthread_create(&t1, nullptr, &increment, &thInfo) != 0) 37 | { 38 | std::cout << "pthread_create for t1 failed! " << std::endl; 39 | return 2; 40 | } 41 | 42 | pthread_t t2; 43 | if (pthread_create(&t2, nullptr, &increment, &thInfo) != 0) 44 | { 45 | std::cout << "pthread_create for t2 failed! " << std::endl; 46 | return 3; 47 | } 48 | 49 | pthread_join(t1, nullptr); 50 | pthread_join(t2, nullptr); 51 | 52 | std::cout << "Threads elaboration finished. Counter = " << thInfo.counter << std::endl; 53 | pthread_mutex_destroy(&thInfo.lock); 54 | return 0; 55 | } 56 | 57 | -------------------------------------------------------------------------------- /Chapter05/posixSemaphore.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct ThreadInfo 6 | { 7 | sem_t sem; 8 | int counter; 9 | }; 10 | 11 | void* increment(void *arg) 12 | { 13 | ThreadInfo* info = static_cast(arg); 14 | sem_wait(&info->sem); 15 | 16 | std::cout << "Thread Started ... " << std::endl; 17 | 18 | for (int i = 0; i < 100000; ++i) 19 | info->counter++; 20 | 21 | std::cout << "Thread Finished ... " << std::endl; 22 | sem_post(&info->sem); 23 | return nullptr; 24 | } 25 | 26 | int main() 27 | { 28 | ThreadInfo thInfo; 29 | thInfo.counter = 0; 30 | if (sem_init(&thInfo.sem, 0, 1) != 0) 31 | { 32 | std::cout << "sem_init failed!" << std::endl; 33 | return 1; 34 | } 35 | 36 | pthread_t t1; 37 | if (pthread_create(&t1, nullptr, &increment, &thInfo) != 0) 38 | { 39 | std::cout << "pthread_create for t1 failed! " << std::endl; 40 | return 2; 41 | } 42 | 43 | pthread_t t2; 44 | if (pthread_create(&t2, nullptr, &increment, &thInfo) != 0) 45 | { 46 | std::cout << "pthread_create for t2 failed! " << std::endl; 47 | return 3; 48 | } 49 | 50 | pthread_join(t1, nullptr); 51 | pthread_join(t2, nullptr); 52 | 53 | std::cout << "posixSemaphore:: Threads elaboration finished. Counter = " << thInfo.counter << std::endl; 54 | sem_destroy(&thInfo.sem); 55 | return 0; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /Chapter05/producerConsumer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | constexpr auto MAX_ITEM_IN_QUEUE = 5; 7 | 8 | struct QueueInfo 9 | { 10 | sem_t mutex; 11 | sem_t full; 12 | sem_t empty; 13 | std::vector queue; 14 | }; 15 | 16 | void* producer(void *arg) 17 | { 18 | QueueInfo* info = (QueueInfo*)arg; 19 | std::cout << "Thread Producer Started ... " << std::endl; 20 | for (int i = 0; i < 1000; i++) 21 | { 22 | sem_wait(&info->full); 23 | 24 | sem_wait(&info->mutex); 25 | info->queue.push_back(i); 26 | std::cout << "Thread Producer Started ... size = " << info->queue.size() << std::endl; 27 | sem_post(&info->mutex); 28 | 29 | sem_post(&info->empty); 30 | } 31 | 32 | std::cout << "Thread Producer Finished ... " << std::endl; 33 | return nullptr; 34 | } 35 | 36 | 37 | void* consumer(void *arg) 38 | { 39 | QueueInfo* info = (QueueInfo*)arg; 40 | std::cout << "Thread Consumer Started ... " << std::endl; 41 | for (int i = 0; i < 1000; i++) 42 | { 43 | sem_wait(&info->empty); 44 | 45 | sem_wait(&info->mutex); 46 | if (!info->queue.empty()) 47 | { 48 | int b = info->queue.back(); 49 | info->queue.pop_back(); 50 | } 51 | std::cout << "Thread Consumer Started ... size = " << info->queue.size() << std::endl; 52 | sem_post(&info->mutex); 53 | 54 | sem_post(&info->full); 55 | } 56 | 57 | std::cout << "Thread Consumer Finished ... " << std::endl; 58 | return nullptr; 59 | } 60 | 61 | int main() 62 | { 63 | QueueInfo thInfo; 64 | if (sem_init(&thInfo.mutex, 0, 1) != 0 || 65 | sem_init(&thInfo.full, 0, MAX_ITEM_IN_QUEUE) != 0 || 66 | sem_init(&thInfo.empty, 0, 0) != 0) 67 | { 68 | std::cout << "sem_init failed!" << std::endl; 69 | return 1; 70 | } 71 | 72 | pthread_t producerPthread; 73 | if (pthread_create(&producerPthread, nullptr, &producer, &thInfo) != 0) 74 | { 75 | std::cout << "pthread_create for producer failed! " << std::endl; 76 | return 2; 77 | } 78 | 79 | pthread_t consumerPthread; 80 | if (pthread_create(&consumerPthread, nullptr, &consumer, &thInfo) != 0) 81 | { 82 | std::cout << "pthread_create for consumer failed! " << std::endl; 83 | return 3; 84 | } 85 | 86 | pthread_join(producerPthread, nullptr); 87 | pthread_join(consumerPthread, nullptr); 88 | 89 | sem_destroy(&thInfo.mutex); 90 | sem_destroy(&thInfo.full); 91 | sem_destroy(&thInfo.empty); 92 | return 0; 93 | } 94 | 95 | -------------------------------------------------------------------------------- /Chapter05/promiseFuture.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Item 5 | { 6 | int age; 7 | std::string nameCode; 8 | std::string surnameCode; 9 | }; 10 | 11 | void asyncProducer(std::promise &prom); 12 | void asyncConsumer(std::future &fut); 13 | 14 | int main() 15 | { 16 | std::promise prom; 17 | std::future fut = prom.get_future(); 18 | 19 | std::async(asyncProducer, std::ref(prom)); 20 | std::async(asyncConsumer, std::ref(fut)); 21 | 22 | return 0; 23 | } 24 | 25 | void asyncConsumer(std::future &fut) 26 | { 27 | 28 | std::cout << "Consumer ... got the result " << std::endl; 29 | Item item = fut.get(); 30 | std::cout << "Age = " << item.age << " Name = " << item.nameCode 31 | << " Surname = " << item.surnameCode << std::endl; 32 | } 33 | 34 | void asyncProducer(std::promise &prom) 35 | { 36 | std::cout << "Producer ... computing " << std::endl; 37 | 38 | // just returning an item! In reality this thread most likely 39 | // perform a high intensive computation to retrive an item and 40 | // returning the output to a client (future) which is waiting the 41 | // results. 42 | Item item; 43 | item.age = 35; 44 | item.nameCode = "Jack"; 45 | item.surnameCode = "Sparrow"; 46 | 47 | prom.set_value(item); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /Chapter05/unique_lock.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct ThreadInfo 6 | { 7 | std::mutex mutex; 8 | int counter; 9 | }; 10 | 11 | void increment(ThreadInfo &info) 12 | { 13 | std::unique_lock lock(info.mutex); 14 | std::cout << "Thread Started ... " << std::endl; 15 | 16 | if (info.counter < 0) 17 | { 18 | lock.unlock(); 19 | return; 20 | } 21 | 22 | for (int i = 0; i < 100000; ++i) 23 | info.counter++; 24 | 25 | std::cout << "Thread Finished ... " << std::endl; 26 | } 27 | 28 | int main() 29 | { 30 | ThreadInfo thInfo; 31 | thInfo.counter = 0; 32 | 33 | std::thread t1 (increment, std::ref(thInfo)); 34 | std::thread t2 (increment, std::ref(thInfo)); 35 | 36 | t1.join(); 37 | t2.join(); 38 | 39 | std::cout << "Unique_lock:: Threads elaboration finished. Counter = " << thInfo.counter << std::endl; 40 | return 0; 41 | } 42 | 43 | -------------------------------------------------------------------------------- /Chapter06/fifo_chat_user1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define MAX_LENGTH 128 8 | 9 | int main() 10 | { 11 | char* fifoChat = "/tmp/chat"; 12 | mkfifo(fifoChat, 0600); 13 | 14 | char msgReceived[MAX_LENGTH], msgToSend[MAX_LENGTH]; 15 | while (1) 16 | { 17 | // write section 18 | int fdUser1 = open(fifoChat, O_WRONLY); 19 | printf("User1: "); 20 | fgets(msgToSend, MAX_LENGTH, stdin); 21 | write(fdUser1, msgToSend, strlen(msgToSend)+1); 22 | close(fdUser1); 23 | 24 | // read section 25 | int fdUser2 = open(fifoChat, O_RDONLY); 26 | read(fdUser2, msgReceived, sizeof(msgReceived)); 27 | printf("User2: %s\n", msgReceived); 28 | close(fdUser2); 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Chapter06/fifo_chat_user2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define MAX_LENGTH 128 8 | 9 | int main() 10 | { 11 | char* myfifo = "/tmp/chat"; 12 | mkfifo(myfifo, 0600); 13 | 14 | char msgReceived[MAX_LENGTH], msgToSend[MAX_LENGTH]; 15 | while (1) 16 | { 17 | int fdUser2 = open(myfifo, O_RDONLY); 18 | read(fdUser2, msgReceived, sizeof(msgReceived)); 19 | printf("User1: %s\n", msgReceived); 20 | close(fdUser2); 21 | 22 | int fdUser1 = open(myfifo, O_WRONLY); 23 | printf("User2: "); 24 | fgets(msgToSend, MAX_LENGTH, stdin); 25 | write(fdUser1, msgToSend, strlen(msgToSend)+1); 26 | close(fdUser1); 27 | } 28 | return 0; 29 | } 30 | 31 | -------------------------------------------------------------------------------- /Chapter06/mq_chat_user_1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define MAX_MESSAGES 10 6 | #define MAX_MSG_SIZE 256 7 | 8 | int main() 9 | { 10 | mqd_t user1Desc, user2Desc; 11 | char message[MAX_MSG_SIZE]; 12 | char message2[MAX_MSG_SIZE]; 13 | 14 | struct mq_attr attr; 15 | attr.mq_flags = 0; 16 | attr.mq_maxmsg = MAX_MESSAGES; 17 | attr.mq_msgsize = MAX_MSG_SIZE; 18 | attr.mq_curmsgs = 0; 19 | 20 | if ((user1Desc = mq_open ("/user1", O_WRONLY | O_CREAT, "0660", &attr)) == -1) 21 | { 22 | perror ("User1: mq_open error"); 23 | return (1); 24 | } 25 | if ((user2Desc = mq_open ("/user2", O_RDONLY | O_CREAT, "0660", &attr)) == -1) 26 | { 27 | perror ("User2: mq_open error"); 28 | return (1); 29 | } 30 | 31 | while (1) 32 | { 33 | // send message to server 34 | printf("USER 1: "); 35 | fgets(message, MAX_MSG_SIZE, stdin); 36 | if (mq_send (user1Desc, message, strlen (message) + 1, 0) == -1) 37 | { 38 | perror ("Not able to send message to User 2"); 39 | continue; 40 | } 41 | 42 | if (mq_receive (user2Desc, message2, MAX_MSG_SIZE, NULL) == -1) 43 | { 44 | perror ("tried to receive a message from User 2 but I've failed!"); 45 | continue; 46 | } 47 | printf("USER 2: %s\n", message2); 48 | } 49 | 50 | return 0; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /Chapter06/mq_chat_user_2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define MAX_MESSAGES 10 6 | #define MAX_MSG_SIZE 256 7 | 8 | int main() 9 | { 10 | mqd_t user1Desc, user2Desc; 11 | char message[MAX_MSG_SIZE]; 12 | char message2[MAX_MSG_SIZE]; 13 | 14 | struct mq_attr attr; 15 | attr.mq_flags = 0; 16 | attr.mq_maxmsg = MAX_MESSAGES; 17 | attr.mq_msgsize = MAX_MSG_SIZE; 18 | attr.mq_curmsgs = 0; 19 | 20 | if ((user1Desc = mq_open ("/user1", O_RDONLY, "0660", &attr)) == -1) 21 | { 22 | perror ("User1: mq_open error"); 23 | return (1); 24 | } 25 | if ((user2Desc = mq_open ("/user2", O_WRONLY, "0660", &attr)) == -1) 26 | { 27 | perror ("User2: mq_open error"); 28 | return (1); 29 | } 30 | 31 | while (1) 32 | { 33 | // send message to server 34 | printf("USER 2: "); 35 | fgets(message, MAX_MSG_SIZE, stdin); 36 | if (mq_send (user2Desc, message, strlen(message) + 1, 0) == -1) 37 | { 38 | perror ("Not able to send message to User 1"); 39 | continue; 40 | } 41 | 42 | if (mq_receive (user1Desc, message2, MAX_MSG_SIZE, NULL) == -1) 43 | { 44 | perror ("tried to receive a message from User 1 but I've failed!"); 45 | continue; 46 | } 47 | printf("USER 1: %s\n", message2); 48 | } 49 | 50 | return 0; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /Chapter06/pipe.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | char* msg1 = "Message sent from Child to Parent"; 8 | char* msg2 = "Message sent from Parent to Child"; 9 | #define MSGSIZE 34 10 | #define IN 0 11 | #define OUT 1 12 | 13 | int main() 14 | { 15 | char inbufToParent[MSGSIZE]; 16 | char inbufToChild[MSGSIZE]; 17 | int childToParent[2], parentToChild[2], pid, nbytes; 18 | 19 | inbufToParent[0] = 0; 20 | inbufToChild[0] = 0; 21 | if (pipe(childToParent) < 0) 22 | return 1; 23 | 24 | if (pipe(parentToChild) < 0) 25 | return 1; 26 | 27 | if ((pid = fork()) > 0) 28 | { 29 | printf("Created child with PID = %d\n", pid); 30 | close(childToParent[IN]); 31 | write(childToParent[OUT], msg1, strlen(msg1)); 32 | close(childToParent[OUT]); 33 | 34 | close (parentToChild[OUT]); 35 | 36 | read(parentToChild[IN], inbufToChild, strlen(msg2)); 37 | printf("%s\n", inbufToChild); 38 | close (parentToChild[IN]); 39 | wait(NULL); 40 | } 41 | else 42 | { 43 | close (childToParent[OUT]); 44 | read(childToParent[IN], inbufToParent, strlen(msg1)); 45 | printf("%s\n", inbufToParent); 46 | close (childToParent[IN]); 47 | 48 | close (parentToChild[IN]); 49 | write(parentToChild[OUT], msg2, strlen(msg2)); 50 | close (parentToChild[OUT]); 51 | } 52 | return 0; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /Chapter06/shm_chat_user1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define STORAGE_ID1 "/SHM_USER1" 8 | #define STORAGE_ID2 "/SHM_USER2" 9 | #define STORAGE_SIZE 32 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | char message1[STORAGE_SIZE]; 14 | char message2[STORAGE_SIZE]; 15 | 16 | int fd1 = shm_open(STORAGE_ID1, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); 17 | int fd2 = shm_open(STORAGE_ID2, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); 18 | if ((fd1 == -1) || (fd2 == -1)) 19 | { 20 | perror("open"); 21 | return 10; 22 | } 23 | 24 | // extend shared memory object as by default it's initialized with size 0 25 | int res1 = ftruncate(fd1, STORAGE_SIZE); 26 | if (res1 == -1) 27 | { 28 | perror("ftruncate"); 29 | return 20; 30 | } 31 | 32 | // map shared memory to process address space 33 | void *addr1 = mmap(NULL, STORAGE_SIZE, PROT_WRITE, MAP_SHARED, fd1, 0); 34 | void *addr2 = mmap(NULL, STORAGE_SIZE, PROT_WRITE, MAP_SHARED, fd2, 0); 35 | if ((addr1 == MAP_FAILED) || (addr2 == MAP_FAILED)) 36 | { 37 | perror("mmap"); 38 | return 30; 39 | } 40 | 41 | while (1) 42 | { 43 | // WRITE 44 | printf("USER 1: "); 45 | fgets(message1, STORAGE_SIZE, stdin); 46 | int len = strlen(message1) + 1; 47 | memcpy(addr1, message1, len); 48 | 49 | // READ 50 | printf("USER 2 (enter to get the message):"); getchar(); 51 | memcpy(message2, addr2, STORAGE_SIZE); 52 | printf("%s\n", message2); 53 | } 54 | 55 | return 0; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /Chapter06/shm_chat_user2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define STORAGE_ID1 "/SHM_USER1" 8 | #define STORAGE_ID2 "/SHM_USER2" 9 | #define STORAGE_SIZE 32 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | char message1[STORAGE_SIZE]; 14 | char message2[STORAGE_SIZE]; 15 | 16 | int fd1 = shm_open(STORAGE_ID1, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); 17 | int fd2 = shm_open(STORAGE_ID2, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); 18 | if ((fd1 == -1) || (fd2 == -1)) 19 | { 20 | perror("open"); 21 | return 10; 22 | } 23 | 24 | // extend shared memory object as by default it's initialized with size 0 25 | int res1 = ftruncate(fd2, STORAGE_SIZE); 26 | if (res1 == -1) 27 | { 28 | perror("ftruncate"); 29 | return 20; 30 | } 31 | 32 | // map shared memory to process address space 33 | void *addr1 = mmap(NULL, STORAGE_SIZE, PROT_WRITE, MAP_SHARED, fd1, 0); 34 | void *addr2 = mmap(NULL, STORAGE_SIZE, PROT_WRITE, MAP_SHARED, fd2, 0); 35 | if ((addr1 == MAP_FAILED) || (addr2 == MAP_FAILED)) 36 | { 37 | perror("mmap"); 38 | return 30; 39 | } 40 | 41 | while (1) 42 | { 43 | // WRITE 44 | printf("USER 2: "); 45 | fgets(message1, STORAGE_SIZE, stdin); 46 | int len = strlen(message1) + 1; 47 | memcpy(addr2, message1, len); 48 | 49 | // READ 50 | printf("USER 1 (enter to get the message):"); getchar(); 51 | memcpy(message2, addr1, STORAGE_SIZE); 52 | printf("%s\n", message2); 53 | } 54 | return 0; 55 | } 56 | 57 | -------------------------------------------------------------------------------- /Chapter07/clientTCP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | constexpr unsigned int SERVER_PORT = 50544; 12 | constexpr unsigned int MAX_BUFFER = 128; 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | if (argc != 2) 17 | { 18 | std::cerr << "Error! usage: ./client localhost" << std::endl; 19 | return 6; 20 | } 21 | 22 | int sockfd = socket(AF_INET, SOCK_STREAM, 0); 23 | if (sockfd < 0) 24 | { 25 | std::cerr << "socket error" << std::endl; 26 | return 1; 27 | } 28 | 29 | struct hostent* server = gethostbyname(argv[1]); 30 | if (server == nullptr) 31 | { 32 | std::cerr << "gethostbyname, no such host" << std::endl; 33 | return 2; 34 | } 35 | 36 | struct sockaddr_in serv_addr; 37 | bzero((char *) &serv_addr, sizeof(serv_addr)); 38 | serv_addr.sin_family = AF_INET; 39 | bcopy((char *)server->h_addr, 40 | (char *)&serv_addr.sin_addr.s_addr, 41 | server->h_length); 42 | serv_addr.sin_port = htons(SERVER_PORT); 43 | if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 44 | { 45 | std::cerr << "connect error: the server does not look running" << std::endl; 46 | return 3; 47 | } 48 | 49 | std::string readBuffer (MAX_BUFFER, 0); 50 | if (read(sockfd, &readBuffer[0], MAX_BUFFER-1) < 0) 51 | { 52 | std::cerr << "read from socket failed" << std::endl; 53 | return 5; 54 | } 55 | std::cout << readBuffer << std::endl; 56 | 57 | std::string writeBuffer (MAX_BUFFER, 0); 58 | std::cout << "What message for the server? : "; 59 | getline(std::cin, writeBuffer); 60 | if (write(sockfd, writeBuffer.c_str(), strlen(writeBuffer.c_str())) < 0) 61 | { 62 | std::cerr << "write to socket" << std::endl; 63 | return 4; 64 | } 65 | 66 | close(sockfd); 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /Chapter07/clientUDP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | constexpr unsigned int SERVER_PORT = 50544; 12 | constexpr unsigned int MAX_BUFFER = 128; 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | int sockfd = socket(AF_INET, SOCK_DGRAM, 0); 17 | if (sockfd < 0) 18 | { 19 | std::cerr << "socket error" << std::endl; 20 | return 1; 21 | } 22 | 23 | struct hostent* server = gethostbyname(argv[1]); 24 | if (server == NULL) 25 | { 26 | std::cerr << "gethostbyname, no such host" << std::endl; 27 | return 2; 28 | } 29 | 30 | struct sockaddr_in serv_addr; 31 | bzero((char *) &serv_addr, sizeof(serv_addr)); 32 | serv_addr.sin_family = AF_INET; 33 | bcopy((char *)server->h_addr, 34 | (char *)&serv_addr.sin_addr.s_addr, 35 | server->h_length); 36 | serv_addr.sin_port = htons(SERVER_PORT); 37 | 38 | std::string outBuffer (MAX_BUFFER, 0); 39 | std::cout << "What message for the server? : "; 40 | getline(std::cin, outBuffer); 41 | unsigned int len = sizeof(serv_addr); 42 | if (sendto(sockfd, outBuffer.c_str(), MAX_BUFFER, 0, (struct sockaddr *) &serv_addr, len) < 0) 43 | { 44 | std::cerr << "sendto failed" << std::endl; 45 | return 3; 46 | } 47 | 48 | std::string inBuffer (MAX_BUFFER, 0); 49 | if (recvfrom(sockfd, &inBuffer[0], MAX_BUFFER, 0, (struct sockaddr *) &serv_addr, &len) < 0) 50 | { 51 | std::cerr << "recvfrom failed" << std::endl; 52 | return 4; 53 | } 54 | std::cout << inBuffer << std::endl; 55 | 56 | close(sockfd); 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /Chapter07/serverTCP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | constexpr unsigned int SERVER_PORT = 50544; 12 | constexpr unsigned int MAX_BUFFER = 128; 13 | constexpr unsigned int MSG_REPLY_LENGTH = 18; 14 | 15 | int main(int argc, char *argv[]) 16 | { 17 | int sockfd = socket(AF_INET, SOCK_STREAM, 0); 18 | if (sockfd < 0) 19 | { 20 | std::cerr << "open socket error" << std::endl; 21 | return 1; 22 | } 23 | 24 | int optval = 1; 25 | setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval , sizeof(int)); 26 | 27 | struct sockaddr_in serv_addr, cli_addr; 28 | bzero((char *) &serv_addr, sizeof(serv_addr)); 29 | serv_addr.sin_family = AF_INET; 30 | serv_addr.sin_addr.s_addr = INADDR_ANY; 31 | serv_addr.sin_port = htons(SERVER_PORT); 32 | if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 33 | { 34 | std::cerr << "bind error" << std::endl; 35 | return 2; 36 | } 37 | 38 | listen(sockfd, 5); 39 | socklen_t clilen = sizeof(cli_addr); 40 | int incomingSock = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); 41 | if (incomingSock < 0) 42 | { 43 | std::cerr << "accept error" << std::endl; 44 | return 3; 45 | } 46 | 47 | std::cout << "server: got connection from = " 48 | << inet_ntoa(cli_addr.sin_addr) 49 | << " and port = " << ntohs(cli_addr.sin_port) << std::endl; 50 | write(incomingSock, "You are connected!", MSG_REPLY_LENGTH); 51 | 52 | std::string buffer (MAX_BUFFER, 0); 53 | if (read(incomingSock, &buffer[0], MAX_BUFFER-1) < 0) 54 | { 55 | std::cerr << "read from socket error" << std::endl; 56 | return 4; 57 | } 58 | std::cout << "Got the message:" << buffer << std::endl; 59 | 60 | close(incomingSock); 61 | close(sockfd); 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /Chapter07/serverUDP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | constexpr unsigned int SERVER_PORT = 50544; 12 | constexpr unsigned int MAX_BUFFER = 128; 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | int sockfd = socket(AF_INET, SOCK_DGRAM, 0); 17 | if (sockfd < 0) 18 | { 19 | std::cerr << "open socket error" << std::endl; 20 | return 1; 21 | } 22 | 23 | int optval = 1; 24 | setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval , sizeof(int)); 25 | 26 | struct sockaddr_in serv_addr, cli_addr; 27 | bzero((char *) &serv_addr, sizeof(serv_addr)); 28 | serv_addr.sin_family = AF_INET; 29 | serv_addr.sin_addr.s_addr = INADDR_ANY; 30 | serv_addr.sin_port = htons(SERVER_PORT); 31 | if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 32 | { 33 | std::cerr << "bind error" << std::endl; 34 | return 2; 35 | } 36 | 37 | std::string buffer (MAX_BUFFER, 0); 38 | unsigned int len; 39 | if (recvfrom(sockfd, &buffer[0], MAX_BUFFER, 0, (struct sockaddr*)& cli_addr, &len) < 0) 40 | { 41 | std::cerr << "recvfrom failed" << std::endl; 42 | return 3; 43 | } 44 | std::cout << "Got the message:" << buffer << std::endl; 45 | 46 | std::string outBuffer ("Message received!"); 47 | if (sendto(sockfd, outBuffer.c_str(), outBuffer.length(), 0, (struct sockaddr*)& cli_addr, len) < 0) 48 | { 49 | std::cerr << "sendto failed" << std::endl; 50 | return 4; 51 | } 52 | 53 | close(sockfd); 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /Chapter08/console_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main () 5 | { 6 | std::string name; 7 | std::cout << "name: "; 8 | std::cin >> name; 9 | 10 | std::string surname; 11 | std::cout << "surname: "; 12 | std::cin >> surname; 13 | 14 | int age; 15 | std::cout << "age: "; 16 | std::cin >> age; 17 | 18 | std::cout << "Hello " << name << ", " << surname << ": " << age << std::endl; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /Chapter08/console_02.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main () 5 | { 6 | std::string fullNameWithCin; 7 | std::cout << "full Name got with cin: "; 8 | std::cin >> fullNameWithCin; 9 | 10 | std::cout << "hello " << fullNameWithCin << std::endl; 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /Chapter08/console_03.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main () 5 | { 6 | std::string fullName; 7 | std::cout << "full Name: "; 8 | std::getline (std::cin, fullName); 9 | std::cout << "Hello " << fullName << std::endl; 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter08/console_04.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main () 6 | { 7 | std::istringstream ss("ono,vaticone,43"); 8 | 9 | std::string token; 10 | while(std::getline(ss, token, ',')) 11 | { 12 | std::cout << token << '\n'; 13 | } 14 | 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /Chapter08/console_05.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main () 6 | { 7 | std::ifstream inFile ("file_console_05.txt", std::ifstream::in); 8 | 9 | std::string line; 10 | while( std::getline(inFile, line) ) 11 | std::cout << line << std::endl; 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter08/console_06.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main () 7 | { 8 | std::ifstream inFile ("file_console_05.txt", std::ifstream::in); 9 | 10 | std::string line; 11 | while( std::getline(inFile, line) ) 12 | { 13 | std::stringstream sline(line); 14 | std::string name, surname; int age{}; 15 | sline >> name >> surname >> age; 16 | std::cout << name << "-" << surname << "-"<< age << std::endl; 17 | } 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter08/console_07.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main () 7 | { 8 | std::stringstream sline; 9 | for (int i = 0; i < 10; ++i) 10 | sline << "name = name_" << i << ", age = " << i*7 << std::endl; 11 | 12 | std::cout << sline.str(); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter08/file_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main () 5 | { 6 | std::ofstream fout; 7 | fout.open("file_01.txt"); 8 | 9 | for (int i = 0; i < 10; ++i) 10 | fout << "User " << i << " => name_" << i << " surname_" << i << std::endl; 11 | 12 | fout.close(); 13 | } 14 | -------------------------------------------------------------------------------- /Chapter08/file_01.txt: -------------------------------------------------------------------------------- 1 | User 0 => name_0 surname_0 2 | User 1 => name_1 surname_1 3 | User 2 => name_2 surname_2 4 | User 3 => name_3 surname_3 5 | User 4 => name_4 surname_4 6 | User 5 => name_5 surname_5 7 | User 6 => name_6 surname_6 8 | User 7 => name_7 surname_7 9 | User 8 => name_8 surname_8 10 | User 9 => name_9 surname_9 11 | -------------------------------------------------------------------------------- /Chapter08/file_02.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main () 5 | { 6 | std::ifstream fiut; 7 | fiut.open("file_01.txt"); 8 | 9 | std::string line; 10 | while (std::getline(fiut, line)) 11 | { 12 | std::cout << line << std::endl; 13 | } 14 | 15 | fiut.close(); 16 | } 17 | -------------------------------------------------------------------------------- /Chapter08/file_03.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main () 5 | { 6 | std::fstream fstr; 7 | fstr.open("file_03.txt", std::ios::trunc | std::ios::out | std::ios::in); 8 | 9 | std::ifstream fiut; 10 | fiut.open("file_01.txt"); 11 | std::string line; 12 | while (std::getline(fiut, line)) 13 | fstr << line << std::endl; 14 | fiut.close(); 15 | 16 | fstr.seekg(0, std::ios::beg); 17 | while (std::getline(fstr, line)) 18 | std::cout << line << std::endl; 19 | 20 | fstr.close(); 21 | } 22 | -------------------------------------------------------------------------------- /Chapter08/file_03.txt: -------------------------------------------------------------------------------- 1 | User 0 => name_0 surname_0 2 | User 1 => name_1 surname_1 3 | User 2 => name_2 surname_2 4 | User 3 => name_3 surname_3 5 | User 4 => name_4 surname_4 6 | User 5 => name_5 surname_5 7 | User 6 => name_6 surname_6 8 | User 7 => name_7 surname_7 9 | User 8 => name_8 surname_8 10 | User 9 => name_9 surname_9 11 | -------------------------------------------------------------------------------- /Chapter08/file_console_05.txt: -------------------------------------------------------------------------------- 1 | firstName01, secondName01, 43 2 | firstName02, secondName02, 22 3 | firstName03, secondName03, 12 4 | firstName04, secondName04, 56 5 | firstName05, secondName05, 26 6 | firstName06, secondName06, 76 7 | firstName07, secondName07, 41 8 | firstName08, secondName08, 62 9 | firstName09, secondName09, 31 10 | firstName10, secondName10, 36 11 | firstName11, secondName11, 19 12 | -------------------------------------------------------------------------------- /Chapter09/chrono_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main () 6 | { 7 | std::cout << "Starting ... " << std::endl; 8 | std::vector elements; 9 | auto start = std::chrono::system_clock::now(); 10 | 11 | for (auto i = 0; i < 100'000'000; ++i) 12 | elements.push_back(i); 13 | 14 | auto end = std::chrono::system_clock::now(); 15 | 16 | // default seconds 17 | std::chrono::duration diff = end - start; 18 | std::cout << "Time Spent for populating a vector with 100M of integer ..." 19 | << diff.count() << "msec" << std::endl; 20 | 21 | auto tpStart = std::chrono::system_clock::to_time_t(start); 22 | std::cout << "Start: " << std::ctime(&tpStart) << std::endl; 23 | 24 | auto tpEnd = std::chrono::system_clock::to_time_t(end); 25 | std::cout << "End: " << std::ctime(&tpEnd) << std::endl; 26 | std::cout << "Ended ... " << std::endl; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /Chapter09/linux_time_01.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void timespec_diff(struct timespec* start, struct timespec* stop, struct timespec* result); 6 | 7 | int main () 8 | { 9 | std::cout << "Starting ..." << std::endl; 10 | struct timespec tsRealTime, tsMonotonicStart; 11 | clock_gettime(CLOCK_REALTIME, &tsRealTime); 12 | clock_gettime(CLOCK_MONOTONIC, &tsMonotonicStart); 13 | 14 | std::cout << "Real Time clock (i.e.: wall clock):" << std::endl; 15 | std::cout << " sec :" << tsRealTime.tv_sec << std::endl; 16 | std::cout << " nanosec :" << tsRealTime.tv_nsec << std::endl; 17 | 18 | std::cout << "Monotonic clock:" << std::endl; 19 | std::cout << " sec :" << tsMonotonicStart.tv_sec << std::endl; 20 | std::cout << " nanosec :" << tsMonotonicStart.tv_nsec << std::endl; 21 | 22 | std::vector elements; 23 | for (int i = 0; i < 100'000'000; ++i) 24 | elements.push_back(i); 25 | 26 | struct timespec tsMonotonicEnd; 27 | clock_gettime(CLOCK_MONOTONIC, &tsMonotonicEnd); 28 | 29 | struct timespec duration; 30 | timespec_diff (&tsMonotonicStart, &tsMonotonicEnd, &duration); 31 | 32 | std::cout << "Time elapsed to populate a vector with 100M elements:" << std::endl; 33 | std::cout << " sec :" << duration.tv_sec << std::endl; 34 | std::cout << " nanosec :" << duration.tv_nsec << std::endl; 35 | std::cout << "Finished ..." << std::endl; 36 | } 37 | 38 | // helper method 39 | void timespec_diff(struct timespec* start, struct timespec* stop, struct timespec* result) 40 | { 41 | if ((stop->tv_nsec - start->tv_nsec) < 0) 42 | { 43 | result->tv_sec = stop->tv_sec - start->tv_sec - 1; 44 | result->tv_nsec = stop->tv_nsec - start->tv_nsec + 1'000'000'000; 45 | } 46 | else 47 | { 48 | result->tv_sec = stop->tv_sec - start->tv_sec; 49 | result->tv_nsec = stop->tv_nsec - start->tv_nsec; 50 | } 51 | return; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /Chapter09/sleep.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include // sleep_for 4 | #include // for sleep 5 | #include // for nanosleep and clock_nanosleep 6 | 7 | int main () 8 | { 9 | std::cout << "Starting ... " << std::endl; 10 | 11 | auto start = std::chrono::steady_clock::now(); 12 | sleep (1); 13 | auto end = std::chrono::steady_clock::now(); 14 | std::cout << "sleep() call cause me to sleep for: " 15 | << std::chrono::duration_cast (end-start).count() 16 | << " millisec" << std::endl; 17 | 18 | struct timespec reqSleep = {.tv_sec = 0, .tv_nsec = 99999999}; 19 | start = std::chrono::steady_clock::now(); 20 | int ret = nanosleep (&reqSleep, NULL); 21 | if (ret) 22 | std::cerr << "nanosleep issue" << std::endl; 23 | 24 | end = std::chrono::steady_clock::now(); 25 | std::cout << "nanosleep() call cause me to sleep for: " 26 | << std::chrono::duration_cast (end-start).count() 27 | << " millisec" << std::endl; 28 | 29 | struct timespec reqClockSleep = {.tv_sec = 1, .tv_nsec = 99999999}; 30 | start = std::chrono::steady_clock::now(); 31 | ret = clock_nanosleep (CLOCK_MONOTONIC, 0, &reqClockSleep, NULL); 32 | if (ret) 33 | std::cerr << "clock_nanosleep issue" << std::endl; 34 | end = std::chrono::steady_clock::now(); 35 | std::cout << "clock_nanosleep() call cause me to sleep for: " 36 | << std::chrono::duration_cast (end-start).count() 37 | << " millisec" << std::endl; 38 | 39 | start = std::chrono::steady_clock::now(); 40 | std::this_thread::sleep_for(std::chrono::milliseconds(1500)); 41 | end = std::chrono::steady_clock::now(); 42 | std::cout << "std::this_thread::sleep_for() call cause me to sleep for: " 43 | << std::chrono::duration_cast (end-start).count() 44 | << " millisec" << std::endl; 45 | std::cout << "End ... " << std::endl; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /Chapter10/signal_ignore.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::cout << "Starting ..." << std::endl; 8 | signal(SIGTERM, SIG_IGN); 9 | while (true) ; 10 | std::cout << "Ending ..." << std::endl; 11 | return 0; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /Chapter10/signal_send.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main(int argc, char* argv[]) 6 | { 7 | std::cout << "Starting ..." << std::endl; 8 | if (argc <= 1) 9 | { 10 | std::cout << "Process pid missing ..." << std::endl; 11 | return 1; 12 | } 13 | int pid = std::atoi(argv[1]); 14 | 15 | kill (pid, SIGTERM); 16 | 17 | std::cout << "Ending ..." << std::endl; 18 | return 0; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /Chapter10/signal_trap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void handleSigTerm (int sig); 6 | 7 | int main() 8 | { 9 | std::cout << "Starting ..." << std::endl; 10 | signal(SIGTERM, handleSigTerm); 11 | while (true) ; 12 | std::cout << "Ending ..." << std::endl; 13 | return 0; 14 | } 15 | 16 | 17 | void handleSigTerm (int sig) 18 | { 19 | std::cout << "Just got " << sig << " signal" << std::endl; 20 | std::cout << "cleaning up some used resources ..." << std::endl; 21 | abort(); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /Chapter10/signal_uncatchable.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::cout << "Starting ..." << std::endl; 8 | signal(SIGKILL, SIG_IGN); 9 | while (true) ; 10 | std::cout << "Ending ..." << std::endl; 11 | return 0; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /Chapter10/signal_uncathable.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | std::cout << "Starting ..." << std::endl; 8 | signal(SIGKILL, SIG_IGN); 9 | while (1) ; 10 | std::cout << "Ending ..." << std::endl; 11 | return 0; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /Chapter11/schedAffinity.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void current_affinity(); 7 | 8 | int main () 9 | { 10 | std::cout << "Before sched_setaffinity => "; 11 | current_affinity(); 12 | 13 | cpu_set_t cpuset; 14 | CPU_ZERO(&cpuset); 15 | cpu_id = 3; 16 | CPU_SET(cpu_id, &cpuset); 17 | 18 | // sched_setaffinity: This function installs the cpusetsize bytes long affinity mask pointed to 19 | // by cpuset for the process or thread with the ID pid. If successful the function returns zero and the scheduler 20 | // will in future take the affinity information into account. 21 | int set_result = sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset); 22 | if (set_result != 0) 23 | { 24 | std::cerr << "Error on sched_setaffinity" << std::endl; 25 | std::cout << errno << "-" << strerror(errno) << std::endl; 26 | } 27 | 28 | // Check what is the actual affinity mask that was assigned to the thread. 29 | // sched_getaffinity: This functions stores the CPU affinity mask for the process or thread with the ID pid in 30 | // the cpusetsize bytes long bitmap pointed to by cpuset. If successful, the function always initializes all bits 31 | // in the cpu_set_t object and returns zero. 32 | // int get_affinity = sched_getaffinity(pid, sizeof(cpu_set_t), &cpuset); 33 | // if (get_affinity != 0) 34 | // { 35 | // std::cout << "Error on sched_getaffinity" << std::endl; 36 | // } 37 | 38 | // CPU_ISSET: This macro returns a nonzero value (true) if cpu is a member of the CPU set set, and zero (false) otherwise. 39 | // if (CPU_ISSET(cpu_id, &cpuset)) 40 | // { 41 | // std::cout << "Successfully set thread " << pid << " to affinity to CPU: " << cpu_id << std::endl; 42 | // } else 43 | // { 44 | // std::cerr << "Failed set thread to affinity to CPU " << std::endl; 45 | // } 46 | 47 | std::cout << "After sched_setaffinity => "; 48 | current_affinity(); 49 | return 0; 50 | } 51 | 52 | // Helper function 53 | void current_affinity() 54 | { 55 | cpu_set_t mask; 56 | if (sched_getaffinity(0, sizeof(cpu_set_t), &mask) == -1) 57 | { 58 | std::cerr << "error on sched_getaffinity"; 59 | return; 60 | } 61 | else 62 | { 63 | long nproc = sysconf(_SC_NPROCESSORS_ONLN); 64 | for (int i = 0; i < nproc; i++) 65 | { 66 | std::cout << CPU_ISSET(i, &mask); 67 | } 68 | std::cout << std::endl; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Chapter11/schedGetInterval.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main () 6 | { 7 | std::cout << "Starting ..." << std::endl; 8 | 9 | struct sched_param sched; 10 | sched.sched_priority = 8; 11 | if (sched_setscheduler(0, SCHED_RR, &sched) < 0) 12 | std::cout << "sched_setscheduler failed = " << strerror(errno) 13 | << std::endl; 14 | else 15 | std::cout << "sched_setscheduler has set this process priority to = " 16 | << sched.sched_priority << std::endl; 17 | 18 | struct timespec tp; 19 | int retCode = sched_rr_get_interval(0, &tp); 20 | if (retCode == -1) 21 | { 22 | std::cout << "sched_rr_get_interval failed = " << strerror(errno) << std::endl; 23 | return 1; 24 | } 25 | 26 | std::cout << "timespec sec = " << tp.tv_sec << " nanosec = " << tp.tv_nsec << std::endl; 27 | std::cout << "End ..." << std::endl; 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /Chapter11/schedNice.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main () 6 | { 7 | std::cout << "Starting ..." << std::endl; 8 | int retCode = nice (-5); 9 | if (retCode == -1) 10 | std::cout << "nice failed = " << strerror(errno) << std::endl; 11 | else 12 | std::cout << "nice value succesfully set = " << std::endl; 13 | 14 | nice (5); 15 | 16 | while (1) ; 17 | std::cout << "End ..." << std::endl; 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /Chapter11/schedParameters.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main () 8 | { 9 | std::cout << "Starting ..." << std::endl; 10 | 11 | int policy = sched_getscheduler(getpid()); 12 | switch(policy) 13 | { 14 | case SCHED_OTHER: std::cout << "current process' policy = SCHED_OTHER" << std::endl ; break; 15 | case SCHED_RR: std::cout << "current process' policy = SCHED_RR" << std::endl; break; 16 | case SCHED_FIFO: std::cout << "current process' policy = SCHED_FIFO" << std::endl; break; 17 | default: std::cout << "Unknown... " << std::endl; 18 | } 19 | 20 | int fifoMin = sched_get_priority_min(SCHED_FIFO); 21 | int fifoMax = sched_get_priority_max(SCHED_FIFO); 22 | std::cout << "MIN Priority for SCHED_FIFO = " << fifoMin << std::endl; 23 | std::cout << "MAX Priority for SCHED_FIFO = " << fifoMax << std::endl; 24 | 25 | struct sched_param sched; 26 | sched.sched_priority = (fifoMax - fifoMin) / 2; 27 | if (sched_setscheduler(getpid(), SCHED_FIFO, &sched) < 0) 28 | std::cout << "sched_setscheduler failed = " << strerror(errno) << std::endl; 29 | else 30 | std::cout << "sched_setscheduler has set this process priority to = " << sched.sched_priority << std::endl; 31 | 32 | policy = sched_getscheduler(getpid()); 33 | std::cout << "=> " << policy << std::endl; 34 | 35 | std::cout << "End ..." << std::endl; 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Chapter11/schedYield.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main () 6 | { 7 | std::cout << "Starting ..." << std::endl; 8 | 9 | for( ;; ) 10 | { 11 | int counter = 0; 12 | for(int i = 0 ; i < 10000 ; ++i) 13 | counter += i; 14 | 15 | if (sched_yield() == -1) 16 | { 17 | std::cout << "sched_yield failed = " << strerror(errno) << std::endl; 18 | return 1; 19 | } 20 | } 21 | 22 | // we should never get here ... 23 | std::cout << "End ..." << std::endl; 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # C++ System Programming Cookbook 5 | 6 | C++ System Programming Cookbook 7 | 8 | This is the code repository for [C++ System Programming Cookbook ](https://www.packtpub.com/programming/c-system-programming-cookbook?utm_source=github&utm_medium=repository&utm_campaign=9781838646554), published by Packt. 9 | 10 | **Practical recipes for Linux system-level programming using the latest C++ features** 11 | 12 | ## What is this book about? 13 | C++ is the preferred language for system programming due to its efficient low-level computation, data abstraction, and object-oriented features. System programming is about designing and writing computer programs that interact closely with the underlying operating system and allow computer hardware to interface with the programmer and the user. The C++ System Programming Cookbook will serve as a reference for developers who want to have ready-to-use solutions for the essential aspects of system programming using the latest C++ standards wherever possible. 14 | 15 | 16 | This book covers the following exciting features: 17 | * Get up to speed with the fundamentals including makefile, man pages, compilation, and linking and debugging 18 | * Understand how to deal with time interfaces, signals, and CPU scheduling 19 | * Develop your knowledge of memory management 20 | * Use processes and threads for advanced synchronizations (mutexes and condition variables) 21 | * Understand interprocess communications (IPC): pipes, FIFOs, message queues, shared memory, and TCP and UDP 22 | * Discover how to interact with the console (console I/O) 23 | 24 | If you feel this book is for you, get your [copy](https://www.amazon.com/dp/1838646558) today! 25 | 26 | https://www.packtpub.com/ 28 | 29 | ## Instructions and Navigations 30 | All of the code is organized into folders. For example, Chapter02. 31 | 32 | The code will look like the following: 33 | ``` 34 | std::cout << "Start ... " << std::endl; 35 | { 36 | User* developer = new User(); 37 | developer->cheers(); 38 | delete developer; 39 | } 40 | ``` 41 | 42 | **Following is what you need for this book:** 43 | This book is for C++ developers who want to gain practical knowledge of systems programming. Though no experience of Linux system programming is assumed, intermediate knowledge of C++ is necessary. 44 | 45 | With the following software and hardware list you can run all code files present in the book (Chapter 1-). 46 | ### Software and Hardware List 47 | | No | Software required | OS required | 48 | | -------- | ------------------------------------ | ----------------------------------- | 49 | | 1 | C++ | Windows, macOS, Linux | 50 | | 2 | Docker | Windows, macOS, Linux | 51 | 52 | 53 | We also provide a PDF file that has color images of the screenshots/diagrams used in this book. [Click here to download it](https://static.packt-cdn.com/downloads/9781838646554_ColorImages.pdf). 54 | 55 | ### Related products 56 | * Advanced C++ Programming Cookbook [[Packt]](https://www.packtpub.com/programming/advanced-c-cookbook?utm_source=github&utm_medium=repository&utm_campaign=9781838559915) [[Amazon]](https://www.amazon.com/dp/B083QG9G7H) 57 | 58 | * Hands-On Embedded Programming with C++17 [[Packt]](https://www.packtpub.com/application-development/hands-embedded-programming-c17?utm_source=github&utm_medium=repository&utm_campaign=9781788629300) [[Amazon]](https://www.amazon.com/dp/1788629302) 59 | 60 | ## Get to Know the Author 61 | **Onorato Vaticone** 62 | is a software engineer with over 18 years of experience. A C++ expert, he has deep, system-level programming experience. An Agile coach and XP advocate, TDD and Simple Design are his everyday tools. He has worked on real-time systems (defense and energy transmission) with C++. During this time, he learned to write multiplatform code. Early in his career, he realized that a form of agility was needed. He holds an MSc in cloud computing and a BSc in computer engineering and software. He finds learning how things work under the hood to be fascinating! 63 | 64 | ### Suggestions and Feedback 65 | [Click here](https://docs.google.com/forms/d/e/1FAIpQLSdy7dATC6QmEL81FIUuymZ0Wy9vH1jHkvpY57OiMeKGqib_Ow/viewform) if you have any feedback or suggestions. 66 | 67 | 68 | ### Download a free PDF 69 | 70 | If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
71 |

https://packt.link/free-ebook/9781838646554

--------------------------------------------------------------------------------