├── 01-intro ├── 01-intro.pdf ├── 01-intro.tex ├── Makefile ├── README.md ├── codes │ ├── Makefile │ ├── cat-copier.c │ ├── learnbyexperience.txt │ ├── ls-w-stat.c │ ├── pid.c │ ├── tiny-ls.c │ ├── toy-shell.c │ ├── toy-shellv2.c │ └── welcome.c ├── editor_test │ ├── README.pdf │ ├── README.tex │ ├── blkparse.txt │ └── blktrace.txt ├── figure │ ├── If_languages_were_drugs.jpg │ ├── If_languages_were_weapons.jpg │ ├── System-Call-and-Library-Function.png │ ├── bill_joy.png │ ├── bill_joy_quotes.jpg │ ├── emacs_dex.png │ ├── emacs_layout.png │ ├── history_1.png │ ├── history_2.png │ ├── ken-dennis-pdp7.jpg │ ├── learning_curve.png │ ├── richard_stallman.png │ ├── vi_directions.png │ ├── vi_modes.png │ ├── vi_tools.png │ ├── vi_why.png │ └── vim_logo.png └── misc │ ├── .emacs │ └── .vimrc ├── 02-file_io ├── 02-file_io.pdf ├── 02-file_io.tex ├── Makefile ├── README.md ├── codes │ ├── Makefile │ ├── fdcount.c │ ├── hole.c │ ├── mycat.c │ └── setfl.c └── figure │ ├── fig-3-9_dup.png │ ├── fig3-7_kernel_DS_open_files.png │ ├── fig3-8_two_processes_open_file.png │ ├── iotest.data │ ├── iotest.gp │ ├── iotest.png │ ├── iotest2.png │ └── stream-pipe.png ├── 03-file_dirs ├── 03-file_dirs.pdf ├── 03-file_dirs.tex ├── Makefile ├── README.md ├── codes │ ├── Makefile │ ├── access.c │ ├── chdir.c │ ├── filetype.c │ ├── futimens_ex.c │ ├── mychmod.c │ ├── myls-s.c │ ├── myls.c │ ├── myumask.c │ └── myunlink.c └── figure │ ├── fig4_13_disk.png │ ├── fig4_14_cylinder.png │ ├── fig4_15_sample.png │ └── fig4_20_effect.png ├── 04-sysfile_info ├── 04-sysfile_info.pdf ├── 04-sysfile_info.tex ├── Makefile ├── README.md ├── codes │ ├── Makefile │ ├── echoall.c │ ├── exit_handlers.c │ ├── foo.c │ ├── foobar.c │ ├── foobar.patch │ ├── getpwnam.c │ ├── hello.c │ ├── layout.c │ ├── sample_passwd │ ├── skel_cmd.c │ └── strftime.c └── figure │ ├── fig6-1_etc_passwd.png │ ├── fig6-4_group.png │ ├── fig6-6_similar.png │ ├── fig6-8_clock.png │ ├── fig6-9_relationship.png │ ├── fig7-2_how_prog.png │ ├── fig7-5_environment.png │ └── fig7-7_environment.png ├── 05-process ├── 05-process.pdf ├── 05-process.tex ├── Makefile ├── README.md ├── codes │ ├── Makefile │ ├── avoid_zombie.c │ ├── awkexample │ ├── echoall.c │ ├── echoarg.c │ ├── exec.c │ ├── exit_stat.c │ ├── fork.c │ ├── interp.c │ ├── master_fork.c │ ├── nice.c │ ├── pruid.c │ ├── race_cond.c │ ├── system.c │ ├── testinterp │ ├── times.c │ ├── tsys.c │ └── zombies.c └── figure │ ├── fig8-15_relationship.png │ ├── fig8-18_ways.png │ ├── fig8-19_summary.png │ └── fig8-2_sharing.png ├── 06-process_rel ├── 06-process_rel.pdf ├── 06-process_rel.tex ├── Makefile ├── README.md └── figure │ └── quote-a-computer-terminal-is-not-some-clunky-old-television-with-a-typewriter-in-front-of-it-it-is-an-douglas-adams-296711.jpg ├── 07-signal ├── 07-signal.pdf ├── 07-signal.tex ├── Makefile ├── README.md ├── codes │ ├── Makefile │ ├── critical.c │ ├── ex_block.c │ ├── reenter.c │ ├── reenter.o │ ├── setops.c │ ├── sigaction_sig.c │ ├── sleep-pause.c │ ├── sleep-pause2.c │ ├── tsleep.c │ └── usr_sig.c └── figure │ ├── fig10-1_unix_sig.png │ ├── fig10-4_reentrant.png │ ├── fig_proc.png │ └── signal_concept.png ├── 08-thread ├── 08-thread.pdf ├── 08-thread.tex ├── Makefile ├── README.md ├── codes │ ├── Makefile │ ├── bar_mac.h │ ├── barrier.c │ ├── condvar.c │ ├── exit-state.c │ ├── exit-wrong.c │ ├── mutex1.c │ ├── mutex2.c │ ├── mutex3.c │ ├── print_thrID.c │ ├── push-pop.c │ ├── rwlock.c │ └── timedlock.c └── figure │ ├── fig11-1.png │ ├── fig11-6.png │ ├── fig11-7.png │ ├── fig11-8.png │ └── fig11-9.png ├── 09-adv_io ├── 09-adv_io.pdf ├── 09-adv_io.tex ├── Makefile ├── README.md ├── codes │ ├── Makefile │ ├── deadlock.c │ ├── mcopy2.c │ ├── nonblocking.c │ ├── readn.c │ ├── rot13a.c │ ├── rot13c2.c │ ├── tellwait.c │ └── writen.c └── figures │ ├── fig14_10-filerange.png │ ├── fig14_2-reclock.png │ ├── fig14_22-iovec.png │ ├── fig14_26-mmap.png │ ├── fig14_3-compatibility.png │ ├── fig14_4-file.png │ └── fig14_8-freebsd.png ├── 10-ipc ├── 10-ipc.pdf ├── 10-ipc.tex ├── Makefile ├── README.md ├── codes │ ├── Makefile │ ├── add2.c │ ├── client.c │ ├── create_fifo.c │ ├── msg_receive.c │ ├── msg_send.c │ ├── myuclc.c │ ├── pipe1.c │ ├── pipe2.c │ ├── pipe4.c │ ├── popen1.c │ ├── popen2.c │ ├── server.c │ ├── shm_receive.c │ ├── shm_send.c │ └── tshm.c └── figures │ ├── fig15_10-result-w.png │ ├── fig15_16-driving.png │ ├── fig15_2-twoways.png │ ├── fig15_20-procedure.png │ ├── fig15_21-using.png │ ├── fig15_23-client.png │ ├── fig15_24-xsi.png │ ├── fig15_25-comparison.png │ ├── fig15_3-halfduplex.png │ ├── fig15_32-memory.png │ ├── fig15_4-pipe.png │ └── fig15_9-result-r.png ├── 11-socket ├── 11-socket.pdf ├── 11-socket.tex ├── Makefile └── figures │ └── fig_socket_syscall.png ├── Editor_Level_Test ├── 20161102_test │ ├── README.md │ ├── manuscript_test.txt │ └── vim_test.pdf ├── first_test_answer.txt └── first_test_score.txt ├── LICENSE ├── README.md ├── beamer_template ├── beamercolorthemesthlm.sty ├── beamerfontthemesthlm.sty ├── beamerthemesthlm.sty └── pictures │ └── foxed.png ├── project1 ├── README.md ├── codes │ ├── Makefile │ ├── mkfs.f2fs │ └── sysp.c ├── f2fs_ctags.pdf ├── f2fs_ctags.tex ├── figure │ ├── command1.png │ ├── command2.png │ ├── command3.png │ ├── f2fsstatus.png │ ├── format.png │ ├── stj.png │ ├── tags.png │ ├── tagsinside.png │ ├── ts.png │ ├── vimctags.png │ ├── vm_config_1.png │ ├── vm_config_2.png │ ├── vm_config_3.png │ ├── vm_config_4.png │ └── vm_config_5.png └── howto_kernel_compile.pdf ├── quiz ├── 20161214_editor_eval │ ├── blkparse.txt │ ├── blkparse_answer.txt │ ├── blktrace.txt │ ├── editor_test.pdf │ └── editor_test.tex ├── README.md ├── quiz_20161005.pdf ├── quiz_20161005.png ├── quiz_20161005_sol.pdf ├── quiz_20161012.pdf ├── quiz_20161012.png ├── quiz_20161012_sol.pdf ├── quiz_20161116.pdf └── quiz_20161116_sol.pdf └── vcs_regex ├── 09-vcs_regex.pdf ├── 09-vcs_regex.tex ├── Makefile ├── README.md ├── codes ├── gpl.txt └── p176.txt └── figures ├── fig1.png ├── fig2.png ├── fig3.png ├── fig4.png └── fig5.png /01-intro/01-intro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/01-intro.pdf -------------------------------------------------------------------------------- /01-intro/Makefile: -------------------------------------------------------------------------------- 1 | texfile = 01-intro.tex 2 | outdir=/tmp 3 | 4 | all: ${texfile} 5 | pdflatex --shell-escape --output-directory ${outdir} $< 6 | 7 | clean: 8 | rm *.aux *.log *.nav *.out *.snm *.toc *.vrb 9 | 10 | o: ${texfile} 11 | gv ${outdir}/$(basename $<).pdf & 12 | 13 | final: ${texfile} 14 | pdflatex --shell-escape --output-directory ${outdir} $< 15 | pdflatex --shell-escape --output-directory ${outdir} $< 16 | cp ${outdir}/$(basename $<).pdf . 17 | -------------------------------------------------------------------------------- /01-intro/README.md: -------------------------------------------------------------------------------- 1 | This is for Class 1 of System Programming 2 | 3 | Visit following link for [Course description](http://resourceful.github.io/classes/2016-09-07-week1-class1-intro/) -------------------------------------------------------------------------------- /01-intro/codes/Makefile: -------------------------------------------------------------------------------- 1 | 2 | PROGRAMS = cat-copier ls-w-stat minimal-cat pid tiny-ls toy-shell toy-shellv2 welcome 3 | 4 | CFLAGS = -g -Wall -O0 5 | 6 | all: ${PROGRAMS} 7 | 8 | %.o: %.c 9 | ${CC} ${CFLAGS} -c $< 10 | 11 | ${PROGRAMS}: %: %.o 12 | ${CC} ${CFLAGS} -o $@ $< 13 | 14 | clean: 15 | rm ${PROGRAMS} *.o 16 | -------------------------------------------------------------------------------- /01-intro/codes/cat-copier.c: -------------------------------------------------------------------------------- 1 | /* 2 | * APUE Figure 1.5 3 | * Stripped down version of 'cat', buffered version. 4 | * Guess what, this is also a primitive version of 'cp': 5 | * Usage: ./cat-copier < ANY_FILE > OUTPUT_FILE 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | int 13 | main(int argc, char **argv) { 14 | int c; 15 | 16 | while ((c = getc(stdin)) != EOF) 17 | if (putc(c, stdout) == EOF) { 18 | fprintf(stderr, "write error\n"); 19 | exit(1); 20 | } 21 | 22 | if (ferror(stdin)) { 23 | fprintf(stderr, "read error\n"); 24 | exit(1); 25 | } 26 | 27 | return(0); 28 | } 29 | -------------------------------------------------------------------------------- /01-intro/codes/learnbyexperience.txt: -------------------------------------------------------------------------------- 1 | The five boxing wizards jump quickly. 2 | See the quick brown fox jump over the lazy dog. 3 | A mad boxer shot a quick, gloved jab to the jaw of his dizzy opponent. 4 | We promptly judged antique ivory buckles for the next prize. 5 | A quart jar of oil mixed with zinc oxide makes a very bright paint. 6 | The job requires extra pluck and zeal from every young wage earner. 7 | 8 | -------------------------------------------------------------------------------- /01-intro/codes/ls-w-stat.c: -------------------------------------------------------------------------------- 1 | /* 2 | * simple-ls.c 3 | * Extremely low-power ls clone. 4 | * ./simple-ls . 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | void 18 | printType(const struct stat sb) { 19 | if (S_ISREG(sb.st_mode)) 20 | printf("regular file"); 21 | else if (S_ISDIR(sb.st_mode)) 22 | printf("directory"); 23 | else if (S_ISCHR(sb.st_mode)) 24 | printf("character special"); 25 | else if (S_ISBLK(sb.st_mode)) 26 | printf("block special"); 27 | else if (S_ISFIFO(sb.st_mode)) 28 | printf("FIFO"); 29 | else if (S_ISLNK(sb.st_mode)) 30 | printf("symbolic link"); 31 | else if (S_ISSOCK(sb.st_mode)) 32 | printf("socket"); 33 | else 34 | printf("unknown"); 35 | } 36 | 37 | int 38 | main(int argc, char **argv) { 39 | 40 | DIR *dp; 41 | struct dirent *dirp; 42 | 43 | if (argc != 2) { 44 | fprintf(stderr, "usage: %s dir_name\n", argv[0]); 45 | exit(1); 46 | } 47 | 48 | if ((dp = opendir(argv[1])) == NULL) { 49 | fprintf(stderr, "can't open '%s'\n", argv[1]); 50 | exit(1); 51 | } 52 | 53 | if (chdir(argv[1]) == -1) { 54 | fprintf(stderr, "can't chdir to '%s': %s\n", argv[1], strerror(errno)); 55 | exit(EXIT_FAILURE); 56 | } 57 | 58 | while ((dirp = readdir(dp)) != NULL) { 59 | struct stat sb; 60 | if (stat(dirp->d_name, &sb) == -1) { 61 | fprintf(stderr, "Can't stat %s: %s\n", dirp->d_name, 62 | strerror(errno)); 63 | 64 | if (lstat(dirp->d_name, &sb) == -1) { 65 | fprintf(stderr,"Can't stat %s: %s\n", dirp->d_name, 66 | strerror(errno)); 67 | continue; 68 | } 69 | } 70 | 71 | printf("%s (", dirp->d_name); 72 | printType(sb); 73 | printf(" - "); 74 | 75 | if (lstat(dirp->d_name, &sb) == -1) { 76 | fprintf(stderr,"Can't stat %s: %s\n", dirp->d_name, 77 | strerror(errno)); 78 | continue; 79 | } 80 | printType(sb); 81 | printf(")\n"); 82 | } 83 | 84 | closedir(dp); 85 | return(0); 86 | } 87 | -------------------------------------------------------------------------------- /01-intro/codes/pid.c: -------------------------------------------------------------------------------- 1 | /* 2 | * APUE Figure 1.6 3 | * This trivial program simply prints out its own PID and exits. 4 | * Usage: ./pid 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | int 12 | main(int argc, char **argv) { 13 | printf("Hello world from process id %d\n", getpid()); 14 | return(0); 15 | } 16 | -------------------------------------------------------------------------------- /01-intro/codes/tiny-ls.c: -------------------------------------------------------------------------------- 1 | /* 2 | * APUE Figure 1.3 3 | * usage: ./tiny-ls . 4 | */ 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | int 13 | main(int argc, char **argv) { 14 | 15 | DIR *dp; 16 | struct dirent *dirp; 17 | 18 | if (argc != 2) { 19 | fprintf(stderr, "usage: %s dir_name\n", argv[0]); 20 | exit(1); 21 | } 22 | 23 | if ((dp = opendir(argv[1])) == NULL ) { 24 | fprintf(stderr, "can't open '%s'\n", argv[1]); 25 | exit(1); 26 | } 27 | 28 | while ((dirp = readdir(dp)) != NULL ) 29 | printf("%s\n", dirp->d_name); 30 | 31 | closedir(dp); 32 | return(0); 33 | } 34 | -------------------------------------------------------------------------------- /01-intro/codes/toy-shell.c: -------------------------------------------------------------------------------- 1 | /* 2 | * APUE Figure 1.7 3 | * Loops, reads input and tries to execute it. 4 | * Note: no tokenization, can be ^C'd, but does look at PATH 5 | * not sorted 6 | * 7 | * ./simple-shell 8 | * %% ls 9 | * %% /bin/ls 10 | * %% /bin/ls -la # error 11 | * %% ^C 12 | * 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | char * 25 | getinput(char *buffer, size_t buflen) { 26 | printf("%% "); 27 | return fgets(buffer, buflen, stdin); 28 | } 29 | 30 | int 31 | main(int argc, char **argv) { 32 | char buf[1024]; 33 | pid_t pid; 34 | int status; 35 | 36 | while (getinput(buf, sizeof(buf))) { 37 | buf[strlen(buf) - 1] = '\0'; 38 | 39 | if((pid=fork()) == -1) { 40 | fprintf(stderr, "shell: can't fork: %s\n", 41 | strerror(errno)); 42 | continue; 43 | } else if (pid == 0) { 44 | /* child */ 45 | execlp(buf, buf, (char *)0); 46 | fprintf(stderr, "shell: couldn't exec %s: %s\n", buf, 47 | strerror(errno)); 48 | exit(EX_DATAERR); 49 | } 50 | 51 | if ((pid=waitpid(pid, &status, 0)) < 0) 52 | fprintf(stderr, "shell: waitpid error: %s\n", 53 | strerror(errno)); 54 | } 55 | 56 | exit(EX_OK); 57 | } 58 | -------------------------------------------------------------------------------- /01-intro/codes/toy-shellv2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * APUE Figure 1.10 3 | * Same as toy-shell.c, but with a SIGINT signal handler. 4 | * Feed EOF (^D) to exit. 5 | * 6 | * Also illustrates forward declaration of a function prototype. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | static void sig_int(int); 20 | 21 | char * 22 | getinput(char *buffer, size_t buflen) { 23 | printf("$$ "); 24 | return fgets(buffer, buflen, stdin); 25 | } 26 | 27 | int 28 | main(int argc, char **argv) { 29 | char buf[1024]; 30 | pid_t pid; 31 | int status; 32 | 33 | if (signal(SIGINT, sig_int) == SIG_ERR) { 34 | fprintf(stderr, "signal error: %s\n", strerror(errno)); 35 | exit(1); 36 | } 37 | 38 | while (getinput(buf, sizeof(buf))) { 39 | buf[strlen(buf) - 1] = '\0'; 40 | 41 | if((pid=fork()) == -1) { 42 | fprintf(stderr, "shell: can't fork: %s\n", 43 | strerror(errno)); 44 | continue; 45 | } else if (pid == 0) { 46 | /* child */ 47 | execlp(buf, buf, (char *)0); 48 | fprintf(stderr, "shell: couldn't exec %s: %s\n", buf, 49 | strerror(errno)); 50 | exit(EX_DATAERR); 51 | } 52 | 53 | if ((pid=waitpid(pid, &status, 0)) < 0) 54 | fprintf(stderr, "shell: waitpid error: %s\n", 55 | strerror(errno)); 56 | } 57 | 58 | exit(EX_OK); 59 | } 60 | 61 | void 62 | sig_int(int signo) { 63 | printf("\nCaught SIGINT!\n"); 64 | } 65 | -------------------------------------------------------------------------------- /01-intro/codes/welcome.c: -------------------------------------------------------------------------------- 1 | /* 2 | * welcome file 3 | */ 4 | 5 | #include 6 | //#include 7 | 8 | int 9 | main(int argc, char **argv) { 10 | printf("Welcome to System Programming, %s!\n", getlogin()) 11 | } 12 | -------------------------------------------------------------------------------- /01-intro/editor_test/README.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/editor_test/README.pdf -------------------------------------------------------------------------------- /01-intro/editor_test/README.tex: -------------------------------------------------------------------------------- 1 | % Author: Seongjin Lee 2 | % Hanyang University, Seoul, Korea 3 | % esos.hanyang.ac.kr 4 | % 2016-09-01 5 | % note: some slides are adopted from \url{www.cs.stevens.edu/~jschauma/631A/} 6 | % https://github.com/resourceful/lecture_sysprog/ 7 | 8 | \documentclass{article} 9 | \usepackage{kotex} 10 | \usepackage{hyperref} 11 | \hypersetup{pdfauthor={Seongjin Lee (insight@gnu.ac.kr)}, 12 | pdfsubject={Editor Skill Test}, 13 | pdfkeywords={vi, emacs, editor, skill test}, 14 | pdfcreator={Seongjin Lee}, 15 | hidelinks} 16 | 17 | 18 | 19 | 20 | \title{Vi and Emacs Skill Test} 21 | \author{Seongjin Lee} 22 | \date{\today} 23 | 24 | \begin{document} 25 | \maketitle 26 | 27 | \noindent 28 | \fbox{ 29 | \parbox{\textwidth}{vi 또는 emacs를 이용하여 “blkparse.txt”를 연 뒤, 다음 지시사항들을 따라 하시기 바랍 니다. 동일한 경로에 “blktrace.txt”도 함께 위치시키시기 바랍니다.} 30 | } 31 | 32 | \begin{enumerate} 33 | \item 51번째 line으로 커서를 이동하시오. 34 | \item ``blktrace'' 문자열을 아래 방향으로 한 번 검색하여 커서를 이동하시오. 35 | \item 현재커서위치에서한line을복사한뒤, 복사한문자열을현재커서위치의다음 line으로 삽입하시오. 36 | \item 현재 커서 위치에서 위 방향으로 ``blkparse'' 문자열을 검색하여 5번 커서를 이동하시 오. 도착한 커서 위치의 line 한 줄을 지우시오. 37 | \item 24~29 line 6줄을 복사한 뒤, 31번 line 시작 위치에 붙여 넣으시오. 38 | \item 38번째 line으로 커서를 이동한 뒤, 일곱 줄을 지우시오. 39 | \item 해당 파일의 첫 행으로 커서를 옮긴 뒤, 현재 커서 위치부터 나오는 ``blkparse'' 문자 열 10개를 ``blocktrace\_parser''로 치환하시오. 40 | \item ``blktrace.txt'' 파일의 본문을, 현재 파일의 444번 Line 시작 위치에 삽입하시오. 41 | \item 해당 파일의 첫 행으로 커서를 옮긴 뒤, 다음과 같이 매크로를 작성하고 수행하시오. 42 | \begin{enumerate} 43 | \item btrace 문자열 검색 $\rightarrow$ line 끝으로 이동$\rightarrow$ btrace is here 입력 44 | \item 작성한 매크로를 7번 반복하시오. 45 | \end{enumerate} 46 | \item 현재까지 변경된 문서를 ``이름\_본인학번.txt''로 저장한 뒤, \href{mailto:insight@gnu.ac.kr}{insight@gnu.ac.kr}로 보내시요. (Ex. 이순신\_2011234567.txt) 47 | \end{enumerate} 48 | \end{document} -------------------------------------------------------------------------------- /01-intro/editor_test/blktrace.txt: -------------------------------------------------------------------------------- 1 | BLKTRACE(8) BLKTRACE(8) 2 | 3 | 4 | 5 | NAME 6 | blktrace - generate traces of the i/o traffic on block devices 7 | 8 | 9 | 10 | SYNOPSIS 11 | blktrace -d dev [ -r debugfs_path ] [ -o output ] [-k ] [ -w time ] [ -a action ] [ -A action_mask ] [ -v ] 12 | 13 | 14 | 15 | DESCRIPTION 16 | blktrace is a block layer IO tracing mechanism which provides detailed information about request queue operations up to 17 | user space. There are three major components: a kernel component, a utility to record the i/o trace information for the 18 | kernel to user space, and utilities to analyse and view the trace information. This man page describes blktrace, which 19 | records the i/o event trace information for a specific block device to a file. 20 | 21 | The blktrace utility extracts event traces from the kernel (via the relaying through the debug file system). Some back‐ 22 | ground details concerning the run-time behaviour of blktrace will help to understand some of the more arcane command 23 | line options: 24 | 25 | 26 | - blktrace receives data from the kernel in buffers passed up through the debug file system (relay). Each device being 27 | traced has a file created in the mounted directory for the debugfs, which defaults to /sys/kernel/debug -- this can 28 | be overridden with the -r command line argument. 29 | 30 | 31 | - blktrace defaults to collecting all events that can be traced. To limit the events being captured, you can specify 32 | one or more filter masks via the -a option. 33 | 34 | Alternatively, one may specify the entire mask utilising a hexadecimal value that is version-specific. (Requires 35 | understanding of the internal representation of the filter mask.) 36 | 37 | 38 | - As noted above, the events are passed up via a series of buffers stored into debugfs files. The size and number of 39 | buffers can be specified via the -b and -n arguments respectively. 40 | 41 | 42 | - blktrace stores the extracted data into files stored in the local directory. The format of the file names is (by 43 | default) device.blktrace.cpu, where device is the base device name (e.g, if we are tracing /dev/sda, the base device 44 | name would be sda); and cpu identifies a CPU for the event stream. 45 | 46 | The device portion of the event file name can be changed via the -o option. 47 | 48 | 49 | - blktrace may also be run concurrently with blkparse to produce live output -- to do this specify -o - for blktrace. 50 | 51 | 52 | - The default behaviour for blktrace is to run forever until explicitly killed by the user (via a control-C, or kill 53 | utility invocation). There are two ways to modify this: 54 | 55 | 56 | 1. You may utilise the blktrace utility itself to kill a running trace -- via the -k option. 57 | 58 | 59 | 2. You can specify a run-time duration for blktrace via the -w option -- then blktrace will run for the specified 60 | number of seconds, and then halt. 61 | 62 | 63 | 64 | OPTIONS 65 | -A hex-mask 66 | --set-mask=hex-mask 67 | Set filter mask to hex-mask (see below for masks) 68 | 69 | -a mask 70 | --act-mask=mask 71 | Add mask to current filter (see below for masks) 72 | 73 | -b size 74 | --buffer-size=size 75 | Specifies buffer size for event extraction (scaled by 1024). The default buffer size is 512KiB. 76 | 77 | -d dev 78 | --dev=dev 79 | Adds dev as a device to trace 80 | 81 | -I file 82 | --input-devs=file 83 | Adds the devices found in file as devices to trace 84 | 85 | -k 86 | --kill 87 | Kill on-going trace 88 | 89 | -n num-sub 90 | --num-sub=num-sub 91 | Specifies number of buffers to use. blktrace defaults to 4 sub buffers. 92 | 93 | -o file 94 | --output=file 95 | Prepend file to output file name(s) 96 | 97 | -r rel-path 98 | --relay=rel-path 99 | Specifies debugfs mount point 100 | 101 | -V 102 | --version Outputs version 103 | 104 | -w seconds 105 | --stopwatch=seconds 106 | Sets run time to the number of seconds specified 107 | 108 | 109 | 110 | FILTER MASKS 111 | The following masks may be passed with the -a command line option, multiple filters may be combined via multiple -a 112 | command line options. 113 | 114 | barrier: barrier attribute 115 | complete: completed by driver 116 | fs: requests 117 | issue: issued to driver 118 | pc: packet command events 119 | queue: queue operations 120 | read: read traces 121 | requeue: requeue operations 122 | sync: synchronous attribute 123 | write: write traces 124 | notify: trace messages 125 | 126 | 127 | 128 | REQUEST TYPES 129 | blktrace distinguishes between two types of block layer requests, file system and SCSI commands. The former are dubbed 130 | fs requests, the latter pc requests. File system requests are normal read/write operations, i.e. any type of read or 131 | write from a specific disk location at a given size. These requests typically originate from a user process, but they 132 | may also be initiated by the vm flushing dirty data to disk or the file system syncing a super or journal block to 133 | disk. pc requests are SCSI commands. blktrace sends the command data block as a payload so that blkparse can decode it. 134 | 135 | 136 | 137 | EXAMPLES 138 | To trace the i/o on the device /dev/hda and parse the output to human readable form, use the following command: 139 | 140 | % blktrace -d /dev/sda -o - | blkparse -i - 141 | 142 | This same behaviour can be achieve with the convenience script btrace. The command 143 | 144 | % btrace /dev/sda 145 | 146 | has exactly the same effect as the previous command. See btrace (8) for more information. 147 | 148 | To trace the i/o on a device and save the output for later processing with blkparse, use blktrace like this: 149 | 150 | % blktrace /dev/sda /dev/sdb 151 | 152 | This will trace i/o on the devices /dev/sda and /dev/sdb and save the recorded information in the files sda and sdb in 153 | the current directory, for the two different devices, respectively. This trace information can later be parsed by the 154 | blkparse utility: 155 | 156 | % blkparse sda sdb 157 | 158 | which will output the previously recorded tracing information in human readable form to stdout. See blkparse (1) for 159 | more information. 160 | 161 | 162 | 163 | AUTHORS 164 | blktrace was written by Jens Axboe, Alan D. Brunelle and Nathan Scott. This man page was created from the blktrace 165 | documentation by Bas Zoetekouw. 166 | 167 | 168 | 169 | REPORTING BUGS 170 | Report bugs to 171 | 172 | 173 | COPYRIGHT 174 | Copyright © 2006 Jens Axboe, Alan D. Brunelle and Nathan Scott. 175 | This is free software. You may redistribute copies of it under the terms of the GNU General Public License 176 | . There is NO WARRANTY, to the extent permitted by law. 177 | This manual page was created for Debian by Bas Zoetekouw. It was derived from the documentation provided by the 178 | authors and it may be used, distributed and modified under the terms of the GNU General Public License, version 2. 179 | On Debian systems, the text of the GNU General Public License can be found in /usr/share/common-licenses/GPL-2. 180 | 181 | 182 | SEE ALSO 183 | btrace (8), blkparse (1), verify_blkparse (1), blkrawverify (1), btt (1) 184 | 185 | 186 | 187 | 188 | blktrace git-20070306202522 March 6, 2007 BLKTRACE(8) 189 | -------------------------------------------------------------------------------- /01-intro/figure/If_languages_were_drugs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/figure/If_languages_were_drugs.jpg -------------------------------------------------------------------------------- /01-intro/figure/If_languages_were_weapons.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/figure/If_languages_were_weapons.jpg -------------------------------------------------------------------------------- /01-intro/figure/System-Call-and-Library-Function.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/figure/System-Call-and-Library-Function.png -------------------------------------------------------------------------------- /01-intro/figure/bill_joy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/figure/bill_joy.png -------------------------------------------------------------------------------- /01-intro/figure/bill_joy_quotes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/figure/bill_joy_quotes.jpg -------------------------------------------------------------------------------- /01-intro/figure/emacs_dex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/figure/emacs_dex.png -------------------------------------------------------------------------------- /01-intro/figure/emacs_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/figure/emacs_layout.png -------------------------------------------------------------------------------- /01-intro/figure/history_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/figure/history_1.png -------------------------------------------------------------------------------- /01-intro/figure/history_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/figure/history_2.png -------------------------------------------------------------------------------- /01-intro/figure/ken-dennis-pdp7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/figure/ken-dennis-pdp7.jpg -------------------------------------------------------------------------------- /01-intro/figure/learning_curve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/figure/learning_curve.png -------------------------------------------------------------------------------- /01-intro/figure/richard_stallman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/figure/richard_stallman.png -------------------------------------------------------------------------------- /01-intro/figure/vi_directions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/figure/vi_directions.png -------------------------------------------------------------------------------- /01-intro/figure/vi_modes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/figure/vi_modes.png -------------------------------------------------------------------------------- /01-intro/figure/vi_tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/figure/vi_tools.png -------------------------------------------------------------------------------- /01-intro/figure/vi_why.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/figure/vi_why.png -------------------------------------------------------------------------------- /01-intro/figure/vim_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/01-intro/figure/vim_logo.png -------------------------------------------------------------------------------- /01-intro/misc/.emacs: -------------------------------------------------------------------------------- 1 | (when (>= emacs-major-version 24) 2 | (require 'package) 3 | (package-initialize) 4 | (add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/") t) 5 | ) 6 | 7 | (require 'color-theme) 8 | (color-theme-initialize) 9 | (setq color-theme-is-global t) 10 | ;(color-theme-classic) 11 | ;(color-theme-robin-hood) 12 | (require 'color-theme-solarized) 13 | (color-theme-solarized-dark) 14 | ;(color-theme-solarized-light) 15 | 16 | ;(add-hook 'text-mode-hook 'turn-on-auto-fill) 17 | 18 | (global-linum-mode t) 19 | 20 | (load "auctex.el" nil t t) 21 | 22 | (setq TeX-auto-save t) 23 | (setq TeX-parse-self t) 24 | 25 | 26 | (set-face-attribute 'default nil :height 220) 27 | 28 | 29 | ;; unfill paragraph and region 30 | (defun unfill-paragraph () 31 | (interactive) 32 | (let ((fill-column (point-max))) 33 | (fill-paragraph nil))) 34 | 35 | (defun unfill-region () 36 | (interactive) 37 | (let ((fill-column (point-max))) 38 | (fill-region (region-beginning) (region-end) nil))) 39 | 40 | 41 | ;; key bindings in Korean 42 | ;; full list on http://wttools.sourceforge.net/emacs-stuff/emacs-keybindings.html 43 | ;; movement keys binding w/ korean 44 | (global-set-key (kbd "C-ㅜ") 'next-line) 45 | (global-set-key (kbd "C-ㅔ") 'previous-line) 46 | (global-set-key (kbd "C-ㄹ") 'forward-char) 47 | (global-set-key (kbd "C-ㅠ") 'backward-char) 48 | (global-set-key (kbd "C-ㅇ") 'delete-forward-char) 49 | (global-set-key (kbd "C-ㅌ C-ㄴ") 'save-buffer) 50 | (global-set-key (kbd "C-ㅌ C-ㅊ") 'save-buffers-kill-emacs) 51 | (global-set-key (kbd "C-ㄴ") 'isearch-forward) 52 | (global-set-key (kbd "C-ㄱ") 'isearch-backward) 53 | (global-set-key (kbd "C-ㅎ") 'keyboard-quit) 54 | (global-set-key (kbd "C-ㅁ") 'beginning-of-line) 55 | (global-set-key (kbd "C-ㄷ") 'end-of-line) 56 | (global-set-key (kbd "C-ㅍ") 'scroll-up) 57 | (global-set-key (kbd "M-ㅍ") 'scroll-down) 58 | (global-set-key (kbd "C-ㅏ") 'kill-whole-line) 59 | (global-set-key (kbd "C-ㅈ") 'kill-region) 60 | (global-set-key (kbd "C-M-ㅏ") 'kill-sexp) 61 | (global-set-key (kbd "M-ㅈ") 'copy-region-as-kill-nomark) 62 | (global-set-key (kbd "C-ㅛ") 'yank) 63 | (global-set-key (kbd "C-ㅍ") 'scroll-up) 64 | (global-set-key (kbd "M-ㅍ") 'scroll-down) 65 | (global-set-key (kbd "C-ㅣ") 'recenter) 66 | (global-set-key (kbd "M-ㅂ") 'fill-paragraph) 67 | -------------------------------------------------------------------------------- /01-intro/misc/.vimrc: -------------------------------------------------------------------------------- 1 | " Use the Molokai theme (originally created for TextMate by Wimer Hazenberg) 2 | colorscheme default 3 | 4 | " Make Vim more useful 5 | set nocompatible 6 | " Use the OS clipboard by default (on versions compiled with `+clipboard`) 7 | set clipboard=unnamed 8 | " Enhance command-line completion 9 | set wildmenu 10 | " Allow cursor keys in insert mode 11 | set esckeys 12 | " Allow backspace in insert mode 13 | set backspace=indent,eol,start 14 | " Optimize for fast terminal connections 15 | set ttyfast 16 | " Add the g flag to search/replace by default 17 | set gdefault 18 | " Use UTF-8 without BOM 19 | set encoding=utf-8 nobomb 20 | " Change mapleader 21 | let mapleader="," 22 | " Don’t add empty newlines at the end of files 23 | set binary 24 | set noeol 25 | " Centralize backups, swapfiles and undo history 26 | set backupdir=~/.vim/backups 27 | set directory=~/.vim/swaps 28 | if exists("&undodir") 29 | set undodir=~/.vim/undo 30 | endif 31 | 32 | " Respect modeline in files 33 | set modeline 34 | set modelines=4 35 | " Enable per-directory .vimrc files and disable unsafe commands in them 36 | set exrc 37 | set secure 38 | " Enable line numbers 39 | set number 40 | " Enable syntax highlighting 41 | syntax on 42 | " Highlight current line 43 | "set cursorline 44 | " Make tabs as wide as two spaces 45 | set tabstop=4 46 | set shiftwidth=4 47 | " Show “invisible” characters 48 | set lcs=tab:▸\ ,trail:·,eol:¬,nbsp:_ 49 | set list 50 | " Highlight searches 51 | set hlsearch 52 | " Ignore case of searches 53 | set ignorecase 54 | " Highlight dynamically as pattern is typed 55 | set incsearch 56 | " Always show status line 57 | set laststatus=2 58 | " Format the status line 59 | set statusline=\ %{HasPaste()}%F%m%r%h\ %w\ \ CWD:\ %r%{getcwd()}%h\ \ \ Line:\ %l 60 | 61 | " Enable mouse in all modes 62 | set mouse=a 63 | " Disable error bells 64 | set noerrorbells 65 | " Don’t reset cursor to start of line when moving around. 66 | set nostartofline 67 | " Show the cursor position 68 | set ruler 69 | " Don’t show the intro message when starting Vim 70 | set shortmess=atI 71 | " Show the current mode 72 | set showmode 73 | " Show the filename in the window titlebar 74 | set title 75 | " Show the (partial) command as it’s being typed 76 | set showcmd 77 | " Use relative line numbers 78 | "if exists("&relativenumber") 79 | " set relativenumber 80 | " au BufReadPost * set relativenumber 81 | "endif 82 | " Start scrolling three lines before the horizontal window border 83 | set scrolloff=3 84 | 85 | " Strip trailing whitespace (,ss) 86 | function! StripWhitespace() 87 | let save_cursor = getpos(".") 88 | let old_query = getreg('/') 89 | :%s/\s\+$//e 90 | call setpos('.', save_cursor) 91 | call setreg('/', old_query) 92 | endfunction 93 | noremap ss :call StripWhitespace() 94 | " Save a file as root (,W) 95 | noremap W :w !sudo tee % > /dev/null 96 | 97 | " REQUIRED. This makes vim invoke Latex-Suite when you open a tex file. 98 | "filetype plugin on 99 | 100 | " Automatic commands 101 | if has("autocmd") 102 | " Enable file type detection 103 | filetype on 104 | " Treat .json files as .js 105 | autocmd BufNewFile,BufRead *.json setfiletype json syntax=javascript 106 | endif 107 | 108 | " IMPORTANT: grep will sometimes skip displaying the file name if you 109 | " search in a single file. This will confuse Latex-Suite. Set your grep 110 | " program to always generate a file-name. 111 | set grepprg=grep\ -nH\ $* 112 | 113 | " OPTIONAL: This enables automatic indentation as you type. 114 | "filetype indent on 115 | "set ai "Auto indent 116 | "set si "Smart indent 117 | 118 | " OPTIONAL: Starting with Vim 7, the filetype of empty .tex files defaults to 119 | " 'plaintex' instead of 'tex', which results in vim-latex not being loaded. 120 | " The following changes the default filetype back to 'tex': 121 | let g:tex_flavor='latex' 122 | 123 | " text wrap 124 | "set textwidth=80 125 | 126 | " Returns true if paste mode is enabled 127 | function! HasPaste() 128 | if &paste 129 | return 'PASTE MODE ' 130 | en 131 | return '' 132 | endfunction 133 | 134 | -------------------------------------------------------------------------------- /02-file_io/02-file_io.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/02-file_io/02-file_io.pdf -------------------------------------------------------------------------------- /02-file_io/Makefile: -------------------------------------------------------------------------------- 1 | texfile = 02-file_io.tex 2 | outdir=/tmp 3 | 4 | all: ${texfile} 5 | pdflatex --shell-escape --output-directory ${outdir} $< 6 | 7 | clean: 8 | rm *.aux *.log *.nav *.out *.snm *.toc *.vrb 9 | 10 | o: ${texfile} 11 | gv ${outdir}/$(basename $<).pdf & 12 | 13 | final: ${texfile} 14 | pdflatex --shell-escape --output-directory ${outdir} $< 15 | pdflatex --shell-escape --output-directory ${outdir} $< 16 | cp ${outdir}/$(basename $<).pdf . 17 | -------------------------------------------------------------------------------- /02-file_io/README.md: -------------------------------------------------------------------------------- 1 | This is for Class 2 of System Programming 2 | 3 | Visit following link for [Course description](http://resourceful.github.io/classes/2016-09-21-week3-class3-file/) -------------------------------------------------------------------------------- /02-file_io/codes/Makefile: -------------------------------------------------------------------------------- 1 | 2 | PROGRAMS = fdcount hole mycat setfl 3 | 4 | CFLAGS = -g -Wall -O0 5 | 6 | all: ${PROGRAMS} 7 | 8 | %.o: %.c 9 | ${CC} ${CFLAGS} -c $< 10 | 11 | ${PROGRAMS}: %: %.o 12 | ${CC} ${CFLAGS} -o $@ $< 13 | 14 | clean: 15 | rm -r ${PROGRAMS} *.o iotest testfiles ftest 16 | 17 | iotest: mycat.c testfiles 18 | for NUM in 1 64 256 512 2048 4096 16384 32768 65536 81920; do \ 19 | echo "BUFFSIZE = $$NUM"; \ 20 | cc -Wall -DBUFFSIZE=$$NUM -o $@ $< ; \ 21 | i=$$(( $$i + 1 )) ; \ 22 | time -p ./$@ < testfiles/temp_file > testfiles/file$$i.copy; \ 23 | echo; \ 24 | done; 25 | 26 | testfiles: 27 | mkdir -p testfiles 28 | dd if=/dev/urandom of=testfiles/temp_file count=104800; \ 29 | 30 | ftest: setfl.c testfiles 31 | for FLAGS in a b c d; do \ 32 | echo "FLAGS = $$FLAGS"; \ 33 | cc -Wall -o $@ $< ; \ 34 | time -p ./$@ -$$FLAGS < testfiles/temp_file > testfiles/file_$$FLAGS; \ 35 | echo ; \ 36 | done; 37 | 38 | -------------------------------------------------------------------------------- /02-file_io/codes/fdcount.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | // adopted from figure 2.17 in the text 10 | #ifdef OPEN_MAX 11 | static long openmax = OPEN_MAX; 12 | #else 13 | static long openmax = 0; 14 | #endif 15 | // If OPEN_MAX is indeterminate, this might be inadequate. 16 | #define OPEN_MAX_GUESS 256 17 | long open_max(void) 18 | { 19 | if (openmax == 0) { 20 | errno = 0; 21 | /* first time through */ 22 | if ((openmax = sysconf(_SC_OPEN_MAX)) < 0) { 23 | if (errno == 0) 24 | openmax = OPEN_MAX_GUESS; /* it is indeterminate */ 25 | else 26 | fprintf(stderr, "sysconf error for _SC_OPEN_MAX"); 27 | } 28 | } 29 | return(openmax); 30 | } 31 | 32 | int main(){ 33 | printf("The number of file decriptors a process can open: %d\n", (int)RLIMIT_NOFILE); 34 | printf("The number of file decriptors an user can open: %ld\n", openmax ); 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /02-file_io/codes/hole.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | char buf1[] = "abcdefghij"; 12 | char buf2[] = "ABCDEFGHIJ"; 13 | 14 | int 15 | main(void) 16 | { 17 | int fd; 18 | 19 | if ((fd = creat("file.hole", S_IRUSR | S_IWUSR )) < 0) 20 | perror("creat error"); 21 | 22 | if (write(fd, buf1, 10) != strlen(buf1)) 23 | perror("buf1 write error"); 24 | /* offset now = 10 */ 25 | 26 | if (lseek(fd, 16384, SEEK_SET) == -1) 27 | perror("lseek error"); 28 | /* offset now = 16384 */ 29 | 30 | if (write(fd, buf2, 10) != strlen(buf2)) 31 | perror("buf2 write error"); 32 | /* offset now = 16394 */ 33 | 34 | exit(0); 35 | } -------------------------------------------------------------------------------- /02-file_io/codes/mycat.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifndef BUFFSIZE 6 | #define BUFFSIZE 4096 7 | #endif 8 | 9 | int 10 | main(void) 11 | { 12 | int n; 13 | char buf[BUFFSIZE]; 14 | 15 | while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0){ 16 | if (write(STDOUT_FILENO, buf, n) != n){ 17 | fprintf(stderr, "write error\n"); 18 | exit(1); 19 | } 20 | } 21 | 22 | if (n < 0){ 23 | fprintf(stderr, "read error\n"); 24 | exit(1); 25 | } 26 | 27 | return(0); 28 | } 29 | -------------------------------------------------------------------------------- /02-file_io/codes/setfl.c: -------------------------------------------------------------------------------- 1 | /* simple-cat.c 2 | * Stripped down version of 'cat'. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define BUFFSIZE 512 12 | 13 | int 14 | main(int argc, char **argv) 15 | { 16 | int n, c; 17 | char buf[BUFFSIZE]; 18 | int flags; 19 | int osync_on = 0, fsync_on = 0, fdatasync_on = 0; 20 | 21 | if (argc < 2){ 22 | printf("usage: %s -{a|b|c|d} < LARGEFILE_IN > LARGEFILE_OUT \n", argv[0]); 23 | printf (" -a for add O_SYNC flag\n"); 24 | printf (" -b for removing O_SYNC flag\n"); 25 | printf (" -c for add fsync call\n"); 26 | printf (" -d for add fdatasync call (doesnot work in OSX)\n"); 27 | return 0; 28 | } 29 | while (( c = getopt (argc, argv, "abcdh")) != -1){ 30 | switch (c){ 31 | case 'a': 32 | printf("O_SYNC is on\n"); 33 | osync_on = 1; 34 | break; 35 | case 'b': 36 | printf("O_SYNC is off\n"); 37 | osync_on = 0; 38 | break; 39 | case 'c': 40 | printf("O_SYNC is off, writes are followed by fsync\n"); 41 | fsync_on = 1; 42 | break; 43 | case 'd': 44 | printf("O_SYNC is off, writes are followed by fdatasync\n"); 45 | fdatasync_on = 1; 46 | break; 47 | case 'h': 48 | printf("usage: %s -{a|b|c|d} < LARGEFILE_IN > LARGEFILE_OUT \n", argv[0]); 49 | printf ("Options are a, b, c, d\n"); 50 | printf (" -a for add O_SYNC flag\n"); 51 | printf (" -b for removing O_SYNC flag\n"); 52 | printf (" -c for add fsync call\n"); 53 | printf (" -d for add fdatasync call (doesnot work in OSX)\n"); 54 | return 0; 55 | case '?': 56 | if (isprint(optopt)) 57 | fprintf (stderr, "Unknown option `-%c'.\n", optopt); 58 | else 59 | fprintf (stderr, "Unknown option `\\x%x'.\n", optopt); 60 | return 1; 61 | default: 62 | abort (); 63 | } 64 | } 65 | if ((flags = fcntl(STDOUT_FILENO, F_GETFL, 0)) < 0) { 66 | perror("Can't get file descriptor flags"); 67 | exit(1); 68 | } 69 | 70 | if (osync_on == 1) 71 | flags |= O_SYNC; 72 | 73 | 74 | if (fcntl(STDOUT_FILENO, F_SETFL, flags) < 0) { 75 | perror("Can't set file descriptor flags"); 76 | exit(1); 77 | } 78 | 79 | while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0 ){ 80 | if ( write(STDOUT_FILENO, buf, n) != n ) { 81 | fprintf(stderr, "write error\n"); 82 | exit(1); 83 | } 84 | if (fsync_on == 1) 85 | fsync(STDOUT_FILENO); 86 | #ifdef __APPLE__ 87 | // fdatsync doesnot work on osx 88 | #else 89 | if (fdatasync_on == 1) 90 | fdatasync(STDOUT_FILENO); 91 | #endif 92 | } 93 | 94 | if (n < 0) { 95 | fprintf(stderr, "read error\n"); 96 | exit(1); 97 | } 98 | 99 | exit(0); 100 | } 101 | -------------------------------------------------------------------------------- /02-file_io/figure/fig-3-9_dup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/02-file_io/figure/fig-3-9_dup.png -------------------------------------------------------------------------------- /02-file_io/figure/fig3-7_kernel_DS_open_files.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/02-file_io/figure/fig3-7_kernel_DS_open_files.png -------------------------------------------------------------------------------- /02-file_io/figure/fig3-8_two_processes_open_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/02-file_io/figure/fig3-8_two_processes_open_file.png -------------------------------------------------------------------------------- /02-file_io/figure/iotest.data: -------------------------------------------------------------------------------- 1 | #BUFSz Time no 2 | 1 116.13 1 3 | 64 2.21 2 4 | 256 0.97 3 5 | 512 0.77 4 6 | 2048 0.62 5 7 | 4096 0.58 6 8 | 16384 0.54 7 9 | 32768 0.55 8 10 | 65536 0.57 9 11 | 81920 0.66 10 -------------------------------------------------------------------------------- /02-file_io/figure/iotest.gp: -------------------------------------------------------------------------------- 1 | reset 2 | set terminal pngcairo enhanced color font "Helvetica, 18" 3 | set output "iotest.png" 4 | set grid 5 | unset key 6 | set style data linespoint 7 | 8 | set xtics ("1" 1, "64" 2, "256" 3, "512" 4, "2048" 5, "4096" 6, "16384" 7, "32768" 8, "65536" 9, "81920" 10) rotate by -45 9 | set xlabel "Buffer Size" 10 | set ylabel "Time" 11 | 12 | set title "I/O Efficiency (Buffer Size Vs Time)" 13 | plot 'iotest.data' using 3:2 lt 1 dt 2 pt 3 14 | 15 | set output "iotest2.png" 16 | set yrange [0:1.8] 17 | plot 'iotest.data' using 3:2 lt 1 dt 2 pt 3 18 | -------------------------------------------------------------------------------- /02-file_io/figure/iotest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/02-file_io/figure/iotest.png -------------------------------------------------------------------------------- /02-file_io/figure/iotest2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/02-file_io/figure/iotest2.png -------------------------------------------------------------------------------- /02-file_io/figure/stream-pipe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/02-file_io/figure/stream-pipe.png -------------------------------------------------------------------------------- /03-file_dirs/03-file_dirs.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/03-file_dirs/03-file_dirs.pdf -------------------------------------------------------------------------------- /03-file_dirs/Makefile: -------------------------------------------------------------------------------- 1 | texfile = 03-file_dirs.tex 2 | outdir=/tmp 3 | 4 | all: ${texfile} 5 | pdflatex --shell-escape --output-directory ${outdir} $< 6 | 7 | clean: 8 | rm *.aux *.log *.nav *.out *.snm *.toc *.vrb 9 | 10 | o: ${texfile} 11 | gv ${outdir}/$(basename $<).pdf & 12 | 13 | final: ${texfile} 14 | pdflatex --shell-escape --output-directory ${outdir} $< 15 | pdflatex --shell-escape --output-directory ${outdir} $< 16 | cp ${outdir}/$(basename $<).pdf . 17 | -------------------------------------------------------------------------------- /03-file_dirs/README.md: -------------------------------------------------------------------------------- 1 | This is for Class 3 of System Programming 2 | 3 | Visit following link for [Course description](http://resourceful.github.io/classes/2016-09-27-week4-class4-filedirs/) 4 | 5 | -------------------------------------------------------------------------------- /03-file_dirs/codes/Makefile: -------------------------------------------------------------------------------- 1 | 2 | PROGRAMS = myls filetype access myumask mychmod myunlink futimens_ex chdir 3 | 4 | CFLAGS = -g -Wall -O0 5 | 6 | all: ${PROGRAMS} 7 | 8 | %.o: %.c 9 | ${CC} ${CFLAGS} -c $< 10 | 11 | ${PROGRAMS}: %: %.o 12 | ${CC} ${CFLAGS} -o $@ $< 13 | 14 | clean: 15 | rm -r ${PROGRAMS} *.o tempfile 16 | 17 | unlink: tempfile myunlink 18 | 19 | tempfile: 20 | echo "creats 500MB file" 21 | dd if=/dev/urandom of=tempfile count=1024000 22 | 23 | -------------------------------------------------------------------------------- /03-file_dirs/codes/access.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int 7 | main(int argc, char **argv) { 8 | 9 | if (argc != 2) { 10 | fprintf(stderr, "%s: Usage: %s filename\n", argv[0], argv[0]); 11 | exit(EXIT_FAILURE); 12 | } 13 | 14 | if (access(argv[1], R_OK) < 0) 15 | printf("access error for %s\n", argv[1]); 16 | else 17 | printf("access OK for %s\n", argv[1]); 18 | 19 | 20 | if (open(argv[1], O_RDONLY) < 0) 21 | printf("open error for %s\n", argv[1]); 22 | else 23 | printf("open for reading OK: %s\n", argv[1]); 24 | 25 | exit(EXIT_SUCCESS); 26 | } 27 | -------------------------------------------------------------------------------- /03-file_dirs/codes/chdir.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | #define MAXPATHLEN 512 8 | 9 | int 10 | main(int argc, char **argv) 11 | { 12 | char buf[MAXPATHLEN]; 13 | 14 | if (argc != 2) { 15 | fprintf(stderr, "%s: requires a directory!\n", argv[0]); 16 | return(EXIT_FAILURE); 17 | } 18 | 19 | if (chdir(argv[1]) < 0) { 20 | fprintf(stderr, "%s: unable to change directory to %s\n", 21 | argv[0], argv[1]); 22 | return(EXIT_FAILURE); 23 | } 24 | 25 | printf("CWD is now: %s\n", getcwd(buf, MAXPATHLEN)); 26 | 27 | if (system("ls -l") != 0) { 28 | perror("unable to run ls(1)"); 29 | exit(EXIT_FAILURE); 30 | } 31 | 32 | exit(EXIT_SUCCESS); 33 | } 34 | -------------------------------------------------------------------------------- /03-file_dirs/codes/filetype.c: -------------------------------------------------------------------------------- 1 | /* 2 | * usage: ./filetype ANY_FILE1 ANY_FILE2 ... 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | int 16 | main(int argc, char *argv[]) 17 | { 18 | int i; 19 | struct stat buf; 20 | char *ptr; 21 | 22 | for (i = 1; i < argc; i++) { 23 | printf("%s: ", argv[i]); 24 | if (lstat(argv[i], &buf) < 0) { 25 | fprintf(stderr,"Can't stat: %s\n", strerror(errno)); 26 | continue; 27 | } 28 | if (S_ISREG(buf.st_mode)) 29 | ptr = "regular"; 30 | else if (S_ISDIR(buf.st_mode)) 31 | ptr = "directory"; 32 | else if (S_ISCHR(buf.st_mode)) 33 | ptr = "character special"; 34 | else if (S_ISBLK(buf.st_mode)) 35 | ptr = "block special"; 36 | else if (S_ISFIFO(buf.st_mode)) 37 | ptr = "fifo"; 38 | else if (S_ISLNK(buf.st_mode)) 39 | ptr = "symbolic link"; 40 | else if (S_ISSOCK(buf.st_mode)) 41 | ptr = "socket"; 42 | else 43 | ptr = "** unknown mode **"; 44 | printf("%s\n", ptr); 45 | } 46 | exit(0); 47 | } 48 | -------------------------------------------------------------------------------- /03-file_dirs/codes/futimens_ex.c: -------------------------------------------------------------------------------- 1 | /* 2 | * code is broken 3 | */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | int 14 | main(int argc, char *argv[]) 15 | { 16 | int i, fd; 17 | struct stat statbuf; 18 | struct timespec time[2]; 19 | 20 | for (i = 1; i < argc; i++) { 21 | if (stat(argv[i], &statbuf) < 0) { /* fetch current times */ 22 | fprintf(stderr, "%s: stat error", argv[i]); 23 | continue; 24 | } 25 | if ((fd = open(argv[i], O_RDWR | O_TRUNC)) < 0) { /* truncate */ 26 | fprintf(stderr, "%s: open error", argv[i]); 27 | continue; 28 | } 29 | time[0].tv_sec = statbuf.st_atime; 30 | time[1].tv_sec = statbuf.st_mtime; 31 | #ifdef __APPLE__ 32 | /* futimens and utimensat doesnot work in some osx */ 33 | /* update to current time */ 34 | if (utimes( fd, time) < 0) 35 | #else 36 | if (futimens(fd, time) < 0) /* reset times */ 37 | #endif 38 | fprintf(stderr, "%s: futimens error", argv[i]); 39 | close(fd); 40 | } 41 | exit(0); 42 | } 43 | -------------------------------------------------------------------------------- /03-file_dirs/codes/mychmod.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Set umask to 077 and touch foo foo1, then run this command. 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | int 12 | main(int argc, char **argv) { 13 | struct stat statbuf; 14 | 15 | /* turn on set-group-ID and turn off group-execute */ 16 | if ( stat("foo", &statbuf) < 0 ) { 17 | fprintf(stderr, "can't stat foo\n"); 18 | exit(EXIT_FAILURE); 19 | } 20 | 21 | /* turn off group execute and turn on set-UID */ 22 | if ( chmod("foo", (statbuf.st_mode & ~S_IXGRP) | S_ISUID) == -1 ) { 23 | fprintf(stderr, "can't chmod foo\n"); 24 | exit(EXIT_FAILURE); 25 | } 26 | 27 | /* set absolute mode to rw-r--r-- */ 28 | if ( chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1 ) { 29 | fprintf(stderr, "can't chmod bar\n"); 30 | exit(EXIT_FAILURE); 31 | } 32 | 33 | exit(EXIT_SUCCESS); 34 | } 35 | -------------------------------------------------------------------------------- /03-file_dirs/codes/myls-s.c: -------------------------------------------------------------------------------- 1 | /* 2 | * myls.c 3 | * usage ./myls . 4 | * Objective - use this file as the basis for printing out various types of the 5 | * file. For example, whether it is a regular file or a directory file, etc. Hints are : , struct stat sb, and stat() S_ISXXX(); 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | int 19 | main(int argc, char **argv) { 20 | 21 | DIR *dp; 22 | struct dirent *dirp; 23 | 24 | struct stat sb; 25 | 26 | if (argc != 2) { 27 | fprintf(stderr, "usage: %s dir_name\n", argv[0]); 28 | exit(1); 29 | } 30 | 31 | if ((dp = opendir(argv[1])) == NULL ) { 32 | fprintf(stderr, "can't open '%s'\n", argv[1]); 33 | exit(1); 34 | } 35 | 36 | while ((dirp = readdir(dp)) != NULL ){ 37 | if (stat(dirp->d_name, &sb) < 0){ 38 | fprintf(stderr, "Can't stat %s: %s\n", dirp->d_name, 39 | strerror(errno)); 40 | } 41 | 42 | printf("%s\t", dirp->d_name); 43 | if(S_ISREG(sb.st_mode)) 44 | printf("regular file\n"); 45 | else if (S_ISDIR(sb.st_mode)) 46 | printf("directory\n"); 47 | else 48 | printf("unknown\n"); 49 | } 50 | 51 | closedir(dp); 52 | return(0); 53 | } 54 | -------------------------------------------------------------------------------- /03-file_dirs/codes/myls.c: -------------------------------------------------------------------------------- 1 | /* 2 | * myls.c 3 | * usage ./myls . 4 | * Objective - use this file as the basis for printing out various types of the 5 | * file. For example, whether it is a regular file or a directory file, etc. Hints are : , struct stat sb, and stat() S_ISXXX(); 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | int 15 | main(int argc, char **argv) { 16 | 17 | DIR *dp; 18 | struct dirent *dirp; 19 | 20 | if (argc != 2) { 21 | fprintf(stderr, "usage: %s dir_name\n", argv[0]); 22 | exit(1); 23 | } 24 | 25 | if ((dp = opendir(argv[1])) == NULL ) { 26 | fprintf(stderr, "can't open '%s'\n", argv[1]); 27 | exit(1); 28 | } 29 | 30 | while ((dirp = readdir(dp)) != NULL ) 31 | printf("%s\t", dirp->d_name); 32 | 33 | closedir(dp); 34 | return(0); 35 | } 36 | -------------------------------------------------------------------------------- /03-file_dirs/codes/myumask.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define RWRWRW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) 11 | 12 | int 13 | main(void) 14 | { 15 | umask(0); 16 | if (creat("foo", RWRWRW) < 0){ 17 | fprintf(stderr, "Unable to create foo\n"); 18 | exit(EXIT_FAILURE); 19 | } 20 | umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); 21 | if (creat("bar", RWRWRW) < 0){ 22 | fprintf(stderr, "creat error for bar"); 23 | exit(EXIT_FAILURE); 24 | } 25 | return EXIT_SUCCESS; 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /03-file_dirs/codes/myunlink.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int 10 | main(void) 11 | { 12 | if (open("tempfile", O_RDWR) < 0){ 13 | fprintf(stderr, "open error"); 14 | exit(EXIT_FAILURE); 15 | } 16 | 17 | if (unlink("tempfile") < 0){ 18 | fprintf(stderr, "unlink error"); 19 | exit(EXIT_FAILURE); 20 | } 21 | 22 | printf("file unlinked\n"); 23 | sleep(15); 24 | printf("done\n"); 25 | exit(0); 26 | } 27 | -------------------------------------------------------------------------------- /03-file_dirs/figure/fig4_13_disk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/03-file_dirs/figure/fig4_13_disk.png -------------------------------------------------------------------------------- /03-file_dirs/figure/fig4_14_cylinder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/03-file_dirs/figure/fig4_14_cylinder.png -------------------------------------------------------------------------------- /03-file_dirs/figure/fig4_15_sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/03-file_dirs/figure/fig4_15_sample.png -------------------------------------------------------------------------------- /03-file_dirs/figure/fig4_20_effect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/03-file_dirs/figure/fig4_20_effect.png -------------------------------------------------------------------------------- /04-sysfile_info/04-sysfile_info.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/04-sysfile_info/04-sysfile_info.pdf -------------------------------------------------------------------------------- /04-sysfile_info/Makefile: -------------------------------------------------------------------------------- 1 | texfile = 04-sysfile_info.tex 2 | outdir=/tmp 3 | 4 | all: ${texfile} 5 | pdflatex --shell-escape --output-directory ${outdir} $< 6 | 7 | clean: 8 | rm *.aux *.log *.nav *.out *.snm *.toc *.vrb 9 | 10 | o: ${texfile} 11 | gv ${outdir}/$(basename $<).pdf & 12 | 13 | final: ${texfile} 14 | pdflatex --shell-escape --output-directory ${outdir} $< 15 | pdflatex --shell-escape --output-directory ${outdir} $< 16 | cp ${outdir}/$(basename $<).pdf . 17 | 18 | -------------------------------------------------------------------------------- /04-sysfile_info/README.md: -------------------------------------------------------------------------------- 1 | This is for Class 4 of System Programming 2 | 3 | Visit following link for [Course description](http://resourceful.github.io/classes/2016-10-03-week5-class5-system/) 4 | 5 | -------------------------------------------------------------------------------- /04-sysfile_info/codes/Makefile: -------------------------------------------------------------------------------- 1 | 2 | PROGRAMS = strftime exit_handlers echoall 3 | 4 | CFLAGS = -g -Wall -O0 5 | 6 | all: ${PROGRAMS} 7 | 8 | %.o: %.c 9 | ${CC} ${CFLAGS} -c $< 10 | 11 | ${PROGRAMS}: %: %.o 12 | ${CC} ${CFLAGS} -o $@ $< 13 | 14 | clean: 15 | rm -r ${PROGRAMS} *.o hello 16 | 17 | hello: hello.o 18 | ${CC} -nostartfiles -o $@ $< -e my_main 19 | -------------------------------------------------------------------------------- /04-sysfile_info/codes/echoall.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int 5 | main(int argc, char *argv[]) 6 | { 7 | int i; 8 | for (i = 0; i < argc; i++) 9 | /* echo all command-line args */ 10 | printf("argv[%d]: %s\n", i, argv[i]); 11 | exit(0); 12 | } -------------------------------------------------------------------------------- /04-sysfile_info/codes/exit_handlers.c: -------------------------------------------------------------------------------- 1 | /* At least 32 exit handlers are pushed onto a stack and they are execute in 2 | * reverse order. 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | int cnt; 9 | 10 | void 11 | my_exit1(void) { 12 | printf("first exit handler: %d\n", cnt); 13 | cnt++; 14 | } 15 | 16 | void my_exit2(void) { 17 | printf("second exit handler: %d\n", cnt); 18 | } 19 | 20 | 21 | int 22 | main(int argc, char **argv) { 23 | cnt = 0; 24 | if (atexit(my_exit2) != 0) { 25 | perror("can't register my_exit2\n"); 26 | exit(1); 27 | } 28 | 29 | if (atexit(my_exit1) != 0) { 30 | perror("can't register my_exit1"); 31 | exit(1); 32 | } 33 | 34 | if (atexit(my_exit1) != 0) { 35 | perror("can't register my_exit1"); 36 | exit(1); 37 | } 38 | 39 | printf("End of main\n"); 40 | 41 | return(0); 42 | } 43 | -------------------------------------------------------------------------------- /04-sysfile_info/codes/foo.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | printf("Hello World\n"); 5 | } 6 | -------------------------------------------------------------------------------- /04-sysfile_info/codes/foobar.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char *argv[]) { 4 | printf("Hello World\n"); 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /04-sysfile_info/codes/foobar.patch: -------------------------------------------------------------------------------- 1 | --- foo.c 2016-09-30 17:04:42.000000000 +0900 2 | +++ foobar.c 2016-09-30 17:05:03.000000000 +0900 3 | @@ -1,5 +1,6 @@ 4 | -#include 5 | +#include 6 | 7 | -int main() { 8 | +int main(int argc, char *argv[]) { 9 | printf("Hello World\n"); 10 | -} 11 | +return 0; 12 | +} 13 | -------------------------------------------------------------------------------- /04-sysfile_info/codes/getpwnam.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct passwd * 6 | getpwnam(const char *name) 7 | { 8 | struct passwd *ptr; 9 | 10 | setpwent(); 11 | while ((ptr = getpwent()) != NULL) 12 | if (strcmp(name, ptr->pw_name) == 0) 13 | break; /* found a match */ 14 | endpwent(); 15 | return(ptr); /* ptr is NULL if no match found */ 16 | } -------------------------------------------------------------------------------- /04-sysfile_info/codes/hello.c: -------------------------------------------------------------------------------- 1 | /* 2 | * compile with following line 3 | * cc -nostartfiles -o hello hello.c -e _my_main 4 | * this example serves two purposes. 5 | * First, it shows that main() is nothing but an term to start the code which 6 | * is used by C Library. main() is linked with _start() fuction in GNU C 7 | * library in linking process. 8 | * Second, press ^C after hello, world is on the screen, and examine the exit 9 | * status with $? 10 | * Is it different from normal exit? 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | int my_main() 18 | { 19 | printf("hello, world\n"); 20 | sleep(5); 21 | return 0; 22 | } 23 | 24 | void _start() 25 | { 26 | int ret = my_main(); 27 | exit(ret); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /04-sysfile_info/codes/layout.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | printf("hello world\n"); 6 | return 0; 7 | } -------------------------------------------------------------------------------- /04-sysfile_info/codes/sample_passwd: -------------------------------------------------------------------------------- 1 | root:x:0:0:root:/root:/bin/bash 2 | squid:x:23:23::/var/spool/squid:/dev/null 3 | nobody:x:65534:65534:Nobody:/home:/bin/sh 4 | sar:x:205:105:Stephen Rago:/home/sar:/bin/bash 5 | -------------------------------------------------------------------------------- /04-sysfile_info/codes/skel_cmd.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define TOK_ADD 5 5 | #define MAXLINE 4096 6 | void do_line(char *); 7 | void cmd_add(void); 8 | int get_token(void); 9 | 10 | int 11 | main(void) 12 | { 13 | char line[MAXLINE]; 14 | 15 | while (fgets(line, MAXLINE, stdin) != NULL) 16 | do_line(line); 17 | exit(0); 18 | } 19 | 20 | char *tok_ptr; /* global pointer for get_token() */ 21 | 22 | void 23 | do_line(char *ptr) /* process one line of input */ 24 | { 25 | int cmd; 26 | 27 | tok_ptr = ptr; 28 | while ((cmd = get_token()) > 0) { 29 | switch (cmd) { /* one case for each command */ 30 | case TOK_ADD: 31 | cmd_add(); 32 | break; 33 | } 34 | } 35 | } 36 | 37 | void 38 | cmd_add(void) 39 | { 40 | int token; 41 | 42 | token = get_token(); 43 | /* rest of processing for this command */ 44 | } 45 | 46 | int 47 | get_token(void) 48 | { 49 | /* fetch next token from line pointed to by tok_ptr */ 50 | } 51 | -------------------------------------------------------------------------------- /04-sysfile_info/codes/strftime.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int 6 | main(void) 7 | { 8 | time_t t; 9 | struct tm *tmp; 10 | char buf1[16]; 11 | char buf2[64]; 12 | 13 | time(&t); 14 | tmp = localtime(&t); 15 | if (strftime(buf1, 16, "time and date: %r, %a %b %d, %Y", tmp) == 0) 16 | printf("buffer length 16 is too small\n"); 17 | else 18 | printf("%s\n", buf1); 19 | if (strftime(buf2, 64, "time and date: %r, %a %b %d, %Y", tmp) == 0) 20 | printf("buffer length 64 is too small\n"); 21 | else 22 | printf("%s\n", buf2); 23 | 24 | exit(0); 25 | } -------------------------------------------------------------------------------- /04-sysfile_info/figure/fig6-1_etc_passwd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/04-sysfile_info/figure/fig6-1_etc_passwd.png -------------------------------------------------------------------------------- /04-sysfile_info/figure/fig6-4_group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/04-sysfile_info/figure/fig6-4_group.png -------------------------------------------------------------------------------- /04-sysfile_info/figure/fig6-6_similar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/04-sysfile_info/figure/fig6-6_similar.png -------------------------------------------------------------------------------- /04-sysfile_info/figure/fig6-8_clock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/04-sysfile_info/figure/fig6-8_clock.png -------------------------------------------------------------------------------- /04-sysfile_info/figure/fig6-9_relationship.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/04-sysfile_info/figure/fig6-9_relationship.png -------------------------------------------------------------------------------- /04-sysfile_info/figure/fig7-2_how_prog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/04-sysfile_info/figure/fig7-2_how_prog.png -------------------------------------------------------------------------------- /04-sysfile_info/figure/fig7-5_environment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/04-sysfile_info/figure/fig7-5_environment.png -------------------------------------------------------------------------------- /04-sysfile_info/figure/fig7-7_environment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/04-sysfile_info/figure/fig7-7_environment.png -------------------------------------------------------------------------------- /05-process/05-process.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/05-process/05-process.pdf -------------------------------------------------------------------------------- /05-process/Makefile: -------------------------------------------------------------------------------- 1 | texfile = 05-process.tex 2 | outdir=/tmp 3 | 4 | all: ${texfile} 5 | pdflatex --shell-escape --output-directory ${outdir} $< 6 | 7 | clean: 8 | rm *.aux *.log *.nav *.out *.snm *.toc *.vrb 9 | 10 | o: ${texfile} 11 | gv ${outdir}/$(basename $<).pdf & 12 | 13 | final: ${texfile} 14 | pdflatex --shell-escape --output-directory ${outdir} $< 15 | pdflatex --shell-escape --output-directory ${outdir} $< 16 | cp ${outdir}/$(basename $<).pdf . 17 | 18 | -------------------------------------------------------------------------------- /05-process/README.md: -------------------------------------------------------------------------------- 1 | This is for Class 5 of System Programming 2 | 3 | Visit following link for [Course description](http://resourceful.github.io/classes/2016-10-10-week6-class6-process-control/) 4 | 5 | -------------------------------------------------------------------------------- /05-process/codes/Makefile: -------------------------------------------------------------------------------- 1 | 2 | PROGRAMS = fork zombies exit_stat avoid_zombie race_cond exec echoall interp echoarg system tsys pruid nice 3 | 4 | CFLAGS = -g -Wall -O0 5 | 6 | all: ${PROGRAMS} 7 | 8 | %.o: %.c 9 | ${CC} ${CFLAGS} -c $< 10 | 11 | ${PROGRAMS}: %: %.o 12 | ${CC} ${CFLAGS} -o $@ $< 13 | 14 | clean: 15 | rm -r ${PROGRAMS} *.o hello 16 | 17 | hello: hello.o 18 | ${CC} -nostartfiles -o $@ $< -e my_main 19 | -------------------------------------------------------------------------------- /05-process/codes/avoid_zombie.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int 7 | main(int argc, char **argv) 8 | { 9 | pid_t pid; 10 | printf("this is parent, pid = %d\n", getpid()); 11 | if ((pid = fork()) < 0) { 12 | fprintf(stderr, "fork error"); 13 | } else if (pid == 0) { 14 | if ((pid = fork()) < 0) /* first child */ 15 | fprintf(stderr, "fork error"); 16 | else if (pid > 0){ 17 | printf("this is first child(%d) exiting\n", getpid()); 18 | exit(0); /* parent from second fork == first child */ 19 | } 20 | /* 21 | * We’re the second child; our parent becomes init as soon 22 | * as our real parent calls exit() in the statement above. 23 | * Here’s where we’d continue executing, knowing that when 24 | * we’re done, init will reap our status. 25 | */ 26 | sleep(2); 27 | printf("second child(%ld), parent pid = %ld\n", 28 | (long)getpid(), (long)getppid()); 29 | exit(0); 30 | } 31 | 32 | printf("this is parent(%d) waiting for child %d\n", getpid(), pid); 33 | if (waitpid(pid, NULL, 0) != pid) /* wait for first child */ 34 | fprintf(stderr, "waitpid error"); 35 | /* 36 | * We’re the parent (the original process); we continue executing, 37 | * knowing that we’re not the parent of the second child. 38 | */ 39 | exit(0); 40 | } -------------------------------------------------------------------------------- /05-process/codes/awkexample: -------------------------------------------------------------------------------- 1 | #!/usr/bin/awk -f 2 | 3 | BEGIN { 4 | for ( i = 0; i < ARGC; i++) 5 | printf "ARGV[%d] = %s \n", i, ARGV[i] 6 | exit 7 | } 8 | -------------------------------------------------------------------------------- /05-process/codes/echoall.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int 5 | main(int argc, char *argv[]) 6 | { 7 | int i; 8 | char **ptr; 9 | extern char **environ; 10 | for (i = 0; i < argc; i++) 11 | printf("argv[%d]: %s\n", i, argv[i]); 12 | for (ptr = environ; *ptr != 0; ptr++) /* and all env strings */ 13 | printf("%s\n", *ptr); 14 | exit(0); 15 | } -------------------------------------------------------------------------------- /05-process/codes/echoarg.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int 5 | main(int argc, char **argv) 6 | { 7 | int i; 8 | for(i = 0 ; i < argc ; i++) /* echo all command-line args */ 9 | printf("argv[%d]: %s \n", i, argv[i]); 10 | exit(0); 11 | } -------------------------------------------------------------------------------- /05-process/codes/exec.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | char *env_init[] = { "USER=unknown", "PATH=/tmp", NULL }; 8 | 9 | int 10 | main(int argc, char **argv) 11 | { 12 | pid_t pid; 13 | 14 | if ((pid = fork()) < 0) { 15 | fprintf(stderr, "fork error\n"); 16 | } else if (pid == 0) { /* specify pathname, specify environment */ 17 | if (execle("/Users/James/_projects/class_systemProgramming_2016/lecture_sysprog/05_process/codes/echoall", "echoall", "myarg1", 18 | "MY ARG2", (char *)0, env_init) < 0){ 19 | fprintf(stderr, "execle error\n"); 20 | printf("#### First fork ended\n"); 21 | } 22 | } 23 | 24 | if (waitpid(pid, NULL, 0) < 0) 25 | fprintf(stderr, "wait error\n"); 26 | 27 | if ((pid = fork()) < 0) { 28 | fprintf(stderr, "fork error\n"); 29 | } else if (pid == 0) { /* specify filename, inherit environment */ 30 | if (execlp("./echoall", "echoall", "only 1 arg", (char *)0) < 0) 31 | fprintf(stderr, "execlp error\n"); 32 | } 33 | 34 | exit(0); 35 | } -------------------------------------------------------------------------------- /05-process/codes/exit_stat.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void 7 | pr_exit(int status) 8 | { 9 | if (WIFEXITED(status)) 10 | printf("normal termination, exit status = %d\n", WEXITSTATUS(status)); 11 | else if (WIFSIGNALED(status)) 12 | printf("abnormal termination, signal number = %d%s\n", WTERMSIG(status), 13 | #ifdef WCOREDUMP 14 | WCOREDUMP(status) ? " (core file generated)" : ""); 15 | #else 16 | ""); 17 | #endif 18 | else if (WIFSTOPPED(status)) 19 | printf("child stopped, singal number = %d\n", WSTOPSIG(status)); 20 | } 21 | 22 | 23 | int 24 | main(int argc, char **argv) 25 | { 26 | pid_t pid; 27 | int status; 28 | if ((pid = fork()) < 0) 29 | fprintf(stderr, "fork error"); 30 | else if (pid == 0) /* child */ 31 | exit(7); 32 | 33 | if (wait(&status) != pid) /* wait for child */ 34 | fprintf(stderr, "wait error"); 35 | pr_exit(status); /* and print its status */ 36 | 37 | if ((pid = fork()) < 0) 38 | fprintf(stderr, "fork error"); 39 | else if (pid == 0) /* child */ 40 | abort(); /* generates SIGABRT */ 41 | 42 | if (wait(&status) != pid) /* wait for child */ 43 | fprintf(stderr, "wait error"); 44 | pr_exit(status); /* and print its status */ 45 | 46 | if ((pid = fork()) < 0) 47 | fprintf(stderr, "fork error"); 48 | else if (pid == 0) /* child */ 49 | status /= 0; /* divide by 0 generates SIGFPE */ 50 | 51 | if (wait(&status) != pid) /* wait for child */ 52 | fprintf(stderr, "wait error"); 53 | pr_exit(status); /* and print its status */ 54 | 55 | exit(0); 56 | } -------------------------------------------------------------------------------- /05-process/codes/fork.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int gvar = 6; // external variable in initialized data 8 | char buf[] = "a write to stdout\n"; 9 | 10 | int 11 | main(int argc, char **argv) { 12 | int var; // automatic variable on the stack 13 | pid_t pid; 14 | 15 | var = 88; 16 | if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1) { 17 | fprintf(stderr, "%s: write error: %s\n", argv[0], strerror(errno)); 18 | exit(1); 19 | } 20 | printf("before fork\n"); // we don't flush stdout 21 | 22 | if ((pid = fork()) < 0) { 23 | fprintf(stderr, "%s: fork error: %s\n", argv[0], strerror(errno)); 24 | exit(1); 25 | } else if (pid == 0) { // child 26 | gvar++; // modify variables 27 | var++; 28 | } else { // parent 29 | sleep(2); 30 | } 31 | 32 | printf("pid = %d, gvar = %d, var = %d\n", getpid(), gvar, var); 33 | exit(0); 34 | } 35 | -------------------------------------------------------------------------------- /05-process/codes/interp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int 8 | main(int argc, char **argv) 9 | { 10 | pid_t pid; 11 | if ((pid = fork()) < 0) { 12 | fprintf(stderr, "fork error\n"); 13 | } else if (pid == 0) { /* child */ 14 | if (execl("/Users/James/_projects/class_systemProgramming_2016/lecture_sysprog/05_process/codes/testinterp", 15 | //if (execl("echoarg", 16 | "testinterp", "myarg1", "MY ARG2", (char *)0) < 0) 17 | fprintf(stderr, "execl error (%d)\n", errno); 18 | } 19 | if (waitpid(pid, NULL, 0) < 0) /* parent */ 20 | fprintf(stderr, "waitpid error\n"); 21 | exit(0); 22 | } -------------------------------------------------------------------------------- /05-process/codes/master_fork.c: -------------------------------------------------------------------------------- 1 | /* 2 | * * forks.c - Examples of Unix process control 3 | * */ 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | /* 12 | * * fork0 - The simplest fork example 13 | * * Call once, return twice 14 | * * Creates child that is identical to parent 15 | * * Returns 0 to child process 16 | * * Returns child PID to parent process 17 | * */ 18 | void fork0() 19 | { 20 | if (fork() == 0) { 21 | printf("Hello from child\n"); 22 | } 23 | else { 24 | printf("Hello from parent\n"); 25 | } 26 | } 27 | 28 | /* 29 | * * fork1 - Simple fork example 30 | * * Parent and child both run same code 31 | * * Child starts with identical private state 32 | * */ 33 | void fork1() 34 | { 35 | int x = 1; 36 | pid_t pid = fork(); 37 | 38 | if (pid == 0) { 39 | printf("Child has x = %d\n", ++x); 40 | } 41 | else { 42 | printf("Parent has x = %d\n", --x); 43 | } 44 | printf("Bye from process %d with x = %d\n", getpid(), x); 45 | } 46 | 47 | /* 48 | * * fork2 - Two consecutive forks 49 | * * Both parent and child can continue forking 50 | * * Ordering undetermined 51 | * */ 52 | void fork2() 53 | { 54 | printf("L0\n"); 55 | fork(); 56 | printf("L1\n"); 57 | fork(); 58 | printf("Bye\n"); 59 | } 60 | 61 | 62 | /* 63 | * * fork3 - Three consective forks 64 | * * Parent and child can continue forking 65 | * */ 66 | void fork3() 67 | { 68 | printf("L0\n"); 69 | fork(); 70 | printf("L1\n"); 71 | fork(); 72 | printf("L2\n"); 73 | fork(); 74 | printf("Bye\n"); 75 | } 76 | 77 | /* 78 | * * fork4 - Nested forks in parents 79 | * */ 80 | void fork4() 81 | { 82 | printf("L0\n"); 83 | if (fork() != 0) { 84 | printf("L1\n"); 85 | if (fork() != 0) { 86 | printf("L2\n"); 87 | fork(); 88 | } 89 | } 90 | printf("Bye\n"); 91 | } 92 | 93 | /* 94 | * * fork5 - Nested forks in children 95 | * */ 96 | void fork5() 97 | { 98 | printf("L0\n"); 99 | if (fork() == 0) { 100 | printf("L1\n"); 101 | if (fork() == 0) { 102 | printf("L2\n"); 103 | fork(); 104 | } 105 | } 106 | printf("Bye\n"); 107 | } 108 | 109 | void cleanup(void) { 110 | printf("Cleaning up\n"); 111 | } 112 | 113 | /* 114 | * * fork6 - Exit system call terminates process 115 | * * call once, return never 116 | * */ 117 | void fork6() 118 | { 119 | atexit(cleanup); 120 | fork(); 121 | exit(0); 122 | } 123 | 124 | /* 125 | * * fork7 - Demonstration of zombies. 126 | * * Run in background and then perform ps 127 | * */ 128 | void fork7() 129 | { 130 | if (fork() == 0) { 131 | /* Child */ 132 | printf("Terminating Child, PID = %d\n", getpid()); 133 | exit(0); 134 | } else { 135 | printf("Running Parent, PID = %d\n", getpid()); 136 | while (1) 137 | ; /* Infinite loop */ 138 | } 139 | } 140 | 141 | /* 142 | * * fork8 - Demonstration of nonterminating child. 143 | * * Child still running even though parent terminated 144 | * * Must kill explicitly 145 | * */ 146 | void fork8() 147 | { 148 | if (fork() == 0) { 149 | /* Child */ 150 | printf("Running Child, PID = %d\n", 151 | getpid()); 152 | while (1) 153 | ; /* Infinite loop */ 154 | } else { 155 | printf("Terminating Parent, PID = %d\n", 156 | getpid()); 157 | exit(0); 158 | } 159 | } 160 | 161 | /* 162 | * * fork9 - synchronizing with and reaping children (wait) 163 | * */ 164 | void fork9() 165 | { 166 | int child_status; 167 | 168 | if (fork() == 0) { 169 | printf("HC: hello from child\n"); 170 | } else { 171 | printf("HP: hello from parent\n"); 172 | wait(&child_status); 173 | printf("CT: child has terminated\n"); 174 | } 175 | printf("Bye\n"); 176 | } 177 | 178 | #define N 5 179 | /* 180 | * * fork10 - Synchronizing with multiple children (wait) 181 | * * Reaps children in arbitrary order 182 | * * WIFEXITED and WEXITSTATUS to get info about terminated children 183 | * */ 184 | void fork10() 185 | { 186 | pid_t pid[N]; 187 | int i, child_status; 188 | 189 | for (i = 0; i < N; i++) 190 | if ((pid[i] = fork()) == 0) { 191 | exit(100+i); /* Child */ 192 | } 193 | for (i = 0; i < N; i++) { /* Parent */ 194 | pid_t wpid = wait(&child_status); 195 | if (WIFEXITED(child_status)) 196 | printf("Child %d terminated with exit status %d\n", 197 | wpid, WEXITSTATUS(child_status)); 198 | else 199 | printf("Child %d terminate abnormally\n", wpid); 200 | } 201 | } 202 | 203 | /* 204 | * * fork11 - Using waitpid to reap specific children 205 | * * Reaps children in order 206 | * */ 207 | void fork11() 208 | { 209 | pid_t pid[N]; 210 | int i; 211 | int child_status; 212 | 213 | for (i = 0; i < N; i++) 214 | if ((pid[i] = fork()) == 0) 215 | exit(100+i); /* Child */ 216 | for (i = 0; i < N; i++) { 217 | pid_t wpid = waitpid(pid[i], &child_status, 0); 218 | if (WIFEXITED(child_status)) 219 | printf("Child %d terminated with exit status %d\n", 220 | wpid, WEXITSTATUS(child_status)); 221 | else 222 | printf("Child %d terminate abnormally\n", wpid); 223 | } 224 | } 225 | 226 | 227 | /********* 228 | * * Signals 229 | * *********/ 230 | 231 | /* 232 | * * fork12 - Sending signals with the kill() function 233 | * */ 234 | void fork12() 235 | { 236 | pid_t pid[N]; 237 | int i; 238 | int child_status; 239 | 240 | for (i = 0; i < N; i++) 241 | if ((pid[i] = fork()) == 0) { 242 | /* Child: Infinite Loop */ 243 | while(1) 244 | ; 245 | } 246 | for (i = 0; i < N; i++) { 247 | printf("Killing process %d\n", pid[i]); 248 | kill(pid[i], SIGINT); 249 | } 250 | 251 | for (i = 0; i < N; i++) { 252 | pid_t wpid = wait(&child_status); 253 | if (WIFEXITED(child_status)) 254 | printf("Child %d terminated with exit status %d\n", 255 | wpid, WEXITSTATUS(child_status)); 256 | else 257 | printf("Child %d terminated abnormally\n", wpid); 258 | } 259 | } 260 | 261 | /* 262 | * * int_handler - SIGINT handler 263 | * */ 264 | void int_handler(int sig) 265 | { 266 | printf("Process %d received signal %d\n", getpid(), sig); 267 | exit(0); 268 | } 269 | 270 | /* 271 | * * fork13 - Simple signal handler example 272 | * */ 273 | void fork13() 274 | { 275 | pid_t pid[N]; 276 | int i; 277 | int child_status; 278 | 279 | signal(SIGINT, int_handler); 280 | for (i = 0; i < N; i++) 281 | if ((pid[i] = fork()) == 0) { 282 | /* Child: Infinite Loop */ 283 | while(1) 284 | ; 285 | } 286 | 287 | for (i = 0; i < N; i++) { 288 | printf("Killing process %d\n", pid[i]); 289 | kill(pid[i], SIGINT); 290 | } 291 | 292 | for (i = 0; i < N; i++) { 293 | pid_t wpid = wait(&child_status); 294 | if (WIFEXITED(child_status)) 295 | printf("Child %d terminated with exit status %d\n", 296 | wpid, WEXITSTATUS(child_status)); 297 | else 298 | printf("Child %d terminated abnormally\n", wpid); 299 | } 300 | } 301 | 302 | 303 | /* 304 | * * child_handler - SIGCHLD handler that reaps one terminated child 305 | * */ 306 | int ccount = 0; 307 | void child_handler(int sig) 308 | { 309 | int child_status; 310 | pid_t pid = wait(&child_status); 311 | ccount--; 312 | printf("Received SIGCHLD signal %d for process %d\n", sig, pid); 313 | } 314 | 315 | /* 316 | * * fork14 - Signal funkiness: Pending signals are not queued 317 | * */ 318 | void fork14() 319 | { 320 | pid_t pid[N]; 321 | int i; 322 | ccount = N; 323 | signal(SIGCHLD, child_handler); 324 | 325 | for (i = 0; i < N; i++) { 326 | if ((pid[i] = fork()) == 0) { 327 | exit(0); /* Child: Exit */ 328 | } 329 | } 330 | while (ccount > 0) 331 | pause(); 332 | } 333 | 334 | 335 | /* 336 | * * child_handler2 - SIGCHLD handler that reaps all terminated children 337 | * */ 338 | void child_handler2(int sig) 339 | { 340 | int child_status; 341 | pid_t pid; 342 | while ((pid = wait(&child_status)) > 0) { 343 | ccount--; 344 | printf("Received signal %d from process %d\n", sig, pid); 345 | } 346 | } 347 | 348 | /* 349 | * * fork15 - Using a handler that reaps multiple children 350 | * */ 351 | void fork15() 352 | { 353 | pid_t pid[N]; 354 | int i; 355 | ccount = N; 356 | 357 | signal(SIGCHLD, child_handler2); 358 | 359 | for (i = 0; i < N; i++) 360 | if ((pid[i] = fork()) == 0) { 361 | /* Child: Exit */ 362 | exit(0); 363 | } 364 | while (ccount > 0) { 365 | pause(); 366 | } 367 | } 368 | 369 | /* 370 | * * fork16 - Demonstration of using /bin/kill program 371 | * */ 372 | void fork16() 373 | { 374 | if (fork() == 0) { 375 | printf("Child1: pid=%d pgrp=%d\n", 376 | getpid(), getpgrp()); 377 | if (fork() == 0) 378 | printf("Child2: pid=%d pgrp=%d\n", 379 | getpid(), getpgrp()); 380 | while(1); 381 | } 382 | } 383 | 384 | /* 385 | * * Demonstration of using ctrl-c and ctrl-z 386 | * */ 387 | void fork17() 388 | { 389 | if (fork() == 0) { 390 | printf("Child: pid=%d pgrp=%d\n", 391 | getpid(), getpgrp()); 392 | } 393 | else { 394 | printf("Parent: pid=%d pgrp=%d\n", 395 | getpid(), getpgrp()); 396 | } 397 | while(1); 398 | } 399 | 400 | 401 | int main(int argc, char *argv[]) 402 | { 403 | int option = 0; 404 | if (argc > 1) 405 | option = atoi(argv[1]); 406 | switch(option) { 407 | case 0: fork0(); 408 | break; 409 | case 1: fork1(); 410 | break; 411 | case 2: fork2(); 412 | break; 413 | case 3: fork3(); 414 | break; 415 | case 4: fork4(); 416 | break; 417 | case 5: fork5(); 418 | break; 419 | case 6: fork6(); 420 | break; 421 | case 7: fork7(); 422 | break; 423 | case 8: fork8(); 424 | break; 425 | case 9: fork9(); 426 | break; 427 | case 10: fork10(); 428 | break; 429 | case 11: fork11(); 430 | break; 431 | case 12: fork12(); 432 | break; 433 | case 13: fork13(); 434 | break; 435 | case 14: fork14(); 436 | break; 437 | case 15: fork15(); 438 | break; 439 | case 16: fork16(); 440 | break; 441 | case 17: fork17(); 442 | break; 443 | default: 444 | printf("Unknown option %d\n", option); 445 | break; 446 | } 447 | return 0; 448 | } 449 | -------------------------------------------------------------------------------- /05-process/codes/nice.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #if defined(MACOS) 9 | #include 10 | #elif defined(SOLARIS) 11 | #include 12 | #elif defined(BSD) 13 | #include 14 | #endif 15 | 16 | unsigned long long count; 17 | struct timeval end; 18 | 19 | void 20 | checktime(char *str) 21 | { 22 | struct timeval tv; 23 | 24 | gettimeofday(&tv, NULL); 25 | if (tv.tv_sec >= end.tv_sec && tv.tv_usec >= end.tv_usec) { 26 | printf("%s count = %lld\n", str, count); 27 | exit(0); 28 | } 29 | } 30 | 31 | int 32 | main(int argc, char *argv[]) 33 | { 34 | pid_t pid; 35 | char *s = NULL; 36 | int nzero, ret; 37 | int adj = 0; 38 | 39 | setbuf(stdout, NULL); 40 | #if defined(NZERO) 41 | nzero = NZERO; 42 | #elif defined(_SC_NZERO) 43 | nzero = sysconf(_SC_NZERO); 44 | #else 45 | //#error NZERO undefined 46 | #define NZERO 20 47 | nzero= NZERO; 48 | #endif 49 | printf("NZERO = %d\n", nzero); 50 | if (argc == 2) 51 | adj = strtol(argv[1], NULL, 10); 52 | gettimeofday(&end, NULL); 53 | end.tv_sec += 10; /* run for 10 seconds */ 54 | 55 | if ((pid = fork()) < 0) { 56 | fprintf(stderr, "fork failed"); 57 | } else if (pid == 0) { /* child */ 58 | s = "child"; 59 | printf("current nice value in child is %d, adjusting by %d\n", 60 | nice(0)+nzero, adj); 61 | errno = 0; 62 | if ((ret = nice(adj)) == -1 && errno != 0) 63 | fprintf(stderr, "child set scheduling priority"); 64 | printf("now child nice value is %d\n", ret+nzero); 65 | } else { /* parent */ 66 | s = "parent"; 67 | printf("current nice value in parent is %d\n", nice(0)+nzero); 68 | } 69 | for(;;) { 70 | if (++count == 0) 71 | printf("%s counter wrap", s); 72 | checktime(s); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /05-process/codes/pruid.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int 6 | main(int argc, char **argv) 7 | { 8 | printf("real uid = %d, effective uid = %d\n", getuid(), geteuid()); 9 | exit(0); 10 | } -------------------------------------------------------------------------------- /05-process/codes/race_cond.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | static void charatatime(char *str); 7 | 8 | int 9 | main(int argc, char **argv) 10 | { 11 | pid_t pid; 12 | if ((pid = fork()) < 0) { 13 | fprintf(stderr, "fork error"); 14 | } else if (pid == 0) { 15 | charatatime("output from child\n"); 16 | } else { 17 | charatatime("this is parent\n"); 18 | } 19 | exit(0); 20 | } 21 | static void 22 | charatatime(char *str) 23 | { 24 | char *ptr; 25 | int c; 26 | setbuf(stdout, NULL); /* set unbuffered */ 27 | for (ptr = str; (c = *ptr++) != 0; ){ 28 | putc(c, stdout); 29 | } 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /05-process/codes/system.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int 8 | system(const char *cmdstring) /* version without signal handling */ 9 | { 10 | pid_t pid; 11 | int status; 12 | 13 | if (cmdstring == NULL) 14 | return(1); /* always a command processor with UNIX */ 15 | if ((pid = fork()) < 0) { 16 | status = -1; /* probably out of processes */ 17 | } else if (pid == 0) { /* child */ 18 | execl("/bin/sh", "sh", "-c", cmdstring, (char *)0); 19 | _exit(127); /* execl error */ 20 | } else { /* parent */ 21 | while (waitpid(pid, &status, 0) < 0) { 22 | if (errno != EINTR) { 23 | status = -1; /* error other than EINTR from waitpid() */ 24 | break; 25 | } 26 | } 27 | } 28 | return(status); 29 | } 30 | 31 | 32 | void 33 | pr_exit(int status) 34 | { 35 | if (WIFEXITED(status)) 36 | printf("normal termination, exit status = %d\n", WEXITSTATUS(status)); 37 | else if (WIFSIGNALED(status)) 38 | printf("abnormal termination, signal number = %d%s\n", WTERMSIG(status), 39 | #ifdef WCOREDUMP 40 | WCOREDUMP(status) ? " (core file generated)" : ""); 41 | #else 42 | ""); 43 | #endif 44 | else if (WIFSTOPPED(status)) 45 | printf("child stopped, singal number = %d\n", WSTOPSIG(status)); 46 | } 47 | 48 | 49 | int 50 | main(int argc, char **argv) 51 | { 52 | int status; 53 | if ((status = system("date")) < 0) 54 | fprintf(stderr, "system() error"); 55 | 56 | pr_exit(status); 57 | 58 | if ((status = system("nosuchcommand")) < 0) 59 | fprintf(stderr, "system() error"); 60 | 61 | pr_exit(status); 62 | 63 | if ((status = system("who; exit 44")) < 0) 64 | fprintf(stderr, "system() error"); 65 | 66 | pr_exit(status); 67 | 68 | exit(0); 69 | } 70 | -------------------------------------------------------------------------------- /05-process/codes/testinterp: -------------------------------------------------------------------------------- 1 | #!/Users/James/_projects/class_SystemProgramming_2016/lecture_sysprog/05_process/codes/echoarg foo 2 | 3 | 4 | -------------------------------------------------------------------------------- /05-process/codes/times.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | static void pr_times(clock_t, struct tms *, struct tms *); 7 | static void do_cmd(char *); 8 | void pr_exit(int status); 9 | 10 | int 11 | main(int argc, char *argv[]) 12 | { 13 | int i; 14 | 15 | setbuf(stdout, NULL); 16 | for (i = 1; i < argc; i++) 17 | do_cmd(argv[i]); /* once for each command-line arg */ 18 | exit(0); 19 | } 20 | 21 | static void 22 | do_cmd(char *cmd) /* execute and time the "cmd" */ 23 | { 24 | struct tms tmsstart, tmsend; 25 | clock_t start, end; 26 | int status; 27 | 28 | printf("\ncommand: %s\n", cmd); 29 | 30 | if ((start = times(&tmsstart)) == -1) /* starting values */ 31 | fprintf(stderr, "times error"); 32 | 33 | if ((status = system(cmd)) < 0) /* execute command */ 34 | fprintf(stderr, "system() error"); 35 | 36 | if ((end = times(&tmsend)) == -1) /* ending values */ 37 | fprintf(stderr, "times error"); 38 | 39 | pr_times(end-start, &tmsstart, &tmsend); 40 | pr_exit(status); 41 | } 42 | 43 | static void 44 | pr_times(clock_t real, struct tms *tmsstart, struct tms *tmsend) 45 | { 46 | static long clktck = 0; 47 | 48 | if (clktck == 0) /* fetch clock ticks per second first time */ 49 | if ((clktck = sysconf(_SC_CLK_TCK)) < 0) 50 | fprintf(stderr, "sysconf error"); 51 | 52 | printf(" real: %7.2f\n", real / (double) clktck); 53 | printf(" user: %7.2f\n", 54 | (tmsend->tms_utime - tmsstart->tms_utime) / (double) clktck); 55 | printf(" sys: %7.2f\n", 56 | (tmsend->tms_stime - tmsstart->tms_stime) / (double) clktck); 57 | printf(" child user: %7.2f\n", 58 | (tmsend->tms_cutime - tmsstart->tms_cutime) / (double) clktck); 59 | printf(" child sys: %7.2f\n", 60 | (tmsend->tms_cstime - tmsstart->tms_cstime) / (double) clktck); 61 | } 62 | 63 | 64 | void 65 | pr_exit(int status) 66 | { 67 | if (WIFEXITED(status)) 68 | printf("normal termination, exit status = %d\n", WEXITSTATUS(status)); 69 | else if (WIFSIGNALED(status)) 70 | printf("abnormal termination, signal number = %d%s\n", WTERMSIG(status), 71 | #ifdef WCOREDUMP 72 | WCOREDUMP(status) ? " (core file generated)" : ""); 73 | #else 74 | ""); 75 | #endif 76 | else if (WIFSTOPPED(status)) 77 | printf("child stopped, singal number = %d\n", WSTOPSIG(status)); 78 | } 79 | 80 | -------------------------------------------------------------------------------- /05-process/codes/tsys.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void 5 | pr_exit(int status) 6 | { 7 | if (WIFEXITED(status)) 8 | printf("normal termination, exit status = %d\n", WEXITSTATUS(status)); 9 | else if (WIFSIGNALED(status)) 10 | printf("abnormal termination, signal number = %d%s\n", WTERMSIG(status), 11 | #ifdef WCOREDUMP 12 | WCOREDUMP(status) ? " (core file generated)" : ""); 13 | #else 14 | ""); 15 | #endif 16 | else if (WIFSTOPPED(status)) 17 | printf("child stopped, singal number = %d\n", WSTOPSIG(status)); 18 | } 19 | 20 | 21 | int 22 | main(int argc, char *argv[]) 23 | { 24 | int status; 25 | if (argc < 2) 26 | fprintf(stderr, "command-line argument required"); 27 | if ((status = system(argv[1])) < 0) 28 | fprintf(stderr, "system() error"); 29 | pr_exit(status); 30 | exit(0); 31 | } -------------------------------------------------------------------------------- /05-process/codes/zombies.c: -------------------------------------------------------------------------------- 1 | /* This program illustrates how zombies are created, and how they 2 | * disappear again. If you like, you can try killing some of the zombies. 3 | */ 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | int 14 | main(int argc, char **argv) { 15 | pid_t pid; 16 | int i; 17 | 18 | printf("Let's create some zombies!\n"); 19 | 20 | for (i=0; i<10; i++) { 21 | if ((pid = fork()) < 0) { 22 | fprintf(stderr, "%s: fork error: %s\n", 23 | argv[0], strerror(errno)); 24 | exit(1); 25 | } 26 | 27 | if (pid == 0) { 28 | /* Do nothing in the child, ie immediately exit. This 29 | * creates a zombie until the parent decides to wait for 30 | * the child. */ 31 | exit(0); 32 | } else { 33 | printf("====\n"); 34 | //system("ps a | grep '[^ ]'a.ou[t]"); 35 | system("ps a | grep a.ou[t]"); 36 | /* We don't wait for our children. This allows 37 | * them to become zombies. We sleep for a short 38 | * time to delay the next iteration of the loop. 39 | * When the parent exits, init will reap the zombies. */ 40 | sleep(2); 41 | /* We wait for every other child to show that 42 | * zombies are reaped eventually if the parent 43 | * waits. */ 44 | if (i%2) 45 | wait(NULL); 46 | } 47 | } 48 | printf("That's enough zombies. Let's have init clean them up.\n"); 49 | printf("Remember to run 'ps a | grep a.ou[t]' to verify.\n"); 50 | exit(0); 51 | } 52 | -------------------------------------------------------------------------------- /05-process/figure/fig8-15_relationship.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/05-process/figure/fig8-15_relationship.png -------------------------------------------------------------------------------- /05-process/figure/fig8-18_ways.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/05-process/figure/fig8-18_ways.png -------------------------------------------------------------------------------- /05-process/figure/fig8-19_summary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/05-process/figure/fig8-19_summary.png -------------------------------------------------------------------------------- /05-process/figure/fig8-2_sharing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/05-process/figure/fig8-2_sharing.png -------------------------------------------------------------------------------- /06-process_rel/06-process_rel.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/06-process_rel/06-process_rel.pdf -------------------------------------------------------------------------------- /06-process_rel/Makefile: -------------------------------------------------------------------------------- 1 | texfile = 06-process_rel.tex 2 | outdir=/tmp 3 | 4 | all: ${texfile} 5 | pdflatex --shell-escape --output-directory ${outdir} $< 6 | 7 | clean: 8 | rm *.aux *.log *.nav *.out *.snm *.toc *.vrb 9 | 10 | o: ${texfile} 11 | gv ${outdir}/$(basename $<).pdf & 12 | 13 | final: ${texfile} 14 | pdflatex --shell-escape --output-directory ${outdir} $< 15 | pdflatex --shell-escape --output-directory ${outdir} $< 16 | cp ${outdir}/$(basename $<).pdf . 17 | -------------------------------------------------------------------------------- /06-process_rel/README.md: -------------------------------------------------------------------------------- 1 | This is lecture note on process relationships 2 | 3 | Visit following link for [course description](http://resourceful.github.io/classes/2016-10-17-week7-class7-processrel/) 4 | -------------------------------------------------------------------------------- /06-process_rel/figure/quote-a-computer-terminal-is-not-some-clunky-old-television-with-a-typewriter-in-front-of-it-it-is-an-douglas-adams-296711.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/06-process_rel/figure/quote-a-computer-terminal-is-not-some-clunky-old-television-with-a-typewriter-in-front-of-it-it-is-an-douglas-adams-296711.jpg -------------------------------------------------------------------------------- /07-signal/07-signal.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/07-signal/07-signal.pdf -------------------------------------------------------------------------------- /07-signal/Makefile: -------------------------------------------------------------------------------- 1 | texfile = 07-signal.tex 2 | outdir=/tmp 3 | 4 | all: ${texfile} 5 | pdflatex --shell-escape --output-directory ${outdir} $< 6 | 7 | clean: 8 | rm *.aux *.log *.nav *.out *.snm *.toc *.vrb 9 | 10 | o: ${texfile} 11 | gv ${outdir}/$(basename $<).pdf & 12 | 13 | final: ${texfile} 14 | pdflatex --shell-escape --output-directory ${outdir} $< 15 | pdflatex --shell-escape --output-directory ${outdir} $< 16 | cp ${outdir}/$(basename $<).pdf . 17 | -------------------------------------------------------------------------------- /07-signal/README.md: -------------------------------------------------------------------------------- 1 | This is Lecture note on signals . 2 | 3 | Visit following link for [course description](http://resourceful.github.io/classes/2016-11-09-week10-class8-signal/) 4 | -------------------------------------------------------------------------------- /07-signal/codes/Makefile: -------------------------------------------------------------------------------- 1 | 2 | PROGRAMS = usr_sig tsleep critical reenter ex_block 3 | 4 | CFLAGS = -g -Wall -O0 5 | 6 | all: ${PROGRAMS} 7 | 8 | %.o: %.c 9 | ${CC} ${CFLAGS} -c $< 10 | 11 | ${PROGRAMS}: %: %.o 12 | ${CC} ${CFLAGS} -o $@ $< 13 | 14 | clean: 15 | rm -r ${PROGRAMS} *.o hello 16 | 17 | hello: hello.o 18 | ${CC} -nostartfiles -o $@ $< -e my_main 19 | -------------------------------------------------------------------------------- /07-signal/codes/critical.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | static void 8 | sig_quit(int signo) 9 | { 10 | printf("caught SIGQUIT\n"); 11 | if (signal(SIGQUIT, SIG_DFL) == SIG_ERR){ 12 | fprintf(stderr, "can't reset SIGQUIT"); 13 | exit(1); 14 | } 15 | } 16 | 17 | int 18 | main(void) 19 | { 20 | sigset_t newmask, oldmask, pendmask; 21 | 22 | printf("C-\\ to generate SIGQUIT signal\n"); 23 | 24 | // Add user function sig_quit fro SIGQUIT 25 | if (signal(SIGQUIT, sig_quit) == SIG_ERR){ 26 | fprintf(stderr, "can't catch SIGQUIT"); 27 | exit(1); 28 | } 29 | 30 | /* 31 | * Block SIGQUIT and save current signal mask. 32 | */ 33 | sigemptyset(&newmask); // empty the signal set 34 | sigaddset(&newmask, SIGQUIT); // add SIGQUIT signal to newmask 35 | 36 | // oldmask saves current signal mask for the process 37 | if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0){ 38 | fprintf(stderr, "SIG_BLOCK error"); 39 | exit(1); 40 | } 41 | 42 | sleep(5); /* SIGQUIT here will remain pending */ 43 | 44 | // return signals that are blocked from delivery and currently pending for the calling process 45 | if (sigpending(&pendmask) < 0){ 46 | fprintf(stderr, "sigpending error"); 47 | exit(1); 48 | } 49 | if (sigismember(&pendmask, SIGQUIT)) 50 | printf("\nSIGQUIT pending\n"); 51 | 52 | /* 53 | * Restore signal mask which unblocks SIGQUIT. 54 | * we could use SIG_UNBLOCK. 55 | */ 56 | if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0){ 57 | fprintf(stderr, "SIG_SETMASK error"); 58 | exit(1); 59 | } 60 | printf("SIGQUIT unblocked\n"); 61 | 62 | printf("C-\\ to generate SIGQUIT signal again\n"); 63 | sleep(5); /* SIGQUIT here will terminate with core file */ 64 | exit(0); 65 | } 66 | 67 | 68 | -------------------------------------------------------------------------------- /07-signal/codes/ex_block.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int do_block = 0; //toggle 7 | int signum; // received signal 8 | 9 | void 10 | hup_handler(int sig) { //hangup signal handler 11 | signum = sig; 12 | } 13 | 14 | void 15 | int_handler(int sig) { //toggle do_block 16 | signum = sig; 17 | do_block = !do_block; 18 | } 19 | 20 | int 21 | main() { 22 | sigset_t signal_set; 23 | 24 | // Install signal handler. 25 | signal(SIGHUP, hup_handler); // hangup 26 | signal(SIGINT, int_handler); // interrupt 27 | 28 | sigemptyset(&signal_set); // empty set of signal_set 29 | sigaddset(&signal_set, SIGHUP); // add signal hang up to set 30 | 31 | while (1) { 32 | if (do_block) // if true block signal_set 33 | sigprocmask(SIG_BLOCK, &signal_set, NULL); 34 | else // if not unblock signal_set 35 | sigprocmask(SIG_UNBLOCK, &signal_set, NULL); 36 | sleep(1000); 37 | printf("Process received signal %d\n", signum); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /07-signal/codes/reenter.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | // change the user name 10 | #ifndef USER 11 | #define USER "James" 12 | #endif 13 | 14 | static void 15 | my_alarm(int signo) 16 | { 17 | struct passwd *rootptr; 18 | 19 | write(STDOUT_FILENO, "in signal handler\n", 18); 20 | if ((rootptr = getpwnam("root")) == NULL){ 21 | write(STDERR_FILENO, "getpwnam(root) error\n", 21); 22 | exit(1); 23 | } 24 | alarm(1); 25 | } 26 | 27 | int 28 | main(void) 29 | { 30 | struct passwd *ptr; 31 | 32 | if (signal(SIGALRM, my_alarm) == SIG_ERR) { 33 | fprintf(stderr, "Unable to establish signal handler: %s\n", strerror(errno)); 34 | exit(1); 35 | } 36 | alarm(1); 37 | for ( ; ; ) { 38 | if ((ptr = getpwnam(USER)) == NULL){ 39 | fprintf(stderr, "user %s not found, getpwnam error\n", USER); 40 | exit(1); 41 | } 42 | if (strcmp(ptr->pw_name, USER) != 0){ 43 | fprintf(stderr, "return value corrupted!, pw_name = %s\n", 44 | ptr->pw_name); 45 | abort(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /07-signal/codes/reenter.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/07-signal/codes/reenter.o -------------------------------------------------------------------------------- /07-signal/codes/setops.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 5 | * usually defines NSIG to include signal number 0. 6 | */ 7 | #define SIGBAD(signo) ((signo) <= 0 || (signo) >= NSIG) 8 | 9 | int 10 | sigaddset(sigset_t *set, int signo) 11 | { 12 | if (SIGBAD(signo)) { 13 | errno = EINVAL; 14 | return(-1); 15 | } 16 | *set |= 1 << (signo - 1); /* turn bit on */ 17 | return(0); 18 | } 19 | 20 | 21 | int 22 | sigdelset(sigset_t *set, int signo) 23 | { 24 | if (SIGBAD(signo)) { 25 | errno = EINVAL; 26 | return(-1); 27 | } 28 | *set &= ~(1 << (signo - 1)); /* turn bit off */ 29 | return(0); 30 | } 31 | 32 | /* tests a certain bit */ 33 | int 34 | sigismember(const sigset_t *set, int signo) 35 | { 36 | if (SIGBAD(signo)) { 37 | errno = EINVAL; 38 | return(-1); 39 | } 40 | return((*set & (1 << (signo - 1))) != 0); 41 | } 42 | -------------------------------------------------------------------------------- /07-signal/codes/sigaction_sig.c: -------------------------------------------------------------------------------- 1 | /* Reliable version of signal(), using POSIX sigaction(). */ 2 | Sigfunc * 3 | signal(int signo, Sigfunc *func) 4 | { 5 | struct sigaction act, oact; 6 | act.sa_handler = func; 7 | 8 | // must initialize the sa_mask member of the structure 9 | sigemptyset(&act.sa_mask); 10 | act.sa_flags = 0; 11 | 12 | if (signo == SIGALRM) { 13 | #ifdef SA_INTERRUPT 14 | act.sa_flags |= SA_INTERRUPT; 15 | #endif 16 | } else { 17 | // intentionally set the SA_RESTART flag 18 | // for all other than SIGALRM 19 | act.sa_flags |= SA_RESTART; 20 | } 21 | if (sigaction(signo, &act, &oact) < 0) 22 | return(SIG_ERR); 23 | return(oact.sa_handler); 24 | } -------------------------------------------------------------------------------- /07-signal/codes/sleep-pause.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static void 5 | sig_alrm(int signo) 6 | { 7 | /* nothing to do, just return to wake up the pause */ 8 | } 9 | 10 | unsigned int 11 | sleep1(unsigned int seconds) 12 | { 13 | if (signal(SIGALRM, sig_alrm) == SIG_ERR) 14 | return(seconds); 15 | alarm(seconds); /* start the timer */ 16 | pause(); /* next caught signal wakes us up */ 17 | return(alarm(0)); /* turn off timer, return unslept time */ 18 | } -------------------------------------------------------------------------------- /07-signal/codes/sleep-pause2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static jmp_buf env_alrm; 6 | 7 | static void 8 | sig_alrm(int signo) 9 | { 10 | longjmp(env_alrm, 1); 11 | } 12 | 13 | unsigned int 14 | sleep2(unsigned int seconds) 15 | { 16 | if (signal(SIGALRM, sig_alrm) == SIG_ERR) 17 | return(seconds); 18 | if (setjmp(env_alrm) == 0) { 19 | alarm(seconds); /* start the timer */ 20 | pause(); /* next caught signal wakes us up */ 21 | } 22 | return(alarm(0)); /* turn off timer, return unslept time */ 23 | } -------------------------------------------------------------------------------- /07-signal/codes/tsleep.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | unsigned int sleep2(unsigned int); 9 | static void sig_int(int); 10 | 11 | static jmp_buf env_alrm; 12 | 13 | int 14 | main(void) 15 | { 16 | unsigned int unslept; 17 | 18 | if (signal(SIGINT, sig_int) == SIG_ERR){ 19 | fprintf(stderr, "signal(SIGINT) error"); 20 | exit(1); 21 | } 22 | unslept = sleep2(5); 23 | printf("sleep2 returned: %u\n", unslept); 24 | exit(0); 25 | } 26 | 27 | static void 28 | sig_int(int signo) 29 | { 30 | int i, j; 31 | volatile int k = 0; 32 | 33 | /* 34 | * Tune these loops to run for more than 5 seconds 35 | * on whatever system this test program is run. 36 | */ 37 | printf("\nsig_int starting\n"); 38 | for (i = 0; i < 900000; i++) 39 | for (j = 0; j < 10000; j++) 40 | k += i * j; 41 | printf("sig_int finished\n"); 42 | } 43 | 44 | static void 45 | sig_alrm(int signo) 46 | { 47 | longjmp(env_alrm, 1); 48 | } 49 | 50 | unsigned int 51 | sleep2(unsigned int seconds) 52 | { 53 | if (signal(SIGALRM, sig_alrm) == SIG_ERR) 54 | return(seconds); 55 | if (setjmp(env_alrm) == 0) { 56 | alarm(seconds); /* start the timer */ 57 | pause(); /* next caught signal wakes us up */ 58 | } 59 | return(alarm(0)); /* turn off timer, return unslept time */ 60 | } 61 | -------------------------------------------------------------------------------- /07-signal/codes/usr_sig.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include // for signalling 6 | #include 7 | 8 | static void sig_usr(int); /* one handler for both signals */ 9 | 10 | int 11 | main(void) { 12 | if (signal(SIGUSR1, sig_usr) == SIG_ERR) { 13 | fprintf(stderr, "Can't catch SIGUSR1: %s", strerror(errno)); 14 | exit(1); 15 | } 16 | if (signal(SIGUSR2, sig_usr) == SIG_ERR) { 17 | fprintf(stderr, "Can't catch SIGUSR2: %s", strerror(errno)); 18 | exit(1); 19 | } 20 | 21 | if (signal(SIGHUP, sig_usr) == SIG_ERR) { 22 | fprintf(stderr, "Can't catch SIGHUP: %s", strerror(errno)); 23 | exit(1); 24 | } 25 | 26 | for ( ; ; ) 27 | pause(); 28 | } 29 | 30 | static void 31 | sig_usr(int signo) { /* argument is signal number */ 32 | if (signo == SIGUSR1) 33 | printf("received SIGUSR1\n"); 34 | else if (signo == SIGUSR2) 35 | printf("received SIGUSR2\n"); 36 | else if (signo == SIGHUP) 37 | printf("received SIGHUP\n"); 38 | else { 39 | fprintf(stderr, "received signal: %d\n", signo); 40 | exit(1); 41 | } 42 | return; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /07-signal/figure/fig10-1_unix_sig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/07-signal/figure/fig10-1_unix_sig.png -------------------------------------------------------------------------------- /07-signal/figure/fig10-4_reentrant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/07-signal/figure/fig10-4_reentrant.png -------------------------------------------------------------------------------- /07-signal/figure/fig_proc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/07-signal/figure/fig_proc.png -------------------------------------------------------------------------------- /07-signal/figure/signal_concept.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/07-signal/figure/signal_concept.png -------------------------------------------------------------------------------- /08-thread/08-thread.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/08-thread/08-thread.pdf -------------------------------------------------------------------------------- /08-thread/Makefile: -------------------------------------------------------------------------------- 1 | texfile = 08-thread.tex 2 | outdir=/tmp 3 | 4 | all: ${texfile} 5 | pdflatex --shell-escape --output-directory ${outdir} $< 6 | 7 | clean: 8 | rm *.aux *.log *.nav *.out *.snm *.toc *.vrb 9 | 10 | o: ${texfile} 11 | gv ${outdir}/$(basename $<).pdf & 12 | 13 | final: ${texfile} 14 | pdflatex --shell-escape --output-directory ${outdir} $< 15 | pdflatex --shell-escape --output-directory ${outdir} $< 16 | cp ${outdir}/$(basename $<).pdf . 17 | -------------------------------------------------------------------------------- /08-thread/README.md: -------------------------------------------------------------------------------- 1 | This is Lecture note on signals . 2 | 3 | Visit following link for [course description](http://resourceful.github.io/classes/2016-11-16-week11-class9-thread/) 4 | -------------------------------------------------------------------------------- /08-thread/codes/Makefile: -------------------------------------------------------------------------------- 1 | 2 | PROGRAMS = print_thrID exit-state exit-wrong push-pop timedlock barrier 3 | 4 | CFLAGS = -g -Wall -O0 5 | 6 | all: ${PROGRAMS} 7 | 8 | %.o: %.c 9 | ${CC} ${CFLAGS} -pthread -lrt -c $< 10 | 11 | ${PROGRAMS}: %: %.o 12 | ${CC} ${CFLAGS} -pthread -lrt -o $@ $< 13 | 14 | clean: 15 | rm -r ${PROGRAMS} *.o hello 16 | 17 | hello: hello.o 18 | ${CC} -nostartfiles -o $@ $< -e my_main 19 | -------------------------------------------------------------------------------- /08-thread/codes/bar_mac.h: -------------------------------------------------------------------------------- 1 | /* code adopted from http://blog.albertarmea.com/post/47089939939/using-pthreadbarrier-on-mac-os-x 2 | */ 3 | 4 | #ifdef __APPLE__ 5 | 6 | #ifndef PTHREAD_BARRIER_H_ 7 | #define PTHREAD_BARRIER_H_ 8 | 9 | #include 10 | #include 11 | 12 | typedef int pthread_barrierattr_t; 13 | typedef struct 14 | { 15 | pthread_mutex_t mutex; 16 | pthread_cond_t cond; 17 | int count; 18 | int tripCount; 19 | } pthread_barrier_t; 20 | 21 | 22 | int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count) 23 | { 24 | if(count == 0) 25 | { 26 | errno = EINVAL; 27 | return -1; 28 | } 29 | if(pthread_mutex_init(&barrier->mutex, 0) < 0) 30 | { 31 | return -1; 32 | } 33 | if(pthread_cond_init(&barrier->cond, 0) < 0) 34 | { 35 | pthread_mutex_destroy(&barrier->mutex); 36 | return -1; 37 | } 38 | barrier->tripCount = count; 39 | barrier->count = 0; 40 | 41 | return 0; 42 | } 43 | 44 | int pthread_barrier_destroy(pthread_barrier_t *barrier) 45 | { 46 | pthread_cond_destroy(&barrier->cond); 47 | pthread_mutex_destroy(&barrier->mutex); 48 | return 0; 49 | } 50 | 51 | int pthread_barrier_wait(pthread_barrier_t *barrier) 52 | { 53 | pthread_mutex_lock(&barrier->mutex); 54 | ++(barrier->count); 55 | if(barrier->count >= barrier->tripCount) 56 | { 57 | barrier->count = 0; 58 | pthread_cond_broadcast(&barrier->cond); 59 | pthread_mutex_unlock(&barrier->mutex); 60 | return 1; 61 | } 62 | else 63 | { 64 | pthread_cond_wait(&barrier->cond, &(barrier->mutex)); 65 | pthread_mutex_unlock(&barrier->mutex); 66 | return 0; 67 | } 68 | } 69 | 70 | #endif // PTHREAD_BARRIER_H_ 71 | #endif // __APPLE__ -------------------------------------------------------------------------------- /08-thread/codes/barrier.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "bar_mac.h" 8 | 9 | #define NTHR 8 /* number of threads */ 10 | #define NUMNUM 8000000L /* number of numbers to sort */ 11 | #define TNUM (NUMNUM/NTHR) /* number to sort per thread */ 12 | 13 | long nums[NUMNUM]; 14 | long snums[NUMNUM]; 15 | 16 | pthread_barrier_t b; 17 | 18 | #ifdef SOLARIS 19 | #define heapsort qsort 20 | #elif linux 21 | #define heapsort qsort 22 | #else 23 | extern int heapsort(void *, size_t, size_t, 24 | int (*)(const void *, const void *)); 25 | #endif 26 | 27 | /* 28 | * Compare two long integers (helper function for heapsort) 29 | */ 30 | int 31 | complong(const void *arg1, const void *arg2) 32 | { 33 | long l1 = *(long *)arg1; 34 | long l2 = *(long *)arg2; 35 | 36 | if (l1 == l2) 37 | return 0; 38 | else if (l1 < l2) 39 | return -1; 40 | else 41 | return 1; 42 | } 43 | 44 | /* 45 | * Worker thread to sort a portion of the set of numbers. 46 | */ 47 | void * 48 | thr_fn(void *arg) 49 | { 50 | long idx = (long)arg; 51 | 52 | heapsort(&nums[idx], TNUM, sizeof(long), complong); 53 | pthread_barrier_wait(&b); 54 | 55 | /* 56 | * Go off and perform more work ... 57 | */ 58 | return((void *)0); 59 | } 60 | 61 | /* 62 | * Merge the results of the individual sorted ranges. 63 | */ 64 | void 65 | merge() 66 | { 67 | long idx[NTHR]; 68 | long i, minidx, sidx, num; 69 | 70 | for (i = 0; i < NTHR; i++) 71 | idx[i] = i * TNUM; 72 | for (sidx = 0; sidx < NUMNUM; sidx++) { 73 | num = LONG_MAX; 74 | for (i = 0; i < NTHR; i++) { 75 | if ((idx[i] < (i+1)*TNUM) && (nums[idx[i]] < num)) { 76 | num = nums[idx[i]]; 77 | minidx = i; 78 | } 79 | } 80 | snums[sidx] = nums[idx[minidx]]; 81 | idx[minidx]++; 82 | } 83 | } 84 | 85 | int 86 | main() 87 | { 88 | unsigned long i; 89 | struct timeval start, end; 90 | long long startusec, endusec; 91 | double elapsed; 92 | int err; 93 | pthread_t tid; 94 | 95 | /* 96 | * Create the initial set of numbers to sort. 97 | */ 98 | srandom(1); 99 | for (i = 0; i < NUMNUM; i++) 100 | nums[i] = random(); 101 | 102 | /* 103 | * Create 8 threads to sort the numbers. 104 | */ 105 | gettimeofday(&start, NULL); 106 | pthread_barrier_init(&b, NULL, NTHR+1); 107 | for (i = 0; i < NTHR; i++) { 108 | err = pthread_create(&tid, NULL, thr_fn, (void *)(i * TNUM)); 109 | if (err != 0){ 110 | fprintf(stderr, "can't create thread"); 111 | } 112 | } 113 | pthread_barrier_wait(&b); 114 | merge(); 115 | gettimeofday(&end, NULL); 116 | 117 | /* 118 | * Print the sorted list. 119 | */ 120 | startusec = start.tv_sec * 1000000 + start.tv_usec; 121 | endusec = end.tv_sec * 1000000 + end.tv_usec; 122 | elapsed = (double)(endusec - startusec) / 1000000.0; 123 | printf("sort took %.4f seconds\n", elapsed); 124 | for (i = 0; i < NUMNUM; i++) 125 | printf("%ld\n", snums[i]); 126 | exit(0); 127 | } 128 | -------------------------------------------------------------------------------- /08-thread/codes/condvar.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct msg { 4 | struct msg *m_next; 5 | /* ... more stuff here ... */ 6 | }; 7 | 8 | struct msg *workq; 9 | 10 | pthread_cond_t qready = PTHREAD_COND_INITIALIZER; 11 | 12 | pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER; 13 | 14 | void 15 | process_msg(void) 16 | { 17 | struct msg *mp; 18 | 19 | for (;;) { 20 | pthread_mutex_lock(&qlock); 21 | while (workq == NULL) 22 | pthread_cond_wait(&qready, &qlock); 23 | mp = workq; 24 | workq = mp->m_next; 25 | pthread_mutex_unlock(&qlock); 26 | /* now process the message mp */ 27 | } 28 | } 29 | 30 | void 31 | enqueue_msg(struct msg *mp) 32 | { 33 | pthread_mutex_lock(&qlock); 34 | mp->m_next = workq; 35 | workq = mp; 36 | pthread_mutex_unlock(&qlock); 37 | pthread_cond_signal(&qready); 38 | } 39 | -------------------------------------------------------------------------------- /08-thread/codes/exit-state.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | void * 8 | thr_fn1(void *arg) 9 | { 10 | printf("thread 1 returning\n"); 11 | return((void *)1); 12 | } 13 | 14 | void * 15 | thr_fn2(void *arg) 16 | { 17 | printf("thread 2 exiting\n"); 18 | pthread_exit((void *)2); 19 | } 20 | int 21 | main(void) 22 | { 23 | int err; 24 | pthread_t tid1, tid2; 25 | void *tret; 26 | err = pthread_create(&tid1, NULL, thr_fn1, NULL); 27 | if (err != 0){ 28 | fprintf(stderr, "can’t create thread 1"); 29 | } 30 | 31 | err = pthread_create(&tid2, NULL, thr_fn2, NULL); 32 | if (err != 0){ 33 | fprintf(stderr, "can’t create thread 2"); 34 | } 35 | 36 | err = pthread_join(tid1, &tret); 37 | if (err != 0){ 38 | fprintf(stderr, "can’t join with thread 1"); 39 | } 40 | printf("thread 1 exit code %ld\n", (long)tret); 41 | 42 | err = pthread_join(tid2, &tret); 43 | if (err != 0){ 44 | fprintf(stderr, "can’t join with thread 2"); 45 | } 46 | 47 | printf("thread 2 exit code %ld\n", (long)tret); 48 | exit(0); 49 | } -------------------------------------------------------------------------------- /08-thread/codes/exit-wrong.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | struct foo { 7 | int a, b, c, d; 8 | }; 9 | 10 | void 11 | printfoo(const char *s, const struct foo *fp) 12 | { 13 | printf("%s", s); 14 | printf(" structure at 0x%lx\n", (unsigned long)fp); 15 | printf(" foo.a = %d\n", fp->a); 16 | printf(" foo.b = %d\n", fp->b); 17 | printf(" foo.c = %d\n", fp->c); 18 | printf(" foo.d = %d\n", fp->d); 19 | } 20 | 21 | void * 22 | thr_fn1(void *arg) 23 | { 24 | struct foo foo = {1, 2, 3, 4}; 25 | printfoo("thread 1:\n", &foo); 26 | pthread_exit((void *)&foo); 27 | } 28 | 29 | void * 30 | thr_fn2(void *arg) 31 | { 32 | printf("thread 2: ID is %lu\n", (unsigned long)pthread_self()); 33 | pthread_exit((void *)0); 34 | } 35 | 36 | int 37 | main(void) 38 | { 39 | int err; 40 | pthread_t tid1, tid2; 41 | struct foo *fp; 42 | err = pthread_create(&tid1, NULL, thr_fn1, NULL); 43 | if (err != 0){ 44 | fprintf(stderr, "can’t create thread 1"); 45 | } 46 | 47 | err = pthread_join(tid1, (void *)&fp); 48 | if (err != 0){ 49 | fprintf(stderr, "can’t join with thread 1"); 50 | } 51 | 52 | sleep(1); 53 | printf("parent starting second thread\n"); 54 | err = pthread_create(&tid2, NULL, thr_fn2, NULL); 55 | if (err != 0){ 56 | fprintf(stderr, "can’t create thread 2"); 57 | } 58 | 59 | sleep(1); 60 | printfoo("parent:\n", fp); 61 | exit(0); 62 | } -------------------------------------------------------------------------------- /08-thread/codes/mutex1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct foo { 5 | int f_count; 6 | pthread_mutex_t f_lock; 7 | int f_id; 8 | /* ... more stuff here ... */ 9 | }; 10 | 11 | struct foo * 12 | foo_alloc(int id) /* allocate the object */ 13 | { 14 | struct foo *fp; 15 | 16 | if ((fp = malloc(sizeof(struct foo))) != NULL) { 17 | fp->f_count = 1; 18 | fp->f_id = id; 19 | if (pthread_mutex_init(&fp->f_lock, NULL) != 0) { 20 | free(fp); 21 | return(NULL); 22 | } 23 | /* ... continue initialization ... */ 24 | } 25 | return(fp); 26 | } 27 | 28 | void 29 | foo_hold(struct foo *fp) /* add a reference to the object */ 30 | { 31 | pthread_mutex_lock(&fp->f_lock); 32 | fp->f_count++; 33 | pthread_mutex_unlock(&fp->f_lock); 34 | } 35 | 36 | void 37 | foo_rele(struct foo *fp) /* release a reference to the object */ 38 | { 39 | pthread_mutex_lock(&fp->f_lock); 40 | if (--fp->f_count == 0) { /* last reference */ 41 | pthread_mutex_unlock(&fp->f_lock); 42 | pthread_mutex_destroy(&fp->f_lock); 43 | free(fp); 44 | } else { 45 | pthread_mutex_unlock(&fp->f_lock); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /08-thread/codes/mutex2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define NHASH 29 5 | #define HASH(id) (((unsigned long)id)%NHASH) 6 | 7 | struct foo *fh[NHASH]; 8 | 9 | pthread_mutex_t hashlock = PTHREAD_MUTEX_INITIALIZER; 10 | 11 | struct foo { 12 | int f_count; 13 | pthread_mutex_t f_lock; 14 | int f_id; 15 | struct foo *f_next; /* protected by hashlock */ 16 | /* ... more stuff here ... */ 17 | }; 18 | 19 | 20 | 21 | /* The allocation function locks the hash list lock, adds the new structure to 22 | * a hash bucket, and before unlocking the hash list lock, locks the mutex in 23 | * the new structure. Since the new structure is placed on a global list, 24 | * other threads can find it, so we need to block them if they try to access 25 | * the new structure, until we are done initializing it. 26 | */ 27 | struct foo * 28 | foo_alloc(int id) /* allocate the object */ 29 | { 30 | struct foo *fp; 31 | int idx; 32 | 33 | if ((fp = malloc(sizeof(struct foo))) != NULL) { 34 | fp->f_count = 1; 35 | fp->f_id = id; 36 | if (pthread_mutex_init(&fp->f_lock, NULL) != 0) { 37 | free(fp); 38 | return(NULL); 39 | } 40 | idx = HASH(id); 41 | pthread_mutex_lock(&hashlock); 42 | fp->f_next = fh[idx]; 43 | fh[idx] = fp; 44 | pthread_mutex_lock(&fp->f_lock); 45 | pthread_mutex_unlock(&hashlock); 46 | /* ... continue initialization ... */ 47 | pthread_mutex_unlock(&fp->f_lock); 48 | } 49 | return(fp); 50 | } 51 | 52 | void 53 | foo_hold(struct foo *fp) /* add a reference to the object */ 54 | { 55 | pthread_mutex_lock(&fp->f_lock); 56 | fp->f_count++; 57 | pthread_mutex_unlock(&fp->f_lock); 58 | } 59 | 60 | 61 | /* The foo_find function locks the hash list lock and searches for the 62 | * requested structure. If it is found, we increase the reference count and 63 | * return a pointer to the structure. 64 | */ 65 | struct foo * 66 | foo_find(int id) /* find an existing object */ 67 | { 68 | struct foo *fp; 69 | 70 | pthread_mutex_lock(&hashlock); 71 | for (fp = fh[HASH(id)]; fp != NULL; fp = fp->f_next) { 72 | if (fp->f_id == id) { 73 | foo_hold(fp); 74 | break; 75 | } 76 | } 77 | pthread_mutex_unlock(&hashlock); 78 | return(fp); 79 | } 80 | 81 | 82 | /* Now with two locks, the foo_rele function is more complicated. If this is 83 | * the last reference, we need to unlock the structure mutex so that we can 84 | * acquire the hash list lock, since we’ll need to remove the structure from 85 | * the hash list. Then we reacquire the structure mutex. Because we could have 86 | * blocked since the last time we held the structure mutex, we need to recheck 87 | * the condition to see whether we still need to free the structure. 88 | */ 89 | void 90 | foo_rele(struct foo *fp) /* release a reference to the object */ 91 | { 92 | struct foo *tfp; 93 | int idx; 94 | 95 | pthread_mutex_lock(&fp->f_lock); 96 | if (fp->f_count == 1) { /* last reference */ 97 | pthread_mutex_unlock(&fp->f_lock); 98 | pthread_mutex_lock(&hashlock); 99 | pthread_mutex_lock(&fp->f_lock); 100 | /* need to recheck the condition */ 101 | if (fp->f_count != 1) { 102 | fp->f_count--; 103 | pthread_mutex_unlock(&fp->f_lock); 104 | pthread_mutex_unlock(&hashlock); 105 | return; 106 | } 107 | /* remove from list */ 108 | idx = HASH(fp->f_id); 109 | tfp = fh[idx]; 110 | if (tfp == fp) { 111 | fh[idx] = fp->f_next; 112 | } else { 113 | while (tfp->f_next != fp) 114 | tfp = tfp->f_next; 115 | tfp->f_next = fp->f_next; 116 | } 117 | pthread_mutex_unlock(&hashlock); 118 | pthread_mutex_unlock(&fp->f_lock); 119 | pthread_mutex_destroy(&fp->f_lock); 120 | free(fp); 121 | } else { 122 | fp->f_count--; 123 | pthread_mutex_unlock(&fp->f_lock); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /08-thread/codes/mutex3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define NHASH 29 5 | #define HASH(id) (((unsigned long)id)%NHASH) 6 | 7 | struct foo *fh[NHASH]; 8 | pthread_mutex_t hashlock = PTHREAD_MUTEX_INITIALIZER; 9 | 10 | struct foo { 11 | int f_count; /* protected by hashlock */ 12 | pthread_mutex_t f_lock; 13 | int f_id; 14 | struct foo *f_next; /* protected by hashlock */ 15 | /* ... more stuff here ... */ 16 | }; 17 | 18 | /* The lock-ordering issues surrounding the hash list and the reference count 19 | * go away when we use the same lock for both purposes. 20 | */ 21 | struct foo * 22 | foo_alloc(int id) /* allocate the object */ 23 | { 24 | struct foo *fp; 25 | int idx; 26 | 27 | if ((fp = malloc(sizeof(struct foo))) != NULL) { 28 | fp->f_count = 1; 29 | fp->f_id = id; 30 | if (pthread_mutex_init(&fp->f_lock, NULL) != 0) { 31 | free(fp); 32 | return(NULL); 33 | } 34 | idx = HASH(id); 35 | pthread_mutex_lock(&hashlock); 36 | fp->f_next = fh[idx]; 37 | fh[idx] = fp; 38 | pthread_mutex_lock(&fp->f_lock); 39 | pthread_mutex_unlock(&hashlock); 40 | /* ... continue initialization ... */ 41 | pthread_mutex_unlock(&fp->f_lock); 42 | } 43 | return(fp); 44 | } 45 | 46 | void 47 | foo_hold(struct foo *fp) /* add a reference to the object */ 48 | { 49 | pthread_mutex_lock(&hashlock); 50 | fp->f_count++; 51 | pthread_mutex_unlock(&hashlock); 52 | } 53 | 54 | struct foo * 55 | foo_find(int id) /* find an existing object */ 56 | { 57 | struct foo *fp; 58 | 59 | pthread_mutex_lock(&hashlock); 60 | for (fp = fh[HASH(id)]; fp != NULL; fp = fp->f_next) { 61 | if (fp->f_id == id) { 62 | fp->f_count++; 63 | break; 64 | } 65 | } 66 | pthread_mutex_unlock(&hashlock); 67 | return(fp); 68 | } 69 | 70 | void 71 | foo_rele(struct foo *fp) /* release a reference to the object */ 72 | { 73 | struct foo *tfp; 74 | int idx; 75 | 76 | pthread_mutex_lock(&hashlock); 77 | if (--fp->f_count == 0) { /* last reference, remove from list */ 78 | idx = HASH(fp->f_id); 79 | tfp = fh[idx]; 80 | if (tfp == fp) { 81 | fh[idx] = fp->f_next; 82 | } else { 83 | while (tfp->f_next != fp) 84 | tfp = tfp->f_next; 85 | tfp->f_next = fp->f_next; 86 | } 87 | pthread_mutex_unlock(&hashlock); 88 | pthread_mutex_destroy(&fp->f_lock); 89 | free(fp); 90 | } else { 91 | pthread_mutex_unlock(&hashlock); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /08-thread/codes/print_thrID.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | pthread_t ntid; 7 | 8 | void 9 | printids(const char *s) 10 | { 11 | pid_t pid; 12 | pthread_t tid; 13 | pid = getpid(); 14 | tid = pthread_self(); 15 | printf("%s pid %lu tid %lu (0x%lx)\n", s, (unsigned long)pid, 16 | (unsigned long)tid, (unsigned long)tid); 17 | } 18 | 19 | void * 20 | thr_fn(void *arg) 21 | { 22 | printids("new thread: "); 23 | return((void *)0); 24 | } 25 | 26 | int 27 | main(void) 28 | { 29 | int err; 30 | err = pthread_create(&ntid, NULL, thr_fn, NULL); 31 | if (err != 0){ 32 | fprintf(stderr, "can’t create thread"); 33 | } 34 | printids("main thread:"); 35 | sleep(1); 36 | exit(0); 37 | } -------------------------------------------------------------------------------- /08-thread/codes/push-pop.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void 7 | cleanup(void *arg) 8 | { 9 | printf("cleanup: %s\n", (char *)arg); 10 | } 11 | 12 | void * 13 | thr_fn1(void *arg) 14 | { 15 | printf("thread 1 start\n"); 16 | pthread_cleanup_push(cleanup, "thread 1 first handler"); 17 | pthread_cleanup_push(cleanup, "thread 1 second handler"); 18 | printf("thread 1 push complete\n"); 19 | if (arg) 20 | return((void *)1); 21 | pthread_cleanup_pop(0); 22 | pthread_cleanup_pop(0); 23 | return((void *)1); 24 | } 25 | 26 | void * 27 | thr_fn2(void *arg) 28 | { 29 | printf("thread 2 start\n"); 30 | pthread_cleanup_push(cleanup, "thread 2 first handler"); 31 | pthread_cleanup_push(cleanup, "thread 2 second handler"); 32 | printf("thread 2 push complete\n"); 33 | if (arg) 34 | pthread_exit((void *)2); 35 | pthread_cleanup_pop(0); 36 | pthread_cleanup_pop(0); 37 | pthread_exit((void *)2); 38 | } 39 | 40 | 41 | int 42 | main(void) 43 | { 44 | int err; 45 | pthread_t tid1, tid2; 46 | void *tret; 47 | 48 | err = pthread_create(&tid1, NULL, thr_fn1, (void *)1); 49 | if (err != 0){ 50 | fprintf(stderr, "can’t create thread 1"); 51 | } 52 | 53 | err = pthread_create(&tid2, NULL, thr_fn2, (void *)1); 54 | if (err != 0){ 55 | fprintf(stderr, "can’t create thread 2"); 56 | } 57 | 58 | err = pthread_join(tid1, &tret); 59 | if (err != 0){ 60 | fprintf(stderr, "can’t join with thread 1"); 61 | } 62 | 63 | printf("thread 1 exit code %ld\n", (long)tret); 64 | 65 | err = pthread_join(tid2, &tret); 66 | if (err != 0){ 67 | fprintf(stderr, "can’t join with thread 2"); 68 | } 69 | 70 | printf("thread 2 exit code %ld\n", (long)tret); 71 | 72 | exit(0); 73 | } -------------------------------------------------------------------------------- /08-thread/codes/rwlock.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct job { 5 | struct job *j_next; 6 | struct job *j_prev; 7 | pthread_t j_id; /* tells which thread handles this job */ 8 | /* ... more stuff here ... */ 9 | }; 10 | 11 | struct queue { 12 | struct job *q_head; 13 | struct job *q_tail; 14 | pthread_rwlock_t q_lock; 15 | }; 16 | 17 | /* 18 | * Initialize a queue. 19 | */ 20 | int 21 | queue_init(struct queue *qp) 22 | { 23 | int err; 24 | 25 | qp->q_head = NULL; 26 | qp->q_tail = NULL; 27 | err = pthread_rwlock_init(&qp->q_lock, NULL); 28 | if (err != 0) 29 | return(err); 30 | /* ... continue initialization ... */ 31 | return(0); 32 | } 33 | 34 | /* 35 | * Insert a job at the head of the queue. 36 | */ 37 | void 38 | job_insert(struct queue *qp, struct job *jp) 39 | { 40 | pthread_rwlock_wrlock(&qp->q_lock); 41 | jp->j_next = qp->q_head; 42 | jp->j_prev = NULL; 43 | if (qp->q_head != NULL) 44 | qp->q_head->j_prev = jp; 45 | else 46 | qp->q_tail = jp; /* list was empty */ 47 | qp->q_head = jp; 48 | pthread_rwlock_unlock(&qp->q_lock); 49 | } 50 | 51 | /* 52 | * Append a job on the tail of the queue. 53 | * we lock the queue’s reader–writer lock in write mode whenever we need to add 54 | * a job to the queue or remove a job from the queue. 55 | */ 56 | void 57 | job_append(struct queue *qp, struct job *jp) 58 | { 59 | pthread_rwlock_wrlock(&qp->q_lock); 60 | jp->j_next = NULL; 61 | jp->j_prev = qp->q_tail; 62 | if (qp->q_tail != NULL) 63 | qp->q_tail->j_next = jp; 64 | else 65 | qp->q_head = jp; /* list was empty */ 66 | qp->q_tail = jp; 67 | pthread_rwlock_unlock(&qp->q_lock); 68 | } 69 | 70 | /* 71 | * Remove the given job from a queue. 72 | */ 73 | void 74 | job_remove(struct queue *qp, struct job *jp) 75 | { 76 | pthread_rwlock_wrlock(&qp->q_lock); 77 | if (jp == qp->q_head) { 78 | qp->q_head = jp->j_next; 79 | if (qp->q_tail == jp) 80 | qp->q_tail = NULL; 81 | else 82 | jp->j_next->j_prev = jp->j_prev; 83 | } else if (jp == qp->q_tail) { 84 | qp->q_tail = jp->j_prev; 85 | jp->j_prev->j_next = jp->j_next; 86 | } else { 87 | jp->j_prev->j_next = jp->j_next; 88 | jp->j_next->j_prev = jp->j_prev; 89 | } 90 | pthread_rwlock_unlock(&qp->q_lock); 91 | } 92 | 93 | /* 94 | * Find a job for the given thread ID. 95 | * Whenever we search the queue, we grab the lock in read mode, allowing all 96 | * the worker threads to search the queue concurrently. 97 | */ 98 | struct job * 99 | job_find(struct queue *qp, pthread_t id) 100 | { 101 | struct job *jp; 102 | 103 | if (pthread_rwlock_rdlock(&qp->q_lock) != 0) 104 | return(NULL); 105 | 106 | for (jp = qp->q_head; jp != NULL; jp = jp->j_next) 107 | if (pthread_equal(jp->j_id, id)) 108 | break; 109 | 110 | pthread_rwlock_unlock(&qp->q_lock); 111 | return(jp); 112 | } 113 | -------------------------------------------------------------------------------- /08-thread/codes/timedlock.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int 8 | main(void) 9 | { 10 | int err; 11 | struct timespec tout; 12 | struct tm *tmp; 13 | char buf[64]; 14 | pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 15 | 16 | pthread_mutex_lock(&lock); 17 | printf("mutex is locked\n"); 18 | clock_gettime(CLOCK_REALTIME, &tout); 19 | tmp = localtime(&tout.tv_sec); 20 | strftime(buf, sizeof(buf), "%r", tmp); 21 | printf("current time is %s\n", buf); 22 | tout.tv_sec += 10; /* 10 seconds from now */ 23 | /* caution: this could lead to deadlock */ 24 | err = pthread_mutex_timedlock(&lock, &tout); 25 | clock_gettime(CLOCK_REALTIME, &tout); 26 | tmp = localtime(&tout.tv_sec); 27 | strftime(buf, sizeof(buf), "%r", tmp); 28 | printf("the time is now %s\n", buf); 29 | if (err == 0) 30 | printf("mutex locked again!\n"); 31 | else 32 | printf("can't lock mutex again: %s\n", strerror(err)); 33 | exit(0); 34 | } 35 | -------------------------------------------------------------------------------- /08-thread/figure/fig11-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/08-thread/figure/fig11-1.png -------------------------------------------------------------------------------- /08-thread/figure/fig11-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/08-thread/figure/fig11-6.png -------------------------------------------------------------------------------- /08-thread/figure/fig11-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/08-thread/figure/fig11-7.png -------------------------------------------------------------------------------- /08-thread/figure/fig11-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/08-thread/figure/fig11-8.png -------------------------------------------------------------------------------- /08-thread/figure/fig11-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/08-thread/figure/fig11-9.png -------------------------------------------------------------------------------- /09-adv_io/09-adv_io.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/09-adv_io/09-adv_io.pdf -------------------------------------------------------------------------------- /09-adv_io/Makefile: -------------------------------------------------------------------------------- 1 | texfile = 10-adv_io.tex 2 | outdir=/tmp 3 | 4 | all: ${texfile} 5 | pdflatex --shell-escape --output-directory ${outdir} $< 6 | 7 | clean: 8 | rm *.aux *.log *.nav *.out *.snm *.toc *.vrb 9 | 10 | o: ${texfile} 11 | gv ${outdir}/$(basename $<).pdf & 12 | 13 | final: ${texfile} 14 | pdflatex --shell-escape --output-directory ${outdir} $< 15 | pdflatex --shell-escape --output-directory ${outdir} $< 16 | cp ${outdir}/$(basename $<).pdf . 17 | -------------------------------------------------------------------------------- /09-adv_io/README.md: -------------------------------------------------------------------------------- 1 | This is Lecture note on advanced I/O 2 | 3 | Visit following link for [course description](http://resourceful.github.io/classes/2016-11-29-week14-class11-advio/) 4 | -------------------------------------------------------------------------------- /09-adv_io/codes/Makefile: -------------------------------------------------------------------------------- 1 | 2 | PROGRAMS = nonblocking rot13a rot13c2 mcopy2 3 | 4 | CFLAGS = -g -Wall -O0 5 | 6 | all: ${PROGRAMS} 7 | 8 | %.o: %.c 9 | ${CC} ${CFLAGS} -c $< 10 | 11 | ${PROGRAMS}: %: %.o 12 | ${CC} ${CFLAGS} -o $@ $< 13 | 14 | clean: 15 | rm -r ${PROGRAMS} *.o deadlock.o deadlock 16 | 17 | deadlock: deadlock.c tellwait.c 18 | ${CC} -c tellwait.c 19 | ${CC} -c deadlock.c 20 | ${CC} -o deadlock deadlock.o tellwait.o 21 | -------------------------------------------------------------------------------- /09-adv_io/codes/deadlock.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | // tellwait.c 7 | void TELL_WAIT(void); /* parent/child from {Sec race_conditions} */ 8 | void TELL_PARENT(pid_t); 9 | void TELL_CHILD(pid_t); 10 | void WAIT_PARENT(void); 11 | void WAIT_CHILD(void); 12 | 13 | #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) 14 | 15 | #define read_lock(fd, offset, whence, len) \ 16 | lock_reg((fd), F_SETLK, F_RDLCK, (offset), (whence), (len)) 17 | #define readw_lock(fd, offset, whence, len) \ 18 | lock_reg((fd), F_SETLKW, F_RDLCK, (offset), (whence), (len)) 19 | #define write_lock(fd, offset, whence, len) \ 20 | lock_reg((fd), F_SETLK, F_WRLCK, (offset), (whence), (len)) 21 | #define writew_lock(fd, offset, whence, len) \ 22 | lock_reg((fd), F_SETLKW, F_WRLCK, (offset), (whence), (len)) 23 | #define un_lock(fd, offset, whence, len) \ 24 | lock_reg((fd), F_SETLK, F_UNLCK, (offset), (whence), (len)) 25 | 26 | int 27 | lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len) 28 | { 29 | struct flock lock; 30 | lock.l_type = type; /* F_RDLCK, F_WRLCK, F_UNLCK */ 31 | lock.l_start = offset; /* byte offset, relative to l_whence */ 32 | lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */ 33 | lock.l_len = len; /* #bytes (0 means to EOF) */ 34 | return(fcntl(fd, cmd, &lock)); 35 | } 36 | 37 | pid_t 38 | lock_test(int fd, int type, off_t offset, int whence, off_t len) 39 | { 40 | struct flock lock; 41 | lock.l_type = type; /* F_RDLCK or F_WRLCK */ 42 | lock.l_start = offset; /* byte offset, relative to l_whence */ 43 | lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */ 44 | lock.l_len = len; /* #bytes (0 means to EOF) */ 45 | 46 | if (fcntl(fd, F_GETLK, &lock) < 0){ 47 | fprintf(stderr, "fcntl error"); 48 | exit(1); 49 | } 50 | 51 | if (lock.l_type == F_UNLCK) 52 | return(0); /* false, region isn't locked by another proc */ 53 | return(lock.l_pid); /* true, return pid of lock owner */ 54 | } 55 | 56 | static void 57 | lockabyte(const char *name, int fd, off_t offset) 58 | { 59 | if (writew_lock(fd, offset, SEEK_SET, 1) < 0){ 60 | fprintf(stderr, "%s: writew_lock error", name); 61 | exit(1); 62 | } 63 | printf("%s: got the lock, byte %lld\n", name, (long long)offset); 64 | } 65 | 66 | int 67 | main(void) 68 | { 69 | int fd; 70 | pid_t pid; 71 | 72 | /* 73 | * Create a file and write two bytes to it. 74 | */ 75 | if ((fd = creat("templock", FILE_MODE)) < 0){ 76 | fprintf(stderr, "creat error"); 77 | exit(1); 78 | } 79 | if (write(fd, "ab", 2) != 2){ 80 | fprintf(stderr, "write error"); 81 | exit(1); 82 | } 83 | 84 | TELL_WAIT(); 85 | if ((pid = fork()) < 0) { 86 | fprintf(stderr, "fork error"); 87 | exit(1); 88 | } else if (pid == 0) { /* child */ 89 | lockabyte("child", fd, 0); 90 | TELL_PARENT(getppid()); 91 | WAIT_PARENT(); 92 | lockabyte("child", fd, 1); 93 | } else { /* parent */ 94 | lockabyte("parent", fd, 1); 95 | TELL_CHILD(pid); 96 | WAIT_CHILD(); 97 | lockabyte("parent", fd, 0); 98 | } 99 | exit(0); 100 | } -------------------------------------------------------------------------------- /09-adv_io/codes/mcopy2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define COPYINCR (1024*1024*1024) /* 1 GB */ 10 | #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) 11 | 12 | int 13 | main(int argc, char *argv[]) 14 | { 15 | int fdin, fdout; 16 | void *src, *dst; 17 | size_t copysz; 18 | struct stat sbuf; 19 | off_t fsz = 0; 20 | 21 | if (argc != 3){ 22 | fprintf(stderr, "usage: %s ", argv[0]); 23 | exit(1); 24 | } 25 | 26 | if ((fdin = open(argv[1], O_RDONLY)) < 0){ 27 | fprintf(stderr, "can't open %s for reading", argv[1]); 28 | exit(1); 29 | } 30 | 31 | if ((fdout = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, 32 | FILE_MODE)) < 0){ 33 | fprintf(stderr, "can't creat %s for writing", argv[2]); 34 | exit(1); 35 | } 36 | 37 | if (fstat(fdin, &sbuf) < 0){ /* need size of input file */ 38 | fprintf(stderr, "fstat error"); 39 | exit(1); 40 | } 41 | 42 | if (ftruncate(fdout, sbuf.st_size) < 0){ /* set output file size */ 43 | fprintf(stderr, "ftruncate error"); 44 | exit(1); 45 | } 46 | 47 | while (fsz < sbuf.st_size) { 48 | if ((sbuf.st_size - fsz) > COPYINCR) 49 | copysz = COPYINCR; 50 | else 51 | copysz = sbuf.st_size - fsz; 52 | 53 | if ((src = mmap(0, copysz, PROT_READ, MAP_SHARED, 54 | fdin, fsz)) == MAP_FAILED){ 55 | fprintf(stderr, "mmap error for input"); 56 | exit(1); 57 | } 58 | if ((dst = mmap(0, copysz, PROT_READ | PROT_WRITE, 59 | MAP_SHARED, fdout, fsz)) == MAP_FAILED){ 60 | fprintf(stderr, "mmap error for output"); 61 | exit(1); 62 | } 63 | 64 | memcpy(dst, src, copysz); /* does the file copy */ 65 | munmap(src, copysz); 66 | munmap(dst, copysz); 67 | fsz += copysz; 68 | } 69 | exit(0); 70 | } 71 | -------------------------------------------------------------------------------- /09-adv_io/codes/nonblocking.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | char buf[500000]; 8 | 9 | 10 | 11 | /* flags are the file status flags to turn off */ 12 | void 13 | clr_fl(int fd, int flags) 14 | { 15 | int val; 16 | 17 | if ((val = fcntl(fd, F_GETFL, 0)) < 0){ 18 | fprintf(stderr, "fcntl F_GETFL error"); 19 | exit(1); 20 | } 21 | 22 | val &= ~flags; /* turn flags off */ 23 | 24 | if (fcntl(fd, F_SETFL, val) < 0){ 25 | fprintf(stderr, "fcntl F_SETFL error"); 26 | exit(1); 27 | } 28 | } 29 | 30 | /* flags are file status flags to turn on */ 31 | void 32 | set_fl(int fd, int flags) 33 | { 34 | int val; 35 | 36 | if ((val = fcntl(fd, F_GETFL, 0)) < 0){ 37 | fprintf(stderr, "fcntl F_GETFL error"); 38 | exit(1); 39 | } 40 | 41 | val |= flags; /* turn on flags */ 42 | 43 | if (fcntl(fd, F_SETFL, val) < 0){ 44 | fprintf(stderr, "fcntl F_SETFL error"); 45 | exit(1); 46 | } 47 | } 48 | 49 | int 50 | main(void) 51 | { 52 | int ntowrite, nwrite; 53 | char *ptr; 54 | ntowrite = read(STDIN_FILENO, buf, sizeof(buf)); 55 | fprintf(stderr, "read %d bytes\n", ntowrite); 56 | 57 | set_fl(STDOUT_FILENO, O_NONBLOCK); /* set nonblocking */ 58 | 59 | ptr = buf; 60 | 61 | while (ntowrite > 0) { 62 | errno = 0; 63 | nwrite = write(STDOUT_FILENO, ptr, ntowrite); 64 | fprintf(stderr, "nwrite = %d, errno = %d\n", nwrite, errno); 65 | if (nwrite > 0) { 66 | ptr += nwrite; 67 | ntowrite -= nwrite; 68 | } 69 | } 70 | 71 | clr_fl(STDOUT_FILENO, O_NONBLOCK); /* clear nonblocking */ 72 | 73 | exit(0); 74 | } -------------------------------------------------------------------------------- /09-adv_io/codes/readn.c: -------------------------------------------------------------------------------- 1 | ssize_t /* Read "n" bytes from a descriptor */ 2 | readn(int fd, void *ptr, size_t n) 3 | { 4 | size_t nleft; 5 | ssize_t nread; 6 | 7 | nleft = n; 8 | while (nleft > 0) { 9 | if ((nread = read(fd, ptr, nleft)) < 0) { 10 | if (nleft == n) 11 | return(-1); /* error, return -1 */ 12 | else 13 | break; /* error, return amount read so far */ 14 | } else if (nread == 0) { 15 | break; /* EOF */ 16 | } 17 | nleft -= nread; 18 | ptr += nread; 19 | } 20 | return(n - nleft); /* return >= 0 */ 21 | } 22 | -------------------------------------------------------------------------------- /09-adv_io/codes/rot13a.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define BSZ 4096 8 | #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) 9 | 10 | unsigned char buf[BSZ]; 11 | 12 | unsigned char 13 | translate(unsigned char c) 14 | { 15 | if (isalpha(c)) { 16 | if (c >= 'n') 17 | c -= 13; 18 | else if (c >= 'a') 19 | c += 13; 20 | else if (c >= 'N') 21 | c -= 13; 22 | else 23 | c += 13; 24 | } 25 | return(c); 26 | } 27 | 28 | int 29 | main(int argc, char* argv[]) 30 | { 31 | int ifd, ofd, i, n, nw; 32 | 33 | if (argc != 3){ 34 | fprintf(stderr, "usage: rot13 infile outfile"); 35 | exit(1); 36 | } 37 | if ((ifd = open(argv[1], O_RDONLY)) < 0){ 38 | fprintf(stderr, "can't open %s", argv[1]); 39 | exit(1); 40 | } 41 | if ((ofd = open(argv[2], O_RDWR|O_CREAT|O_TRUNC, FILE_MODE)) < 0){ 42 | fprintf(stderr, "can't create %s", argv[2]); 43 | exit(1); 44 | } 45 | 46 | while ((n = read(ifd, buf, BSZ)) > 0) { 47 | for (i = 0; i < n; i++) 48 | buf[i] = translate(buf[i]); 49 | if ((nw = write(ofd, buf, n)) != n) { 50 | if (nw < 0){ 51 | fprintf(stderr, "write failed"); 52 | exit(1); 53 | } 54 | else { 55 | fprintf(stderr, "short write (%d/%d)", nw, n); 56 | exit(1); 57 | } 58 | } 59 | } 60 | 61 | fsync(ofd); 62 | exit(0); 63 | } 64 | -------------------------------------------------------------------------------- /09-adv_io/codes/rot13c2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define BSZ 4096 11 | #define NBUF 8 12 | #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) 13 | 14 | enum rwop { 15 | UNUSED = 0, 16 | READ_PENDING = 1, 17 | WRITE_PENDING = 2 18 | }; 19 | 20 | struct buf { 21 | enum rwop op; 22 | int last; 23 | struct aiocb aiocb; 24 | unsigned char data[BSZ]; 25 | }; 26 | 27 | struct buf bufs[NBUF]; 28 | 29 | unsigned char 30 | translate(unsigned char c) 31 | { 32 | if (isalpha(c)) { 33 | if (c >= 'n') 34 | c -= 13; 35 | else if (c >= 'a') 36 | c += 13; 37 | else if (c >= 'N') 38 | c -= 13; 39 | else 40 | c += 13; 41 | } 42 | return(c); 43 | } 44 | 45 | int 46 | main(int argc, char* argv[]) 47 | { 48 | int ifd, ofd, i, j, n, err, numop; 49 | struct stat sbuf; 50 | const struct aiocb *aiolist[NBUF]; 51 | off_t off = 0; 52 | 53 | if (argc != 3){ 54 | fprintf(stderr, "usage: rot13 infile outfile"); 55 | exit(1); 56 | } 57 | if ((ifd = open(argv[1], O_RDONLY)) < 0){ 58 | fprintf(stderr, "can't open %s", argv[1]); 59 | exit(1); 60 | } 61 | if ((ofd = open(argv[2], O_RDWR|O_CREAT|O_TRUNC, FILE_MODE)) < 0){ 62 | fprintf(stderr, "can't create %s", argv[2]); 63 | exit(1); 64 | } 65 | if (fstat(ifd, &sbuf) < 0){ 66 | fprintf(stderr, "fstat failed"); 67 | exit(1); 68 | } 69 | 70 | /* initialize the buffers */ 71 | for (i = 0; i < NBUF; i++) { 72 | bufs[i].op = UNUSED; 73 | bufs[i].aiocb.aio_buf = bufs[i].data; 74 | bufs[i].aiocb.aio_sigevent.sigev_notify = SIGEV_NONE; 75 | aiolist[i] = NULL; 76 | } 77 | 78 | numop = 0; 79 | for (;;) { 80 | for (i = 0; i < NBUF; i++) { 81 | switch (bufs[i].op) { 82 | case UNUSED: 83 | /* 84 | * Read from the input file if more data 85 | * remains unread. 86 | */ 87 | if (off < sbuf.st_size) { 88 | bufs[i].op = READ_PENDING; 89 | bufs[i].aiocb.aio_fildes = ifd; 90 | bufs[i].aiocb.aio_offset = off; 91 | off += BSZ; 92 | if (off >= sbuf.st_size) 93 | bufs[i].last = 1; 94 | bufs[i].aiocb.aio_nbytes = BSZ; 95 | if (aio_read(&bufs[i].aiocb) < 0){ 96 | fprintf(stderr, "aio_read failed"); 97 | exit(1); 98 | } 99 | aiolist[i] = &bufs[i].aiocb; 100 | numop++; 101 | } 102 | break; 103 | 104 | case READ_PENDING: 105 | if ((err = aio_error(&bufs[i].aiocb)) == EINPROGRESS) 106 | continue; 107 | if (err != 0) { 108 | if (err == -1){ 109 | fprintf(stderr, "aio_error failed"); 110 | exit(1); 111 | } 112 | else{ 113 | fprintf(stderr, "read failed"); 114 | exit(1); 115 | } 116 | } 117 | 118 | /* 119 | * A read is complete; translate the buffer 120 | * and write it. 121 | */ 122 | if ((n = aio_return(&bufs[i].aiocb)) < 0){ 123 | fprintf(stderr, "aio_return failed"); 124 | exit(1); 125 | } 126 | if (n != BSZ && !bufs[i].last){ 127 | fprintf(stderr, "short read (%d/%d)", n, BSZ); 128 | exit(1); 129 | } 130 | for (j = 0; j < n; j++) 131 | bufs[i].data[j] = translate(bufs[i].data[j]); 132 | bufs[i].op = WRITE_PENDING; 133 | bufs[i].aiocb.aio_fildes = ofd; 134 | bufs[i].aiocb.aio_nbytes = n; 135 | if (aio_write(&bufs[i].aiocb) < 0){ 136 | fprintf(stderr, "aio_write failed"); 137 | exit(1); 138 | } 139 | /* retain our spot in aiolist */ 140 | break; 141 | 142 | case WRITE_PENDING: 143 | if ((err = aio_error(&bufs[i].aiocb)) == EINPROGRESS) 144 | continue; 145 | if (err != 0) { 146 | if (err == -1){ 147 | fprintf(stderr, "aio_error failed"); 148 | exit(1); 149 | } 150 | else{ 151 | fprintf(stderr, "write failed"); 152 | exit(1); 153 | } 154 | } 155 | 156 | /* 157 | * A write is complete; mark the buffer as unused. 158 | */ 159 | if ((n = aio_return(&bufs[i].aiocb)) < 0){ 160 | fprintf(stderr, "aio_return failed"); 161 | exit(1); 162 | } 163 | if (n != bufs[i].aiocb.aio_nbytes){ 164 | fprintf(stderr, "short write (%d/%d)", n, BSZ); 165 | exit(1); 166 | } 167 | aiolist[i] = NULL; 168 | bufs[i].op = UNUSED; 169 | numop--; 170 | break; 171 | } 172 | } 173 | if (numop == 0) { 174 | if (off >= sbuf.st_size) 175 | break; 176 | } else { 177 | if (aio_suspend(aiolist, NBUF, NULL) < 0){ 178 | fprintf(stderr, "aio_suspend failed"); 179 | exit(1); 180 | } 181 | } 182 | } 183 | 184 | bufs[0].aiocb.aio_fildes = ofd; 185 | if (aio_fsync(O_SYNC, &bufs[0].aiocb) < 0){ 186 | fprintf(stderr, "aio_fsync failed"); 187 | exit(1); 188 | } 189 | exit(0); 190 | } 191 | -------------------------------------------------------------------------------- /09-adv_io/codes/tellwait.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | static volatile sig_atomic_t sigflag; /* set nonzero by sig handler */ 7 | static sigset_t newmask, oldmask, zeromask; 8 | 9 | static void 10 | sig_usr(int signo) /* one signal handler for SIGUSR1 and SIGUSR2 */ 11 | { 12 | sigflag = 1; 13 | } 14 | 15 | void 16 | TELL_WAIT(void) 17 | { 18 | if (signal(SIGUSR1, sig_usr) == SIG_ERR){ 19 | fprintf(stderr, "signal(SIGUSR1) error"); 20 | exit(1); 21 | } 22 | if (signal(SIGUSR2, sig_usr) == SIG_ERR){ 23 | fprintf(stderr, "signal(SIGUSR2) error"); 24 | exit(1); 25 | } 26 | sigemptyset(&zeromask); 27 | sigemptyset(&newmask); 28 | sigaddset(&newmask, SIGUSR1); 29 | sigaddset(&newmask, SIGUSR2); 30 | 31 | /* Block SIGUSR1 and SIGUSR2, and save current signal mask */ 32 | if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0){ 33 | fprintf(stderr, "SIG_BLOCK error"); 34 | exit(1); 35 | } 36 | } 37 | 38 | void 39 | TELL_PARENT(pid_t pid) 40 | { 41 | kill(pid, SIGUSR2); /* tell parent we're done */ 42 | } 43 | 44 | void 45 | WAIT_PARENT(void) 46 | { 47 | while (sigflag == 0) 48 | sigsuspend(&zeromask); /* and wait for parent */ 49 | sigflag = 0; 50 | 51 | /* Reset signal mask to original value */ 52 | if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0){ 53 | fprintf(stderr, "SIG_SETMASK error"); 54 | exit(1); 55 | } 56 | } 57 | 58 | void 59 | TELL_CHILD(pid_t pid) 60 | { 61 | kill(pid, SIGUSR1); /* tell child we're done */ 62 | } 63 | 64 | void 65 | WAIT_CHILD(void) 66 | { 67 | while (sigflag == 0) 68 | sigsuspend(&zeromask); /* and wait for child */ 69 | sigflag = 0; 70 | 71 | /* Reset signal mask to original value */ 72 | if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0){ 73 | fprintf(stderr, "SIG_SETMASK error"); 74 | exit(1); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /09-adv_io/codes/writen.c: -------------------------------------------------------------------------------- 1 | ssize_t /* Write "n" bytes to a descriptor */ 2 | writen(int fd, const void *ptr, size_t n) 3 | { 4 | size_t nleft; 5 | ssize_t nwritten; 6 | 7 | nleft = n; 8 | while (nleft > 0) { 9 | if ((nwritten = write(fd, ptr, nleft)) < 0) { 10 | if (nleft == n) 11 | return(-1); /* error, return -1 */ 12 | else 13 | break; /* error, return amount written so far */ 14 | } else if (nwritten == 0) { 15 | break; 16 | } 17 | nleft -= nwritten; 18 | ptr += nwritten; 19 | } 20 | return(n - nleft); /* return >= 0 */ 21 | } 22 | -------------------------------------------------------------------------------- /09-adv_io/figures/fig14_10-filerange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/09-adv_io/figures/fig14_10-filerange.png -------------------------------------------------------------------------------- /09-adv_io/figures/fig14_2-reclock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/09-adv_io/figures/fig14_2-reclock.png -------------------------------------------------------------------------------- /09-adv_io/figures/fig14_22-iovec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/09-adv_io/figures/fig14_22-iovec.png -------------------------------------------------------------------------------- /09-adv_io/figures/fig14_26-mmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/09-adv_io/figures/fig14_26-mmap.png -------------------------------------------------------------------------------- /09-adv_io/figures/fig14_3-compatibility.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/09-adv_io/figures/fig14_3-compatibility.png -------------------------------------------------------------------------------- /09-adv_io/figures/fig14_4-file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/09-adv_io/figures/fig14_4-file.png -------------------------------------------------------------------------------- /09-adv_io/figures/fig14_8-freebsd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/09-adv_io/figures/fig14_8-freebsd.png -------------------------------------------------------------------------------- /10-ipc/10-ipc.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/10-ipc/10-ipc.pdf -------------------------------------------------------------------------------- /10-ipc/Makefile: -------------------------------------------------------------------------------- 1 | texfile = 11_ipc.tex 2 | outdir=/tmp 3 | 4 | all: ${texfile} 5 | pdflatex --shell-escape --output-directory ${outdir} $< 6 | 7 | clean: 8 | rm *.aux *.log *.nav *.out *.snm *.toc *.vrb 9 | 10 | o: ${texfile} 11 | gv ${outdir}/$(basename $<).pdf & 12 | 13 | final: ${texfile} 14 | pdflatex --shell-escape --output-directory ${outdir} $< 15 | pdflatex --shell-escape --output-directory ${outdir} $< 16 | cp ${outdir}/$(basename $<).pdf . 17 | 18 | -------------------------------------------------------------------------------- /10-ipc/README.md: -------------------------------------------------------------------------------- 1 | This is Lecture note on interprocess communication 2 | 3 | Visit following link for [course description](http://resourceful.github.io/classes/2016-12-07-week15-class12-ipc/) 4 | -------------------------------------------------------------------------------- /10-ipc/codes/Makefile: -------------------------------------------------------------------------------- 1 | 2 | PROGRAMS = pipe1 pipe2 pipe4 popen1 popen2 myuclc add2 create_fifo server client msg_send msg_receive tshm shm_send shm_receive 3 | 4 | CFLAGS = -g -Wall -O0 5 | 6 | all: ${PROGRAMS} 7 | 8 | %.o: %.c 9 | ${CC} ${CFLAGS} -c $< 10 | 11 | ${PROGRAMS}: %: %.o 12 | ${CC} ${CFLAGS} -o $@ $< 13 | 14 | clean: 15 | rm -r ${PROGRAMS} *.o 16 | 17 | -------------------------------------------------------------------------------- /10-ipc/codes/add2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define MAXLINE 4096 /* max line length */ 7 | 8 | int 9 | main(void) 10 | { 11 | int n, int1, int2; 12 | char line[MAXLINE]; 13 | 14 | while ((n = read(STDIN_FILENO, line, MAXLINE)) > 0) { 15 | line[n] = 0; /* null terminate */ 16 | if (sscanf(line, "%d%d", &int1, &int2) == 2) { 17 | sprintf(line, "%d\n", int1 + int2); 18 | n = strlen(line); 19 | if (write(STDOUT_FILENO, line, n) != n){ 20 | fprintf(stderr, "write error"); 21 | exit(1); 22 | } 23 | } else { 24 | if (write(STDOUT_FILENO, "invalid args\n", 13) != 13){ 25 | fprintf(stderr, "write error"); 26 | exit(1); 27 | } 28 | } 29 | } 30 | exit(0); 31 | } 32 | -------------------------------------------------------------------------------- /10-ipc/codes/client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | char *buf; 9 | int choice = 1; 10 | int fifo_server, fifo_client; 11 | 12 | printf("Chose one of following options to send to the server\n"); 13 | printf("\t\t 1 for the name of the OS \n \ 14 | 2 for the name of distribution \n \ 15 | 3 for the version of Kernel \n"); 16 | printf("Your choice: "); 17 | scanf("%d",&choice); 18 | 19 | fifo_server=open("FIFO-server",O_RDWR); 20 | if(fifo_server < 0) { 21 | fprintf(stderr, "Error in opening file"); 22 | exit(-1); 23 | } 24 | 25 | write(fifo_server, &choice, sizeof(int)); 26 | 27 | fifo_client=open("FIFO-client", O_RDWR); 28 | 29 | if(fifo_client < 0) { 30 | fprintf(stderr, "Error in opening file"); 31 | exit(-1); 32 | } 33 | 34 | buf=malloc(10*sizeof(char)); 35 | read (fifo_client, buf, 10*sizeof(char)); 36 | printf("\n ### Server replied with %s ###\n", buf); 37 | 38 | close(fifo_server); 39 | close(fifo_client); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /10-ipc/codes/create_fifo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() 6 | { 7 | int server, client; 8 | 9 | /* create a FIFO for server */ 10 | server = mkfifo("FIFO-server", 0666); 11 | if(server < 0) { 12 | fprintf(stderr, "Failed to create a FIFO for server"); 13 | exit(-1); 14 | } 15 | 16 | /* create a FIFO for client */ 17 | client = mkfifo("FIFO-client", 0666); 18 | if(client < 0) { 19 | fprintf(stderr, "Failed to create a FIFO for client"); 20 | exit(-1); 21 | } 22 | 23 | printf("FIFO for server and child created successfuly"); 24 | 25 | return 0; 26 | } -------------------------------------------------------------------------------- /10-ipc/codes/msg_receive.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define MSGSZ 128 8 | 9 | /* Declare the message structure */ 10 | 11 | typedef struct msgbuf { 12 | long mtype; 13 | char mtext[MSGSZ]; 14 | } message_buf; 15 | 16 | 17 | int main() 18 | { 19 | int msqid; 20 | key_t key; 21 | message_buf rbuf; 22 | 23 | if((key = ftok("Makefile", 'R')) == -1){ 24 | perror("ftok"); 25 | exit(1); 26 | } 27 | 28 | if ((msqid = msgget(key, 0666)) < 0) { 29 | perror("msgget"); 30 | exit(1); 31 | } 32 | 33 | /* Receive an answer of message type 1. */ 34 | if (msgrcv(msqid, &rbuf, MSGSZ, 1, 0) < 0) { 35 | perror("msgrcv"); 36 | exit(1); 37 | } 38 | 39 | /* Print the answer. */ 40 | printf("%s\n", rbuf.mtext); 41 | exit(0); 42 | } 43 | -------------------------------------------------------------------------------- /10-ipc/codes/msg_send.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define MSGSZ 128 9 | 10 | /* the message structure. */ 11 | typedef struct mymesg { 12 | long mtype; 13 | char mtext[MSGSZ]; 14 | } message_buf; 15 | 16 | int main() 17 | { 18 | int msqid; 19 | int msgflg = IPC_CREAT | 0666; 20 | key_t key; 21 | message_buf sbuf; 22 | size_t buf_length; 23 | 24 | if((key = ftok("Makefile", 'R')) == -1){ 25 | perror("ftok"); 26 | exit(1); 27 | } 28 | 29 | fprintf(stderr, "\nmsgget: Calling msgget(%#x, %#o)\n", key, msgflg); 30 | 31 | if ((msqid = msgget(key, msgflg )) < 0) { 32 | perror("msgget"); 33 | exit(1); 34 | } 35 | fprintf(stderr,"msgget: msgget succeeded: msqid = %d\n", msqid); 36 | 37 | /* We'll send message type 1 */ 38 | sbuf.mtype = 1; 39 | printf("Enter a message to add to the message queue: "); 40 | scanf("%[^\n]", sbuf.mtext); 41 | getchar(); 42 | 43 | buf_length = strlen(sbuf.mtext) + 1 ; 44 | 45 | /* Send a message.*/ 46 | if (msgsnd(msqid, &sbuf, buf_length, IPC_NOWAIT) < 0) { 47 | printf ("%d, %ld, %s, %ld\n", msqid, sbuf.mtype, sbuf.mtext, buf_length); 48 | perror("msgsnd"); 49 | exit(1); 50 | } else 51 | printf("Message: \"%s\" Sent\n", sbuf.mtext); 52 | 53 | exit(0); 54 | } 55 | -------------------------------------------------------------------------------- /10-ipc/codes/myuclc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int 7 | main(void) 8 | { 9 | int c; 10 | 11 | while ((c = getchar()) != EOF) { 12 | if (isupper(c)) 13 | c = tolower(c); 14 | else if (islower(c)) 15 | c = toupper(c); 16 | if (putchar(c) == EOF){ 17 | fprintf(stderr, "output error"); 18 | exit(1); 19 | } 20 | if (c == '\n') 21 | fflush(stdout); 22 | } 23 | exit(0); 24 | } 25 | -------------------------------------------------------------------------------- /10-ipc/codes/pipe1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | #define MAXLINE 4096 /* max line length */ 7 | 8 | int 9 | main(void) 10 | { 11 | int n; 12 | int fd[2]; 13 | pid_t pid; 14 | char line[MAXLINE]; 15 | 16 | if (pipe(fd) < 0){ 17 | fprintf(stderr, "pipe error"); 18 | exit(1); 19 | } 20 | if ((pid = fork()) < 0) { 21 | fprintf(stderr, "fork error"); 22 | exit(1); 23 | } else if (pid > 0) { /* parent */ 24 | close(fd[0]); 25 | write(fd[1], "hello world\n", 12); 26 | } else { /* child */ 27 | close(fd[1]); 28 | n = read(fd[0], line, MAXLINE); 29 | write(STDOUT_FILENO, line, n); 30 | } 31 | exit(0); 32 | } 33 | -------------------------------------------------------------------------------- /10-ipc/codes/pipe2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define MAXLINE 4096 /* max line length */ 8 | #define DEF_PAGER "/usr/bin/more" /* default pager program */ 9 | 10 | int 11 | main(int argc, char *argv[]) 12 | { 13 | int n; 14 | int fd[2]; 15 | pid_t pid; 16 | char *pager, *argv0; 17 | char line[MAXLINE]; 18 | FILE *fp; 19 | 20 | if (argc != 2){ 21 | fprintf(stderr, "usage: a.out "); 22 | exit(1); 23 | } 24 | 25 | if ((fp = fopen(argv[1], "r")) == NULL){ 26 | fprintf(stderr, "can't open %s", argv[1]); 27 | exit(1); 28 | } 29 | if (pipe(fd) < 0){ 30 | fprintf(stderr, "pipe error"); 31 | exit(1); 32 | } 33 | 34 | if ((pid = fork()) < 0) { 35 | fprintf(stderr, "fork error"); 36 | exit(1); 37 | } else if (pid > 0) { /* parent */ 38 | close(fd[0]); /* close read end */ 39 | 40 | /* parent copies argv[1] to pipe */ 41 | while (fgets(line, MAXLINE, fp) != NULL) { 42 | n = strlen(line); 43 | if (write(fd[1], line, n) != n) 44 | fprintf(stderr, "write error to pipe"); 45 | } 46 | if (ferror(fp)) 47 | fprintf(stderr, "fgets error"); 48 | 49 | close(fd[1]); /* close write end of pipe for reader */ 50 | 51 | if (waitpid(pid, NULL, 0) < 0){ 52 | fprintf(stderr, "waitpid error"); 53 | exit(1); 54 | } 55 | exit(0); 56 | } else { /* child */ 57 | close(fd[1]); /* close write end */ 58 | if (fd[0] != STDIN_FILENO) { 59 | if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO){ 60 | fprintf(stderr, "dup2 error to stdin"); 61 | exit(1); 62 | } 63 | close(fd[0]); /* don't need this after dup2 */ 64 | } 65 | 66 | /* get arguments for execl() */ 67 | if ((pager = getenv("PAGER")) == NULL) 68 | pager = DEF_PAGER; 69 | if ((argv0 = strrchr(pager, '/')) != NULL) 70 | argv0++; /* step past rightmost slash */ 71 | else 72 | argv0 = pager; /* no slash in pager */ 73 | 74 | if (execl(pager, argv0, (char *)0) < 0){ 75 | fprintf(stderr, "execl error for %s", pager); 76 | exit(1); 77 | } 78 | } 79 | exit(0); 80 | } 81 | -------------------------------------------------------------------------------- /10-ipc/codes/pipe4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define MAXLINE 4096 /* max line length */ 7 | 8 | static void sig_pipe(int); /* our signal handler */ 9 | 10 | int 11 | main(void) 12 | { 13 | int n, fd1[2], fd2[2]; 14 | pid_t pid; 15 | char line[MAXLINE]; 16 | 17 | if (signal(SIGPIPE, sig_pipe) == SIG_ERR){ 18 | fprintf(stderr, "signal error"); 19 | exit(1); 20 | } 21 | 22 | if (pipe(fd1) < 0 || pipe(fd2) < 0){ 23 | fprintf(stderr, "pipe error"); 24 | exit(1); 25 | } 26 | 27 | if ((pid = fork()) < 0) { 28 | fprintf(stderr, "fork error"); 29 | exit(1); 30 | } else if (pid > 0) { /* parent */ 31 | close(fd1[0]); 32 | close(fd2[1]); 33 | 34 | while (fgets(line, MAXLINE, stdin) != NULL) { 35 | if(strcmp(line, "quit\n") == 0 ) 36 | exit(0); 37 | n = strlen(line); 38 | if (write(fd1[1], line, n) != n){ 39 | fprintf(stderr, "write error to pipe"); 40 | exit(1); 41 | } 42 | if ((n = read(fd2[0], line, MAXLINE)) < 0){ 43 | fprintf(stderr, "read error from pipe"); 44 | exit(1); 45 | } 46 | if (n == 0) { 47 | fprintf(stderr, "child closed pipe"); 48 | break; 49 | } 50 | line[n] = 0; /* null terminate */ 51 | if (fputs(line, stdout) == EOF){ 52 | fprintf(stderr, "fputs error"); 53 | exit(1); 54 | } 55 | } 56 | 57 | if (ferror(stdin)){ 58 | fprintf(stderr, "fgets error on stdin"); 59 | exit(1); 60 | } 61 | exit(0); 62 | } else { /* child */ 63 | close(fd1[1]); 64 | close(fd2[0]); 65 | if (fd1[0] != STDIN_FILENO) { 66 | if (dup2(fd1[0], STDIN_FILENO) != STDIN_FILENO){ 67 | fprintf(stderr, "dup2 error to stdin"); 68 | exit(1); 69 | } 70 | close(fd1[0]); 71 | } 72 | 73 | if (fd2[1] != STDOUT_FILENO) { 74 | if (dup2(fd2[1], STDOUT_FILENO) != STDOUT_FILENO){ 75 | fprintf(stderr, "dup2 error to stdout"); 76 | exit(1); 77 | } 78 | close(fd2[1]); 79 | } 80 | if (execl("./add2", "add2", (char *)0) < 0){ 81 | fprintf(stderr, "execl error"); 82 | exit(1); 83 | } 84 | } 85 | exit(0); 86 | } 87 | 88 | static void 89 | sig_pipe(int signo) 90 | { 91 | printf("SIGPIPE caught\n"); 92 | exit(1); 93 | } 94 | -------------------------------------------------------------------------------- /10-ipc/codes/popen1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define MAXLINE 4096 /* max line length */ 8 | 9 | int 10 | main(void) 11 | { 12 | char line[MAXLINE]; 13 | FILE *fpin; 14 | 15 | if ((fpin = popen("./myuclc", "r")) == NULL){ 16 | fprintf(stderr, "popen error"); 17 | exit(1); 18 | } 19 | 20 | /* type 111 to exit the program */ 21 | while (strcmp(line, "111\n") != 0){ 22 | fputs("prompt> ", stdout); 23 | fflush(stdout); 24 | if (fgets(line, MAXLINE, fpin) == NULL) /* read from pipe */ 25 | break; 26 | if (fputs(line, stdout) == EOF) 27 | fprintf(stderr, "fputs error to pipe"); 28 | } 29 | if (pclose(fpin) == -1){ 30 | fprintf(stderr, "pclose error"); 31 | exit(1); 32 | } 33 | putchar('\n'); 34 | exit(0); 35 | } 36 | -------------------------------------------------------------------------------- /10-ipc/codes/popen2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define MAXLINE 4096 /* max line length */ 7 | #define PAGER "${PAGER:-more}" /* environment variable, or default */ 8 | 9 | int 10 | main(int argc, char *argv[]) 11 | { 12 | char line[MAXLINE]; 13 | FILE *fpin, *fpout; 14 | 15 | if (argc != 2){ 16 | fprintf(stderr, "usage: a.out "); 17 | exit(1); 18 | } 19 | if ((fpin = fopen(argv[1], "r")) == NULL){ 20 | fprintf(stderr, "can't open %s", argv[1]); 21 | exit(1); 22 | } 23 | 24 | if ((fpout = popen(PAGER, "w")) == NULL){ 25 | fprintf(stderr, "popen error"); 26 | exit(1); 27 | } 28 | 29 | /* copy argv[1] to pager */ 30 | while (fgets(line, MAXLINE, fpin) != NULL) { 31 | if (fputs(line, fpout) == EOF){ 32 | fprintf(stderr, "fputs error to pipe"); 33 | exit(1); 34 | } 35 | } 36 | if (ferror(fpin)){ 37 | fprintf(stderr, "fgets error"); 38 | exit(1); 39 | } 40 | if (pclose(fpout) == -1){ 41 | fprintf(stderr, "pclose error"); 42 | exit(1); 43 | } 44 | 45 | exit(0); 46 | } 47 | -------------------------------------------------------------------------------- /10-ipc/codes/server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main() 8 | { 9 | int FIFO_server,FIFO_client; 10 | int choice; 11 | char *buf; 12 | 13 | FIFO_server = open("FIFO-server", O_RDWR); 14 | if(FIFO_server < 0) { 15 | fprintf(stderr, "Error opening server side FIFO file"); 16 | exit(-1); 17 | } 18 | 19 | read(FIFO_server, &choice, sizeof(int)); 20 | 21 | sleep(1); 22 | 23 | FIFO_client = open("FIFO-client", O_RDWR); 24 | if(FIFO_client < 0) { 25 | fprintf(stderr, "Error opening client side FIFO file"); 26 | exit(-1); 27 | } 28 | 29 | switch(choice) { 30 | case 1: 31 | buf="Linux"; 32 | break; 33 | case 2: 34 | buf="Debian"; 35 | break; 36 | case 3: 37 | buf="4.0"; 38 | } 39 | 40 | write(FIFO_client,buf,10*sizeof(char)); 41 | printf("\n### Data sent to client ###\n"); 42 | 43 | close(FIFO_server); 44 | close(FIFO_client); 45 | return 0; 46 | } -------------------------------------------------------------------------------- /10-ipc/codes/shm_receive.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define SHSIZE 100 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | int shmid; 14 | key_t key; 15 | char *shm; 16 | char *s; 17 | char *message = "The client sends a reply0"; 18 | 19 | // generate key 20 | if( (key = ftok("Makefile", 'R')) == -1 ) 21 | { 22 | perror("ftok"); 23 | exit(1); 24 | } 25 | 26 | // connect to the segment 27 | if ( (shmid = shmget( key, SHSIZE, 0666 )) < 0 ) 28 | { 29 | perror( "shmget" ); 30 | exit(1); 31 | } 32 | 33 | // attach to the segment to get a pointer to it 34 | if ( (shm = shmat( shmid, NULL, 0 )) == (char *) -1 ) 35 | { 36 | perror( "shmat" ); 37 | exit(1); 38 | } 39 | 40 | 41 | printf("Reading server side message from Shared Memory\n"); 42 | sleep(1); 43 | 44 | // read shared memory 45 | for( s = shm ; *s != '0' ; s++ ) 46 | printf( "%c", *s ); 47 | 48 | printf( "\n" ); 49 | 50 | 51 | printf("Terminating the program\n"); 52 | sleep(1); 53 | // generate termination condition 54 | *shm = '*'; 55 | 56 | sleep(1); 57 | 58 | printf("Client sends a message back\n"); 59 | memcpy( shm, message, strlen(message) ); 60 | sleep(2); 61 | return 0; 62 | } -------------------------------------------------------------------------------- /10-ipc/codes/shm_send.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define SHSIZE 100 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | int shmid; 14 | key_t key; 15 | char *shm, *s; 16 | char *message = "The server sends a line of text0"; 17 | 18 | // generate key 19 | if ( (key = ftok("Makefile", 'R')) == -1 ) 20 | { 21 | perror("ftok"); 22 | exit(1); 23 | } 24 | 25 | // connect to the segment 26 | if ( (shmid = shmget( key, SHSIZE, IPC_CREAT | 0666 )) < 0 ) 27 | { 28 | perror( "shmget" ); 29 | exit(1); 30 | } 31 | 32 | // attach to the segment to get a pointer to it 33 | if ( (shm = shmat( shmid, NULL, 0 )) == (char *) -1 ) 34 | { 35 | perror( "shmat" ); 36 | exit(1); 37 | } 38 | 39 | // modify segment 40 | memcpy( shm, message, strlen(message) ); 41 | 42 | printf("Server side message is: %s\n", message); 43 | printf("Waiting for Client to change the memory\n"); 44 | 45 | // Wait for termination condition 46 | while( *shm != '*' ) 47 | sleep( 1 ); 48 | 49 | sleep (1); 50 | printf("\nClient changed the memory, and the message is: \n"); 51 | for( s = shm ; *s != '0' ; s++ ) 52 | printf( "%c", *s ); 53 | 54 | 55 | sleep( 1 ); 56 | 57 | return 0; 58 | } -------------------------------------------------------------------------------- /10-ipc/codes/tshm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define ARRAY_SIZE 40000 6 | #define MALLOC_SIZE 100000 7 | #define SHM_SIZE 100000 8 | #define SHM_MODE 0600 /* user read/write */ 9 | 10 | char array[ARRAY_SIZE]; /* uninitialized data = bss */ 11 | 12 | int 13 | main(void) 14 | { 15 | int shmid; 16 | char *ptr, *shmptr; 17 | 18 | printf("array[] from %p to %p\n", (void *)&array[0], 19 | (void *)&array[ARRAY_SIZE]); 20 | printf("stack around %p\n", (void *)&shmid); 21 | 22 | if ((ptr = malloc(MALLOC_SIZE)) == NULL){ 23 | perror("malloc error"); 24 | exit(1); 25 | } 26 | printf("malloced from %p to %p\n", (void *)ptr, 27 | (void *)ptr+MALLOC_SIZE); 28 | 29 | if ((shmid = shmget(IPC_PRIVATE, SHM_SIZE, SHM_MODE)) < 0){ 30 | perror("shmget error"); 31 | exit(1); 32 | } 33 | if ((shmptr = shmat(shmid, 0, 0)) == (void *)-1){ 34 | perror("shmat error"); 35 | exit(1); 36 | } 37 | printf("shared memory attached from %p to %p\n", (void *)shmptr, 38 | (void *)shmptr+SHM_SIZE); 39 | 40 | if (shmctl(shmid, IPC_RMID, 0) < 0){ 41 | perror("shmctl error"); 42 | exit(1); 43 | } 44 | 45 | exit(0); 46 | } 47 | -------------------------------------------------------------------------------- /10-ipc/figures/fig15_10-result-w.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/10-ipc/figures/fig15_10-result-w.png -------------------------------------------------------------------------------- /10-ipc/figures/fig15_16-driving.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/10-ipc/figures/fig15_16-driving.png -------------------------------------------------------------------------------- /10-ipc/figures/fig15_2-twoways.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/10-ipc/figures/fig15_2-twoways.png -------------------------------------------------------------------------------- /10-ipc/figures/fig15_20-procedure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/10-ipc/figures/fig15_20-procedure.png -------------------------------------------------------------------------------- /10-ipc/figures/fig15_21-using.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/10-ipc/figures/fig15_21-using.png -------------------------------------------------------------------------------- /10-ipc/figures/fig15_23-client.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/10-ipc/figures/fig15_23-client.png -------------------------------------------------------------------------------- /10-ipc/figures/fig15_24-xsi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/10-ipc/figures/fig15_24-xsi.png -------------------------------------------------------------------------------- /10-ipc/figures/fig15_25-comparison.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/10-ipc/figures/fig15_25-comparison.png -------------------------------------------------------------------------------- /10-ipc/figures/fig15_3-halfduplex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/10-ipc/figures/fig15_3-halfduplex.png -------------------------------------------------------------------------------- /10-ipc/figures/fig15_32-memory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/10-ipc/figures/fig15_32-memory.png -------------------------------------------------------------------------------- /10-ipc/figures/fig15_4-pipe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/10-ipc/figures/fig15_4-pipe.png -------------------------------------------------------------------------------- /10-ipc/figures/fig15_9-result-r.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/10-ipc/figures/fig15_9-result-r.png -------------------------------------------------------------------------------- /11-socket/11-socket.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/11-socket/11-socket.pdf -------------------------------------------------------------------------------- /11-socket/Makefile: -------------------------------------------------------------------------------- 1 | texfile = 12_socket.tex 2 | outdir=/tmp 3 | 4 | all: ${texfile} 5 | pdflatex --shell-escape --output-directory ${outdir} $< 6 | 7 | clean: 8 | rm *.aux *.log *.nav *.out *.snm *.toc *.vrb 9 | 10 | o: ${texfile} 11 | gv ${outdir}/$(basename $<).pdf & 12 | 13 | final: ${texfile} 14 | pdflatex --shell-escape --output-directory ${outdir} $< 15 | pdflatex --shell-escape --output-directory ${outdir} $< 16 | cp ${outdir}/$(basename $<).pdf . 17 | 18 | -------------------------------------------------------------------------------- /11-socket/figures/fig_socket_syscall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/11-socket/figures/fig_socket_syscall.png -------------------------------------------------------------------------------- /Editor_Level_Test/20161102_test/README.md: -------------------------------------------------------------------------------- 1 | ## Directions 2 | 3 | * download vim_test.pdf and manuscript_test.txt 4 | * manuscript_test.txt is the file you are goint to use for the test 5 | * vim_test.pdf includes all the changes you have to make on the txt file 6 | * when you are done editing, use your name in english as the result file name 7 | * archive the file and send the file to insight@hanyang.ac.kr 8 | * use tar cjvf YOUR_RESULT_FILE.tar.gz YOUR_RESULT_FILE.txt -------------------------------------------------------------------------------- /Editor_Level_Test/20161102_test/vim_test.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/Editor_Level_Test/20161102_test/vim_test.pdf -------------------------------------------------------------------------------- /Editor_Level_Test/first_test_score.txt: -------------------------------------------------------------------------------- 1 | #Name number of differences 2 | 01_허주환_2013011190.txt 11 3 | 02_ParkSeonha_2015004120.txt 0 4 | 03_제갈지혜_2015004257.txt 1 5 | 04_지형탁_2013011156.txt 1 6 | 05_김상우_2013010971.txt 1 7 | 06_강병욱_2011021764.txt 47 8 | 07_강희범_2015003972.txt 2 9 | 08_kangeunsoek_2013010926.txt 7 10 | 09_CHOIJUNYOUNG_2013011178.txt 1 11 | 10_Seung-ho_Yang_2013011060.txt 10 12 | 11_ChoiJooYoon_2012003277.txt 9 13 | 12_JUNGMINYOUNG_2013011145.txt 11 14 | 13_김명진_2013010960.txt 9 15 | 14_권기택_2015003990.txt 6 16 | 15_박한솔_2013011059.txt 2 17 | 16_이지웅_2012003200.txt 8 18 | 17_Park-donghyuck_2014004020.txt 18 19 | 18_김동환_2015004020.txt 6 20 | 19_이경준_2015004175.txt 6 21 | 20_김태훈_2015004084.txt 6 22 | 21_서왕규_2014004066.txt 6 23 | 22_김준근_2014003981.txt 8 24 | 23_서성빈_2015004148.txt 6 25 | 24_김도현_2015004011.txt 8 26 | 25_고진석_2015003981.txt 6 27 | 26_오승준_2015004157.txt 6 28 | 27_KimTaewoo_2013011015.txt 2 29 | 28_choikiwon_2014004184.txt 11 30 | 29_김동훈_2015004039.txt 6 31 | 30_박한솔_2013011059.txt 2 32 | 31_KimHyochan_2013011026.txt 15 33 | 32_김범수_2015004057.txt 1 34 | 33_김경한_2015004002.txt 1 35 | 34_YoonSeobLee_2015004211.txt 3 36 | 35_LeeJungho_2015004220.txt 15 37 | 36_문혜라_2015004111.txt 6 38 | 37_김수진_2015004066.txt 7 39 | 38_우효경_2012003136.txt 6 40 | 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is course material for System Programming class in Hanyang University 2 | 3 | please check [here (http://resourceful.github.io/classes)](http://resourceful.github.io/classes) for more info. 4 | -------------------------------------------------------------------------------- /beamer_template/beamercolorthemesthlm.sty: -------------------------------------------------------------------------------- 1 | %-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 2 | % COLOR PALETTE 3 | %-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 4 | 5 | \ProvidesPackage{beamercolorthemev42} 6 | 7 | %-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 8 | % OPTIONS 9 | %-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 10 | 11 | \newif\if@beamer@sthlm@cblock 12 | \@beamer@sthlm@cblockfalse 13 | \DeclareOptionBeamer{cblock}{\@beamer@sthlm@cblocktrue} 14 | 15 | \newif\if@beamer@sthlm@greybg 16 | \@beamer@sthlm@greybgfalse 17 | \DeclareOptionBeamer{greybg}{\@beamer@sthlm@greybgtrue} 18 | 19 | \DeclareOptionBeamer*{% 20 | \PackageWarning{beamercolorthemesthlm}{Unknown option `\CurrentOption'}% 21 | } 22 | 23 | \ProcessOptionsBeamer 24 | 25 | %-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 26 | % STOCKHOLMS COLOR THEME 27 | %-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 28 | 29 | %== BLUE 30 | \definecolor{sthlmLightBlue}{RGB}{214,237,252} % HEX #d6edfc 31 | \newcommand{\csthlmLightBlue}[1]{{\color{sthlmLightBlue}{#1}}} 32 | \definecolor{sthlmBlue}{RGB}{0,110,191} % HEX #006ebf 33 | \newcommand{\csthlmBlue}[1]{{\color{sthlmBlue}{#1}}} 34 | %\definecolor{sthlmDarkBlue}{RGB}{} %HEX # 35 | %\newcommand{\csthlmDarkBlue}[1]{{\color{sthlmDarkBlue}{#1}}} 36 | 37 | %== GREEN 38 | 39 | \definecolor{sthlmLightGreen}{RGB}{213,247,244} % HEX #0d5f7f4 40 | \newcommand{\csthlmLightGreen}[1]{{\color{sthlmLightGreen}{#1}}} 41 | \definecolor{sthlmGreen}{RGB}{0,134,127} % #00867f 42 | \newcommand{\csthlmGreen}[1]{{\color{sthlmGreen}{#1}}} 43 | 44 | %== GREY 45 | %\definecolor{sthlmLightGrey}{RGB}{} 46 | %\newcommand{\csthlmLightGrey}[1]{{\color{sthlmLightGrey}{#1}}} 47 | \definecolor{sthlmGrey}{RGB}{245,243,238} % HEX #f5f3ee 48 | \newcommand{\csthlmGrey}[1]{{\color{sthlmGrey}{#1}}} 49 | \definecolor{sthlmDarkGrey}{RGB}{51,51,51} % HEX #333333 50 | \newcommand{\csthlmDarkGrey}[1]{{\color{sthlmDarkGrey}{#1}}} 51 | 52 | %== ORANGE 53 | \definecolor{sthlmLightOrange}{RGB}{255,215,210} % HEX #ffd7d2 54 | \newcommand{\csthlmLightOrange}[1]{{\color{sthlmLightOrange}{#1}}} 55 | \definecolor{sthlmOrange}{RGB}{221,74,44} % HEX #dd4a2c 56 | \newcommand{\csthlmOrange}[1]{{\color{sthlmOrange}{#1}}} 57 | 58 | %== PURPLE 59 | 60 | \definecolor{sthlmLightPurple}{RGB}{241,230,252} % HEX #f1e6fc 61 | \newcommand{\csthlmLightPurple}[1]{{\color{sthlmLightPurple}{#1}}} 62 | \definecolor{sthlmPurple}{RGB}{93,35,125} % HEX #5d237d 63 | \newcommand{\csthlmPurple}[1]{{\color{sthlmPurple}{#1}}} 64 | 65 | %== RED 66 | 67 | \definecolor{sthlmLightRed}{RGB}{254,222,237} % HEX #c40064 68 | \newcommand{\csthlmLightRed}[1]{{\color{sthlmLightRed}{#1}}} 69 | \definecolor{sthlmRed}{RGB}{196,0,100} % HEX #fedeed 70 | \newcommand{\csthlmRed}[1]{{\color{sthlmRed}{#1}}} 71 | %\definecolor{sthlmDarkRed}{RGB}{} % HEX # 72 | %\newcommand{\csthlmDarkRed}[1]{{\color{sthlmDarkRed}{#1}}} 73 | 74 | %== YELLOW 75 | 76 | %\definecolor{sthlmLightYellow}{RGB}{} 77 | %\newcommand{\csthlmLightYellow}[1]{{\color{sthlmLightYellow}{#1}}} 78 | \definecolor{sthlmYellow}{RGB}{252,191,10} % HEX #fcbf0a 79 | \newcommand{\csthlmYellow}[1]{{\color{sthlmYellow}{#1}}} 80 | 81 | %-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 82 | % ISSR COLORS 83 | %-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 84 | 85 | %== BLUE 86 | \definecolor{issrBlue}{RGB}{0,111,174} % HEX #0066cc 87 | \newcommand{\cissrBlue}[1]{{\color{issrBlue}{#1}}} 88 | 89 | %== GREY 90 | \definecolor{issrGrey}{RGB}{167,169,172} % HEX #999999 91 | \newcommand{\cissrGrey}[1]{{\color{issrGrey}{#1}}} 92 | 93 | %-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 94 | % GLOBAL COLOR THEME 95 | %-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 96 | 97 | %== BLUE 98 | 99 | \newcommand{\cLightBlue}[1]{{\color{sthlmLightBlue}{#1}}} 100 | \newcommand{\crLightBlue}{\color{sthlmLightBlue}} 101 | \newcommand{\cnLightBlue}{sthlmLightBlue} 102 | \newcommand{\cBlue}[1]{{\color{sthlmBlue}{#1}}} 103 | \newcommand{\crBlue}{\color{sthlmBlue}} 104 | \newcommand{\cnBlue}{sthlmBlue} 105 | %\newcommand{\cDarkBlue}[1]{{\color{}{#1}}} 106 | %\newcommand{\crDarkBlue}{\color{}} 107 | %\newcommand{\cnDarkBlue}{} 108 | 109 | %== GREEN 110 | 111 | %\newcommand{\cLightGreen}[1]{{\color{}{#1}}} 112 | %\newcommand{\crLightGreen}{\color{}} 113 | \newcommand{\cnLightGreen}{sthlmLightGreen} 114 | \newcommand{\cGreen}[1]{{\color{sthlmGreen}{#1}}} 115 | \newcommand{\crGreen}{\color{sthlmGreen}} 116 | \newcommand{\cnGreen}{sthlmGreen} 117 | %\newcommand{\cDarkGreen}[1]{{\color{}{#1}}} 118 | %\newcommand{\crDarkGreen}{\color{}} 119 | %\newcommand{\cnDarkGreen}{sthlmDarkGreen} 120 | 121 | %== GREY 122 | 123 | \newcommand{\cLightGrey}[1]{{\color{sthlmLightGrey}{#1}}} 124 | \newcommand{\crLightGrey}{\color{sthlmLightGrey}} 125 | \newcommand{\cnLightGrey}{sthlmLightGrey} 126 | \newcommand{\cGrey}[1]{{\color{sthlmGrey}{#1}}} 127 | \newcommand{\crGrey}{\color{sthlmGrey}} 128 | \newcommand{\cnGrey}{sthlmGrey} 129 | \newcommand{\cDarkGrey}[1]{{\color{sthlmDarkGrey}{#1}}} 130 | \newcommand{\crDarkGrey}{\color{sthlmDarkGrey}} 131 | \newcommand{\cnDarkGrey}{sthlmDarkGrey} 132 | 133 | %== ORANGE 134 | 135 | \newcommand{\cLightOrange}[1]{{\color{sthlmLightOrange}{#1}}} 136 | \newcommand{\crLightOrange}{\color{sthlmLightOrange}} 137 | \newcommand{\cnLightOrange}{sthlmLightOrange} 138 | \newcommand{\cOrange}[1]{{\color{}{#1}}} 139 | \newcommand{\crOrange}{\color{sthlmOrange}} 140 | \newcommand{\cnOrange}{sthlmOrange} 141 | %\newcommand{\cDarkOrange}[1]{{\color{}{#1}}} 142 | %\newcommand{\crDarkOrange}{\color{}} 143 | %\newcommand{\cnDarkOrange}{} 144 | 145 | %== PURPLE 146 | 147 | \newcommand{\cLightPurple}[1]{{\color{sthlmLightPurple}{#1}}} 148 | \newcommand{\crLightPurple}{\color{sthlmLightPurple}} 149 | \newcommand{\cnLightPurple}{sthlmLightPurple} 150 | \newcommand{\cPurple}[1]{{\color{sthlmPurple}{#1}}} 151 | \newcommand{\crPurple}{\color{sthlmPurple}} 152 | \newcommand{\cnPurple}{sthlmPurple} 153 | %\newcommand{\cDarkPurple}[1]{{\color{}{#1}}} 154 | %\newcommand{\crDarkPurple}{\color{}} 155 | %\newcommand{\cnDarkPurple}{} 156 | 157 | %== RED 158 | 159 | \newcommand{\cLightRed}[1]{{\color{sthlmLightRed}{#1}}} 160 | \newcommand{\crLightRed}{\color{sthlmLightRed}} 161 | \newcommand{\cnLightRed}{sthlmLightRed} 162 | \newcommand{\cRed}[1]{{\color{sthlmRed}{#1}}} 163 | \newcommand{\crRed}{\color{sthlmRed}} 164 | \newcommand{\cnRed}{sthlmRed} 165 | \newcommand{\cDarkRed}[1]{{\color{sthlmDarkRed}{#1}}} 166 | \newcommand{\crDarkRed}{\color{sthlmDarkRed}} 167 | \newcommand{\cnDarkRed}{sthlmDarkRed} 168 | 169 | %== YELLOW 170 | 171 | %\newcommand{\cLightYellow}[1]{{\color{}{#1}}} 172 | %\newcommand{\crLightYellow}{\color{}} 173 | %\newcommand{\cnLightYellow}{sthlmLightYellow} 174 | \newcommand{\cYellow}[1]{{\color{sthlmYellow}{#1}}} 175 | \newcommand{\crYellow}{\color{sthlmYellow}} 176 | \newcommand{\cnYellow}{sthlmYellow} 177 | %\newcommand{\cDarkYellow}[1]{{\color{}{#1}}} 178 | %\newcommand{\crDarkYellow}{\color{}} 179 | %\newcommand{\cnDarkYellow}{} 180 | 181 | 182 | % General 183 | \setbeamercolor{normal text}{fg=sthlmDarkGrey} 184 | \setbeamercolor{structure}{fg=sthlmDarkGrey} 185 | \setbeamercolor{alerted text}{fg=sthlmRed} 186 | \setbeamercolor{example text}{fg=sthlmGreen} 187 | \setbeamercolor{copyright text}{fg=sthlmPurple} 188 | 189 | % Palettes 190 | \setbeamercolor{palette primary}{fg=sthlmGrey, bg=sthlmDarkGrey} 191 | \setbeamercolor{palette secondary}{fg=sthlmDarkGrey,bg=sthlmGrey} 192 | \setbeamercolor{palette tertiary}{fg=sthlmLightBlue, bg=sthlmDarkGrey} 193 | \setbeamercolor{palette quaternary}{fg=sthlmGrey, bg=sthlmBlue} 194 | \setbeamercolor{mini frame}{bg=sthlmGrey} 195 | \setbeamercolor{section in head/foot}{fg=sthlmDarkGrey, bg=sthlmGrey} 196 | 197 | % Titlepage 198 | \setbeamercolor{title}{parent=normal text} 199 | \setbeamercolor{subtitle}{fg=sthlmBlue} 200 | \setbeamercolor{institute}{parent=normal text} 201 | 202 | % Content 203 | \setbeamercolor{frametitle}{parent=palette primary} 204 | 205 | % Blocks 206 | \setbeamercolor{block title}{fg=white,bg=sthlmBlue} 207 | \setbeamercolor{block body}{fg=sthlmDarkGrey, bg=sthlmGrey} 208 | \setbeamercolor{block title example}{fg=white, bg=sthlmGreen} 209 | \setbeamercolor{block body example}{fg=sthlmDarkGrey, bg=sthlmLightGreen} 210 | \setbeamercolor{block title alerted}{fg=white, bg=sthlmRed} 211 | \setbeamercolor{block body alerted}{fg=sthlmDarkGrey, bg=sthlmLightRed} 212 | 213 | % Notes 214 | \setbeamercolor{note page}{fg=sthlmDarkGrey,bg=sthlmGrey} 215 | \setbeamercolor{note title}{fg=white, bg=sthlmDarkGrey} 216 | \setbeamercolor{note date}{parent=note title} 217 | 218 | % Page Number 219 | \setbeamercolor{page number in head/foot}{fg=sthlmDarkGrey} 220 | \setbeamercolor{qed}{fg=sthlmGreen} 221 | \setbeamercolor{itemize item}{fg=sthlmBlue} 222 | \setbeamercolor{itemize subitem}{fg=sthlmRed} 223 | \setbeamercolor{itemize subsubitem}{fg=sthlmPurple} 224 | 225 | \if@beamer@sthlm@greybg 226 | % General 227 | \setbeamercolor{normal text}{fg=sthlmDarkGrey,bg=sthlmGrey} 228 | \setbeamercolor{block body}{fg=sthlmDarkGrey, bg=sthlmLightBlue} 229 | \fi 230 | 231 | \if@beamer@sthlm@cblock 232 | 233 | \setbeamercolor{block title}{fg=white,bg=sthlmBlue} 234 | \setbeamercolor{block body}{fg=sthlmDarkGrey, bg=sthlmLightBlue} 235 | \setbeamercolor{block title example}{fg=white, bg=sthlmGreen} 236 | \setbeamercolor{block body example}{fg=sthlmDarkGrey, bg=sthlmLightGreen} 237 | \setbeamercolor{block title alerted}{fg=white, bg=sthlmRed} 238 | \setbeamercolor{block body alerted}{fg=sthlmDarkGrey, bg=sthlmLightRed} 239 | 240 | \setbeamercolor{qed}{fg=sthlmDarkGrey} 241 | \setbeamercolor{itemize item}{fg=sthlmBlue} 242 | \setbeamercolor{itemize subitem}{fg=sthlmRed} 243 | \setbeamercolor{itemize subsubitem}{fg=sthlmDarkGrey} 244 | \fi 245 | 246 | \mode -------------------------------------------------------------------------------- /beamer_template/beamerfontthemesthlm.sty: -------------------------------------------------------------------------------- 1 | %-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 2 | % FONT FAMILES 3 | %-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 4 | \ProvidesPackage{beamerfontthememsthlm} 5 | 6 | % NEWPX FONT (Latex) 7 | 8 | \if@donewPxFont% 9 | % Load newPx Font % 10 | \usefonttheme{professionalfonts} 11 | \usefonttheme{serif} 12 | \RequirePackage[T1]{fontenc} 13 | \RequirePackage[full]{textcomp} 14 | \RequirePackage[osf]{newpxtext} % osf for text, not math 15 | \RequirePackage{cabin} % sans serif 16 | \RequirePackage[varqu,varl]{inconsolata} % sans serif mono font 17 | \RequirePackage[bigdelims,vvarbb]{newpxmath} % bb from STIX 18 | \RequirePackage[cal=boondoxo]{mathalfa} % This package provides a standard means of setting math alphabets associated with the macros \mathcal, \mathbb, \mathfrak 19 | \fi% 20 | 21 | % PROPRIETARY STOCKHOLM STAD FONTS (XeTeX) 22 | 23 | \if@dosthlmStadFont% 24 | % Load sthlmStad Fonts % 25 | \usefonttheme{professionalfonts} 26 | \RequirePackage[no-math]{fontspec} 27 | \defaultfontfeatures{Mapping=tex-text} 28 | \setsansfont[BoldFont={Stockholm Type Display Bold}]{Stockholm Type Display Regular} 29 | 30 | \AtBeginEnvironment{tabular}{\setsansfont[BoldFont={Stockholm Type}, Numbers={Monospaced}]{Stockholm Type}} 31 | \fi% 32 | 33 | %-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 34 | % FONT ASSIGMENTS 35 | %-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 36 | % Title Page 37 | \setbeamerfont{title}{family=\sffamily, series=\scshape, size=\huge} 38 | \setbeamerfont{subtitle}{size=\Large} 39 | \setbeamerfont{date}{size=\large} 40 | \setbeamerfont{author}{size=\large} 41 | \setbeamerfont{institute}{size=\large} 42 | 43 | % Section 44 | \setbeamerfont{section title}{size=\Large} 45 | 46 | % Content 47 | \setbeamerfont{frametitle}{family=\sffamily, size=\Large} 48 | \setbeamerfont{copyright text}{size=\tiny} 49 | \setbeamerfont{block title}{series=\sffamily, size=\large} 50 | \setbeamerfont{block title alerted}{family=\sffamily, size=\large} 51 | \setbeamerfont{alerted text}{series=\scshape} 52 | \setbeamerfont{block title example}{family=\sffamily, size=\large} 53 | \setbeamerfont{example text}{series=\scshape} 54 | 55 | \setbeamerfont{caption}{size=\small} 56 | \setbeamerfont{caption name}{family=\small} 57 | 58 | \setbeamerfont{page number in head/foot}{size=\scriptsize} 59 | 60 | 61 | \linespread{1.15} -------------------------------------------------------------------------------- /beamer_template/pictures/foxed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/beamer_template/pictures/foxed.png -------------------------------------------------------------------------------- /project1/README.md: -------------------------------------------------------------------------------- 1 | More details about project 1 is found on [this link](http://resourceful.github.io/classes/2016-09-21-announcing-the-project/) 2 | -------------------------------------------------------------------------------- /project1/codes/Makefile: -------------------------------------------------------------------------------- 1 | PROGRAMS = sysp 2 | 3 | CFLAGS = -g -Wall -O0 4 | 5 | all: ${PROGRAMS} 6 | 7 | %.o: %.c 8 | ${CC} ${CFLAGS} -c $< 9 | 10 | ${PROGRAMS}: %: %.o 11 | ${CC} ${CFLAGS} -o $@ $< 12 | 13 | clean: 14 | rm -r ${PROGRAMS} *.o 15 | 16 | -------------------------------------------------------------------------------- /project1/codes/mkfs.f2fs: -------------------------------------------------------------------------------- 1 | ../f2fs-tools/mkfs/mkfs.f2fs -------------------------------------------------------------------------------- /project1/codes/sysp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | void withSync() { 15 | int idx = 0; 16 | int g = 0; 17 | int f[9]; 18 | for(idx = 0; idx <= 9; idx++) { 19 | char filename[20]; 20 | sprintf(filename, "f_%d.txt", idx); 21 | if(idx == 0) 22 | { 23 | g = open(filename, O_RDWR | O_CREAT); 24 | lseek (g, 0, SEEK_END); 25 | int records = 1; 26 | int i = 0; 27 | char *buf = NULL; 28 | buf = (char*) malloc(1024 * 64); 29 | memset (buf, 0xcafe, 1024 * 64); 30 | for(i = 0; i < records; i++) { 31 | write(g, buf, 1 * 1024); 32 | } 33 | } else { 34 | f[idx] = open(filename, O_RDWR | O_CREAT); 35 | 36 | lseek (f[idx], 0, SEEK_END); 37 | 38 | int records = 1; 39 | int i = 0; 40 | char *buf = NULL; 41 | 42 | buf = (char*) malloc(1024 * 64); 43 | memset (buf, 0xcafe, 1024 * 64); 44 | 45 | for(i = 0; i < records; i++) { 46 | write(f[idx], buf, 1 * 1024); 47 | } 48 | usleep(1000); 49 | if(idx == 9) {fsync(f[idx]);} 50 | close (f[idx]); 51 | } 52 | } 53 | close(g); 54 | } 55 | 56 | int main(int argc, const char * argv[]) { 57 | withSync(); 58 | return 0; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /project1/f2fs_ctags.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/project1/f2fs_ctags.pdf -------------------------------------------------------------------------------- /project1/figure/command1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/project1/figure/command1.png -------------------------------------------------------------------------------- /project1/figure/command2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/project1/figure/command2.png -------------------------------------------------------------------------------- /project1/figure/command3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/project1/figure/command3.png -------------------------------------------------------------------------------- /project1/figure/f2fsstatus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/project1/figure/f2fsstatus.png -------------------------------------------------------------------------------- /project1/figure/format.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/project1/figure/format.png -------------------------------------------------------------------------------- /project1/figure/stj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/project1/figure/stj.png -------------------------------------------------------------------------------- /project1/figure/tags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/project1/figure/tags.png -------------------------------------------------------------------------------- /project1/figure/tagsinside.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/project1/figure/tagsinside.png -------------------------------------------------------------------------------- /project1/figure/ts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/project1/figure/ts.png -------------------------------------------------------------------------------- /project1/figure/vimctags.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/project1/figure/vimctags.png -------------------------------------------------------------------------------- /project1/figure/vm_config_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/project1/figure/vm_config_1.png -------------------------------------------------------------------------------- /project1/figure/vm_config_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/project1/figure/vm_config_2.png -------------------------------------------------------------------------------- /project1/figure/vm_config_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/project1/figure/vm_config_3.png -------------------------------------------------------------------------------- /project1/figure/vm_config_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/project1/figure/vm_config_4.png -------------------------------------------------------------------------------- /project1/figure/vm_config_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/project1/figure/vm_config_5.png -------------------------------------------------------------------------------- /project1/howto_kernel_compile.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/project1/howto_kernel_compile.pdf -------------------------------------------------------------------------------- /quiz/20161214_editor_eval/blktrace.txt: -------------------------------------------------------------------------------- 1 | BLKTRACE(8) BLKTRACE(8) 2 | 3 | 4 | 5 | NAME 6 | blktrace - generate traces of the i/o traffic on block devices 7 | 8 | 9 | 10 | SYNOPSIS 11 | blktrace -d dev [ -r debugfs_path ] [ -o output ] [-k ] [ -w time ] [ -a action ] [ -A action_mask ] [ -v ] 12 | 13 | 14 | 15 | DESCRIPTION 16 | blktrace is a block layer IO tracing mechanism which provides detailed information about request queue operations up to 17 | user space. There are three major components: a kernel component, a utility to record the i/o trace information for the 18 | kernel to user space, and utilities to analyse and view the trace information. This man page describes blktrace, which 19 | records the i/o event trace information for a specific block device to a file. 20 | 21 | The blktrace utility extracts event traces from the kernel (via the relaying through the debug file system). Some back‐ 22 | ground details concerning the run-time behaviour of blktrace will help to understand some of the more arcane command 23 | line options: 24 | 25 | 26 | - blktrace receives data from the kernel in buffers passed up through the debug file system (relay). Each device being 27 | traced has a file created in the mounted directory for the debugfs, which defaults to /sys/kernel/debug -- this can 28 | be overridden with the -r command line argument. 29 | 30 | 31 | - blktrace defaults to collecting all events that can be traced. To limit the events being captured, you can specify 32 | one or more filter masks via the -a option. 33 | 34 | Alternatively, one may specify the entire mask utilising a hexadecimal value that is version-specific. (Requires 35 | understanding of the internal representation of the filter mask.) 36 | 37 | 38 | - As noted above, the events are passed up via a series of buffers stored into debugfs files. The size and number of 39 | buffers can be specified via the -b and -n arguments respectively. 40 | 41 | 42 | - blktrace stores the extracted data into files stored in the local directory. The format of the file names is (by 43 | default) device.blktrace.cpu, where device is the base device name (e.g, if we are tracing /dev/sda, the base device 44 | name would be sda); and cpu identifies a CPU for the event stream. 45 | 46 | The device portion of the event file name can be changed via the -o option. 47 | 48 | 49 | - blktrace may also be run concurrently with blkparse to produce live output -- to do this specify -o - for blktrace. 50 | 51 | 52 | - The default behaviour for blktrace is to run forever until explicitly killed by the user (via a control-C, or kill 53 | utility invocation). There are two ways to modify this: 54 | 55 | 56 | 1. You may utilise the blktrace utility itself to kill a running trace -- via the -k option. 57 | 58 | 59 | 2. You can specify a run-time duration for blktrace via the -w option -- then blktrace will run for the specified 60 | number of seconds, and then halt. 61 | 62 | 63 | 64 | OPTIONS 65 | -A hex-mask 66 | --set-mask=hex-mask 67 | Set filter mask to hex-mask (see below for masks) 68 | 69 | -a mask 70 | --act-mask=mask 71 | Add mask to current filter (see below for masks) 72 | 73 | -b size 74 | --buffer-size=size 75 | Specifies buffer size for event extraction (scaled by 1024). The default buffer size is 512KiB. 76 | 77 | -d dev 78 | --dev=dev 79 | Adds dev as a device to trace 80 | 81 | -I file 82 | --input-devs=file 83 | Adds the devices found in file as devices to trace 84 | 85 | -k 86 | --kill 87 | Kill on-going trace 88 | 89 | -n num-sub 90 | --num-sub=num-sub 91 | Specifies number of buffers to use. blktrace defaults to 4 sub buffers. 92 | 93 | -o file 94 | --output=file 95 | Prepend file to output file name(s) 96 | 97 | -r rel-path 98 | --relay=rel-path 99 | Specifies debugfs mount point 100 | 101 | -V 102 | --version Outputs version 103 | 104 | -w seconds 105 | --stopwatch=seconds 106 | Sets run time to the number of seconds specified 107 | 108 | 109 | 110 | FILTER MASKS 111 | The following masks may be passed with the -a command line option, multiple filters may be combined via multiple -a 112 | command line options. 113 | 114 | barrier: barrier attribute 115 | complete: completed by driver 116 | fs: requests 117 | issue: issued to driver 118 | pc: packet command events 119 | queue: queue operations 120 | read: read traces 121 | requeue: requeue operations 122 | sync: synchronous attribute 123 | write: write traces 124 | notify: trace messages 125 | 126 | 127 | 128 | REQUEST TYPES 129 | blktrace distinguishes between two types of block layer requests, file system and SCSI commands. The former are dubbed 130 | fs requests, the latter pc requests. File system requests are normal read/write operations, i.e. any type of read or 131 | write from a specific disk location at a given size. These requests typically originate from a user process, but they 132 | may also be initiated by the vm flushing dirty data to disk or the file system syncing a super or journal block to 133 | disk. pc requests are SCSI commands. blktrace sends the command data block as a payload so that blkparse can decode it. 134 | 135 | 136 | 137 | EXAMPLES 138 | To trace the i/o on the device /dev/hda and parse the output to human readable form, use the following command: 139 | 140 | % blktrace -d /dev/sda -o - | blkparse -i - 141 | 142 | This same behaviour can be achieve with the convenience script btrace. The command 143 | 144 | % btrace /dev/sda 145 | 146 | has exactly the same effect as the previous command. See btrace (8) for more information. 147 | 148 | To trace the i/o on a device and save the output for later processing with blkparse, use blktrace like this: 149 | 150 | % blktrace /dev/sda /dev/sdb 151 | 152 | This will trace i/o on the devices /dev/sda and /dev/sdb and save the recorded information in the files sda and sdb in 153 | the current directory, for the two different devices, respectively. This trace information can later be parsed by the 154 | blkparse utility: 155 | 156 | % blkparse sda sdb 157 | 158 | which will output the previously recorded tracing information in human readable form to stdout. See blkparse (1) for 159 | more information. 160 | 161 | 162 | 163 | AUTHORS 164 | blktrace was written by Jens Axboe, Alan D. Brunelle and Nathan Scott. This man page was created from the blktrace 165 | documentation by Bas Zoetekouw. 166 | 167 | 168 | 169 | REPORTING BUGS 170 | Report bugs to 171 | 172 | 173 | COPYRIGHT 174 | Copyright © 2006 Jens Axboe, Alan D. Brunelle and Nathan Scott. 175 | This is free software. You may redistribute copies of it under the terms of the GNU General Public License 176 | . There is NO WARRANTY, to the extent permitted by law. 177 | This manual page was created for Debian by Bas Zoetekouw. It was derived from the documentation provided by the 178 | authors and it may be used, distributed and modified under the terms of the GNU General Public License, version 2. 179 | On Debian systems, the text of the GNU General Public License can be found in /usr/share/common-licenses/GPL-2. 180 | 181 | 182 | SEE ALSO 183 | btrace (8), blkparse (1), verify_blkparse (1), blkrawverify (1), btt (1) 184 | 185 | 186 | 187 | 188 | blktrace git-20070306202522 March 6, 2007 BLKTRACE(8) 189 | -------------------------------------------------------------------------------- /quiz/20161214_editor_eval/editor_test.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/quiz/20161214_editor_eval/editor_test.pdf -------------------------------------------------------------------------------- /quiz/20161214_editor_eval/editor_test.tex: -------------------------------------------------------------------------------- 1 | % Author: Seongjin Lee 2 | % Hanyang University, Seoul, Korea 3 | % esos.hanyang.ac.kr 4 | 5 | \documentclass[12pt]{article} 6 | \usepackage{kotex} 7 | 8 | 9 | 10 | \title{Editor Evaluation Excerscise} 11 | \author{Seongjin Lee} 12 | \date{2016-12-14} 13 | 14 | \begin{document} 15 | \maketitle 16 | 17 | vi 또는 emacs를 이용하여 ``blkparse.txt''를 연 뒤, 다음 지시사항을 따라 하시기 바랍니다. 동일한 경로에 ``blktrace.txt''도 있는지 확인합니다. 18 | 19 | \begin{enumerate} 20 | \item 51번째 줄로 이동 21 | \item ``blktrace'' 문자열을 아래 방향으로 한 번 검색하여 커서 이동 22 | \item 현재커서위치에서한line을복사한뒤,복사한문자열을현재커서위치의다음 line으로 삽입하시오. 23 | \item 현재 커서 위치에서 위 방향으로 ``blkparse'' 문자열을 검색하여 5번 커서를 이동하시 오. 도착한 커서 위치의 line 한 줄을 지우시오. 24 | \item 24~29 line 6줄을 복사한 뒤, 31번 line 시작 위치에 붙여 넣으시오. 25 | \item 38번째 line으로 커서를 이동한 뒤, 일곱 줄을 지우시오. 26 | \item 해당 파일의 첫 행으로 커서를 옮긴 뒤, 현재 커서 위치부터 나오는 ``blkparse'' 문자 열 10개를 ``blocktrace\_parser''로 치환하시오. 27 | \item ``blktrace.txt'' 파일의 본문을, 현재 파일의 444번 Line 시작 위치에 삽입하시오. 28 | \item 해당 파일의 첫 행으로 커서를 옮긴 뒤, 다음과 같이 매크로를 작성하고 수행하시오. 29 | \begin{enumerate} 30 | \item btrace 문자열 검색 $\rightarrow$ line 끝으로 이동 $\rightarrow$ btrace is here 입력 31 | \item 작성한 매크로를 7번 반복하시오. 32 | \end{enumerate} 33 | \item 새로운 이름으로 저장 34 | \end{enumerate} 35 | 36 | 37 | \end{document} 38 | -------------------------------------------------------------------------------- /quiz/README.md: -------------------------------------------------------------------------------- 1 | ## Quiz, Solutions, and Results 2 | 3 | * The first quiz : average 18.5 4 | * The second quiz : average 16.6 5 | -------------------------------------------------------------------------------- /quiz/quiz_20161005.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/quiz/quiz_20161005.pdf -------------------------------------------------------------------------------- /quiz/quiz_20161005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/quiz/quiz_20161005.png -------------------------------------------------------------------------------- /quiz/quiz_20161005_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/quiz/quiz_20161005_sol.pdf -------------------------------------------------------------------------------- /quiz/quiz_20161012.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/quiz/quiz_20161012.pdf -------------------------------------------------------------------------------- /quiz/quiz_20161012.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/quiz/quiz_20161012.png -------------------------------------------------------------------------------- /quiz/quiz_20161012_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/quiz/quiz_20161012_sol.pdf -------------------------------------------------------------------------------- /quiz/quiz_20161116.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/quiz/quiz_20161116.pdf -------------------------------------------------------------------------------- /quiz/quiz_20161116_sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/quiz/quiz_20161116_sol.pdf -------------------------------------------------------------------------------- /vcs_regex/09-vcs_regex.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/vcs_regex/09-vcs_regex.pdf -------------------------------------------------------------------------------- /vcs_regex/Makefile: -------------------------------------------------------------------------------- 1 | texfile = 09-vcs_regex.tex 2 | outdir=/tmp 3 | 4 | all: ${texfile} 5 | pdflatex --shell-escape --output-directory ${outdir} $< 6 | 7 | clean: 8 | rm *.aux *.log *.nav *.out *.snm *.toc *.vrb 9 | 10 | o: ${texfile} 11 | gv ${outdir}/$(basename $<).pdf & 12 | 13 | final: ${texfile} 14 | pdflatex --shell-escape --output-directory ${outdir} $< 15 | pdflatex --shell-escape --output-directory ${outdir} $< 16 | cp ${outdir}/$(basename $<).pdf . 17 | -------------------------------------------------------------------------------- /vcs_regex/README.md: -------------------------------------------------------------------------------- 1 | This is Lecture note on version control system and regular expressions. 2 | 3 | Visit following link for [course description](http://resourceful.github.io/classes/2016-11-22-week12-class10-vcsregex/) 4 | -------------------------------------------------------------------------------- /vcs_regex/codes/p176.txt: -------------------------------------------------------------------------------- 1 | Name BrainWeight BodyWeight 2 | Mountain beaver 8.1 1.35 3 | Cow 423 465 4 | Graywolf 119.5 36.33 5 | Goat 115 27.66 6 | Guineapig 5.5 1.04 7 | Diplodocus 50 11700 8 | Asian elephant 4603 2547 9 | Donkey 419 187.1 10 | Horse 655 521 11 | Potar monkey 115 10 12 | Cat 25.6 3.3 13 | Giraffe 680 529 14 | Gorilla 406 207 15 | Human 1320 62 16 | African elephant 5712 6654 17 | Triceratops 70 9400 18 | Rhesus monkey 179 6.8 19 | Kangaroo 56 35 20 | Hamster 1 0.12 21 | Mouse 0.4 0.023 22 | Rabbit 12.1 2.5 23 | Sheep 175 55.5 24 | Jaguar 157 100 25 | Chimpanzee 440 52.16 26 | Brachiosaurus 154.5 87000 27 | Rat 1.9 0.28 28 | Mole 3 0.122 29 | Pig 180 192 30 | -------------------------------------------------------------------------------- /vcs_regex/figures/fig1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/vcs_regex/figures/fig1.png -------------------------------------------------------------------------------- /vcs_regex/figures/fig2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/vcs_regex/figures/fig2.png -------------------------------------------------------------------------------- /vcs_regex/figures/fig3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/vcs_regex/figures/fig3.png -------------------------------------------------------------------------------- /vcs_regex/figures/fig4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/vcs_regex/figures/fig4.png -------------------------------------------------------------------------------- /vcs_regex/figures/fig5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resourceful/lecture_sysprog/26e907dbed42b544d04a73f7cc3a5066a7ef71f9/vcs_regex/figures/fig5.png --------------------------------------------------------------------------------