├── .gitignore ├── .travis.yml ├── 01-history-and-standards └── README.md ├── 02-fundamentals-and-concepts └── README.md ├── 03-system-programming-concepts ├── README.md ├── Sconstruct └── ch3_1.c ├── 04-file-io-universal-io-model ├── .cproject ├── .project ├── README.md ├── Sconstruct ├── cpholes.c ├── holy_file.c └── tee.c ├── 05-file-io-further-details ├── .cproject ├── .project ├── README.md ├── SConstruct ├── append_seek.c ├── atomic_append.c ├── dup.c ├── large_file.c └── vector_fileio.c ├── 06-processes ├── README.md ├── SConstruct ├── longjmp_retfunc.c └── myenviron.c ├── 07-memory-allocation ├── README.md ├── SConstruct ├── free_and_sbrk.c ├── free_and_sbrk_7_1.c └── po_malloc_free.c ├── 08-users-and-groups ├── README.md ├── SConstruct └── getpwnam.c ├── 09-process-credentials ├── README.md ├── SConstruct └── initgroups.c ├── 10-time └── README.md ├── 11-system-limits-and-options ├── README.md ├── SConstruct └── t_fpathconf.c ├── 12-system-and-process-information ├── README.md ├── SConstruct ├── proclib.c ├── proclib.h ├── proclist.c ├── pstree.c └── sherlock.c ├── 13-file-io-buffering ├── README.md ├── SConscript ├── SConstruct ├── copy.c ├── run_copy_tests.sh ├── run_write_tests.sh ├── tail.c ├── tim.py └── write_bytes.c ├── 14-file-systems ├── README.md ├── SConstruct ├── benchmarkwrites.c └── runtests.sh ├── 15-file-attributes ├── README.md ├── SConstruct ├── chattr.c ├── exercise1_parta.sh ├── exercise1_partb.sh ├── exercise1_partc.sh ├── exercise2_stattest.c ├── exercise3_tstat.c └── exercise6_chmod.c ├── 16-extended-attributes ├── README.md ├── SConstruct └── setfattr.c ├── 17-access-control-lists ├── README.md ├── SConstruct └── dispacl.c ├── LICENSE.md ├── README.md ├── build.sh └── tlpi-dist ├── BUILDING ├── CHANGES ├── COPYING ├── Makefile ├── Makefile.inc ├── Makefile.inc.FreeBSD ├── Makefile.inc.HP-UX ├── Makefile.inc.MacOSX ├── Makefile.inc.Solaris ├── Makefile.inc.Tru64 ├── README ├── acl ├── Makefile ├── acl_update.c └── acl_view.c ├── altio ├── Makefile ├── demo_sigio.c ├── epoll_input.c ├── poll_pipes.c ├── select_mq.c ├── self_pipe.c └── t_select.c ├── cap ├── Makefile └── check_password_caps.c ├── daemons ├── Makefile ├── become_daemon.c ├── become_daemon.h ├── daemon_SIGHUP.c ├── t_syslog.c └── test_become_daemon.c ├── dirs_links ├── Makefile ├── bad_symlink.c ├── file_type_stats.c ├── list_files.c ├── list_files_readdir_r.c ├── nftw_dir_tree.c ├── t_dirbasename.c ├── t_unlink.c └── view_symlink.c ├── filebuff ├── Makefile ├── copy.c ├── direct_read.c ├── mix23_linebuff.c ├── mix23io.c └── write_bytes.c ├── fileio ├── Makefile ├── atomic_append.c ├── bad_exclusive_open.c ├── copy.c ├── large_file.c ├── multi_descriptors.c ├── seek_io.c ├── t_readv.c └── t_truncate.c ├── filelock ├── Makefile ├── create_pid_file.c ├── create_pid_file.h ├── i_fcntl_locking.c ├── region_locking.c ├── region_locking.h └── t_flock.c ├── files ├── Makefile ├── chiflag.c ├── file_perms.c ├── file_perms.h ├── t_chown.c ├── t_stat.c ├── t_umask.c ├── t_utime.c └── t_utimes.c ├── filesys ├── Makefile ├── t_mount.c ├── t_statfs.c ├── t_statvfs.c └── t_umount.c ├── getopt ├── Makefile └── t_getopt.c ├── inotify ├── Makefile ├── demo_inotify.c └── dnotify.c ├── lib ├── Build_ename.sh ├── Makefile ├── README ├── alt_functions.c ├── alt_functions.h ├── become_daemon.c ├── become_daemon.h ├── binary_sems.c ├── binary_sems.h ├── create_pid_file.c ├── create_pid_file.h ├── curr_time.c ├── curr_time.h ├── error_functions.c ├── error_functions.h ├── event_flags.c ├── event_flags.h ├── file_perms.c ├── file_perms.h ├── get_num.c ├── get_num.h ├── inet_sockets.c ├── inet_sockets.h ├── itimerspec_from_str.c ├── itimerspec_from_str.h ├── print_rlimit.c ├── print_rlimit.h ├── print_rusage.c ├── print_rusage.h ├── print_wait_status.c ├── print_wait_status.h ├── pty_fork.c ├── pty_fork.h ├── pty_master_open.c ├── pty_master_open.h ├── rdwrn.c ├── rdwrn.h ├── read_line.c ├── read_line.h ├── region_locking.c ├── region_locking.h ├── semun.h ├── signal.c ├── signal_functions.c ├── signal_functions.h ├── tlpi_hdr.h ├── tty_functions.c ├── tty_functions.h ├── ugid_functions.c ├── ugid_functions.h ├── unix_sockets.c └── unix_sockets.h ├── loginacct ├── Makefile ├── dump_utmpx.c ├── utmpx_login.c └── view_lastlog.c ├── memalloc ├── Makefile └── free_and_sbrk.c ├── mmap ├── Makefile ├── anon_mmap.c ├── mmcat.c ├── mmcopy.c ├── t_mmap.c └── t_remap_file_pages.c ├── pgsjc ├── Makefile ├── catch_SIGHUP.c ├── disc_SIGHUP.c ├── handling_SIGTSTP.c ├── job_mon.c ├── orphaned_pgrp_SIGHUP.c └── t_setsid.c ├── pipes ├── Makefile ├── change_case.c ├── fifo_seqnum.h ├── fifo_seqnum_client.c ├── fifo_seqnum_server.c ├── pipe_ls_wc.c ├── pipe_sync.c ├── popen_glob.c └── simple_pipe.c ├── pmsg ├── Makefile ├── mq_notify_sig.c ├── mq_notify_sigwaitinfo.c ├── mq_notify_thread.c ├── pmsg_create.c ├── pmsg_getattr.c ├── pmsg_receive.c ├── pmsg_send.c └── pmsg_unlink.c ├── proc ├── Makefile ├── bad_longjmp.c ├── display_env.c ├── longjmp.c ├── mem_segments.c ├── modify_env.c ├── necho.c ├── setenv.c ├── setjmp_vars.c └── t_getenv.c ├── proccred ├── Makefile └── idshow.c ├── procexec ├── Makefile ├── acct_on.c ├── acct_v3_view.c ├── acct_view.c ├── child_status.c ├── closeonexec.c ├── demo_clone.c ├── envargs.c ├── execlp.c ├── exit_handlers.c ├── footprint.c ├── fork_file_sharing.c ├── fork_sig_sync.c ├── fork_stdio_buf.c ├── fork_whos_on_first.c ├── fork_whos_on_first.count.awk ├── longest_line.awk ├── make_zombie.c ├── multi_SIGCHLD.c ├── multi_wait.c ├── necho.c ├── orphan.c ├── print_wait_status.c ├── print_wait_status.h ├── simple_system.c ├── system.c ├── t_clone.c ├── t_execl.c ├── t_execle.c ├── t_execlp.c ├── t_execve.c ├── t_fork.c ├── t_system.c ├── t_vfork.c └── vfork_fd_test.c ├── procpri ├── Makefile ├── demo_sched_fifo.c ├── sched_set.c ├── sched_view.c ├── t_sched_getaffinity.c ├── t_sched_setaffinity.c └── t_setpriority.c ├── procres ├── Makefile ├── print_rlimit.c ├── print_rlimit.h ├── print_rusage.c ├── print_rusage.h ├── rlimit_nproc.c ├── rusage.c └── rusage_wait.c ├── progconc ├── Makefile └── syscall_speed.c ├── psem ├── Makefile ├── psem_create.c ├── psem_getvalue.c ├── psem_post.c ├── psem_timedwait.c ├── psem_trywait.c ├── psem_unlink.c ├── psem_wait.c └── thread_incr_psem.c ├── pshm ├── Makefile ├── pshm_create.c ├── pshm_read.c ├── pshm_unlink.c └── pshm_write.c ├── pty ├── Makefile ├── pty_fork.c ├── pty_fork.h ├── pty_master_open.c ├── pty_master_open.h ├── pty_master_open_bsd.c ├── script.c └── unbuffer.c ├── shlibs ├── Demo_no_lib.sh ├── Demo_shared_lib.sh ├── Demo_static_lib.sh ├── Makefile ├── demo_Bsymbolic │ ├── build.sh │ ├── foo1.c │ ├── foo2.c │ ├── foo3.c │ └── prog.c ├── dynload.c ├── mod1.c ├── mod2.c ├── mod3.c ├── prog.c ├── rpath_demo │ ├── build-rpath-link.sh │ ├── build.sh │ ├── d1 │ │ └── modx1.c │ ├── d2 │ │ └── modx2.c │ └── prog.c └── version_scripts │ ├── sv_build.sh │ ├── sv_lib_v1.c │ ├── sv_lib_v2.c │ ├── sv_libabc.c │ ├── sv_prog.c │ ├── sv_prog_abc.c │ ├── sv_prog_complex.c │ ├── sv_v1.map │ ├── sv_v2.map │ ├── vis.map │ ├── vis_build.sh │ ├── vis_comm.c │ ├── vis_f1.c │ └── vis_f2.c ├── signals ├── Makefile ├── catch_rtsigs.c ├── demo_SIGFPE.c ├── ignore_pending_sig.c ├── intquit.c ├── nonreentrant.c ├── ouch.c ├── sig_receiver.c ├── sig_sender.c ├── sig_speed_sigsuspend.c ├── siginterrupt.c ├── sigmask_longjmp.c ├── signal.c ├── signal_functions.c ├── signal_functions.h ├── signalfd_sigval.c ├── t_kill.c ├── t_sigaltstack.c ├── t_sigqueue.c ├── t_sigsuspend.c └── t_sigwaitinfo.c ├── sockets ├── Makefile ├── README ├── i6d_ucase.h ├── i6d_ucase_cl.c ├── i6d_ucase_sv.c ├── id_echo.h ├── id_echo_cl.c ├── id_echo_sv.c ├── inet_sockets.c ├── inet_sockets.h ├── is_echo_cl.c ├── is_echo_inetd_sv.c ├── is_echo_sv.c ├── is_echo_v2_sv.c ├── is_seqnum.h ├── is_seqnum_cl.c ├── is_seqnum_sv.c ├── is_seqnum_v2.h ├── is_seqnum_v2_cl.c ├── is_seqnum_v2_sv.c ├── rdwrn.c ├── rdwrn.h ├── read_line.c ├── read_line.h ├── read_line_buf.c ├── read_line_buf.h ├── scm_cred.h ├── scm_cred_recv.c ├── scm_cred_send.c ├── scm_rights.h ├── scm_rights_recv.c ├── scm_rights_send.c ├── sendfile.c ├── socknames.c ├── t_gethostbyname.c ├── t_getservbyname.c ├── ud_ucase.h ├── ud_ucase_cl.c ├── ud_ucase_sv.c ├── unix_sockets.c ├── unix_sockets.h ├── us_abstract_bind.c ├── us_xfr.h ├── us_xfr_cl.c ├── us_xfr_sv.c ├── us_xfr_v2.h ├── us_xfr_v2_cl.c └── us_xfr_v2_sv.c ├── svipc ├── Makefile ├── svmsg_demo_server.c └── t_ftok.c ├── svmsg ├── Makefile ├── svmsg_chqbytes.c ├── svmsg_create.c ├── svmsg_file.h ├── svmsg_file_client.c ├── svmsg_file_server.c ├── svmsg_info.c ├── svmsg_ls.c ├── svmsg_receive.c ├── svmsg_rm.c └── svmsg_send.c ├── svsem ├── Makefile ├── binary_sems.c ├── binary_sems.h ├── event_flags.c ├── event_flags.h ├── semun.h ├── svsem_bad_init.c ├── svsem_create.c ├── svsem_demo.c ├── svsem_good_init.c ├── svsem_info.c ├── svsem_mon.c ├── svsem_op.c ├── svsem_rm.c └── svsem_setall.c ├── svshm ├── Makefile ├── svshm_attach.c ├── svshm_create.c ├── svshm_info.c ├── svshm_lock.c ├── svshm_mon.c ├── svshm_rm.c ├── svshm_unlock.c ├── svshm_xfr.h ├── svshm_xfr_reader.c └── svshm_xfr_writer.c ├── sysinfo ├── Makefile ├── procfs_pidmax.c ├── procfs_user_exe.c └── t_uname.c ├── syslim ├── Makefile ├── t_fpathconf.c └── t_sysconf.c ├── threads ├── Makefile ├── detached_attrib.c ├── one_time_init.c ├── prod_condvar.c ├── prod_no_condvar.c ├── simple_thread.c ├── strerror.c ├── strerror_test.c ├── strerror_tls.c ├── strerror_tsd.c ├── thread_cancel.c ├── thread_cleanup.c ├── thread_incr.c ├── thread_incr_mutex.c └── thread_multijoin.c ├── time ├── Makefile ├── calendar_time.c ├── curr_time.c ├── curr_time.h ├── process_time.c ├── show_time.c ├── strtime.c └── t_stime.c ├── timers ├── Makefile ├── demo_timerfd.c ├── itimerspec_from_str.c ├── itimerspec_from_str.h ├── ptmr_null_evp.c ├── ptmr_sigev_signal.c ├── ptmr_sigev_thread.c ├── real_timer.c ├── t_clock_nanosleep.c ├── t_nanosleep.c └── timed_read.c ├── tty ├── Makefile ├── demo_SIGWINCH.c ├── new_intr.c ├── no_echo.c ├── test_tty_functions.c ├── tty_functions.c ├── tty_functions.h └── ttyname.c ├── users_groups ├── Makefile ├── check_password.c ├── t_getpwent.c ├── t_getpwnam_r.c ├── ugid_functions.c └── ugid_functions.h ├── vmem ├── Makefile ├── madvise_dontneed.c ├── memlock.c └── t_mprotect.c └── xattr ├── Makefile ├── t_setxattr.c └── xattr_view.c /.gitignore: -------------------------------------------------------------------------------- 1 | # Editor files 2 | *~ 3 | \#*\# 4 | 5 | # C Object Files 6 | a.out 7 | *.o 8 | *.a 9 | build_* 10 | 11 | # Python Files 12 | *.pyc 13 | *.pyo 14 | 15 | # Scons trash 16 | .sconsign* 17 | 18 | # Our binary executables (pattern for scons scripts) 19 | prog_* 20 | 21 | # eclipse trash 22 | *.*project* 23 | 24 | # test files 25 | testfile*.txt 26 | tfile 27 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Travis CI Build/Test Configuration 3 | # 4 | language: c 5 | before_install: 6 | - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test 7 | - sudo apt-get update -qq 8 | - sudo apt-get install gcc-5 9 | - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 90 10 | - sudo apt-get install libacl1-dev 11 | script: ./build.sh 12 | -------------------------------------------------------------------------------- /01-history-and-standards/README.md: -------------------------------------------------------------------------------- 1 | Chapter 01: History and Standards 2 | ================================= 3 | 4 | This chapter has no exercises. 5 | -------------------------------------------------------------------------------- /02-fundamentals-and-concepts/README.md: -------------------------------------------------------------------------------- 1 | Chapter 02: Fundamental Concepts 2 | ================================ 3 | 4 | This chapter has no exercises. 5 | -------------------------------------------------------------------------------- /03-system-programming-concepts/README.md: -------------------------------------------------------------------------------- 1 | Chapter 03: System Programming Concepts 2 | ======================================= 3 | 4 | Question 3-1 5 | ------------ 6 | 7 | **Question:** 8 | 9 | When using the linux-specific reboot() system call to reboot the 10 | system, the second argument, magic2, must be specified as one of a 11 | set of magic numbers (e.g. LINUX_REBOOT_MAGIC2). What is the 12 | significance of these numbers? (Converting them to hexadecimal 13 | provides a clue) 14 | 15 | **Answer:** 16 | 17 | ``` 18 | ~/Projects/OpenSource/linux-programming-interface-exercises/ch3 $ ./ch3_1 19 | LINUX_REBOOT_MAGIC1 = 0xFEE1DEAD (-18751827) 20 | LINUX_REBOOT_MAGIC2 = 0x28121969 (672274793) 21 | ``` 22 | 23 | The magic numbers are not present for most function calls but to 24 | prevent erroneous calls to reboot (let's say that the pc just happened 25 | to go to this code, we want some addititional security). The numbers 26 | themselves (in hexadecimal) each have clever meaning: 27 | 28 | - 0xFEE1DEAD: Feel Dead? Self-explanatory. 29 | - 0x28121969: 28th of December 1969 is the birthday of Linus 30 | Torvalds! 31 | -------------------------------------------------------------------------------- /03-system-programming-concepts/Sconstruct: -------------------------------------------------------------------------------- 1 | Program('prog_ch3_1', 'ch3_1.c') -------------------------------------------------------------------------------- /03-system-programming-concepts/ch3_1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | printf("LINUX_REBOOT_MAGIC1 = 0x%08X (%d)\n", LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC1); 8 | printf("LINUX_REBOOT_MAGIC2 = 0x%08X (%d)\n", LINUX_REBOOT_MAGIC2, LINUX_REBOOT_MAGIC2); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /04-file-io-universal-io-model/README.md: -------------------------------------------------------------------------------- 1 | Chapter 04: File I/O: The Universal I/O Model 2 | ============================================= 3 | 4 | Exercise 4-1 5 | ------------ 6 | 7 | **Question:** 8 | 9 | The tee command reads its standar input until end-of-file, writing a 10 | copy of the input to standard output and to the file named in its 11 | command-line argument. (We show an example of the use of this command 12 | hwne we discuss FIFOs in Section 44.7.) Implement tee using I/O 13 | system calls. By default, tee overwites any existing file with the 14 | given name. Impelment the -a command-line option (tee -a file), which 15 | casuses te to append text to the end of a file if it already exists. 16 | (Refer to Appendix B for desription ofthe getopt() function, which can 17 | be used to parse command-line options.) 18 | 19 | **Answer:** 20 | See tee.c (prog_tee output from scons) 21 | 22 | Exercise 4-2 23 | ------------ 24 | 25 | **Question:** 26 | 27 | Write a program like cp that, when used to copy a regular file that 28 | contains holes (sequences of null bytes), also creates correspdonding 29 | holes in the target file. 30 | 31 | **Answer:** 32 | 33 | See cpholes.c (prog_cpholes from scons) 34 | -------------------------------------------------------------------------------- /04-file-io-universal-io-model/Sconstruct: -------------------------------------------------------------------------------- 1 | CFLAGS = '-g' 2 | 3 | env = Environment(CFLAGS=CFLAGS) 4 | env.Program('prog_holyfile', 'holy_file.c') 5 | env.Program('prog_tee', 'tee.c') 6 | env.Program('prog_cpholes', 'cpholes.c') 7 | -------------------------------------------------------------------------------- /05-file-io-further-details/SConstruct: -------------------------------------------------------------------------------- 1 | env = Environment(CFLAGS='-g -Wall -Werror -pedantic -std=c99') 2 | env.Program('prog_large_file', 'large_file.c') 3 | env.Program('prog_append_seek', 'append_seek.c') 4 | env.Program('prog_atomic_append', 'atomic_append.c') 5 | env.Program('prog_dup', 'dup.c') 6 | env.Program('prog_vector', 'vector_fileio.c') -------------------------------------------------------------------------------- /05-file-io-further-details/append_seek.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Write a program that opens and existing file for writing with the 3 | * O_APPEND flag, and then seeks to the beginning of the file before 4 | * writing some data. Where does the data appear in the file? Why? 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #define PATTERN "Hello, world!" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | int fd; 16 | 17 | /* File opened as append */ 18 | if (argc != 2) { 19 | printf("Must specify a file (argument 1)\n"); 20 | return 1; 21 | } 22 | fd = open(argv[1], O_RDWR | O_APPEND); 23 | 24 | /* attempt to seek to the beginning of the file */ 25 | lseek(fd, 0, SEEK_SET); 26 | 27 | /* Now, write some bytes */ 28 | write(fd, PATTERN, sizeof(PATTERN)); 29 | close(fd); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /05-file-io-further-details/large_file.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Modify the program in listing 5-3 to use standard file I/O system 3 | * calls (open() and lseek()) and the off_t data type. Compile the 4 | * program with the _FILE_OFFSET_BITS macro set to 64, and test it to 5 | * show that a large file can be successfully created. 6 | */ 7 | 8 | //#define _LARGEFILE64_SOURCE 9 | #define _FILE_OFFSET_BITS (64) 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | int main(int argc, char *argv[]) 18 | { 19 | int fd; 20 | off_t off; 21 | 22 | if (argc != 3 || strcmp(argv[1], "--help") == 0) { 23 | printf("%s pathname offset\n", argv[0]); 24 | return 1; 25 | } 26 | 27 | fd = open(argv[1], O_RDWR | O_CREAT, 28 | S_IRUSR | S_IWUSR); 29 | if (fd == -1) { 30 | printf("open\n"); 31 | return 1; 32 | } 33 | 34 | off = atoll(argv[2]); 35 | if (lseek(fd, off, SEEK_SET) == -1) { 36 | printf("lseek\n"); 37 | return 1; 38 | } 39 | 40 | if (write(fd, "text", 4) == -1) { 41 | printf("write\n"); 42 | return 1; 43 | } 44 | printf("Success\n"); 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /06-processes/SConstruct: -------------------------------------------------------------------------------- 1 | env = Environment(CFLAGS='-g -Wall -Werror -pedantic -std=c99') 2 | env.Program('prog_longjmp_retfunc', 'longjmp_retfunc.c') -------------------------------------------------------------------------------- /06-processes/longjmp_retfunc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Write a program to see what happens if we try to longjmp() into a 3 | * function that has already returned. 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | static jmp_buf env; 10 | 11 | void func(int doJmpSwitch) 12 | { 13 | if (doJmpSwitch) { 14 | switch (setjmp(env)) { 15 | case 0: 16 | printf("case 0\n"); 17 | break; 18 | case 1: 19 | printf("case 1\n"); 20 | break; 21 | case 2: 22 | printf("case 2\n"); 23 | break; 24 | } 25 | } 26 | } 27 | 28 | int main(int argc, char *argv[]) 29 | { 30 | (void)argc; 31 | (void)argv; 32 | func(1); 33 | func(0); 34 | longjmp(env, 0); 35 | } 36 | -------------------------------------------------------------------------------- /07-memory-allocation/SConstruct: -------------------------------------------------------------------------------- 1 | env = Environment(CFLAGS='-g -Wall -Werror -pedantic -std=c99') 2 | env.Program('prog_free_and_sbrk', 'free_and_sbrk.c') 3 | env.Program('prog_free_and_sbrk_7_1', 'free_and_sbrk_7_1.c') 4 | env.Program('prog_malloc', 'po_malloc_free.c') 5 | -------------------------------------------------------------------------------- /08-users-and-groups/README.md: -------------------------------------------------------------------------------- 1 | Chapter 08: Users and Groups 2 | ============================ 3 | 4 | Exercise 8-1 5 | ------------ 6 | 7 | **Question** 8 | 9 | When we execute the following code, we find that it displays the same 10 | number twice, even though two users have different IDs in the password 11 | file. Why is this? 12 | 13 | printf("%ld %ld\n", (long) (getpwnam("avr")->pw_uid), 14 | (long) (getpwnam("tsr")->pw_uid)); 15 | 16 | **Answer** 17 | 18 | Actually, this problem is not correct, as `pw_uid` is passed by value. 19 | 20 | The author of the book has corrected this problem, refer to 21 | `http://man7.org/tlpi/errata/` for the new problem and the solution 22 | provided by the author. 23 | 24 | getpwnam() is not reentrant. That is, with both calls it returns a 25 | refernce to the same statically allocated strcture in memory. So, 26 | only the result from the second call (for "tsr") will be present for 27 | each. If one had instead done the following, the expected results 28 | should be provided: 29 | 30 | printf("%ld ", (long) (getpwnam("avr")->pw_uid)); 31 | printf("%ld\n", (long) (getpwnam("tsr")->pw_uid)); 32 | 33 | Exercise 8-2 34 | ------------ 35 | 36 | **Question** 37 | 38 | Implement getpwnam() using setpwent(), getpwent(), and endpwent(). 39 | 40 | **Answer** 41 | 42 | See getpwnam.c. Here's an example run of the test application: 43 | 44 | ``` 45 | $ ./prog_getpwnam posborne 46 | struct passwd { 47 | pw_name="posborne", 48 | pw_uid=1000, 49 | pw_gid=1000, 50 | pw_dir="/home/posborne", 51 | pw_shell="/bin/bash" 52 | } 53 | ``` 54 | 55 | -------------------------------------------------------------------------------- /08-users-and-groups/SConstruct: -------------------------------------------------------------------------------- 1 | env = Environment(CFLAGS='-g -Wall -Werror -pedantic -std=c99') 2 | env.Program('prog_getpwnam', 'getpwnam.c') 3 | -------------------------------------------------------------------------------- /09-process-credentials/SConstruct: -------------------------------------------------------------------------------- 1 | env = Environment(CFLAGS='-g -Wall -Werror -pedantic -std=c99') 2 | env.Program('prog_initgroups', 'initgroups.c') 3 | -------------------------------------------------------------------------------- /10-time/README.md: -------------------------------------------------------------------------------- 1 | Chapter 10: Time 2 | ================ 3 | 4 | Exercise 10-1 5 | ------------- 6 | 7 | **Question** 8 | 9 | Assume a system where the value returned by the call 10 | sysconf(_SC_CLK_TCK) is 100. Assuming that the clock_t value returned 11 | by times() is a signed 32-bit integer, how long will it take before 12 | this value cycles so that it restarts at 0? Perform the same 13 | calculation for the CLOCKS_PER_SEC value returned by clock(). 14 | 15 | **Answer** 16 | 17 | sysconf(_SC_CLK_TCK) tells us the number of ticks per second and 18 | times() tell us the number of ticks that have elapsed. Given that the 19 | maximum value of a signed 32-bit integer is 2147483647, and the elapsed 20 | time in units of clock ticks is 2147483647 - 0 + 1 = 2147483648. We can 21 | calculate out the max time to be: 22 | 23 | >>> secs = 2147483648 / 100.0 24 | >>> print secs 25 | 21474836.47 26 | >>> minutes = secs / 60 27 | >>> hours = minutes / 60 28 | >>> days = hours / 24 29 | >>> print days 30 | 248.55134814814812 31 | >>> years = days / 365 32 | >>> print years 33 | 0.6809625976661592 34 | 35 | At 1 million, as is the case on my machine we get: 36 | 37 | >>> secs = 2147483648 / 1000000.0 38 | >>> print secs 39 | 2147.483648 40 | >>> hours = secs / 60.0 / 60.0 41 | >>> print hours 42 | 0.5965232355555555 43 | -------------------------------------------------------------------------------- /11-system-limits-and-options/README.md: -------------------------------------------------------------------------------- 1 | Chapter 11: System Limits and Options 2 | ===================================== 3 | 4 | Exercise 11-1 5 | ------------- 6 | 7 | **Question** 8 | 9 | Try running the program in List 11-1 on other UNIX implmeentation if 10 | you have access to them. 11 | 12 | **Answer** 13 | 14 | (No access to other UNIX implementations at this time...) 15 | 16 | Exercise 11-2 17 | ------------- 18 | 19 | **Question** 20 | 21 | Try running the program in listing 11-2 on other file systems. 22 | 23 | **Answer** 24 | 25 | ``` 26 | == STDIN == 27 | _PC_NAME_MAX: 255 28 | _PC_PATH_MAX: 4096 29 | _PC_PIPE_BUF: 4096 30 | 31 | == ext4 == 32 | _PC_NAME_MAX: 255 33 | _PC_PATH_MAX: 4096 34 | _PC_PIPE_BUF: 4096 35 | 36 | ``` -------------------------------------------------------------------------------- /11-system-limits-and-options/SConstruct: -------------------------------------------------------------------------------- 1 | env = Environment(CFLAGS='-g -Wall -Werror -pedantic -std=c99') 2 | env.Program('prog_fpath', 't_fpathconf.c') 3 | -------------------------------------------------------------------------------- /11-system-limits-and-options/t_fpathconf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | static void fpathconfPrint(const char *msg, int fd, int name) 10 | { 11 | long lim; 12 | errno = 0; 13 | lim = fpathconf(fd, name); 14 | if (lim != -1) { 15 | printf("%s %ld\n", msg, lim); 16 | } else { 17 | if (errno == 0) 18 | printf("%s (indeterminate)\n", msg); 19 | else 20 | return; 21 | } 22 | } 23 | 24 | 25 | int main(int argc, char *argv[]) 26 | { 27 | printf("== STDIN ==\n"); 28 | fpathconfPrint("_PC_NAME_MAX: ", STDIN_FILENO, _PC_NAME_MAX); 29 | fpathconfPrint("_PC_PATH_MAX: ", STDIN_FILENO, _PC_PATH_MAX); 30 | fpathconfPrint("_PC_PIPE_BUF: ", STDIN_FILENO, _PC_PIPE_BUF); 31 | 32 | printf("\n== ext4 ==\n"); 33 | int fd = open("t_fpathconf.c", O_RDONLY); 34 | fpathconfPrint("_PC_NAME_MAX: ", fd, _PC_NAME_MAX); 35 | fpathconfPrint("_PC_PATH_MAX: ", fd, _PC_PATH_MAX); 36 | fpathconfPrint("_PC_PIPE_BUF: ", fd, _PC_PIPE_BUF); 37 | close(fd); 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /12-system-and-process-information/SConstruct: -------------------------------------------------------------------------------- 1 | env = Environment(CFLAGS='-g -Wall -Werror -pedantic -std=c99') 2 | 3 | def make_prog(progname, cfile, **kwargs): 4 | env.Program(progname, cfile, LIBS=['proclib'], LIBPATH='.', **kwargs) 5 | 6 | env.Library('proclib', ['proclib.c']) 7 | make_prog('prog_proclist', 'proclist.c') 8 | make_prog('prog_pstree', 'pstree.c') 9 | make_prog('prog_sherlock', 'sherlock.c') 10 | -------------------------------------------------------------------------------- /12-system-and-process-information/proclib.c: -------------------------------------------------------------------------------- 1 | #include "proclib.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | /* In-place time of string, s, to remove whitespace */ 8 | void trim(char * s) { 9 | char * p = s; 10 | int l = strlen(p); 11 | 12 | while(isspace(p[l - 1])) p[--l] = 0; 13 | while(* p && isspace(* p)) ++p, --l; 14 | 15 | memmove(s, p, l + 1); 16 | } 17 | -------------------------------------------------------------------------------- /12-system-and-process-information/proclib.h: -------------------------------------------------------------------------------- 1 | #ifndef _proclib_header 2 | #define _proclib_header 3 | 4 | /* In-place time of string, s, to remove whitespace */ 5 | void trim(char * s); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /13-file-io-buffering/SConscript: -------------------------------------------------------------------------------- 1 | Import('env') 2 | Import('variant') 3 | env.Program('prog_copy', 'copy.c') 4 | 5 | -------------------------------------------------------------------------------- /13-file-io-buffering/run_copy_tests.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | echo '= build_10 =' 3 | ./tim.py ./build_10/prog_copy testfile.txt testfile2.txt 4 | 5 | echo '= build_10_sync =' 6 | ./tim.py ./build_10_sync/prog_copy testfile.txt testfile2.txt 7 | 8 | echo '= build_512 =' 9 | ./tim.py ./build_512/prog_copy testfile.txt testfile2.txt 10 | 11 | echo '= build_512_sync =' 12 | ./tim.py ./build_512_sync/prog_copy testfile.txt testfile2.txt 13 | 14 | echo '= build_512000 =' 15 | ./tim.py ./build_512000/prog_copy testfile.txt testfile2.txt 16 | 17 | echo '= build_512000_sync =' 18 | ./tim.py ./build_512000_sync/prog_copy testfile.txt testfile2.txt 19 | 20 | -------------------------------------------------------------------------------- /13-file-io-buffering/run_write_tests.sh: -------------------------------------------------------------------------------- 1 | echo '== write_bytes tests ==' 2 | echo './prog_write_bytes testfile3.txt 10000000 10' 3 | ./tim.py ./prog_write_bytes testfile3.txt 10000000 10 4 | echo './prog_write_bytes testfile3.txt 10000000 512' 5 | ./tim.py ./prog_write_bytes testfile3.txt 10000000 512 6 | echo './prog_write_bytes testfile3.txt 10000000 1024' 7 | ./tim.py ./prog_write_bytes testfile3.txt 10000000 1024 8 | echo './prog_write_bytes testfile3.txt 10000000 10000' 9 | ./tim.py ./prog_write_bytes testfile3.txt 10000000 10000 10 | -------------------------------------------------------------------------------- /13-file-io-buffering/tim.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import time 3 | import sys 4 | import subprocess 5 | 6 | 7 | def main(): 8 | st = time.time() 9 | subprocess.call(" ".join(sys.argv[1:]), shell=True) 10 | print "time: %0.3fs" % (time.time() - st, ) 11 | 12 | 13 | if __name__ == '__main__': 14 | main() 15 | -------------------------------------------------------------------------------- /14-file-systems/SConstruct: -------------------------------------------------------------------------------- 1 | env = Environment(CFLAGS='-g -Wall -Werror -pedantic -std=c99') 2 | env.Program('prog_benchmarkwrites', 'benchmarkwrites.c') 3 | -------------------------------------------------------------------------------- /14-file-systems/runtests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "" 4 | echo "** Tests with ext4 FS **" 5 | ./prog_benchmarkwrites -n 100000 tst 6 | echo "" 7 | ./prog_benchmarkwrites -n 100000 -r tst 8 | echo "" 9 | 10 | echo "" 11 | echo "** Tests with tmpfs FS **" 12 | ./prog_benchmarkwrites -n 100000 tmpfs/tst 13 | echo "" 14 | ./prog_benchmarkwrites -n 100000 -r tmpfs/tst 15 | echo "" 16 | 17 | echo "" 18 | echo "** Tests with ntfs4 FS **" 19 | ./prog_benchmarkwrites -n 100000 /media/ssd/ntfstst 20 | echo "" 21 | ./prog_benchmarkwrites -n 100000 -r /media/ssd/ntfstst 22 | -------------------------------------------------------------------------------- /15-file-attributes/SConstruct: -------------------------------------------------------------------------------- 1 | env = Environment(CFLAGS='-g -Wall -Werror -pedantic -std=c99') 2 | env.Program('prog_stattest', 'exercise2_stattest.c') 3 | env.Program('prog_tstat', 'exercise3_tstat.c') 4 | env.Program('prog_chmod', 'exercise6_chmod.c') 5 | env.Program('prog_chattr', 'chattr.c') 6 | -------------------------------------------------------------------------------- /15-file-attributes/exercise1_parta.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Show that even if all, other, group have access to a file, but not 4 | # user that access to the file is restricted. 5 | # 6 | F="test/ex1a_testfile.txt" 7 | if [ -d "test" ]; then 8 | rm -rf test 9 | fi 10 | mkdir -p test 11 | echo "foo" > "$F" 12 | chmod a+rwx "$F" 13 | chmod g+rwx "$F" 14 | chmod o+rwx "$F" 15 | 16 | chmod u-rwx "$F" 17 | ls -al "$F" 18 | cat "$F" 19 | -------------------------------------------------------------------------------- /15-file-attributes/exercise1_partb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Verify that on a directory with read but not execute permissions 4 | # that the files can be listed but not accessed, regardless of 5 | # permissions. 6 | # 7 | DIR="test" 8 | if [ -d "$DIR" ]; then 9 | rm -rf "$DIR" 10 | fi 11 | mkdir "$DIR" 12 | touch "$DIR/a" && echo "hello, world" > "$DIR/a" && chmod +rwx "$DIR/a" 13 | touch "$DIR/b" && echo "hello, world" > "$DIR/b" && chmod +rwx "$DIR/b" 14 | chmod +r "$DIR" 15 | chmod -xw "$DIR" 16 | 17 | ls -al "$DIR" 18 | cat "$DIR/a" 19 | cat "$DIR/b" -------------------------------------------------------------------------------- /15-file-attributes/exercise2_stattest.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Verify that calls to stat() do not change any of a file's 3 | * timestamps. 4 | */ 5 | #include 6 | #include 7 | #include 8 | 9 | int main(int argc, char **argv) 10 | { 11 | struct stat initial_stat; 12 | struct stat post_stat_stat; 13 | stat("exercise2_stattest.c", &initial_stat); 14 | stat("exercise2_stattest.c", &post_stat_stat); 15 | 16 | printf("== Initial Stat ==\n"); 17 | printf("st_atime: %d\n", (int)initial_stat.st_atime); 18 | printf("st_mtime: %d\n", (int)initial_stat.st_mtime); 19 | printf("st_ctime: %d\n", (int)initial_stat.st_ctime); 20 | 21 | printf("\n... Waiting 2 seconds ...\n\n"); 22 | sleep(2); 23 | 24 | printf("== After First stat() call ==\n"); 25 | printf("st_atime: %d\n", (int)post_stat_stat.st_atime); 26 | printf("st_mtime: %d\n", (int)post_stat_stat.st_mtime); 27 | printf("st_ctime: %d\n", (int)post_stat_stat.st_ctime); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /16-extended-attributes/README.md: -------------------------------------------------------------------------------- 1 | Chapter 16: Extended Attributes 2 | =============================== 3 | 4 | Exercise 16-1 5 | ------------- 6 | 7 | **Question** 8 | 9 | Write a program that can be used to create or modify a user EA for a 10 | file (i.e., a simple version of setfattr(1)). The filename and the EA 11 | name and value should be supplied as command-line arguments to the 12 | program. 13 | 14 | **Answer** 15 | 16 | See setfattr.c. Example: 17 | 18 | ``` 19 | $ ./prog_setfattr -n user.x -v "Hello, world!" tfile 20 | $ getfattr -d tfile 21 | # file: tfile 22 | user.x="Hello, world!" 23 | 24 | $ ./prog_setfattr -x user.x tfile 25 | $ getfattr -d tfile 26 | ``` 27 | -------------------------------------------------------------------------------- /16-extended-attributes/SConstruct: -------------------------------------------------------------------------------- 1 | env = Environment(CFLAGS='-g -Wall -Werror -pedantic -std=c99') 2 | env.Program('prog_setfattr', 'setfattr.c') 3 | -------------------------------------------------------------------------------- /17-access-control-lists/README.md: -------------------------------------------------------------------------------- 1 | Chapter 17: Access Control Lists 2 | ================================ 3 | 4 | Exercise 17-1 5 | ------------- 6 | 7 | **Question** 8 | 9 | Write a program that displays the permissions from the ACL entry that 10 | corresponds to a particular user or group. The program should take 11 | two command-line arguments. The first argument is iether of the 12 | letters u or g, indicating whether the second argument identifies a 13 | user or group. (The functions defined in Listing 8-1, on page 159, can 14 | be used to allow the second command-line argument to be specified 15 | numerically or as a name.) If the ACL entry that corresponds to the 16 | given user or group falls into the group class, then the program 17 | should additionally display the permissions that would apply after 18 | the ACL entry has been modified by the ACL mask entry. 19 | 20 | **Answer** 21 | 22 | [] 23 | 24 | -------------------------------------------------------------------------------- /17-access-control-lists/SConstruct: -------------------------------------------------------------------------------- 1 | env = Environment(CFLAGS='-g -Wall -Werror -pedantic -std=c99') 2 | env.Program('prog_dispacl', 'dispacl.c', LIBS=['acl', ]) 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Paul Osborne 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 | linux-programming-interface-exercises 2 | ===================================== 3 | 4 | [![Build Status](https://travis-ci.org/posborne/linux-programming-interface-exercises.svg)](https://travis-ci.org/posborne/linux-programming-interface-exercises) 5 | 6 | My solutions to The Linux Programming Interface Exercises 7 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "$ gcc --version" 4 | gcc --version 5 | 6 | set -e 7 | 8 | for dir in $(find ./ -mindepth 1 -maxdepth 1 -type d); do 9 | cd $dir 10 | if [ -f ./SConstruct ]; then 11 | echo "== BUILDING $dir ==" 12 | scons -c 13 | scons 14 | fi 15 | cd - 16 | done 17 | -------------------------------------------------------------------------------- /tlpi-dist/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile to build all programs in all subdirectories 2 | # 3 | # DIRS is a list of all subdirectories containing makefiles 4 | # (The library directory is first so that the library gets built first) 5 | # 6 | 7 | DIRS = lib \ 8 | acl altio \ 9 | cap \ 10 | daemons dirs_links \ 11 | fileio filelock files filesys getopt \ 12 | inotify \ 13 | loginacct \ 14 | memalloc \ 15 | mmap \ 16 | pgsjc pipes pmsg \ 17 | proc proccred procexec procpri procres \ 18 | progconc \ 19 | psem pshm pty \ 20 | shlibs \ 21 | signals sockets \ 22 | svipc svmsg svsem svshm \ 23 | sysinfo \ 24 | threads time timers tty \ 25 | users_groups \ 26 | vmem \ 27 | xattr 28 | 29 | # Dummy targets for building and clobbering everything in all subdirectories 30 | 31 | all: 32 | @ for dir in ${DIRS}; do (cd $${dir}; ${MAKE}) ; done 33 | 34 | allgen: 35 | @ for dir in ${DIRS}; do (cd $${dir}; ${MAKE} allgen) ; done 36 | 37 | clean: 38 | @ for dir in ${DIRS}; do (cd $${dir}; ${MAKE} clean) ; done 39 | -------------------------------------------------------------------------------- /tlpi-dist/Makefile.inc: -------------------------------------------------------------------------------- 1 | # Makefile.inc - common definitions used by all makefiles 2 | 3 | TLPI_DIR = .. 4 | TLPI_LIB = ${TLPI_DIR}/libtlpi.a 5 | TLPI_INCL_DIR = ${TLPI_DIR}/lib 6 | 7 | LINUX_LIBRT = -lrt 8 | LINUX_LIBDL = -ldl 9 | LINUX_LIBACL = -lacl 10 | LINUX_LIBCRYPT = -lcrypt 11 | LINUX_LIBCAP = -lcap 12 | 13 | # "-Wextra" is a more descriptive synonym for "-W", but only 14 | # available in more recent gcc versions 15 | 16 | IMPL_CFLAGS = -std=c99 -D_XOPEN_SOURCE=600 \ 17 | -g -I${TLPI_INCL_DIR} \ 18 | -pedantic \ 19 | -Wall \ 20 | -W \ 21 | -Wpointer-arith \ 22 | -Wmissing-prototypes \ 23 | -Wno-sign-compare \ 24 | -Wno-unused-parameter \ 25 | -Wno-format-y2k \ 26 | -Wno-long-long 27 | 28 | CFLAGS = ${IMPL_CFLAGS} 29 | 30 | IMPL_THREAD_FLAGS = -pthread 31 | 32 | IMPL_LDLIBS = ${TLPI_LIB} -lm 33 | 34 | LDLIBS = ${IMPL_LDLIBS} 35 | 36 | RM = rm -f 37 | -------------------------------------------------------------------------------- /tlpi-dist/Makefile.inc.FreeBSD: -------------------------------------------------------------------------------- 1 | # Makefile.inc - common definitions used by all makefiles 2 | # FreeBSD version 3 | 4 | TLPI_DIR = .. 5 | TLPI_LIB = ${TLPI_DIR}/libtlpi.a 6 | TLPI_INCL_DIR = ${TLPI_DIR}/lib 7 | 8 | IMPL_CFLAGS += -g -I${TLPI_INCL_DIR} 9 | CFLAGS = ${IMPL_CFLAGS} 10 | IMPL_THREAD_FLAGS = -pthread 11 | 12 | IMPL_LDLIBS = ${TLPI_LIB} -lcrypt -lm 13 | LDLIBS = ${IMPL_LDLIBS} 14 | 15 | RM = rm -f 16 | -------------------------------------------------------------------------------- /tlpi-dist/Makefile.inc.HP-UX: -------------------------------------------------------------------------------- 1 | # Makefile.inc - common definitions used by all makefiles 2 | # HP-UX Version 3 | 4 | TLPI_DIR = .. 5 | TLPI_LIB = ${TLPI_DIR}/libtlpi.a 6 | TLPI_INCL_DIR = ${TLPI_DIR}/lib 7 | 8 | LINUX_LIBRT = -lrt 9 | LINUX_LIBDL = -ldl 10 | LINUX_LIBACL = -lacl 11 | LINUX_LIBCRYPT = -lcrypt 12 | LINUX_LIBCAP = -lcap 13 | 14 | IMPL_CFLAGS = -g -I${TLPI_INCL_DIR} -D_XOPEN_SOURCE_EXTENDED 15 | CFLAGS = ${IMPL_CFLAGS} 16 | IMPL_THREAD_FLAGS = -mt 17 | 18 | IMPL_LDLIBS = ${TLPI_LIB} -lm 19 | LDFLAGS = ${IMPL_LDLIBS} 20 | LDLIBS = ${IMPL_LDLIBS} 21 | 22 | RM = rm -f 23 | -------------------------------------------------------------------------------- /tlpi-dist/Makefile.inc.MacOSX: -------------------------------------------------------------------------------- 1 | # Makefile.inc - common definitions used by all makefiles 2 | # Mac OS (Lion) version 3 | 4 | TLPI_DIR = .. 5 | TLPI_LIB = ${TLPI_DIR}/libtlpi.a 6 | TLPI_INCL_DIR = ${TLPI_DIR}/lib 7 | 8 | IMPL_CFLAGS += -g -I${TLPI_INCL_DIR} 9 | CFLAGS = ${IMPL_CFLAGS} 10 | IMPL_THREAD_FLAGS = 11 | 12 | IMPL_LDLIBS = ${TLPI_LIB} -lm 13 | LDLIBS = ${IMPL_LDLIBS} 14 | 15 | RM = rm -f 16 | -------------------------------------------------------------------------------- /tlpi-dist/Makefile.inc.Solaris: -------------------------------------------------------------------------------- 1 | # Makefile.inc - common definitions used by all makefiles 2 | # Solaris version 3 | 4 | TLPI_DIR = .. 5 | TLPI_LIB = ${TLPI_DIR}/libtlpi.a 6 | TLPI_INCL_DIR = ${TLPI_DIR}/lib 7 | 8 | IMPL_CFLAGS += -g -I${TLPI_INCL_DIR} -D__EXTENSIONS__ -D_XOPEN_SOURCE=600 -D_XPG4_2 -D_POSIX_C_SOURCE=199506 9 | CFLAGS = ${IMPL_CFLAGS} 10 | IMPL_THREAD_FLAGS = -mt 11 | 12 | IMPL_LDLIBS = ${TLPI_LIB} -lsocket -lnsl -lrt -ldl -lm -lresolv 13 | LDLIBS = ${IMPL_LDLIBS} 14 | 15 | RM = rm -f 16 | -------------------------------------------------------------------------------- /tlpi-dist/Makefile.inc.Tru64: -------------------------------------------------------------------------------- 1 | # Makefile.inc - common definitions used by all makefiles 2 | # Tru64 version 3 | 4 | TLPI_DIR = .. 5 | TLPI_LIB = ${TLPI_DIR}/libtlpi.a 6 | TLPI_INCL_DIR = ${TLPI_DIR}/lib 7 | 8 | IMPL_CFLAGS = -g -I${TLPI_INCL_DIR} -D_POSIX_PII_SOCKET -D_OSF_SOURCE 9 | CFLAGS = ${IMPL_CFLAGS} 10 | IMPL_THREAD_FLAGS = -pthread 11 | 12 | IMPL_LDLIBS = ${TLPI_LIB} -lrt -lm 13 | LOADLIBES = ${IMPL_LDLIBS} 14 | LDLIBS = ${IMPL_LDLIBS} 15 | 16 | RM = rm -f 17 | -------------------------------------------------------------------------------- /tlpi-dist/acl/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = 4 | 5 | LINUX_EXE = acl_update acl_view 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | acl_update : acl_update.o 14 | ${CC} -o $@ acl_update.o ${CFLAGS} ${LDLIBS} ${LINUX_LIBACL} 15 | 16 | acl_view : acl_view.o 17 | ${CC} -o $@ acl_view.o ${CFLAGS} ${LDLIBS} ${LINUX_LIBACL} 18 | 19 | clean : 20 | ${RM} ${EXE} *.o 21 | 22 | showall : 23 | @ echo ${EXE} 24 | 25 | ${EXE} : ${LPLIB} # True as a rough approximation 26 | -------------------------------------------------------------------------------- /tlpi-dist/altio/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = demo_sigio poll_pipes select_mq self_pipe t_select 4 | 5 | LINUX_EXE = epoll_input 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/cap/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = 4 | 5 | LINUX_EXE = check_password_caps 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | demo_caps: demo_caps.o 20 | ${CC} -o $@ demo_caps.o ${CFLAGS} ${LDLIBS} ${LINUX_LIBCAP} 21 | 22 | check_password_caps: check_password_caps.o 23 | ${CC} -o $@ check_password_caps.o ${CFLAGS} ${LDLIBS} \ 24 | ${LINUX_LIBCAP} ${LINUX_LIBCRYPT} 25 | 26 | ${EXE} : ${LPLIB} # True as a rough approximation 27 | -------------------------------------------------------------------------------- /tlpi-dist/daemons/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = daemon_SIGHUP t_syslog test_become_daemon 4 | 5 | EXE = ${GEN_EXE} ${LINUX_EXE} 6 | 7 | all : ${EXE} 8 | 9 | allgen : ${GEN_EXE} 10 | 11 | clean : 12 | ${RM} ${EXE} *.o 13 | 14 | showall : 15 | @ echo ${EXE} 16 | 17 | ${EXE} : ${LPLIB} # True as a rough approximation 18 | -------------------------------------------------------------------------------- /tlpi-dist/daemons/become_daemon.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* become_daemon.h 12 | 13 | Header file for become_daemon.c. 14 | */ 15 | #ifndef BECOME_DAEMON_H /* Prevent double inclusion */ 16 | #define BECOME_DAEMON_H 17 | 18 | /* Bit-mask values for 'flags' argument of becomeDaemon() */ 19 | 20 | #define BD_NO_CHDIR 01 /* Don't chdir("/") */ 21 | #define BD_NO_CLOSE_FILES 02 /* Don't close all open files */ 22 | #define BD_NO_REOPEN_STD_FDS 04 /* Don't reopen stdin, stdout, and 23 | stderr to /dev/null */ 24 | #define BD_NO_UMASK0 010 /* Don't do a umask(0) */ 25 | 26 | #define BD_MAX_CLOSE 8192 /* Maximum file descriptors to close if 27 | sysconf(_SC_OPEN_MAX) is indeterminate */ 28 | 29 | int becomeDaemon(int flags); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /tlpi-dist/daemons/test_become_daemon.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* test_become_daemon.c 12 | 13 | Test our becomeDaemon() function. 14 | */ 15 | #include "become_daemon.h" 16 | #include "tlpi_hdr.h" 17 | 18 | int 19 | main(int argc, char *argv[]) 20 | { 21 | becomeDaemon(0); 22 | 23 | /* Normally a daemon would live forever; we just sleep for a while */ 24 | 25 | sleep((argc > 1) ? getInt(argv[1], GN_GT_0, "sleep-time") : 20); 26 | 27 | exit(EXIT_SUCCESS); 28 | } 29 | -------------------------------------------------------------------------------- /tlpi-dist/dirs_links/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = bad_symlink list_files list_files_readdir_r \ 4 | t_dirbasename t_unlink view_symlink 5 | 6 | FTW_EXE = nftw_dir_tree file_type_stats 7 | 8 | LINUX_EXE = 9 | 10 | EXE = ${GEN_EXE} ${LINUX_EXE} ${FTW_EXE} 11 | 12 | all : ${EXE} 13 | 14 | allftw : ${FTW_EXE} 15 | 16 | allgen : ${GEN_EXE} 17 | 18 | clean : 19 | ${RM} ${EXE} *.o 20 | 21 | showall : 22 | @ echo ${EXE} 23 | 24 | ${EXE} : ${LPLIB} # True as a rough approximation 25 | -------------------------------------------------------------------------------- /tlpi-dist/dirs_links/t_dirbasename.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* t_dirbasename.c 12 | 13 | Demonstrate the use of dirname() and basename() to break a pathname 14 | into directory and filename components. 15 | 16 | Usage: t_dirbasename path... 17 | 18 | The program calls dirname() and basename() for each of the pathnames 19 | supplied on the command-line. 20 | */ 21 | #include 22 | #include "tlpi_hdr.h" 23 | 24 | int 25 | main(int argc, char *argv[]) 26 | { 27 | char *t1, *t2; 28 | int j; 29 | 30 | for (j = 1; j < argc; j++) { 31 | t1 = strdup(argv[j]); 32 | if (t1 == NULL) 33 | errExit("strdup"); 34 | t2 = strdup(argv[j]); 35 | if (t2 == NULL) 36 | errExit("strdup"); 37 | 38 | printf("%s ==> %s + %s\n", argv[j], dirname(t1), basename(t2)); 39 | 40 | free(t1); 41 | free(t2); 42 | } 43 | 44 | exit(EXIT_SUCCESS); 45 | } 46 | -------------------------------------------------------------------------------- /tlpi-dist/filebuff/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = copy mix23_linebuff mix23io write_bytes 4 | 5 | LINUX_EXE = direct_read 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/filebuff/mix23_linebuff.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* mix23_linebuff.c 12 | 13 | Illustrates the impact of stdio buffering when using stdio library 14 | functions and I/O system calls to work on the same file. Observe the 15 | difference in output when running this program with output directed 16 | to a terminal and again with output directed to a file. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | int 24 | main(int argc, char *argv[]) 25 | { 26 | printf("If I had more time, \n"); 27 | write(STDOUT_FILENO, "I would have written you a shorter letter.\n", 43); 28 | exit(EXIT_SUCCESS); 29 | } 30 | -------------------------------------------------------------------------------- /tlpi-dist/filebuff/mix23io.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* mix23io.c 12 | 13 | Illustrates the impact of stdio buffering when using stdio library functions 14 | and I/O system calls to work on the same file. 15 | 16 | Try running this program (with stdout directed to the terminal) without and 17 | with a command-line argument (any string). 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | int 25 | main(int argc, char *argv[]) 26 | { 27 | printf("To man the world is twofold, "); 28 | if (argc > 1) 29 | printf("\n"); 30 | write(STDOUT_FILENO, "in accordance with his twofold attitude.\n", 41); 31 | 32 | exit(EXIT_SUCCESS); 33 | } 34 | -------------------------------------------------------------------------------- /tlpi-dist/fileio/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = atomic_append bad_exclusive_open copy \ 4 | multi_descriptors seek_io t_readv t_truncate 5 | 6 | LINUX_EXE = large_file 7 | 8 | EXE = ${GEN_EXE} ${LINUX_EXE} 9 | 10 | all : ${EXE} 11 | 12 | allgen : ${GEN_EXE} 13 | 14 | clean : 15 | ${RM} ${EXE} *.o 16 | 17 | showall : 18 | @ echo ${EXE} 19 | 20 | ${EXE} : ${LPLIB} # True as a rough approximation 21 | -------------------------------------------------------------------------------- /tlpi-dist/fileio/large_file.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* large_file.c 12 | 13 | Demonstrate the use of the (obsolete) Large File System API. 14 | 15 | This program is Linux-specific. 16 | */ 17 | #define _LARGEFILE64_SOURCE 18 | #include 19 | #include 20 | #include "tlpi_hdr.h" 21 | 22 | int 23 | main(int argc, char *argv[]) 24 | { 25 | int fd; 26 | off64_t off; 27 | 28 | if (argc != 3 || strcmp(argv[1], "--help") == 0) 29 | usageErr("%s pathname offset\n", argv[0]); 30 | 31 | fd = open64(argv[1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); 32 | if (fd == -1) 33 | errExit("open64"); 34 | 35 | off = atoll(argv[2]); 36 | if (lseek64(fd, off, SEEK_SET) == -1) 37 | errExit("lseek64"); 38 | 39 | if (write(fd, "test", 4) == -1) 40 | errExit("write"); 41 | exit(EXIT_SUCCESS); 42 | } 43 | -------------------------------------------------------------------------------- /tlpi-dist/fileio/t_truncate.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* t_truncate.c 12 | 13 | Demonstrate the use of the truncate() system call to truncate the file 14 | named in argv[1] to the length specified in argv[2] 15 | */ 16 | #include "tlpi_hdr.h" 17 | 18 | int 19 | main(int argc, char *argv[]) 20 | { 21 | if (argc != 3 || strcmp(argv[1], "--help") == 0) 22 | usageErr("%s file length\n", argv[0]); 23 | 24 | if (truncate(argv[1], getLong(argv[2], GN_ANY_BASE, "length")) == -1) 25 | errExit("truncate"); 26 | 27 | exit(EXIT_SUCCESS); 28 | } 29 | -------------------------------------------------------------------------------- /tlpi-dist/filelock/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = i_fcntl_locking t_flock 4 | 5 | EXE = ${GEN_EXE} ${LINUX_EXE} 6 | 7 | all : ${EXE} 8 | 9 | allgen : ${GEN_EXE} 10 | 11 | clean : 12 | ${RM} ${EXE} *.o 13 | 14 | showall : 15 | @ echo ${EXE} 16 | 17 | ${EXE} : ${LPLIB} # True as a rough approximation 18 | -------------------------------------------------------------------------------- /tlpi-dist/filelock/create_pid_file.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* create_pid_file.h 12 | 13 | Header file for create_pid_file.c. 14 | */ 15 | #ifndef CREATE_PID_FILE_H /* Prevent accidental double inclusion */ 16 | #define CREATE_PID_FILE_H 17 | 18 | #define CPF_CLOEXEC 1 19 | 20 | int createPidFile(const char *progName, const char *pidFile, int flags); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /tlpi-dist/filelock/region_locking.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* region_locking.h 12 | 13 | Header file for region_locking.c. 14 | */ 15 | #ifndef REGION_LOCKING_H 16 | #define REGION_LOCKING_H 17 | 18 | #include 19 | 20 | int lockRegion(int fd, int type, int whence, int start, int len); 21 | 22 | int lockRegionWait(int fd, int type, int whence, int start, int len); 23 | 24 | pid_t regionIsLocked(int fd, int type, int whence, int start, int len); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /tlpi-dist/files/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = t_chown t_stat t_umask t_utime t_utimes 4 | 5 | LINUX_EXE = chiflag 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/files/file_perms.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* file_perms.h 12 | 13 | Header file for file_perms.c. 14 | */ 15 | #ifndef FILE_PERMS_H 16 | #define FILE_PERMS_H 17 | 18 | #include 19 | 20 | #define FP_SPECIAL 1 /* Include set-user-ID, set-group-ID, and sticky 21 | bit information in returned string */ 22 | 23 | char *filePermStr(mode_t perm, int flags); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /tlpi-dist/filesys/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = t_statvfs 4 | 5 | LINUX_EXE = t_statfs t_mount t_umount 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/filesys/t_umount.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* t_umount.c 12 | 13 | Demonstrate the use of the umount() system call to unmount a mount point. 14 | 15 | Usage: t_umount mount-point 16 | 17 | This program is Linux-specific. 18 | */ 19 | #include 20 | #include "tlpi_hdr.h" 21 | 22 | int 23 | main(int argc, char *argv[]) 24 | { 25 | if (argc != 2 || strcmp(argv[1], "--help") == 0) 26 | usageErr("%s mount-point\n", argv[0]); 27 | 28 | if (umount(argv[1]) == -1) 29 | errExit("umount"); 30 | 31 | exit(EXIT_SUCCESS); 32 | } 33 | -------------------------------------------------------------------------------- /tlpi-dist/getopt/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = t_getopt 4 | 5 | LINUX_EXE = 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/inotify/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = 4 | 5 | LINUX_EXE = demo_inotify dnotify 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allftw : ${FTW_EXE} 12 | 13 | allgen : ${GEN_EXE} 14 | 15 | clean : 16 | ${RM} ${EXE} *.o 17 | 18 | showall : 19 | @ echo ${EXE} 20 | 21 | ${EXE} : ${LPLIB} # True as a rough approximation 22 | -------------------------------------------------------------------------------- /tlpi-dist/lib/Build_ename.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Create a new version of the file ename.c.inc by parsing symbolic 4 | # error names defined in errno.h 5 | # 6 | echo '#include ' | cpp -dM | 7 | sed -n -e '/#define *E/s/#define *//p' |sort -k2n | 8 | awk ' 9 | BEGIN { 10 | entries_per_line = 4 11 | line_len = 68; 12 | last = 0; 13 | varname =" enames"; 14 | print "static char *ename[] = {"; 15 | line = " /* 0 */ \"\""; 16 | } 17 | 18 | { 19 | if ($2 ~ /^E[A-Z0-9]*$/) { # These entries are sorted at top 20 | synonym[$1] = $2; 21 | } else { 22 | while (last + 1 < $2) { 23 | last++; 24 | line = line ", "; 25 | if (length(line ename) > line_len || last == 1) { 26 | print line; 27 | line = " /* " last " */ "; 28 | line = sprintf(" /* %3d */ ", last); 29 | } 30 | line = line "\"" "\"" ; 31 | } 32 | last = $2; 33 | ename = $1; 34 | for (k in synonym) 35 | if (synonym[k] == $1) ename = ename "/" k; 36 | 37 | line = line ", "; 38 | if (length(line ename) > line_len || last == 1) { 39 | print line; 40 | line = " /* " last " */ "; 41 | line = sprintf(" /* %3d */ ", last);; 42 | } 43 | line = line "\"" ename "\"" ; 44 | } 45 | } 46 | END { 47 | print line; 48 | print "};" 49 | print ""; 50 | print "#define MAX_ENAME " last; 51 | } 52 | ' 53 | 54 | -------------------------------------------------------------------------------- /tlpi-dist/lib/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile to build library used by all programs 2 | # 3 | # This make file relies on the assumption that each C file in this 4 | # directory belongs in the library 5 | # 6 | # This makefile is very simple so that every version of make 7 | # should be able to handle it 8 | # 9 | include ../Makefile.inc 10 | 11 | # The library build is "brute force" -- we don't bother with 12 | # dependency checking. 13 | 14 | allgen : 15 | sh Build_ename.sh > ename.c.inc 16 | echo 1>&2 "ename.c.inc built" 17 | ${CC} -c -g ${CFLAGS} *.c 18 | ${RM} ${TLPI_LIB} 19 | ${AR} rs ${TLPI_LIB} *.o 20 | 21 | clean : 22 | ${RM} *.o ename.c.inc ${TLPI_LIB} 23 | 24 | -------------------------------------------------------------------------------- /tlpi-dist/lib/README: -------------------------------------------------------------------------------- 1 | A small design note... Many of the library functions defined in the 2 | source code modules in this directory handle errors from system calls 3 | and C library functions by simply terminating the process. This 4 | isn't acceptable design for a "real world" suite of library functions; 5 | I did things this way to keep the source code simpler and shorter. 6 | A properly designed function should indicate an error to its caller 7 | using a status argument or some special function return value. 8 | -------------------------------------------------------------------------------- /tlpi-dist/lib/alt_functions.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* alt_functions.h 12 | 13 | Header file for alt_functions.c. 14 | */ 15 | #ifndef ALT_FUNCTIONS_H 16 | #define ALT_FUNCTIONS_H /* Prevent accidental double inclusion */ 17 | 18 | #if defined(__osf__) || defined(__hpux) || defined(_AIX) || \ 19 | defined(__sgi) || defined(__APPLE__) 20 | #define strsignal(sig) ALT_strsignal(sig) 21 | #endif 22 | char *ALT_strsignal(int sig); 23 | 24 | #if defined(__hpux) || defined(__osf__) 25 | #define hstrerror(err) ALT_hstrerror(err) 26 | #endif 27 | char *ALT_hstrerror(int sig); 28 | 29 | #if defined(__hpux) || defined(__osf__) 30 | #define posix_openpt(flags) ALT_posix_openpt(flags) 31 | #endif 32 | int ALT_posix_openpt(int flags); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /tlpi-dist/lib/become_daemon.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* become_daemon.h 12 | 13 | Header file for become_daemon.c. 14 | */ 15 | #ifndef BECOME_DAEMON_H /* Prevent double inclusion */ 16 | #define BECOME_DAEMON_H 17 | 18 | /* Bit-mask values for 'flags' argument of becomeDaemon() */ 19 | 20 | #define BD_NO_CHDIR 01 /* Don't chdir("/") */ 21 | #define BD_NO_CLOSE_FILES 02 /* Don't close all open files */ 22 | #define BD_NO_REOPEN_STD_FDS 04 /* Don't reopen stdin, stdout, and 23 | stderr to /dev/null */ 24 | #define BD_NO_UMASK0 010 /* Don't do a umask(0) */ 25 | 26 | #define BD_MAX_CLOSE 8192 /* Maximum file descriptors to close if 27 | sysconf(_SC_OPEN_MAX) is indeterminate */ 28 | 29 | int becomeDaemon(int flags); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /tlpi-dist/lib/binary_sems.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* binary_sems.h 12 | 13 | Header file for binary_sems.c. 14 | */ 15 | #ifndef BINARY_SEMS_H /* Prevent accidental double inclusion */ 16 | #define BINARY_SEMS_H 17 | 18 | #include "tlpi_hdr.h" 19 | 20 | /* Variables controlling operation of functions below */ 21 | 22 | extern Boolean bsUseSemUndo; /* Use SEM_UNDO during semop()? */ 23 | extern Boolean bsRetryOnEintr; /* Retry if semop() interrupted by 24 | signal handler? */ 25 | 26 | int initSemAvailable(int semId, int semNum); 27 | 28 | int initSemInUse(int semId, int semNum); 29 | 30 | int reserveSem(int semId, int semNum); 31 | 32 | int releaseSem(int semId, int semNum); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /tlpi-dist/lib/create_pid_file.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* create_pid_file.h 12 | 13 | Header file for create_pid_file.c. 14 | */ 15 | #ifndef CREATE_PID_FILE_H /* Prevent accidental double inclusion */ 16 | #define CREATE_PID_FILE_H 17 | 18 | #define CPF_CLOEXEC 1 19 | 20 | int createPidFile(const char *progName, const char *pidFile, int flags); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /tlpi-dist/lib/curr_time.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* curr_time.c 12 | 13 | Implement our currTime() function. 14 | */ 15 | #include 16 | #include "curr_time.h" /* Declares function defined here */ 17 | 18 | #define BUF_SIZE 1000 19 | 20 | /* Return a string containing the current time formatted according to 21 | the specification in 'format' (see strftime(3) for specifiers). 22 | If 'format' is NULL, we use "%c" as a specifier (which gives the' 23 | date and time as for ctime(3), but without the trailing newline). 24 | Returns NULL on error. */ 25 | 26 | char * 27 | currTime(const char *format) 28 | { 29 | static char buf[BUF_SIZE]; /* Nonreentrant */ 30 | time_t t; 31 | size_t s; 32 | struct tm *tm; 33 | 34 | t = time(NULL); 35 | tm = localtime(&t); 36 | if (tm == NULL) 37 | return NULL; 38 | 39 | s = strftime(buf, BUF_SIZE, (format != NULL) ? format : "%c", tm); 40 | 41 | return (s == 0) ? NULL : buf; 42 | } 43 | -------------------------------------------------------------------------------- /tlpi-dist/lib/curr_time.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* curr_time.h 12 | 13 | Header file for curr_time.c. 14 | */ 15 | #ifndef CURR_TIME_H 16 | #define CURR_TIME_H /* Prevent accidental double inclusion */ 17 | 18 | char *currTime(const char *fmt); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /tlpi-dist/lib/event_flags.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* event_flags.h 12 | 13 | Header file for event_flags.c. 14 | 15 | The event flags operations are: 16 | 17 | set a flag: setEventFlag(semId, semNum) 18 | clear a flag: clearEventFlag(semId, semNum) 19 | wait for flag to be set: waitForEventFlag(semId, semNum) 20 | read a flag's value: getFlagState(semId, semNum, &isSet) 21 | 22 | NB: The semantics of System V semaphores require that the "set" 23 | value for a flag is 0 and the "clear" value is 1. 24 | */ 25 | #ifndef EVENT_FLAGS_H 26 | #define EVENT_FLAGS_H /* Prevent accidental double inclusion */ 27 | 28 | #include "tlpi_hdr.h" 29 | 30 | int waitForEventFlag(int semId, int semNum); 31 | 32 | int clearEventFlag(int semId, int semNum); 33 | 34 | int setEventFlag(int semId, int semNum); 35 | 36 | int getFlagState(int semId, int semNum, Boolean *isSet); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /tlpi-dist/lib/file_perms.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* file_perms.h 12 | 13 | Header file for file_perms.c. 14 | */ 15 | #ifndef FILE_PERMS_H 16 | #define FILE_PERMS_H 17 | 18 | #include 19 | 20 | #define FP_SPECIAL 1 /* Include set-user-ID, set-group-ID, and sticky 21 | bit information in returned string */ 22 | 23 | char *filePermStr(mode_t perm, int flags); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /tlpi-dist/lib/get_num.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* get_num.h 12 | 13 | Header file for get_num.c. 14 | */ 15 | #ifndef GET_NUM_H 16 | #define GET_NUM_H 17 | 18 | #define GN_NONNEG 01 /* Value must be >= 0 */ 19 | #define GN_GT_0 02 /* Value must be > 0 */ 20 | 21 | /* By default, integers are decimal */ 22 | #define GN_ANY_BASE 0100 /* Can use any base - like strtol(3) */ 23 | #define GN_BASE_8 0200 /* Value is expressed in octal */ 24 | #define GN_BASE_16 0400 /* Value is expressed in hexadecimal */ 25 | 26 | long getLong(const char *arg, int flags, const char *name); 27 | 28 | int getInt(const char *arg, int flags, const char *name); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /tlpi-dist/lib/inet_sockets.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* inet_sockets.h 12 | 13 | Header file for inet_sockets.c. 14 | */ 15 | #ifndef INET_SOCKETS_H 16 | #define INET_SOCKETS_H /* Prevent accidental double inclusion */ 17 | 18 | #include 19 | #include 20 | 21 | int inetConnect(const char *host, const char *service, int type); 22 | 23 | int inetListen(const char *service, int backlog, socklen_t *addrlen); 24 | 25 | int inetBind(const char *service, int type, socklen_t *addrlen); 26 | 27 | char *inetAddressStr(const struct sockaddr *addr, socklen_t addrlen, 28 | char *addrStr, int addrStrLen); 29 | 30 | #define IS_ADDR_STR_LEN 4096 31 | /* Suggested length for string buffer that caller 32 | should pass to inetAddressStr(). Must be greater 33 | than (NI_MAXHOST + NI_MAXSERV + 4) */ 34 | #endif 35 | -------------------------------------------------------------------------------- /tlpi-dist/lib/itimerspec_from_str.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* itimerspec_from_str.h 12 | 13 | Header file for itimerspec_from_str.c. 14 | */ 15 | #ifndef ITIMERSPEC_FROM_STR_H 16 | #define ITIMERSPEC_FROM_STR_H 17 | 18 | #include 19 | 20 | void itimerspecFromStr(char *str, struct itimerspec *tsp); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /tlpi-dist/lib/print_rlimit.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* print_rlimit.h 12 | 13 | Header file for print_rlimit.c. 14 | */ 15 | #ifndef PRINT_RLIMIT_H /* Prevent accidental double inclusion */ 16 | #define PRINT_RLIMIT_H 17 | 18 | int printRlimit(const char *msg, int resource); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /tlpi-dist/lib/print_rusage.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* print_rusage.h 12 | 13 | Header file for print_rusage.c. 14 | */ 15 | #ifndef PRINT_RUSAGE_H /* Prevent accidental double inclusion */ 16 | #define PRINT_RUSAGE_H 17 | 18 | #include 19 | 20 | void printRusage(const char *leader, const struct rusage *ru); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /tlpi-dist/lib/print_wait_status.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* print_wait_status.h 12 | 13 | Header file for print_wait_status.c. 14 | */ 15 | #ifndef PRINT_WAIT_STATUS_H /* Prevent accidental double inclusion */ 16 | #define PRINT_WAIT_STATUS_H 17 | 18 | void printWaitStatus(const char *msg, int status); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /tlpi-dist/lib/pty_fork.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* pty_fork.h 12 | 13 | Header file for pty_fork.c. 14 | */ 15 | #ifndef FORK_PTY_H 16 | #define FORK_PTY_H 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | pid_t ptyFork(int *masterFd, char *slaveName, size_t snLen, 23 | const struct termios *slaveTermios, const struct winsize *slaveWS); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /tlpi-dist/lib/pty_master_open.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* pty_open.h 12 | 13 | Header file for pty_open.c (and pty_master_open_bsd.c). 14 | */ 15 | #ifndef PTY_MASTER_OPEN_H 16 | #define PTY_MASTER_OPEN_H 17 | 18 | #include 19 | 20 | int ptyMasterOpen(char *slaveName, size_t snLen); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /tlpi-dist/lib/rdwrn.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* rdwrn.h 12 | 13 | Header file for rdwrn.c. 14 | */ 15 | #ifndef RDWRN_H 16 | #define RDWRN_H 17 | 18 | #include 19 | 20 | ssize_t readn(int fd, void *buf, size_t len); 21 | 22 | ssize_t writen(int fd, const void *buf, size_t len); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /tlpi-dist/lib/read_line.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* read_line.h 12 | 13 | Header file for read_line.c. 14 | */ 15 | #ifndef READ_LINE_H 16 | #define READ_LINE_H 17 | 18 | #include 19 | 20 | ssize_t readLine(int fd, void *buffer, size_t n); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /tlpi-dist/lib/region_locking.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* region_locking.h 12 | 13 | Header file for region_locking.c. 14 | */ 15 | #ifndef REGION_LOCKING_H 16 | #define REGION_LOCKING_H 17 | 18 | #include 19 | 20 | int lockRegion(int fd, int type, int whence, int start, int len); 21 | 22 | int lockRegionWait(int fd, int type, int whence, int start, int len); 23 | 24 | pid_t regionIsLocked(int fd, int type, int whence, int start, int len); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /tlpi-dist/lib/semun.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* semun.h 12 | 13 | Definition of the semun union used by the System V semaphore semop() 14 | system call. 15 | */ 16 | #ifndef SEMUN_H 17 | #define SEMUN_H /* Prevent accidental double inclusion */ 18 | 19 | #include /* For portability */ 20 | #include 21 | 22 | #if ! defined(__FreeBSD__) && ! defined(__OpenBSD__) && \ 23 | ! defined(__sgi) && ! defined(__APPLE__) 24 | /* Some implementations already declare this union */ 25 | 26 | union semun { /* Used in calls to semctl() */ 27 | int val; 28 | struct semid_ds * buf; 29 | unsigned short * array; 30 | #if defined(__linux__) 31 | struct seminfo * __buf; 32 | #endif 33 | }; 34 | 35 | #endif 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /tlpi-dist/lib/signal_functions.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* signal_functions.h 12 | 13 | Header file for signal_functions.c. 14 | */ 15 | #ifndef SIGNAL_FUNCTIONS_H 16 | #define SIGNAL_FUNCTIONS_H 17 | 18 | #include 19 | #include "tlpi_hdr.h" 20 | 21 | int printSigMask(FILE *of, const char *msg); 22 | 23 | int printPendingSigs(FILE *of, const char *msg); 24 | 25 | void printSigset(FILE *of, const char *ldr, const sigset_t *mask); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /tlpi-dist/lib/tty_functions.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* tty_functions.h 12 | 13 | Header file for tty_functions.c. 14 | */ 15 | #ifndef TTY_FUNCTIONS_H 16 | #define TTY_FUNCTIONS_H 17 | 18 | #include 19 | 20 | int ttySetCbreak(int fd, struct termios *prevTermios); 21 | 22 | int ttySetRaw(int fd, struct termios *prevTermios); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /tlpi-dist/lib/ugid_functions.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* ugid_functions.h 12 | 13 | Header file for ugid_functions.c. 14 | */ 15 | #ifndef UGID_FUNCTIONS_H 16 | #define UGID_FUNCTIONS_H 17 | 18 | #include "tlpi_hdr.h" 19 | 20 | char *userNameFromId(uid_t uid); 21 | 22 | uid_t userIdFromName(const char *name); 23 | 24 | char *groupNameFromId(gid_t gid); 25 | 26 | gid_t groupIdFromName(const char *name); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /tlpi-dist/lib/unix_sockets.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* unix_sockets.h 12 | 13 | Header file for unix_sockets.c. 14 | */ 15 | #ifndef UNIX_SOCKETS_H 16 | #define UNIX_SOCKETS_H /* Prevent accidental double inclusion */ 17 | 18 | #include 19 | #include 20 | 21 | int unixBuildAddress(const char *path, struct sockaddr_un *addr); 22 | 23 | int unixConnect(const char *path, int type); 24 | 25 | int unixListen(const char *path, int backlog); 26 | 27 | int unixBind(const char *path, int type); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /tlpi-dist/loginacct/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = 4 | 5 | LINUX_EXE = dump_utmpx utmpx_login view_lastlog 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/memalloc/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = free_and_sbrk 4 | 5 | LINUX_EXE = 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/mmap/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = anon_mmap mmcat mmcopy t_mmap 4 | 5 | LINUX_EXE = t_remap_file_pages 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/pgsjc/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = catch_SIGHUP disc_SIGHUP job_mon \ 4 | orphaned_pgrp_SIGHUP handling_SIGTSTP t_setsid 5 | 6 | EXE = ${GEN_EXE} ${LINUX_EXE} 7 | 8 | all : ${EXE} 9 | 10 | allgen : ${GEN_EXE} 11 | 12 | clean : 13 | ${RM} ${EXE} *.o 14 | 15 | showall : 16 | @ echo ${EXE} 17 | 18 | ${EXE} : ${LPLIB} # True as a rough approximation 19 | -------------------------------------------------------------------------------- /tlpi-dist/pgsjc/t_setsid.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* t_setsid.c 12 | 13 | Demonstrate the use of setsid(2) to start a new session. 14 | */ 15 | #if ! defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 500 16 | #define _XOPEN_SOURCE 500 17 | #endif 18 | #include 19 | #include 20 | #include "tlpi_hdr.h" 21 | 22 | int 23 | main(int argc, char *argv[]) 24 | { 25 | if (fork() != 0) /* Exit if parent, or on error */ 26 | _exit(EXIT_SUCCESS); 27 | 28 | if (setsid() == -1) 29 | errExit("setsid"); 30 | 31 | printf("PID=%ld, PGID=%ld, SID=%ld\n", (long) getpid(), 32 | (long) getpgrp(), (long) getsid(0)); 33 | 34 | /* Following should fail, since we don't have a controlling terminal */ 35 | 36 | if (open("/dev/tty", O_RDWR) == -1) 37 | errExit("open /dev/tty"); 38 | exit(EXIT_SUCCESS); 39 | } 40 | -------------------------------------------------------------------------------- /tlpi-dist/pipes/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = change_case fifo_seqnum_client fifo_seqnum_server \ 4 | pipe_ls_wc pipe_sync popen_glob simple_pipe 5 | 6 | EXE = ${GEN_EXE} ${LINUX_EXE} 7 | 8 | all : ${EXE} 9 | 10 | allgen : ${GEN_EXE} 11 | 12 | fifo_seqnum_client.o fifo_seqnum_server.o : fifo_seqnum.h 13 | 14 | clean : 15 | ${RM} ${EXE} *.o 16 | 17 | showall : 18 | @ echo ${EXE} 19 | 20 | ${EXE} : ${LPLIB} # True as a rough approximation 21 | -------------------------------------------------------------------------------- /tlpi-dist/pmsg/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = mq_notify_sig mq_notify_sigwaitinfo mq_notify_thread \ 4 | pmsg_create pmsg_getattr pmsg_receive pmsg_send pmsg_unlink 5 | 6 | LINUX_EXE = 7 | 8 | EXE = ${GEN_EXE} ${LINUX_EXE} 9 | 10 | all : ${EXE} 11 | 12 | allgen : ${GEN_EXE} 13 | 14 | LDLIBS = ${IMPL_LDLIBS} ${LINUX_LIBRT} 15 | # All of the programs in this directory need the 16 | # realtime library, librt. 17 | 18 | mq_notify_thread: mq_notify_thread.c 19 | ${CC} -o $@ ${IMPL_THREAD_FLAGS} mq_notify_thread.c \ 20 | ${CFLAGS} ${LDLIBS} 21 | 22 | clean : 23 | ${RM} ${EXE} *.o 24 | 25 | showall : 26 | @ echo ${EXE} 27 | 28 | ${EXE} : ${LPLIB} # True as a rough approximation 29 | -------------------------------------------------------------------------------- /tlpi-dist/pmsg/pmsg_getattr.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* pmsg_getattr.c 12 | 13 | Display attributes of a POSIX message queue. 14 | 15 | Linux supports POSIX message queues since kernel 2.6.6. 16 | */ 17 | #include 18 | #include "tlpi_hdr.h" 19 | 20 | int 21 | main(int argc, char *argv[]) 22 | { 23 | mqd_t mqd; 24 | struct mq_attr attr; 25 | 26 | if (argc != 2 || strcmp(argv[1], "--help") == 0) 27 | usageErr("%s mq-name\n", argv[0]); 28 | 29 | mqd = mq_open(argv[1], O_RDONLY); 30 | if (mqd == (mqd_t) -1) 31 | errExit("mq_open"); 32 | 33 | if (mq_getattr(mqd, &attr) == -1) 34 | errExit("mq_getattr"); 35 | 36 | printf("Maximum # of messages on queue: %ld\n", attr.mq_maxmsg); 37 | printf("Maximum message size: %ld\n", attr.mq_msgsize); 38 | printf("# of messages currently on queue: %ld\n", attr.mq_curmsgs); 39 | exit(EXIT_SUCCESS); 40 | } 41 | -------------------------------------------------------------------------------- /tlpi-dist/pmsg/pmsg_unlink.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* pmsg_unlink.c 12 | 13 | Usage: pmsg_unlink mq-name 14 | 15 | Unlink a POSIX message queue. 16 | 17 | Linux supports POSIX message queues since kernel 2.6.6. 18 | */ 19 | #include 20 | #include "tlpi_hdr.h" 21 | 22 | int 23 | main(int argc, char *argv[]) 24 | { 25 | if (argc != 2 || strcmp(argv[1], "--help") == 0) 26 | usageErr("%s mq-name\n", argv[0]); 27 | 28 | if (mq_unlink(argv[1]) == -1) 29 | errExit("mq_unlink"); 30 | exit(EXIT_SUCCESS); 31 | } 32 | -------------------------------------------------------------------------------- /tlpi-dist/proc/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = bad_longjmp display_env longjmp \ 4 | necho setjmp_vars setjmp_vars_opt t_getenv 5 | 6 | LINUX_EXE = modify_env 7 | 8 | EXE = ${GEN_EXE} ${LINUX_EXE} 9 | 10 | all : ${EXE} 11 | 12 | allgen : ${GEN_EXE} 13 | 14 | clean : 15 | ${RM} ${EXE} *.o 16 | 17 | showall : 18 | @ echo ${EXE} 19 | 20 | ${EXE} : ${LPLIB} # True as a rough approximation 21 | -------------------------------------------------------------------------------- /tlpi-dist/proc/display_env.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* display_env.c 12 | 13 | Display the process environment list. 14 | */ 15 | #include "tlpi_hdr.h" 16 | 17 | extern char **environ; 18 | /* Or define _GNU_SOURCE to get it from */ 19 | 20 | int 21 | main(int argc, char *argv[]) 22 | { 23 | char **ep; 24 | 25 | for (ep = environ; *ep != NULL; ep++) 26 | puts(*ep); 27 | 28 | exit(EXIT_SUCCESS); 29 | } 30 | -------------------------------------------------------------------------------- /tlpi-dist/proc/necho.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* necho.c 12 | 13 | A simple version of echo(1): echo our command-line arguments. 14 | */ 15 | #include "tlpi_hdr.h" 16 | 17 | int 18 | main(int argc, char *argv[]) 19 | { 20 | int j; 21 | 22 | for (j = 0; j < argc; j++) 23 | printf("argv[%d] = %s\n", j, argv[j]); 24 | 25 | exit(EXIT_SUCCESS); 26 | } 27 | -------------------------------------------------------------------------------- /tlpi-dist/proc/t_getenv.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* t_getenv.c 12 | 13 | Demonstrate the use of getenv() to retrieve the value of an 14 | environment variable. 15 | */ 16 | #include "tlpi_hdr.h" 17 | 18 | int 19 | main(int argc, char *argv[]) 20 | { 21 | char *val; 22 | 23 | if (argc != 2 || strcmp(argv[1], "--help") == 0) 24 | usageErr("%s environ-var\n", argv[0]); 25 | 26 | val = getenv(argv[1]); 27 | printf("%s\n", (val != NULL) ? val : "No such variable"); 28 | 29 | exit(EXIT_SUCCESS); 30 | } 31 | -------------------------------------------------------------------------------- /tlpi-dist/proccred/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = 4 | 5 | LINUX_EXE = idshow 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/procexec/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = acct_on acct_view child_status closeonexec envargs exit_handlers \ 4 | footprint fork_file_sharing fork_sig_sync \ 5 | fork_stdio_buf fork_whos_on_first \ 6 | make_zombie multi_SIGCHLD multi_wait necho orphan \ 7 | t_execl t_execle t_execve t_execlp t_fork t_system \ 8 | t_vfork vfork_fd_test 9 | 10 | LINUX_EXE = demo_clone t_clone acct_v3_view 11 | 12 | EXE = ${GEN_EXE} ${LINUX_EXE} 13 | 14 | all : ${EXE} 15 | 16 | allgen : ${GEN_EXE} 17 | 18 | clean : 19 | ${RM} ${EXE} *.o 20 | 21 | showall : 22 | @ echo ${EXE} 23 | 24 | ${EXE} : ${LPLIB} # True as a rough approximation 25 | -------------------------------------------------------------------------------- /tlpi-dist/procexec/acct_on.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* acct_on.c 12 | 13 | Use acct(2) to enable or disable process accounting. 14 | */ 15 | #define _BSD_SOURCE 16 | #include 17 | #include "tlpi_hdr.h" 18 | 19 | int 20 | main(int argc, char *argv[]) 21 | { 22 | if (argc > 2 || (argc > 1 && strcmp(argv[1], "--help") == 0)) 23 | usageErr("%s [file]\n"); 24 | 25 | if (acct(argv[1]) == -1) 26 | errExit("acct"); 27 | 28 | printf("Process accounting %s\n", 29 | (argv[1] == NULL) ? "disabled" : "enabled"); 30 | exit(EXIT_SUCCESS); 31 | } 32 | -------------------------------------------------------------------------------- /tlpi-dist/procexec/closeonexec.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* closeonexec.c 12 | 13 | Demonstrate retrieving and updating of the file descriptor 14 | close-on-exec flag. 15 | */ 16 | #include 17 | #include "tlpi_hdr.h" 18 | 19 | int 20 | main(int argc, char *argv[]) 21 | { 22 | int flags; 23 | 24 | if (argc > 1) { 25 | flags = fcntl(STDOUT_FILENO, F_GETFD); /* Fetch flags */ 26 | if (flags == -1) 27 | errExit("fcntl - F_GETFD"); 28 | 29 | flags |= FD_CLOEXEC; /* Turn on FD_CLOEXEC */ 30 | 31 | if (fcntl(STDOUT_FILENO, F_SETFD, flags) == -1) /* Update flags */ 32 | errExit("fcntl - F_SETFD"); 33 | } 34 | 35 | execlp("ls", "ls", "-l", argv[0], (char *) NULL); 36 | errExit("execlp"); 37 | } 38 | -------------------------------------------------------------------------------- /tlpi-dist/procexec/envargs.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* envargs.c 12 | 13 | Display argument list and environment. 14 | */ 15 | #include "tlpi_hdr.h" 16 | 17 | extern char **environ; 18 | 19 | int 20 | main(int argc, char *argv[]) 21 | { 22 | int j; 23 | char **ep; 24 | 25 | /* Display argument list */ 26 | 27 | for (j = 0; j < argc; j++) 28 | printf("argv[%d] = %s\n", j, argv[j]); 29 | 30 | /* Display environment list */ 31 | 32 | for (ep = environ; *ep != NULL; ep++) 33 | printf("environ: %s\n", *ep); 34 | 35 | exit(EXIT_SUCCESS); 36 | } 37 | -------------------------------------------------------------------------------- /tlpi-dist/procexec/fork_stdio_buf.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* fork_stdio_buf.c 12 | 13 | Experiment with fork() and stdio buffering. 14 | */ 15 | #include "tlpi_hdr.h" 16 | 17 | int 18 | main(int argc, char *argv[]) 19 | { 20 | printf("Hello world\n"); 21 | write(STDOUT_FILENO, "Ciao\n", 5); 22 | 23 | if (fork() == -1) 24 | errExit("fork"); 25 | 26 | /* Both child and parent continue execution here */ 27 | 28 | exit(EXIT_SUCCESS); 29 | } 30 | -------------------------------------------------------------------------------- /tlpi-dist/procexec/fork_whos_on_first.count.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/awk -f 2 | # 3 | # fork_whos_on_first.count.awk 4 | # 5 | # Copyright, Michael Kerrisk, 2002 6 | # 7 | # Read (on stdin) the results of running the fork_whos_on_first.c 8 | # program to assess the percentage iof cases in which parent or child 9 | # was first to print a post-fork() message 10 | # 11 | BEGIN { 12 | last = -1; 13 | } 14 | 15 | { 16 | # match pairs of lines by field 1 (loop counter) 17 | 18 | if ($1 != last) { 19 | cat[$2]++; 20 | tot++; 21 | } 22 | last = $1; 23 | } 24 | 25 | # Our input file may be long - periodically print a progress 26 | # message with statistics so far 27 | NR % 200000 == 0 { 28 | print "Num children = ", NR / 2; 29 | for (k in cat) 30 | printf "%-6s %6d %6.2f%%\n", k, cat[k], cat[k] / tot * 100; 31 | } 32 | 33 | END { 34 | print "All done"; 35 | for (k in cat) 36 | printf "%-6s %6d %6.2f%%\n", k, cat[k], cat[k] / tot * 100; 37 | } 38 | -------------------------------------------------------------------------------- /tlpi-dist/procexec/longest_line.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/awk -f 2 | length > max { max = length; } 3 | END { print max; } 4 | -------------------------------------------------------------------------------- /tlpi-dist/procexec/necho.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* necho.c 12 | 13 | A simple version of echo(1): echo our command-line arguments. 14 | */ 15 | #include "tlpi_hdr.h" 16 | 17 | int 18 | main(int argc, char *argv[]) 19 | { 20 | int j; 21 | 22 | for (j = 0; j < argc; j++) 23 | printf("argv[%d] = %s\n", j, argv[j]); 24 | 25 | exit(EXIT_SUCCESS); 26 | } 27 | -------------------------------------------------------------------------------- /tlpi-dist/procexec/print_wait_status.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* print_wait_status.h 12 | 13 | Header file for print_wait_status.c. 14 | */ 15 | #ifndef PRINT_WAIT_STATUS_H /* Prevent accidental double inclusion */ 16 | #define PRINT_WAIT_STATUS_H 17 | 18 | void printWaitStatus(const char *msg, int status); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /tlpi-dist/procexec/simple_system.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* simple_system.c 12 | 13 | A simple implementation of system(3) that excludes signal manipulation. 14 | 15 | See also system.c. 16 | */ 17 | #include 18 | #include 19 | #include 20 | 21 | int 22 | system(char *command) 23 | { 24 | int status; 25 | pid_t childPid; 26 | 27 | switch (childPid = fork()) { 28 | case -1: /* Error */ 29 | return -1; 30 | 31 | case 0: /* Child */ 32 | execl("/bin/sh", "sh", "-c", command, (char *) NULL); 33 | _exit(127); /* Failed exec */ 34 | 35 | default: /* Parent */ 36 | if (waitpid(childPid, &status, 0) == -1) 37 | return -1; 38 | else 39 | return status; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tlpi-dist/procexec/t_execl.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* t_execl.c 12 | 13 | Demonstrate the use of execl() to execute printenv(1). 14 | */ 15 | #include 16 | #include "tlpi_hdr.h" 17 | 18 | int 19 | main(int argc, char *argv[]) 20 | { 21 | printf("Initial value of USER: %s\n", getenv("USER")); 22 | if (putenv("USER=britta") != 0) 23 | errExit("putenv"); 24 | 25 | /* exec printenv to display the USER and SHELL environment vars */ 26 | 27 | execl("/usr/bin/printenv", "printenv", "USER", "SHELL", (char *) NULL); 28 | errExit("execl"); /* If we get here, something went wrong */ 29 | } 30 | -------------------------------------------------------------------------------- /tlpi-dist/procexec/t_execle.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* t_execle.c 12 | 13 | Demonstrate the use of execle() to execute a program. 14 | */ 15 | #include "tlpi_hdr.h" 16 | 17 | int 18 | main(int argc, char *argv[]) 19 | { 20 | char *envVec[] = { "GREET=salut", "BYE=adieu", NULL }; 21 | char *filename; 22 | 23 | if (argc != 2 || strcmp(argv[1], "--help") == 0) 24 | usageErr("%s pathname\n", argv[0]); 25 | 26 | /* Execute the program specified in argv[1] */ 27 | 28 | filename = strrchr(argv[1], '/'); /* Get basename from argv[1] */ 29 | if (filename != NULL) 30 | filename++; 31 | else 32 | filename = argv[1]; 33 | 34 | execle(argv[1], filename, "hello world", (char *) NULL, envVec); 35 | errExit("execle"); /* If we get here, something went wrong */ 36 | } 37 | -------------------------------------------------------------------------------- /tlpi-dist/procexec/t_execlp.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* t_execlp.c 12 | 13 | Demonstrate the use of execlp() to execute a program. 14 | */ 15 | #include "tlpi_hdr.h" 16 | 17 | int 18 | main(int argc, char *argv[]) 19 | { 20 | if (argc != 2 || strcmp(argv[1], "--help") == 0) 21 | usageErr("%s pathname\n", argv[0]); 22 | 23 | /* Execute the program specified in argv[1] */ 24 | 25 | execlp(argv[1], argv[1], "hello world", (char *) NULL); 26 | errExit("execlp"); /* If we get here, something went wrong */ 27 | } 28 | -------------------------------------------------------------------------------- /tlpi-dist/procpri/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = demo_sched_fifo sched_set sched_view t_setpriority 4 | 5 | LINUX_EXE = t_sched_setaffinity t_sched_getaffinity 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/procres/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = rusage rusage_wait 4 | 5 | LINUX_EXE = rlimit_nproc 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/procres/print_rlimit.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* print_rlimit.h 12 | 13 | Header file for print_rlimit.c. 14 | */ 15 | #ifndef PRINT_RLIMIT_H /* Prevent accidental double inclusion */ 16 | #define PRINT_RLIMIT_H 17 | 18 | int printRlimit(const char *msg, int resource); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /tlpi-dist/procres/print_rusage.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* print_rusage.h 12 | 13 | Header file for print_rusage.c. 14 | */ 15 | #ifndef PRINT_RUSAGE_H /* Prevent accidental double inclusion */ 16 | #define PRINT_RUSAGE_H 17 | 18 | #include 19 | 20 | void printRusage(const char *leader, const struct rusage *ru); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /tlpi-dist/progconc/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = syscall_speed 4 | 5 | LINUX_EXE = 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | syscall_speed : syscall_speed.o 17 | ${CC} -o $@ syscall_speed.o ${CFLAGS} ${LDLIBS} 18 | 19 | showall : 20 | @ echo ${EXE} 21 | 22 | ${EXE} : ${LPLIB} # True as a rough approximation 23 | -------------------------------------------------------------------------------- /tlpi-dist/psem/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = psem_getvalue psem_create psem_post psem_unlink \ 4 | psem_timedwait psem_trywait psem_wait thread_incr_psem 5 | 6 | LINUX_EXE = 7 | 8 | EXE = ${GEN_EXE} ${LINUX_EXE} 9 | 10 | all : ${EXE} 11 | 12 | allgen : ${GEN_EXE} 13 | 14 | LDLIBS = ${IMPL_LDLIBS} ${LINUX_LIBRT} 15 | # All of the programs in this directory need the 16 | # realtime library, librt. 17 | 18 | thread_incr_psem: thread_incr_psem.o 19 | ${CC} -o $@ thread_incr_psem.o \ 20 | ${CFLAGS} ${IMPL_THREAD_FLAGS} ${LDLIBS} 21 | 22 | clean : 23 | ${RM} ${EXE} *.o 24 | 25 | showall : 26 | @ echo ${EXE} 27 | 28 | ${EXE} : ${LPLIB} # True as a rough approximation 29 | -------------------------------------------------------------------------------- /tlpi-dist/psem/psem_getvalue.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* psem_getvalue.c 12 | 13 | Obtain the value of a POSIX named semaphore. 14 | 15 | On Linux, named semaphores are supported with kernel 2.6 or later, and 16 | a glibc that provides the NPTL threading implementation. 17 | */ 18 | #include 19 | #include "tlpi_hdr.h" 20 | 21 | int 22 | main(int argc, char *argv[]) 23 | { 24 | int value; 25 | sem_t *sem; 26 | 27 | if (argc != 2) 28 | usageErr("%s sem-name\n", argv[0]); 29 | 30 | sem = sem_open(argv[1], 0); 31 | if (sem == SEM_FAILED) 32 | errExit("sem_open"); 33 | 34 | if (sem_getvalue(sem, &value) == -1) 35 | errExit("sem_getvalue"); 36 | 37 | printf("%d\n", value); 38 | exit(EXIT_SUCCESS); 39 | } 40 | -------------------------------------------------------------------------------- /tlpi-dist/psem/psem_post.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* psem_post.c 12 | 13 | Increase the value of a POSIX named semaphore. 14 | 15 | See also psem_wait.c. 16 | 17 | On Linux, named semaphores are supported with kernel 2.6 or later, and 18 | a glibc that provides the NPTL threading implementation. 19 | */ 20 | #include 21 | #include "tlpi_hdr.h" 22 | 23 | int 24 | main(int argc, char *argv[]) 25 | { 26 | sem_t *sem; 27 | 28 | if (argc != 2) 29 | usageErr("%s sem-name\n", argv[0]); 30 | 31 | sem = sem_open(argv[1], 0); 32 | if (sem == SEM_FAILED) 33 | errExit("sem_open"); 34 | 35 | if (sem_post(sem) == -1) 36 | errExit("sem_post"); 37 | exit(EXIT_SUCCESS); 38 | } 39 | -------------------------------------------------------------------------------- /tlpi-dist/psem/psem_trywait.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* psem_trywait.c 12 | 13 | Try to decrease the value of a POSIX named semaphore using the 14 | nonblocking sem_trywait() function. 15 | 16 | On Linux, named semaphores are supported with kernel 2.6 or later, and 17 | a glibc that provides the NPTL threading implementation. 18 | */ 19 | #include 20 | #include "tlpi_hdr.h" 21 | 22 | int 23 | main(int argc, char *argv[]) 24 | { 25 | sem_t *sem; 26 | 27 | if (argc < 2 || strcmp(argv[1], "--help") == 0) 28 | usageErr("%s sem-name\n", argv[0]); 29 | 30 | sem = sem_open(argv[1], 0); 31 | if (sem == SEM_FAILED) 32 | errExit("sem_open"); 33 | 34 | if (sem_trywait(sem) == -1) 35 | errExit("sem_trywait"); 36 | 37 | exit(EXIT_SUCCESS); 38 | } 39 | -------------------------------------------------------------------------------- /tlpi-dist/psem/psem_unlink.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* psem_unlink.c 12 | 13 | Unlink a POSIX named semaphore. 14 | 15 | On Linux, named semaphores are supported with kernel 2.6 or later, and 16 | a glibc that provides the NPTL threading implementation. 17 | */ 18 | #include 19 | #include "tlpi_hdr.h" 20 | 21 | int 22 | main(int argc, char *argv[]) 23 | { 24 | if (argc != 2 || strcmp(argv[1], "--help") == 0) 25 | usageErr("%s sem-name\n", argv[0]); 26 | 27 | if (sem_unlink(argv[1]) == -1) 28 | errExit("sem_unlink"); 29 | exit(EXIT_SUCCESS); 30 | } 31 | -------------------------------------------------------------------------------- /tlpi-dist/psem/psem_wait.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* psem_wait.c 12 | 13 | Decrease the value of a POSIX named semaphore. 14 | 15 | See also psem_post.c. 16 | 17 | On Linux, named semaphores are supported with kernel 2.6 or later, and 18 | a glibc that provides the NPTL threading implementation. 19 | */ 20 | #include 21 | #include "tlpi_hdr.h" 22 | 23 | int 24 | main(int argc, char *argv[]) 25 | { 26 | sem_t *sem; 27 | 28 | if (argc < 2 || strcmp(argv[1], "--help") == 0) 29 | usageErr("%s sem-name\n", argv[0]); 30 | 31 | sem = sem_open(argv[1], 0); 32 | if (sem == SEM_FAILED) 33 | errExit("sem_open"); 34 | 35 | if (sem_wait(sem) == -1) 36 | errExit("sem_wait"); 37 | 38 | printf("%ld sem_wait() succeeded\n", (long) getpid()); 39 | exit(EXIT_SUCCESS); 40 | } 41 | -------------------------------------------------------------------------------- /tlpi-dist/pshm/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = pshm_create pshm_read pshm_write pshm_unlink 4 | 5 | LINUX_EXE = 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | CFLAGS = ${IMPL_CFLAGS} ${LINUX_LIBRT} 14 | # On Linux, all of the programs in this directory need the 15 | # realtime library, librt. 16 | 17 | clean : 18 | ${RM} ${EXE} *.o 19 | 20 | showall : 21 | @ echo ${EXE} 22 | 23 | ${EXE} : ${LPLIB} # True as a rough approximation 24 | -------------------------------------------------------------------------------- /tlpi-dist/pshm/pshm_unlink.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* pshm_unlink.c 12 | 13 | Usage: pshm_unlink shm-name 14 | 15 | Remove the POSIX shared memory object identified by 'name' 16 | */ 17 | #include 18 | #include 19 | #include "tlpi_hdr.h" 20 | 21 | int 22 | main(int argc, char *argv[]) 23 | { 24 | if (argc != 2 || strcmp(argv[1], "--help") == 0) 25 | usageErr("%s shm-name\n", argv[0]); 26 | 27 | if (shm_unlink(argv[1]) == -1) 28 | errExit("shm_unlink"); 29 | exit(EXIT_SUCCESS); 30 | } 31 | -------------------------------------------------------------------------------- /tlpi-dist/pty/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = script unbuffer 4 | 5 | LINUX_EXE = 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/pty/pty_fork.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* pty_fork.h 12 | 13 | Header file for pty_fork.c. 14 | */ 15 | #ifndef FORK_PTY_H 16 | #define FORK_PTY_H 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | pid_t ptyFork(int *masterFd, char *slaveName, size_t snLen, 23 | const struct termios *slaveTermios, const struct winsize *slaveWS); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /tlpi-dist/pty/pty_master_open.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* pty_open.h 12 | 13 | Header file for pty_open.c (and pty_master_open_bsd.c). 14 | */ 15 | #ifndef PTY_MASTER_OPEN_H 16 | #define PTY_MASTER_OPEN_H 17 | 18 | #include 19 | 20 | int ptyMasterOpen(char *slaveName, size_t snLen); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/Demo_no_lib.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Build a program without using libraries 4 | 5 | cc -c -g prog.c mod1.c mod2.c mod3.c 6 | cc -g -o prog_nolib prog.o mod1.o mod2.o mod3.o 7 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/Demo_shared_lib.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Build a program using a shared library 4 | # 5 | # Objects for library must be compiled with PIC (position 6 | # independent code) generation 7 | 8 | gcc -g -c -fPIC -Wall mod1.c mod2.c mod3.c 9 | 10 | # Create library with "real name" (libXYZ.so.maj#.min#.rel#) 11 | # and embed the "soname" (libXYZ.so.maj#) 12 | 13 | gcc -g -shared -Wl,-soname,libdemo.so.1 -o libdemo.so.1.0.1 \ 14 | mod1.o mod2.o mod3.o 15 | 16 | # Create "soname" (libXYZ.so.maj# - a symbolic link to real name) 17 | 18 | ln -sf libdemo.so.1.0.1 libdemo.so.1 19 | 20 | # Create "linker name" (libXYZ.so - a symbolic link to "soname") 21 | 22 | ln -sf libdemo.so.1 libdemo.so 23 | 24 | # Build program by linking against "linker name" 25 | 26 | cc -g -Wall -c prog.c 27 | cc -g -o prog_so prog.o -L. -ldemo 28 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/Demo_static_lib.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Build a program using a static library 3 | # 4 | 5 | cc -g -c mod1.c mod2.c mod3.c 6 | ar r libdemo.a mod1.o mod2.o mod3.o 7 | 8 | cc -g -o prog_static prog.c libdemo.a 9 | # Or: cc -g -o prog_static prog.c -L. -ldemo 10 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = dynload 4 | 5 | LINUX_EXE = 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | dynload : dynload.o 14 | ${CC} -o $@ dynload.o ${CFLAGS} ${LDLIBS} ${LINUX_LIBDL} 15 | 16 | clean : 17 | ${RM} ${EXE} *.o *.so.* 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/demo_Bsymbolic/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -v 4 | 5 | gcc -g -shared -fPIC -o libfoo1.so foo1.c 6 | gcc -g -Wl,-Bsymbolic -shared -fPIC -o libfoo2.so foo2.c 7 | gcc -g -Wl,-Bsymbolic -Wl,-allow-shlib-undefined \ 8 | -shared -fPIC -o libfoo3.so foo3.c 9 | 10 | gcc -g -o prog prog.c -L. -lfoo1 -lfoo2 -lfoo3 11 | 12 | LD_LIBRARY_PATH=. ./prog 13 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/demo_Bsymbolic/foo1.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* foo1.c 12 | 13 | */ 14 | #include 15 | #include 16 | 17 | void 18 | xyz(void) 19 | { 20 | printf(" func1-xyz\n"); 21 | } 22 | 23 | void 24 | abc(void) 25 | { 26 | printf(" func1-abc\n"); 27 | } 28 | 29 | void 30 | func1(int x) 31 | { 32 | printf("Called func1\n"); 33 | xyz(); 34 | abc(); 35 | } 36 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/demo_Bsymbolic/foo2.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* foo2.c 12 | 13 | */ 14 | #include 15 | #include 16 | 17 | void 18 | xyz(void) 19 | { 20 | printf(" func2-xyz\n"); 21 | } 22 | 23 | void 24 | abc(void) 25 | { 26 | printf(" func1-abc\n"); 27 | } 28 | 29 | void 30 | func2(int x) 31 | { 32 | printf("Called func2\n"); 33 | xyz(); 34 | abc(); 35 | } 36 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/demo_Bsymbolic/foo3.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* foo3.c 12 | 13 | */ 14 | #include 15 | #include 16 | 17 | void 18 | xyz(void) 19 | { 20 | printf(" func3-xyz\n"); 21 | } 22 | 23 | void 24 | func3(int x) 25 | { 26 | printf("Called func3\n"); 27 | xyz(); 28 | abc(); 29 | } 30 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/demo_Bsymbolic/prog.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* prog.c 12 | 13 | */ 14 | #include 15 | #include 16 | 17 | void 18 | xyz(void) 19 | { 20 | printf(" main-xyz\n"); 21 | } /* void */ 22 | 23 | int 24 | main(int argc, char*argv[]) 25 | { 26 | void func1(void), func2(void), func3(void); 27 | 28 | func1(); 29 | func2(); 30 | 31 | exit(EXIT_SUCCESS); 32 | } 33 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/mod1.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* mod1.c */ 12 | 13 | #include 14 | #include 15 | int test1[250000] = { 1, 2, 3 }; 16 | 17 | #ifndef VERSION 18 | #define VERSION "" 19 | #endif 20 | 21 | void 22 | x1(void) { 23 | printf("Called mod1-x1 " VERSION "\n"); 24 | } 25 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/mod2.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* mod2.c */ 12 | 13 | #include 14 | #include 15 | int test2[100000] = { 1, 2, 3 }; 16 | 17 | #ifndef VERSION 18 | #define VERSION "" 19 | #endif 20 | 21 | void 22 | x2(void) { 23 | printf("Called mod2-x2 " VERSION "\n"); 24 | } 25 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/mod3.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* mod3.c */ 12 | 13 | #include 14 | #include 15 | int test3[10000] = { 1, 2, 3 }; 16 | 17 | #ifndef VERSION 18 | #define VERSION "" 19 | #endif 20 | 21 | void 22 | x3(void) { 23 | printf("Called mod3-x3 " VERSION "\n"); 24 | } 25 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/prog.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* prog.c */ 12 | 13 | #include 14 | #include 15 | 16 | void x1(void); 17 | void x2(void); 18 | 19 | int 20 | main(int argc, char *argv[]) 21 | { 22 | x1(); 23 | x2(); 24 | exit(EXIT_SUCCESS); 25 | } 26 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/rpath_demo/build-rpath-link.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # build-rpath-link.sh 4 | # 5 | # Build script for -rpath-link linker option example 6 | # 7 | set -v 8 | 9 | ROOT=$PWD 10 | 11 | cd $ROOT/d2 12 | gcc -g -c -fPIC -Wall modx2.c 13 | gcc -g -shared -o libx2.so modx2.o 14 | 15 | cd $ROOT/d1 16 | gcc -g -c -fPIC -Wall modx1.c 17 | gcc -g -shared -o libx1.so modx1.o \ 18 | -L$ROOT/d2 -lx2 19 | 20 | cd $ROOT 21 | gcc -g -Wall -o prog prog.c \ 22 | -Wl,-rpath,$ROOT/d1 -L$ROOT/d1 -lx1 \ 23 | -Wl,-rpath-link,$ROOT/d2 24 | 25 | objdump --all-headers prog | grep RPATH 26 | objdump --all-headers d1/libx1.so | grep RPATH 27 | ldd prog 28 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/rpath_demo/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # build.sh 4 | # 5 | # Build script for -rpath linker option example 6 | # 7 | set -v 8 | 9 | ROOT="$PWD" 10 | 11 | # Enabling the following means the executable rpath with be 12 | # built as a DT_RUNPATH entry rather than a DT_RPATH entry 13 | 14 | #DTAGS="-Wl,--enable-new-dtags" 15 | 16 | cd $ROOT/d2 17 | gcc -g -c -fPIC -Wall modx2.c 18 | gcc -g -shared -o libx2.so modx2.o 19 | 20 | cd $ROOT/d1 21 | gcc -g -c -fPIC -Wall modx1.c 22 | gcc -g -shared -o libx1.so modx1.o $DTAGS \ 23 | -Wl,-rpath,$ROOT/d2 -L$ROOT/d2 -lx2 24 | 25 | cd $ROOT 26 | gcc -g -Wall -o prog prog.c $DTAGS \ 27 | -Wl,-rpath,$ROOT/d1 -L$ROOT/d1 -lx1 28 | 29 | objdump -p prog | grep PATH 30 | objdump -p d1/libx1.so | grep PATH 31 | ldd prog 32 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/rpath_demo/d1/modx1.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* modx1.c */ 12 | 13 | void 14 | x1(void) { 15 | void x2(void); 16 | 17 | x2(); 18 | } 19 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/rpath_demo/d2/modx2.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* modx2.c */ 12 | 13 | #include 14 | 15 | void 16 | x2(void) { 17 | printf("Called modx2\n"); 18 | } 19 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/rpath_demo/prog.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* prog.c 12 | 13 | */ 14 | #include 15 | 16 | int 17 | main(int argc, char *argv[]) 18 | { 19 | void x1(void); 20 | 21 | x1 (); 22 | 23 | exit(EXIT_SUCCESS); 24 | } 25 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/version_scripts/sv_build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # sv_build.sh 4 | # 5 | set -v 6 | 7 | # Build version 1 of shared library 8 | 9 | gcc -g -c -fPIC -Wall sv_lib_v1.c 10 | gcc -g -shared -o libsv.so sv_lib_v1.o -Wl,--version-script,sv_v1.map 11 | 12 | gcc -g -o p1 sv_prog.c libsv.so 13 | 14 | LD_LIBRARY_PATH=. ./p1 15 | 16 | # Build version 2 of shared library 17 | 18 | gcc -g -c -fPIC -Wall sv_lib_v2.c 19 | gcc -g -shared -o libsv.so sv_lib_v2.o -Wl,--version-script,sv_v2.map 20 | 21 | gcc -g -o p2 sv_prog.c libsv.so 22 | 23 | LD_LIBRARY_PATH=. ./p2 24 | LD_LIBRARY_PATH=. ./p1 25 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/version_scripts/sv_lib_v1.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* sv_lib_v1.c 12 | 13 | */ 14 | #include 15 | 16 | void xyz(void) { printf("v1 xyz()\n"); } 17 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/version_scripts/sv_lib_v2.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* sv_lib_v2.c 12 | 13 | */ 14 | 15 | #include 16 | 17 | __asm__(".symver xyz_old,xyz@VER_1"); 18 | __asm__(".symver xyz_new,xyz@@VER_2"); 19 | 20 | void xyz_old(void) { printf("v1 xyz\n"); } 21 | 22 | void xyz_new(void) { printf("v2 xyz\n"); } 23 | 24 | void pqr(void) { printf("v2 pqr\n"); } 25 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/version_scripts/sv_libabc.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* sv_libabc.c 12 | 13 | */ 14 | #include 15 | 16 | void 17 | abc(void) 18 | { 19 | void xyz(void); 20 | 21 | printf("abc() calling xyz()\n"); 22 | xyz(); 23 | } 24 | 25 | __asm__(".symver xyz,xyz@VER_1"); 26 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/version_scripts/sv_prog.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* sv_prog.c 12 | 13 | */ 14 | #include 15 | 16 | int 17 | main(int argc, char *argv[]) 18 | { 19 | void xyz(void); 20 | 21 | xyz(); 22 | 23 | exit(EXIT_SUCCESS); 24 | } 25 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/version_scripts/sv_prog_abc.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* sv_prog_abc.c 12 | 13 | */ 14 | #include 15 | #include 16 | 17 | int 18 | main(int argc, char *argv[]) 19 | { 20 | void xyz(void), abc(void); 21 | 22 | printf("main() calling xyz()\n"); 23 | xyz(); 24 | 25 | abc(); 26 | 27 | exit(EXIT_SUCCESS); 28 | } 29 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/version_scripts/sv_prog_complex.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* sv_prog_complex.c 12 | 13 | */ 14 | #include 15 | #include 16 | #include 17 | 18 | //void xxx(void) { printf("Hi there\n"); } 19 | 20 | int main(int argc, char *argv[]) { 21 | void xyz(void); 22 | void xyz_old(void), xyz_new(void); 23 | void abc(void); 24 | 25 | printf("Calling abc()\n"); 26 | abc(); 27 | 28 | printf("Calling xyz()\n"); 29 | xyz(); 30 | 31 | printf("Calling xyz_new()\n"); 32 | xyz_new(); 33 | 34 | printf("Calling xyz_old()\n"); 35 | xyz_old(); 36 | 37 | //xxx(); 38 | 39 | exit(0); 40 | } 41 | //__asm__(".symver xyz_old,xyz@VER_1"); 42 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/version_scripts/sv_v1.map: -------------------------------------------------------------------------------- 1 | VER_1 { 2 | global: xyz; 3 | local: *; # Hide all other symbols 4 | }; 5 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/version_scripts/sv_v2.map: -------------------------------------------------------------------------------- 1 | VER_1 { 2 | global: xyz; 3 | local: *; # Hide all other symbols 4 | }; 5 | 6 | VER_2 { 7 | global: pqr; 8 | } VER_1; 9 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/version_scripts/vis.map: -------------------------------------------------------------------------------- 1 | VER_1 { 2 | global: 3 | vis_f1; 4 | vis_f2; 5 | local: 6 | *; 7 | }; 8 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/version_scripts/vis_build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # vis_build.sh 4 | # 5 | # Show how versions scripts can be used to control symbol visibility. 6 | # 7 | set -v 8 | 9 | # In the following, vis_comm() is accidentally exported by the 10 | # shared library 11 | 12 | gcc -g -c -fPIC -Wall vis_comm.c vis_f1.c vis_f2.c 13 | gcc -g -shared -o vis.so vis_comm.o vis_f1.o vis_f2.o 14 | readelf --syms --use-dynamic vis.so | grep vis_ 15 | 16 | # Now we use a version script to control exactly which symbols 17 | # are exported by the library 18 | 19 | gcc -g -c -fPIC -Wall vis_comm.c vis_f1.c vis_f2.c 20 | gcc -g -shared -o vis.so vis_comm.o vis_f1.o vis_f2.o \ 21 | -Wl,--version-script,vis.map 22 | readelf --syms --use-dynamic vis.so | grep vis_ 23 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/version_scripts/vis_comm.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* vis_comm.c 12 | 13 | */ 14 | int /* Function used by vis_f1() and vis_f2() */ 15 | vis_comm(int j) 16 | { 17 | return j * j; 18 | } 19 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/version_scripts/vis_f1.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* vis_f1.c 12 | 13 | */ 14 | int 15 | vis_f1(int k) 16 | { 17 | int vis_comm(int j); 18 | 19 | return vis_comm(k) / 2; 20 | } 21 | -------------------------------------------------------------------------------- /tlpi-dist/shlibs/version_scripts/vis_f2.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* vis_f2.c 12 | 13 | */ 14 | int 15 | vis_f2(int k) 16 | { 17 | int vis_comm(int j); 18 | 19 | return vis_comm(k) * vis_comm(k); 20 | } 21 | -------------------------------------------------------------------------------- /tlpi-dist/signals/ouch.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* ouch.c 12 | 13 | Catch the SIGINT signal, generated by typing control-C (^C). 14 | 15 | Note that although we use signal() to establish the signal handler in this 16 | program, the use of sigaction() is always preferable for this task. 17 | */ 18 | #include 19 | #include "tlpi_hdr.h" 20 | 21 | static void 22 | sigHandler(int sig) 23 | { 24 | printf("Ouch!\n"); /* UNSAFE (see Section 21.1.2) */ 25 | } 26 | 27 | int 28 | main(int argc, char *argv[]) 29 | { 30 | int j; 31 | 32 | /* Establish handler for SIGINT */ 33 | 34 | if (signal(SIGINT, sigHandler) == SIG_ERR) 35 | errExit("signal"); 36 | 37 | /* Loop continuously waiting for signals to be delivered */ 38 | 39 | for (j = 0; ; j++) { 40 | printf("%d\n", j); 41 | sleep(3); /* Loop slowly... */ 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tlpi-dist/signals/siginterrupt.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* siginterrupt.c 12 | 13 | An implementation of the siginterrupt(3) library function. 14 | */ 15 | #include 16 | #include 17 | 18 | int 19 | siginterrupt(int sig, int flag) 20 | { 21 | int status; 22 | struct sigaction act; 23 | 24 | status = sigaction(sig, NULL, &act); 25 | if (status == -1) 26 | return -1; 27 | 28 | if (flag) 29 | act.sa_flags &= ~SA_RESTART; 30 | else 31 | act.sa_flags |= SA_RESTART; 32 | 33 | return sigaction(sig, &act, NULL); 34 | } 35 | -------------------------------------------------------------------------------- /tlpi-dist/signals/signal_functions.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* signal_functions.h 12 | 13 | Header file for signal_functions.c. 14 | */ 15 | #ifndef SIGNAL_FUNCTIONS_H 16 | #define SIGNAL_FUNCTIONS_H 17 | 18 | #include 19 | #include "tlpi_hdr.h" 20 | 21 | int printSigMask(FILE *of, const char *msg); 22 | 23 | int printPendingSigs(FILE *of, const char *msg); 24 | 25 | void printSigset(FILE *of, const char *ldr, const sigset_t *mask); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /tlpi-dist/sockets/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = i6d_ucase_sv i6d_ucase_cl \ 4 | id_echo_cl id_echo_sv \ 5 | is_echo_cl is_echo_sv is_echo_inetd_sv is_echo_v2_sv \ 6 | is_seqnum_sv is_seqnum_cl is_seqnum_v2_sv is_seqnum_v2_cl \ 7 | socknames t_gethostbyname t_getservbyname \ 8 | ud_ucase_sv ud_ucase_cl \ 9 | us_xfr_cl us_xfr_sv us_xfr_v2_cl us_xfr_v2_sv 10 | 11 | LINUX_EXE = scm_cred_recv scm_cred_send scm_rights_recv scm_rights_send \ 12 | us_abstract_bind 13 | 14 | EXE = ${GEN_EXE} ${LINUX_EXE} 15 | 16 | all : ${EXE} 17 | 18 | allgen : ${GEN_EXE} 19 | 20 | i6d_ucase_sv.o i6d_ucase_cl.o : i6d_ucase.h 21 | 22 | id_echo_cl.o id_echo_sv.o : id_echo.h 23 | 24 | is_seqnum_sv.o is_seqnum_cl.o : is_seqnum.h 25 | 26 | is_seqnum_v2_sv.o is_seqnum_v2_cl.o : is_seqnum_v2.h 27 | 28 | scm_cred_recv.o scm_cred_send.o : scm_cred.h 29 | 30 | scm_rights_recv.o scm_rights_send.o : scm_rights.h 31 | 32 | us_xfr_sv.o us_xfr_cl.o : us_xfr.h 33 | 34 | us_xfr_v2_sv.o us_xfr_v2_cl.o : us_xfr_v2.h 35 | 36 | ud_ucase_sv.o ud_ucase_cl.o : ud_ucase.h 37 | 38 | clean : 39 | ${RM} ${EXE} *.o 40 | 41 | showall : 42 | @ echo ${EXE} 43 | 44 | ${EXE} : ${LPLIB} # True as a rough approximation 45 | -------------------------------------------------------------------------------- /tlpi-dist/sockets/README: -------------------------------------------------------------------------------- 1 | Many of the programs in this directory are named according to the 2 | conventions described below. 3 | 4 | A prefix identifies the socket domain in which the program operates, 5 | and the socket type employed. The socket domain is indicated by one 6 | or two letters: 7 | 8 | u UNIX 9 | i Internet (both v4 and v6) 10 | i6 Internet v6 only 11 | 12 | The socket type is one of the following: 13 | 14 | d datagram 15 | s socket 16 | 17 | A suffix indicates whether the program is a client or server: 18 | 19 | cl client 20 | sv server 21 | 22 | Thus, id_echo_sv.c is a server program that uses datagram sockets in 23 | the Internet domain. 24 | -------------------------------------------------------------------------------- /tlpi-dist/sockets/i6d_ucase.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* i6d_ucase.h 12 | 13 | Header file for i6d_ucase_sv.c and i6d_ucase_cl.c. 14 | */ 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "tlpi_hdr.h" 20 | 21 | #define BUF_SIZE 10 /* Maximum size of messages exchanged 22 | between client and server */ 23 | 24 | #define PORT_NUM 50002 /* Server port number */ 25 | -------------------------------------------------------------------------------- /tlpi-dist/sockets/id_echo.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* id_echo.h 12 | 13 | Header file for id_echo_sv.c and id_echo_cl.c. 14 | */ 15 | #include "inet_sockets.h" /* Declares our socket functions */ 16 | #include "tlpi_hdr.h" 17 | 18 | #define SERVICE "echo" /* Name of UDP service */ 19 | 20 | #define BUF_SIZE 500 /* Maximum size of datagrams that can 21 | be read by client and server */ 22 | -------------------------------------------------------------------------------- /tlpi-dist/sockets/inet_sockets.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* inet_sockets.h 12 | 13 | Header file for inet_sockets.c. 14 | */ 15 | #ifndef INET_SOCKETS_H 16 | #define INET_SOCKETS_H /* Prevent accidental double inclusion */ 17 | 18 | #include 19 | #include 20 | 21 | int inetConnect(const char *host, const char *service, int type); 22 | 23 | int inetListen(const char *service, int backlog, socklen_t *addrlen); 24 | 25 | int inetBind(const char *service, int type, socklen_t *addrlen); 26 | 27 | char *inetAddressStr(const struct sockaddr *addr, socklen_t addrlen, 28 | char *addrStr, int addrStrLen); 29 | 30 | #define IS_ADDR_STR_LEN 4096 31 | /* Suggested length for string buffer that caller 32 | should pass to inetAddressStr(). Must be greater 33 | than (NI_MAXHOST + NI_MAXSERV + 4) */ 34 | #endif 35 | -------------------------------------------------------------------------------- /tlpi-dist/sockets/is_echo_inetd_sv.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* is_echo_inetd_sv.c 12 | 13 | An inetd-invoked implementation of the TCP "echo" service. 14 | 15 | Compare this program with is_echo_sv.c. 16 | */ 17 | #include 18 | #include "tlpi_hdr.h" 19 | 20 | #define BUF_SIZE 4096 21 | 22 | int 23 | main(int argc, char *argv[]) 24 | { 25 | char buf[BUF_SIZE]; 26 | ssize_t numRead; 27 | 28 | while ((numRead = read(STDIN_FILENO, buf, BUF_SIZE)) > 0) { 29 | if (write(STDOUT_FILENO, buf, numRead) != numRead) { 30 | syslog(LOG_ERR, "write() failed: %s", strerror(errno)); 31 | exit(EXIT_FAILURE); 32 | } 33 | } 34 | 35 | if (numRead == -1) { 36 | syslog(LOG_ERR, "Error from read(): %s", strerror(errno)); 37 | exit(EXIT_FAILURE); 38 | } 39 | 40 | exit(EXIT_SUCCESS); 41 | } 42 | -------------------------------------------------------------------------------- /tlpi-dist/sockets/is_seqnum.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* is_seqnum.h 12 | 13 | Header file for is_seqnum_sv.c and is_seqnum_cl.c. 14 | */ 15 | #include 16 | #include 17 | #include 18 | #include "read_line.h" /* Declaration of readLine() */ 19 | #include "tlpi_hdr.h" 20 | 21 | #define PORT_NUM "50000" /* Port number for server */ 22 | 23 | #define INT_LEN 30 /* Size of string able to hold largest 24 | integer (including terminating '\n') */ 25 | -------------------------------------------------------------------------------- /tlpi-dist/sockets/is_seqnum_v2.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* is_seqnum_v2.h 12 | 13 | Header file for is_seqnum_v2_sv.c and is_seqnum_v2_cl.c. 14 | */ 15 | #include 16 | #include 17 | #include 18 | #include "inet_sockets.h" /* Declares our socket functions */ 19 | #include "read_line.h" /* Declaration of readLine() */ 20 | #include "tlpi_hdr.h" 21 | 22 | #define PORT_NUM_STR "50000" /* Port number for server */ 23 | 24 | #define INT_LEN 30 /* Size of string able to hold largest 25 | integer (including terminating '\n') */ 26 | -------------------------------------------------------------------------------- /tlpi-dist/sockets/rdwrn.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* rdwrn.h 12 | 13 | Header file for rdwrn.c. 14 | */ 15 | #ifndef RDWRN_H 16 | #define RDWRN_H 17 | 18 | #include 19 | 20 | ssize_t readn(int fd, void *buf, size_t len); 21 | 22 | ssize_t writen(int fd, const void *buf, size_t len); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /tlpi-dist/sockets/read_line.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* read_line.h 12 | 13 | Header file for read_line.c. 14 | */ 15 | #ifndef READ_LINE_H 16 | #define READ_LINE_H 17 | 18 | #include 19 | 20 | ssize_t readLine(int fd, void *buffer, size_t n); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /tlpi-dist/sockets/read_line_buf.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* read_line_buf.h 12 | 13 | Header file for read_line_buf.c (implementation of readLineBuf()). 14 | */ 15 | #ifndef READ_LINE_BUF_H /* Prevent accidental double inclusion */ 16 | #define READ_LINE_BUF_H 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #define RL_MAX_BUF 10 23 | 24 | struct ReadLineBuf { 25 | int fd; /* File descriptor from which to read */ 26 | char buf[RL_MAX_BUF]; /* Current buffer from file */ 27 | int next; /* Index of next unread character in 'buf' */ 28 | ssize_t len; /* Number of characters in 'buf' */ 29 | }; 30 | 31 | void readLineBufInit(int fd, struct ReadLineBuf *rlbuf); 32 | 33 | ssize_t readLineBuf(struct ReadLineBuf *rlbuf, char *buffer, size_t n); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /tlpi-dist/sockets/scm_cred.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* scm_cred.h 12 | 13 | Header file used by scm_cred_send.c and scm_cred_recv.c. 14 | */ 15 | #define _GNU_SOURCE /* To get SCM_CREDENTIALS definition from 16 | */ 17 | #include 18 | #include 19 | #include "unix_sockets.h" /* Declares our socket functions */ 20 | #include "tlpi_hdr.h" 21 | 22 | #define SOCK_PATH "scm_cred" 23 | -------------------------------------------------------------------------------- /tlpi-dist/sockets/scm_rights.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* scm_rights.h 12 | 13 | Header file used by scm_rights_send.c and scm_rights_recv.c. 14 | */ 15 | #include 16 | #include 17 | #include 18 | #include "unix_sockets.h" /* Declares our unix*() socket functions */ 19 | #include "tlpi_hdr.h" 20 | 21 | #define SOCK_PATH "scm_rights" 22 | -------------------------------------------------------------------------------- /tlpi-dist/sockets/ud_ucase.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* ud_ucase.h 12 | 13 | Header file for ud_ucase_sv.c and ud_ucase_cl.c. 14 | 15 | These programs employ sockets in /tmp. This makes it easy to compile 16 | and run the programs. However, for a security reasons, a real-world 17 | application should never create sensitive files in /tmp. (As a simple of 18 | example of the kind of security problems that can result, a malicious 19 | user could create a file using the name defined in SV_SOCK_PATH, and 20 | thereby cause a denial of service attack against this application. 21 | See Section 38.7 of "The Linux Programming Interface" for more details 22 | on this subject.) 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include "tlpi_hdr.h" 28 | 29 | #define BUF_SIZE 10 /* Maximum size of messages exchanged 30 | between client to server */ 31 | 32 | #define SV_SOCK_PATH "/tmp/ud_ucase" 33 | -------------------------------------------------------------------------------- /tlpi-dist/sockets/unix_sockets.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* unix_sockets.h 12 | 13 | Header file for unix_sockets.c. 14 | */ 15 | #ifndef UNIX_SOCKETS_H 16 | #define UNIX_SOCKETS_H /* Prevent accidental double inclusion */ 17 | 18 | #include 19 | #include 20 | 21 | int unixBuildAddress(const char *path, struct sockaddr_un *addr); 22 | 23 | int unixConnect(const char *path, int type); 24 | 25 | int unixListen(const char *path, int backlog); 26 | 27 | int unixBind(const char *path, int type); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /tlpi-dist/sockets/us_xfr.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* us_xfr.h 12 | 13 | Header file for us_xfr_sv.c and us_xfr_cl.c. 14 | 15 | These programs employ a socket in /tmp. This makes it easy to compile 16 | and run the programs. However, for a security reasons, a real-world 17 | application should never create sensitive files in /tmp. (As a simple of 18 | example of the kind of security problems that can result, a malicious 19 | user could create a file using the name defined in SV_SOCK_PATH, and 20 | thereby cause a denial of service attack against this application. 21 | See Section 38.7 of "The Linux Programming Interface" for more details 22 | on this subject.) 23 | */ 24 | #include 25 | #include 26 | #include "tlpi_hdr.h" 27 | 28 | #define SV_SOCK_PATH "/tmp/us_xfr" 29 | 30 | #define BUF_SIZE 100 31 | -------------------------------------------------------------------------------- /tlpi-dist/sockets/us_xfr_v2.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* us_xfr_v2.h 12 | 13 | Header file for us_xfr_sv.c and us_xfr_cl.c. 14 | */ 15 | #include "unix_sockets.h" /* Declares our socket functions */ 16 | #include "tlpi_hdr.h" 17 | 18 | #define SV_SOCK_PATH "us_xfr_v2" 19 | 20 | #define BUF_SIZE 100 21 | -------------------------------------------------------------------------------- /tlpi-dist/svipc/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = svmsg_demo_server t_ftok 4 | 5 | LINUX_EXE = 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/svmsg/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = svmsg_chqbytes svmsg_file_client svmsg_file_server \ 4 | svmsg_create svmsg_receive svmsg_rm msg_send 5 | 6 | LINUX_EXE = svmsg_info svmsg_ls 7 | 8 | EXE = ${GEN_EXE} ${LINUX_EXE} 9 | 10 | all : ${EXE} 11 | 12 | allgen : ${GEN_EXE} 13 | 14 | clean : 15 | ${RM} ${EXE} *.o 16 | 17 | svmsg_file_client.o svmsg_file_server.o : svmsg_file.h 18 | 19 | showall : 20 | @ echo ${EXE} 21 | 22 | ${EXE} : ${LPLIB} # True as a rough approximation 23 | -------------------------------------------------------------------------------- /tlpi-dist/svmsg/svmsg_chqbytes.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* svmsg_chqbytes.c 12 | 13 | Usage: svmsg_chqbytes msqid max-bytes 14 | 15 | Change the 'msg_qbytes' setting of the System V message queue identified 16 | by 'msqid'. 17 | */ 18 | #include 19 | #include 20 | #include "tlpi_hdr.h" 21 | 22 | int 23 | main(int argc, char *argv[]) 24 | { 25 | struct msqid_ds ds; 26 | int msqid; 27 | 28 | if (argc != 3 || strcmp(argv[1], "--help") == 0) 29 | usageErr("%s msqid max-bytes\n", argv[0]); 30 | 31 | /* Retrieve copy of associated data structure from kernel */ 32 | 33 | msqid = getInt(argv[1], 0, "msqid"); 34 | if (msgctl(msqid, IPC_STAT, &ds) == -1) 35 | errExit("msgctl"); 36 | 37 | ds.msg_qbytes = getInt(argv[2], 0, "max-bytes"); 38 | 39 | /* Update associated data structure in kernel */ 40 | 41 | if (msgctl(msqid, IPC_SET, &ds) == -1) 42 | errExit("msgctl"); 43 | 44 | exit(EXIT_SUCCESS); 45 | } 46 | -------------------------------------------------------------------------------- /tlpi-dist/svmsg/svmsg_info.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* svmsg_info.c 12 | 13 | Demonstrate the use of the MSG_INFO operation to retrieve a 'msginfo' 14 | structure containing the current usage of System V message queue resources. 15 | 16 | This program is Linux-specific. 17 | */ 18 | #define _GNU_SOURCE 19 | #include 20 | #include 21 | #include "tlpi_hdr.h" 22 | 23 | int 24 | main(int argc, char *argv[]) 25 | { 26 | struct msginfo info; 27 | int s; 28 | 29 | s = msgctl(0, MSG_INFO, (struct msqid_ds *) &info); 30 | if (s == -1) 31 | errExit("msgctl"); 32 | 33 | printf("Maximum ID index = %d\n", s); 34 | printf("queues in_use = %ld\n", (long) info.msgpool); 35 | printf("msg_hdrs = %ld\n", (long) info.msgmap); 36 | printf("msg_bytes = %ld\n", (long) info.msgmax); 37 | exit(EXIT_SUCCESS); 38 | } 39 | -------------------------------------------------------------------------------- /tlpi-dist/svmsg/svmsg_rm.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* svmsg_rm.c 12 | 13 | Remove the System V message queues identified by the command-line arguments. 14 | */ 15 | #include 16 | #include 17 | #include "tlpi_hdr.h" 18 | 19 | int 20 | main(int argc, char *argv[]) 21 | { 22 | int j; 23 | 24 | if (argc > 1 && strcmp(argv[1], "--help") == 0) 25 | usageErr("%s [msqid...]\n", argv[0]); 26 | 27 | for (j = 1; j < argc; j++) 28 | if (msgctl(getInt(argv[j], 0, "msqid"), IPC_RMID, NULL) == -1) 29 | errExit("msgctl %s", argv[j]); 30 | 31 | exit(EXIT_SUCCESS); 32 | } 33 | -------------------------------------------------------------------------------- /tlpi-dist/svsem/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = svsem_create dem_demo svsem_mon svsem_op svsem_rm svsem_setall 4 | 5 | LINUX_EXE = svsem_info 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/svsem/binary_sems.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* binary_sems.h 12 | 13 | Header file for binary_sems.c. 14 | */ 15 | #ifndef BINARY_SEMS_H /* Prevent accidental double inclusion */ 16 | #define BINARY_SEMS_H 17 | 18 | #include "tlpi_hdr.h" 19 | 20 | /* Variables controlling operation of functions below */ 21 | 22 | extern Boolean bsUseSemUndo; /* Use SEM_UNDO during semop()? */ 23 | extern Boolean bsRetryOnEintr; /* Retry if semop() interrupted by 24 | signal handler? */ 25 | 26 | int initSemAvailable(int semId, int semNum); 27 | 28 | int initSemInUse(int semId, int semNum); 29 | 30 | int reserveSem(int semId, int semNum); 31 | 32 | int releaseSem(int semId, int semNum); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /tlpi-dist/svsem/event_flags.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* event_flags.h 12 | 13 | Header file for event_flags.c. 14 | 15 | The event flags operations are: 16 | 17 | set a flag: setEventFlag(semId, semNum) 18 | clear a flag: clearEventFlag(semId, semNum) 19 | wait for flag to be set: waitForEventFlag(semId, semNum) 20 | read a flag's value: getFlagState(semId, semNum, &isSet) 21 | 22 | NB: The semantics of System V semaphores require that the "set" 23 | value for a flag is 0 and the "clear" value is 1. 24 | */ 25 | #ifndef EVENT_FLAGS_H 26 | #define EVENT_FLAGS_H /* Prevent accidental double inclusion */ 27 | 28 | #include "tlpi_hdr.h" 29 | 30 | int waitForEventFlag(int semId, int semNum); 31 | 32 | int clearEventFlag(int semId, int semNum); 33 | 34 | int setEventFlag(int semId, int semNum); 35 | 36 | int getFlagState(int semId, int semNum, Boolean *isSet); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /tlpi-dist/svsem/semun.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* semun.h 12 | 13 | Definition of the semun union used by the System V semaphore semop() 14 | system call. 15 | */ 16 | #ifndef SEMUN_H 17 | #define SEMUN_H /* Prevent accidental double inclusion */ 18 | 19 | #include /* For portability */ 20 | #include 21 | 22 | #if ! defined(__FreeBSD__) && ! defined(__OpenBSD__) && \ 23 | ! defined(__sgi) && ! defined(__APPLE__) 24 | /* Some implementations already declare this union */ 25 | 26 | union semun { /* Used in calls to semctl() */ 27 | int val; 28 | struct semid_ds * buf; 29 | unsigned short * array; 30 | #if defined(__linux__) 31 | struct seminfo * __buf; 32 | #endif 33 | }; 34 | 35 | #endif 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /tlpi-dist/svsem/svsem_info.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* svsem_info.c 12 | 13 | Demonstrate the use of the SEM_INFO operation to retrieve a 'seminfo' 14 | structure containing the current usage of System V semaphore resources. 15 | 16 | This program is Linux-specific. 17 | */ 18 | #define _GNU_SOURCE 19 | #include 20 | #include 21 | #include "semun.h" /* Definition of semun union */ 22 | #include "tlpi_hdr.h" 23 | 24 | int 25 | main(int argc, char *argv[]) 26 | { 27 | struct seminfo info; 28 | union semun arg; 29 | int s; 30 | 31 | arg.__buf = &info; 32 | 33 | s = semctl(0, 0, SEM_INFO, arg); 34 | if (s == -1) 35 | errExit("semctl"); 36 | 37 | printf("Maximum ID index = %d\n", s); 38 | printf("sets in_use = %ld\n", (long) info.semusz); 39 | printf("used_sems = %ld\n", (long) info.semaem); 40 | exit(EXIT_SUCCESS); 41 | } 42 | -------------------------------------------------------------------------------- /tlpi-dist/svsem/svsem_rm.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* svsem_rm.c 12 | 13 | Remove the System V semaphore sets whose IDs are specified by the 14 | command-line arguments. 15 | */ 16 | #include 17 | #include 18 | #include "semun.h" /* Definition of semun union */ 19 | #include "tlpi_hdr.h" 20 | 21 | int 22 | main(int argc, char *argv[]) 23 | { 24 | int j; 25 | union semun dummy; 26 | 27 | if (argc > 1 && strcmp(argv[1], "--help") == 0) 28 | usageErr("%s [semid...]\n", argv[0]); 29 | 30 | for (j = 1; j < argc; j++) 31 | if (semctl(getInt(argv[j], 0, "semid"), 0, IPC_RMID, dummy) == -1) 32 | errExit("semctl %s", argv[j]); 33 | 34 | exit(EXIT_SUCCESS); 35 | } 36 | -------------------------------------------------------------------------------- /tlpi-dist/svshm/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = svshm_attach svshm_create svshm_mon svshm_rm \ 4 | svshm_xfr_reader svshm_xfr_writer 5 | 6 | LINUX_EXE = svshm_info svshm_lock svshm_unlock 7 | 8 | EXE = ${GEN_EXE} ${LINUX_EXE} 9 | 10 | all : ${EXE} 11 | 12 | allgen : ${GEN_EXE} 13 | 14 | clean : 15 | ${RM} ${EXE} *.o 16 | 17 | svshm_xfr_reader.o svshm_xfr_writer.o: svshm_xfr.h 18 | 19 | showall : 20 | @ echo ${EXE} 21 | 22 | ${EXE} : ${LPLIB} # True as a rough approximation 23 | -------------------------------------------------------------------------------- /tlpi-dist/svshm/svshm_lock.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* svshm_lock.c 12 | 13 | Lock the System V shared memory segments identified by the 14 | command-line arguments. 15 | 16 | See also svshm_unlock.c. 17 | */ 18 | #include 19 | #include 20 | #include "tlpi_hdr.h" 21 | 22 | int 23 | main(int argc, char *argv[]) 24 | { 25 | int j; 26 | 27 | for (j = 1; j < argc; j++) 28 | if (shmctl(getInt(argv[j], 0, "shmid"), SHM_LOCK, NULL) == -1) 29 | errExit("shmctl"); 30 | 31 | sleep(5); 32 | 33 | exit(EXIT_SUCCESS); 34 | } 35 | -------------------------------------------------------------------------------- /tlpi-dist/svshm/svshm_rm.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* svshm_rm.c 12 | 13 | Remove the System V shared memory segments identified by the 14 | command-line arguments 15 | */ 16 | #include 17 | #include 18 | #include "tlpi_hdr.h" 19 | 20 | int 21 | main(int argc, char *argv[]) 22 | { 23 | int j; 24 | 25 | if (argc > 1 && strcmp(argv[1], "--help") == 0) 26 | usageErr("%s [shmid...]\n", argv[0]); 27 | 28 | for (j = 1; j < argc; j++) 29 | if (shmctl(getInt(argv[j], 0, "shmid"), IPC_RMID, NULL) == -1) 30 | errExit("shmctl %s", argv[j]); 31 | 32 | exit(EXIT_SUCCESS); 33 | } 34 | -------------------------------------------------------------------------------- /tlpi-dist/svshm/svshm_unlock.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* svshm_unlock.c 12 | 13 | Unlock the System V shared memory segments identified by the 14 | command-line arguments. 15 | 16 | See also svshm_lock.c. 17 | */ 18 | #include 19 | #include 20 | #include "tlpi_hdr.h" 21 | 22 | int 23 | main(int argc, char *argv[]) 24 | { 25 | int j; 26 | 27 | for (j = 1; j < argc; j++) 28 | if (shmctl(getInt(argv[j], 0, "shmid"), SHM_UNLOCK, NULL) == -1) 29 | errExit("shmctl"); 30 | 31 | exit(EXIT_SUCCESS); 32 | } 33 | -------------------------------------------------------------------------------- /tlpi-dist/sysinfo/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = t_uname 4 | 5 | LINUX_EXE = procfs_pidmax procfs_user_exe 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/sysinfo/t_uname.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* t_uname.c 12 | 13 | Demonstrate the use of the uname() system call, which returns various 14 | identifying information about the system. 15 | */ 16 | #define _GNU_SOURCE 17 | #include 18 | #include "tlpi_hdr.h" 19 | 20 | int 21 | main(int argc, char *argv[]) 22 | { 23 | struct utsname uts; 24 | 25 | if (uname(&uts) == -1) 26 | errExit("uname"); 27 | 28 | printf("Node name: %s\n", uts.nodename); 29 | printf("System name: %s\n", uts.sysname); 30 | printf("Release: %s\n", uts.release); 31 | printf("Version: %s\n", uts.version); 32 | printf("Machine: %s\n", uts.machine); 33 | #ifdef _GNU_SOURCE 34 | printf("Domain name: %s\n", uts.domainname); 35 | #endif 36 | exit(EXIT_SUCCESS); 37 | } 38 | -------------------------------------------------------------------------------- /tlpi-dist/syslim/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = t_fpathconf t_sysconf 4 | 5 | LINUX_EXE = 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/threads/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = detached_attrib one_time_init prod_condvar prod_no_condvar \ 4 | simple_thread strerror_test strerror_test_tsd \ 5 | thread_cancel thread_cleanup thread_incr thread_incr_mutex \ 6 | thread_multijoin 7 | 8 | LINUX_EXE = strerror_test_tls 9 | 10 | EXE = ${GEN_EXE} ${LINUX_EXE} 11 | 12 | all : ${EXE} 13 | 14 | allgen : ${GEN_EXE} 15 | 16 | CFLAGS = ${IMPL_CFLAGS} ${IMPL_THREAD_FLAGS} 17 | LDLIBS = ${IMPL_LDLIBS} ${IMPL_THREAD_FLAGS} 18 | 19 | strerror_test: strerror_test.o strerror.o 20 | ${CC} -o $@ strerror_test.o strerror.o \ 21 | ${CFLAGS} ${LDLIBS} 22 | 23 | strerror_test_tsd: strerror_test.o strerror_tsd.o 24 | ${CC} -o $@ strerror_test.o strerror_tsd.o \ 25 | ${CFLAGS} ${LDLIBS} 26 | 27 | strerror_test_tls: strerror_test.o strerror_tls.o 28 | ${CC} -o $@ strerror_test.o strerror_tls.o \ 29 | ${CFLAGS} ${LDLIBS} 30 | 31 | clean : 32 | ${RM} ${EXE} *.o 33 | 34 | showall : 35 | @ echo ${EXE} 36 | 37 | ${EXE} : ${LPLIB} # True as a rough approximation 38 | -------------------------------------------------------------------------------- /tlpi-dist/threads/simple_thread.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* simple_thread.c 12 | 13 | A simple POSIX threads example: create a thread, and then join with it. 14 | */ 15 | #include 16 | #include "tlpi_hdr.h" 17 | 18 | static void * 19 | threadFunc(void *arg) 20 | { 21 | char *s = (char *) arg; 22 | 23 | printf("%s", s); 24 | 25 | return (void *) strlen(s); 26 | } 27 | 28 | int 29 | main(int argc, char *argv[]) 30 | { 31 | pthread_t t1; 32 | void *res; 33 | int s; 34 | 35 | s = pthread_create(&t1, NULL, threadFunc, "Hello world\n"); 36 | if (s != 0) 37 | errExitEN(s, "pthread_create"); 38 | 39 | printf("Message from main()\n"); 40 | s = pthread_join(t1, &res); 41 | if (s != 0) 42 | errExitEN(s, "pthread_join"); 43 | 44 | printf("Thread returned %ld\n", (long) res); 45 | 46 | exit(EXIT_SUCCESS); 47 | } 48 | -------------------------------------------------------------------------------- /tlpi-dist/time/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = calendar_time show_time process_time strtime t_stime 4 | 5 | EXE = ${GEN_EXE} ${LINUX_EXE} 6 | 7 | all : ${EXE} 8 | 9 | allgen : ${GEN_EXE} 10 | 11 | clean : 12 | ${RM} ${EXE} *.o 13 | 14 | showall : 15 | @ echo ${EXE} 16 | 17 | ${EXE} : ${LPLIB} # True as a rough approximation 18 | -------------------------------------------------------------------------------- /tlpi-dist/time/curr_time.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* curr_time.c 12 | 13 | Implement our currTime() function. 14 | */ 15 | #include 16 | #include "curr_time.h" /* Declares function defined here */ 17 | 18 | #define BUF_SIZE 1000 19 | 20 | /* Return a string containing the current time formatted according to 21 | the specification in 'format' (see strftime(3) for specifiers). 22 | If 'format' is NULL, we use "%c" as a specifier (which gives the' 23 | date and time as for ctime(3), but without the trailing newline). 24 | Returns NULL on error. */ 25 | 26 | char * 27 | currTime(const char *format) 28 | { 29 | static char buf[BUF_SIZE]; /* Nonreentrant */ 30 | time_t t; 31 | size_t s; 32 | struct tm *tm; 33 | 34 | t = time(NULL); 35 | tm = localtime(&t); 36 | if (tm == NULL) 37 | return NULL; 38 | 39 | s = strftime(buf, BUF_SIZE, (format != NULL) ? format : "%c", tm); 40 | 41 | return (s == 0) ? NULL : buf; 42 | } 43 | -------------------------------------------------------------------------------- /tlpi-dist/time/curr_time.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* curr_time.h 12 | 13 | Header file for curr_time.c. 14 | */ 15 | #ifndef CURR_TIME_H 16 | #define CURR_TIME_H /* Prevent accidental double inclusion */ 17 | 18 | char *currTime(const char *fmt); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /tlpi-dist/time/t_stime.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* t_stime.c 12 | 13 | Demonstrate the use of stime() to set the system time. 14 | 15 | Requires superuser privileges. 16 | */ 17 | #define _SVID_SOURCE /* For stime() */ 18 | #if ! defined(__sun) 19 | #ifndef _XOPEN_SOURCE 20 | #define _XOPEN_SOURCE /* For strptime() */ 21 | #endif 22 | #endif 23 | #include 24 | #include "tlpi_hdr.h" 25 | 26 | int 27 | main(int argc, char *argv[]) 28 | { 29 | struct tm tm; 30 | time_t t; 31 | 32 | if (argc != 2 || strcmp(argv[1], "--help") == 0) 33 | usageErr("%s \"DD MMM YYYY HH:MM:SS\"\n", argv[0]); 34 | 35 | if (strptime(argv[1], "%d %b %Y %H:%M:%S", &tm) == NULL) 36 | fatal("strptime failed"); 37 | 38 | t = mktime(&tm); 39 | if (stime(&t) == -1) 40 | errExit("stime"); 41 | 42 | exit(EXIT_SUCCESS); 43 | } 44 | -------------------------------------------------------------------------------- /tlpi-dist/timers/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = demo_timerfd ptmr_null_evp ptmr_sigev_signal ptmr_sigev_thread \ 4 | real_timer t_nanosleep timed_read 5 | 6 | LINUX_EXE = t_clock_nanosleep demo_timerfd 7 | 8 | EXE = ${GEN_EXE} ${LINUX_EXE} 9 | 10 | all : ${EXE} 11 | 12 | allgen : ${GEN_EXE} 13 | 14 | demo_timerfd: demo_timerfd.o 15 | ${CC} -o $@ demo_timerfd.o ${CFLAGS} ${LDLIBS} ${LINUX_LIBRT} 16 | 17 | ptmr_null_evp: ptmr_null_evp.o 18 | ${CC} -o $@ ptmr_null_evp.o ${CFLAGS} ${LDLIBS} ${LINUX_LIBRT} 19 | 20 | ptmr_sigev_signal: ptmr_sigev_signal.o 21 | ${CC} -o $@ ptmr_sigev_signal.o ${CFLAGS} ${LDLIBS} ${LINUX_LIBRT} 22 | 23 | ptmr_sigev_thread: ptmr_sigev_thread.c 24 | ${CC} -o $@ ${IMPL_THREAD_FLAGS} ptmr_sigev_thread.c \ 25 | ${CFLAGS} ${LDLIBS} ${LINUX_LIBRT} 26 | 27 | t_clock_nanosleep: t_clock_nanosleep.o 28 | ${CC} -o $@ t_clock_nanosleep.o ${CFLAGS} ${LDLIBS} ${LINUX_LIBRT} 29 | 30 | clean : 31 | ${RM} ${EXE} *.o 32 | 33 | showall : 34 | @ echo ${EXE} 35 | 36 | ${EXE} : ${LPLIB} # True as a rough approximation 37 | -------------------------------------------------------------------------------- /tlpi-dist/timers/itimerspec_from_str.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* itimerspec_from_str.h 12 | 13 | Header file for itimerspec_from_str.c. 14 | */ 15 | #ifndef ITIMERSPEC_FROM_STR_H 16 | #define ITIMERSPEC_FROM_STR_H 17 | 18 | #include 19 | 20 | void itimerspecFromStr(char *str, struct itimerspec *tsp); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /tlpi-dist/tty/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = demo_SIGWINCH new_intr no_echo test_tty_functions 4 | 5 | EXE = ${GEN_EXE} ${LINUX_EXE} 6 | 7 | all : ${EXE} 8 | 9 | allgen : ${GEN_EXE} 10 | 11 | clean : 12 | ${RM} ${EXE} *.o 13 | 14 | showall : 15 | @ echo ${EXE} 16 | 17 | ${EXE} : ${LPLIB} # True as a rough approximation 18 | -------------------------------------------------------------------------------- /tlpi-dist/tty/tty_functions.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* tty_functions.h 12 | 13 | Header file for tty_functions.c. 14 | */ 15 | #ifndef TTY_FUNCTIONS_H 16 | #define TTY_FUNCTIONS_H 17 | 18 | #include 19 | 20 | int ttySetCbreak(int fd, struct termios *prevTermios); 21 | 22 | int ttySetRaw(int fd, struct termios *prevTermios); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /tlpi-dist/users_groups/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = t_getpwent t_getpwnam_r 4 | 5 | LINUX_EXE = check_password idshow 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | check_password : check_password.o 17 | ${CC} -o $@ check_password.o ${LDFLAGS} ${LDLIBS} ${LINUX_LIBCRYPT} 18 | 19 | showall : 20 | @ echo ${EXE} 21 | 22 | ${EXE} : ${LPLIB} # True as a rough approximation 23 | -------------------------------------------------------------------------------- /tlpi-dist/users_groups/t_getpwent.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* t_getpwent.c 12 | 13 | Demonstrate the use of getpwent() to retrieve records from the system 14 | password file. 15 | */ 16 | #include 17 | #include "tlpi_hdr.h" 18 | 19 | int 20 | main(int argc, char *argv[]) 21 | { 22 | struct passwd *pwd; 23 | 24 | while ((pwd = getpwent()) != NULL) 25 | printf("%-8s %5ld\n", pwd->pw_name, (long) pwd->pw_uid); 26 | endpwent(); 27 | exit(EXIT_SUCCESS); 28 | } 29 | -------------------------------------------------------------------------------- /tlpi-dist/users_groups/ugid_functions.h: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* ugid_functions.h 12 | 13 | Header file for ugid_functions.c. 14 | */ 15 | #ifndef UGID_FUNCTIONS_H 16 | #define UGID_FUNCTIONS_H 17 | 18 | #include "tlpi_hdr.h" 19 | 20 | char *userNameFromId(uid_t uid); 21 | 22 | uid_t userIdFromName(const char *name); 23 | 24 | char *groupNameFromId(gid_t gid); 25 | 26 | gid_t groupIdFromName(const char *name); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /tlpi-dist/vmem/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = memlock madvise_dontneed 4 | 5 | LINUX_EXE = t_mprotect 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/xattr/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.inc 2 | 3 | GEN_EXE = 4 | 5 | LINUX_EXE = t_setxattr xattr_view 6 | 7 | EXE = ${GEN_EXE} ${LINUX_EXE} 8 | 9 | all : ${EXE} 10 | 11 | allgen : ${GEN_EXE} 12 | 13 | clean : 14 | ${RM} ${EXE} *.o 15 | 16 | showall : 17 | @ echo ${EXE} 18 | 19 | ${EXE} : ${LPLIB} # True as a rough approximation 20 | -------------------------------------------------------------------------------- /tlpi-dist/xattr/t_setxattr.c: -------------------------------------------------------------------------------- 1 | /**********************************************************************\ 2 | * Copyright (C) Michael Kerrisk, 2010. * 3 | * * 4 | * This program is free software. You may use, modify, and redistribute * 5 | * it under the terms of the GNU Affero General Public License as * 6 | * published by the Free Software Foundation, either version 3 or (at * 7 | * your option) any later version. This program is distributed without * 8 | * any warranty. See the file COPYING for details. * 9 | \**********************************************************************/ 10 | 11 | /* t_setxattr.c 12 | 13 | Demonstrate the use of setxattr() to set a file extended attribute. 14 | 15 | This program is Linux (2.6 and later) specific. 16 | 17 | See also view_xattr.c. 18 | */ 19 | #include 20 | #include "tlpi_hdr.h" 21 | 22 | int 23 | main(int argc, char *argv[]) 24 | { 25 | char *value; 26 | 27 | if (argc < 2 || strcmp(argv[1], "--help") == 0) 28 | usageErr("%s file\n", argv[0]); 29 | 30 | value = "The past is not dead."; 31 | if (setxattr(argv[1], "user.x", value, strlen(value), 0) == -1) 32 | errExit("setxattr"); 33 | 34 | value = "In fact, it's not even past."; 35 | if (setxattr(argv[1], "user.y", value, strlen(value), 0) == -1) 36 | errExit("setxattr"); 37 | 38 | exit(EXIT_SUCCESS); 39 | } 40 | --------------------------------------------------------------------------------