├── README.md ├── aging.c ├── asm.o ├── b ├── cleanup.sh ├── filea ├── fsizes.c ├── ioctl.c ├── mmap_ex.c ├── mmap_ex_fstat.c ├── net_info.sh ├── page_replacement.c ├── page_size.sh ├── producer.c ├── pthread_ex.c ├── race.sh ├── rbits ├── relocate.c ├── rev_bytes.c ├── secure.sh ├── shell.c ├── syscalls.c ├── tlb.c ├── trace.c └── user.sh /README.md: -------------------------------------------------------------------------------- 1 | system-code 2 | =========== 3 | 4 | Code related to system programming (os, admin, etc.) 5 | -------------------------------------------------------------------------------- /aging.c: -------------------------------------------------------------------------------- 1 | /* 2 | aging.c Simulation of the aging algorithm found in paging systems 3 | sample execution: ./aging 4 rbits 4 | */ 5 | 6 | #include 7 | #include 8 | #define UINT_BIT 8 9 | 10 | /* just for testing */ 11 | void uint_to_binary(unsigned int n, char s[UINT_BIT + 1]) 12 | { 13 | unsigned int mask; 14 | int i; 15 | 16 | mask = 0x01 << UINT_BIT - 1; 17 | i = 0; 18 | while (mask != 0 && i < UINT_BIT) { 19 | if (n & mask) 20 | s[i] = '1'; 21 | else 22 | s[i] = '0'; 23 | mask >>= 1; 24 | i++; 25 | } 26 | s[i] = '\0'; 27 | 28 | return; 29 | } 30 | 31 | 32 | int main (int argc, char *argv[]) 33 | { 34 | const unsigned int MAX_CHARS = 10; 35 | const int ERROR = -1; 36 | const unsigned int MAX_FR = 8; 37 | const unsigned int MAX_LINE = 30; 38 | char binary[UINT_BIT + 1]; 39 | 40 | if (argc != 3) 41 | { 42 | fprintf (stderr, "Usage: %s [frames] [file]\n", argv[0]); 43 | return ERROR; 44 | } 45 | 46 | /* number of page frames */ 47 | const size_t FLEN = strnlen (argv[1], MAX_FR); 48 | char f_num[FLEN + 2]; 49 | f_num[FLEN] = 0; 50 | strncpy (f_num, argv[1], FLEN); 51 | unsigned int frame_num = 0; 52 | if (0 == (frame_num = atoi (f_num))) 53 | { 54 | fprintf (stderr, "Invalid argument: %s\n", f_num); 55 | return ERROR; 56 | } 57 | 58 | /* 1 counter per frame */ 59 | unsigned int counter[frame_num]; 60 | int x; 61 | for (x = 0; x != frame_num; ++x) 62 | { 63 | counter[x] = 0; 64 | } 65 | 66 | /* input file */ 67 | const size_t LEN = strnlen (argv[2], MAX_CHARS); 68 | char i_file[LEN + 2]; 69 | i_file[LEN] = 0; 70 | strncpy (i_file, argv[2], LEN); 71 | 72 | FILE *fp = NULL; 73 | if (NULL == (fp = fopen(i_file, "r"))) 74 | { 75 | fprintf (stderr, "Invalid file: %s\n", i_file); 76 | return ERROR; 77 | } 78 | 79 | /* read the contents */ 80 | char line[MAX_LINE + 2]; 81 | int cnt = 0; 82 | while (NULL != fgets (line, MAX_LINE, fp)) 83 | { 84 | /* validate input */ 85 | if ((strnlen (line, MAX_LINE) - 1) != frame_num) 86 | { 87 | fprintf (stderr, "Invalid input: %s", line); 88 | return ERROR; 89 | } 90 | /* parse the values of a clock tick */ 91 | int j; 92 | for (j = 0; j != frame_num; ++j) 93 | { 94 | /* shift the counter 1 bit right */ 95 | counter[j] >>= 0x1; 96 | 97 | /* and put 1 if the R bit is 1 */ 98 | if ('1' == line[j]) 99 | { 100 | counter[j] |= 0x1 << 7; 101 | } 102 | } 103 | } 104 | 105 | /* print the final contents of the counters */ 106 | int k; 107 | for (k = 0; k != frame_num; ++k) 108 | { 109 | uint_to_binary(counter[k], binary); 110 | printf("%s\n", binary); 111 | } 112 | 113 | fclose (fp); 114 | return 0; 115 | } 116 | -------------------------------------------------------------------------------- /asm.o: -------------------------------------------------------------------------------- 1 | push %ebp 2 | mov %esp,%ebp 3 | and $0xfffffff0,%esp 4 | sub $0x20,%esp 5 | movl $0x0,0x1c(%esp) 6 | jmp 24 7 | movl $0x0,(%esp) 8 | call 1b 9 | addl $0x1,0x1c(%esp) 10 | cmpl $0x9,0x1c(%esp) 11 | jle 13 12 | mov $0x0,%eax 13 | leave 14 | ret 15 | -------------------------------------------------------------------------------- /b: -------------------------------------------------------------------------------- 1 | koap -------------------------------------------------------------------------------- /cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # cleanup the configuration files of the removed packages 4 | 5 | if [ "${UID}" -ne 0 ] ; then 6 | echo "you need root privileges!" 7 | exit 1 8 | else 9 | COLUMNS=1000 dpkg --list | grep ^rc | awk '{print $2}' | xargs dpkg -P 10 | #dpkg-query --show --showformat='${Status}\t${Package}\n'| grep ^deinstall | cut -f2 | xargs dpkg -P 11 | fi 12 | -------------------------------------------------------------------------------- /filea: -------------------------------------------------------------------------------- 1 | koap 2 | -------------------------------------------------------------------------------- /fsizes.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #define LEN(arr) (sizeof(arr)) / (sizeof(arr[0])) 7 | 8 | enum {BINS = 5}; 9 | enum {TRUE, FALSE}; 10 | 11 | void print_hor_hist (const int, const int []); 12 | 13 | int main (void) 14 | { 15 | struct dirent *de; 16 | struct stat finfo; 17 | DIR *dp = opendir ("./"); 18 | const unsigned long bin_size = 1024; 19 | int bins[BINS]; 20 | int i; 21 | int bin_pos; 22 | 23 | for (i = 0; i != BINS; ++i) 24 | { 25 | bins[i] = 0; 26 | } 27 | 28 | if (NULL == dp) 29 | { 30 | perror ("opendir"); 31 | return -1; 32 | } 33 | 34 | while ((de = readdir (dp))) 35 | { 36 | if (strcmp (".", de->d_name) != 0 && strcmp ("..", de->d_name) != 0) 37 | { 38 | stat (de->d_name, &finfo); 39 | bin_pos = ((long)finfo.st_size / bin_size); 40 | /* printf ("%s: %ld bytes goes in bin %d\n", de->d_name, (long)finfo.st_size, (bin_pos > BINS - 1 ? BINS - 1 : bin_pos)); */ 41 | i = (bin_pos > BINS - 1 ? BINS - 1 : bin_pos); 42 | ++bins[i]; 43 | } 44 | } 45 | 46 | print_hor_hist (LEN (bins), bins); 47 | 48 | closedir (dp); 49 | 50 | return 0; 51 | } 52 | 53 | void print_hor_hist (const int size, const int arr[]) 54 | { 55 | int i, j; 56 | for (i = 0; i != size; ++i) 57 | { 58 | printf ("%4d: ", i); 59 | 60 | for (j = 0; j != arr[i]; ++j) 61 | { 62 | putchar ('*'); 63 | } 64 | 65 | putchar ('\n'); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /ioctl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int main (void) 10 | { 11 | int fd, status = 0; 12 | 13 | /* ioctl example (TODO: find a better one) */ 14 | if (fd = open ("/dev/ttyS0", O_RDONLY) == -1) 15 | { 16 | perror ("open"); 17 | } 18 | if (ioctl(fd, TIOCMGET, &status) == -1) 19 | { 20 | printf("TIOCMGET failed: %s\n", 21 | strerror(errno)); 22 | } 23 | else { 24 | if (status & TIOCM_DTR) 25 | puts("TIOCM_DTR is not set"); 26 | else 27 | puts("TIOCM_DTR is set"); 28 | } 29 | close(fd); 30 | 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /mmap_ex.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | /** 11 | * Write to a memory mapped file 12 | * 13 | * @param fd The file descriptor 14 | * @param buf The file contents 15 | * 16 | * @return The number of bytes written. -1 on 17 | * error. 18 | */ 19 | int m_write (const int fd, const char *buf) 20 | { 21 | const int error = -1; 22 | const char *m_ptr = buf; 23 | const int f_size = 24 | (strlen (buf) * sizeof (char)); /* buffer size */ 25 | 26 | char *map_ptr; 27 | char *i; 28 | int written = 0; /* bytes written */ 29 | 30 | /* Stretch the file size to the size of the input file */ 31 | /* When not applied `file' reports no magic and the size */ 32 | /* report of `du', `ls', etc. is wrong */ 33 | if (lseek (fd, f_size - 1, SEEK_SET) == -1) 34 | { 35 | perror ("lseek"); 36 | return error; 37 | } 38 | 39 | /* Something needs to be written at the end of the file to */ 40 | /* have the file actually have the new size. If not done, 41 | a SIGBUS signal error is generated */ 42 | if (write (fd, "", 1) != 1) 43 | { 44 | perror ("write"); 45 | return error; 46 | } 47 | 48 | /* Now the file is ready to be mmapped. */ 49 | if ((map_ptr = mmap (0, f_size, PROT_WRITE, MAP_SHARED, 50 | fd, 0)) == MAP_FAILED) 51 | { 52 | perror ("mmap"); 53 | return error; 54 | } 55 | 56 | /* write the contents of the input file 57 | to the mmapped file */ 58 | i = map_ptr; 59 | while (++written && (*i++ = *m_ptr++)) ; 60 | 61 | /* free the mmapped memory */ 62 | if (munmap (map_ptr, f_size) == -1) 63 | { 64 | perror ("munmap"); 65 | return error; 66 | } 67 | 68 | return written; 69 | } 70 | 71 | /** 72 | * Read from a memory mapped file 73 | * 74 | * @param fd The file descriptor 75 | * @param buf The output buffer 76 | * 77 | * @return The number of bytes read. -1 on 78 | * error 79 | */ 80 | int m_read (const int fd, char *buf) 81 | { 82 | const int error = -1; 83 | const int f_size = 84 | (strlen (buf) * sizeof (char) + 1); /* buffer size */ 85 | 86 | char *m_ptr = buf; 87 | char *map_ptr; 88 | int read = 0; /* bytes read */ 89 | char *i; 90 | 91 | /* mmap the file */ 92 | if ((map_ptr = mmap (0, f_size, PROT_READ, MAP_SHARED, 93 | fd, 0)) == MAP_FAILED) 94 | { 95 | perror ("mmap"); 96 | return error; 97 | } 98 | 99 | /* read the file contents */ 100 | i = map_ptr; 101 | while (++read && (*m_ptr++ = *i++)) ; 102 | 103 | /* free the mmapped memory */ 104 | if (munmap (map_ptr, f_size) == -1) 105 | { 106 | perror ("munmap"); 107 | return error; 108 | } 109 | 110 | return read; 111 | } 112 | 113 | 114 | int main (void) 115 | { 116 | const char message[] = "file contents\n"; /* contents written */ 117 | const char o_path[] = "file1"; /* file name */ 118 | const mode_t mode = S_IRUSR | S_IWUSR; /* open mode */ 119 | const char *m_ptr = message; 120 | 121 | char i_msg[strlen (message) + 1]; /* contents read */ 122 | int fd; /* file descriptor */ 123 | int i; 124 | 125 | /* open for writing an mmapped file */ 126 | if ((fd = open (o_path, O_RDWR | O_CREAT, 127 | mode)) == -1) 128 | { 129 | perror ("open"); 130 | goto error; 131 | } 132 | 133 | /* write the file using map */ 134 | if ((i = m_write (fd, message)) == -1) 135 | { 136 | perror ("m_write"); 137 | goto error; 138 | } 139 | 140 | printf ("mapped: %d bytes\n", i); 141 | 142 | close (fd); 143 | 144 | /* open for reading mmapped files */ 145 | if ((fd = open (o_path, O_RDONLY)) == -1) 146 | { 147 | perror ("open"); 148 | goto error; 149 | } 150 | 151 | /* read the file using mmap */ 152 | if ((i = m_read (fd, i_msg)) == -1) 153 | { 154 | perror ("m_read"); 155 | goto error; 156 | } 157 | 158 | printf ("read: %d bytes\n", i); 159 | printf ("%s", i_msg); 160 | 161 | close (fd); 162 | return 0; 163 | 164 | error: 165 | close (fd); 166 | return 1; 167 | } 168 | -------------------------------------------------------------------------------- /mmap_ex_fstat.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | /** 11 | * Write to a memory mapped file 12 | * 13 | * @param fd The file descriptor 14 | * @param buf The file contents 15 | * 16 | * @return The number of bytes written. 17 | * -1 on error 18 | */ 19 | int m_write (int fd, const char *buf) 20 | { 21 | const int error = -1; 22 | const char *m_ptr = buf; 23 | const int f_size = 24 | (strlen (buf) * sizeof (char)) + 1; /* buffer size */ 25 | 26 | char *map_ptr; 27 | char *i; 28 | int written = 0; /* bytes written */ 29 | 30 | /* Stretch the file size to the size of the input file */ 31 | /* When not applied `file' reports no magic and the size */ 32 | /* report of `du', `ls', etc. is wrong */ 33 | if (lseek (fd, f_size - 1, SEEK_SET) == -1) 34 | { 35 | perror ("lseek"); 36 | return error; 37 | } 38 | 39 | /* Something needs to be written at the end of the file to */ 40 | /* have the file actually have the new size. If not done, 41 | a SIGBUS signal error is generated */ 42 | if (write (fd, "", 1) != 1) 43 | { 44 | perror ("write"); 45 | return error; 46 | } 47 | 48 | /* Now the file is ready to be mmapped. */ 49 | if ((map_ptr = mmap (0, f_size, PROT_WRITE, MAP_SHARED, 50 | fd, 0)) == MAP_FAILED) 51 | { 52 | perror ("mmap"); 53 | return error; 54 | } 55 | 56 | /* write the contents of the input file 57 | to the mmapped file */ 58 | i = map_ptr; 59 | while (++written && (*i++ = *m_ptr++)) ; 60 | 61 | /* free the mmapped memory */ 62 | if (munmap (map_ptr, f_size) == -1) 63 | { 64 | perror ("munmap"); 65 | return error; 66 | } 67 | 68 | return written; 69 | } 70 | 71 | 72 | 73 | 74 | /** 75 | * Get the size of a file using 76 | * fstat 77 | * 78 | * @param fd The file descriptor 79 | * 80 | * @return The size in bytes. -1 81 | * on error 82 | */ 83 | int get_fsize (int fd) 84 | { 85 | const int error = -1; 86 | struct stat f_stat; 87 | 88 | if (fstat (fd, &f_stat) == -1) 89 | { 90 | perror ("fstat"); 91 | return error; 92 | } 93 | 94 | return f_stat.st_size; 95 | } 96 | 97 | int main (void) 98 | { 99 | /* const char i_path[] = "/etc/motd"; */ 100 | const char message[] = "the file contents\n"; 101 | const char *m_ptr = message; 102 | const char o_path[] = "file1"; 103 | const int mode = 0664; 104 | 105 | /* int i_fd; */ 106 | int o_fd; 107 | int f_size; 108 | int i; 109 | 110 | /* if ((i_fd = open (i_path, O_RDONLY)) == -1) */ 111 | /* { */ 112 | /* perror ("open"); */ 113 | /* goto error; */ 114 | /* } */ 115 | 116 | if ((o_fd = open (o_path, O_RDWR | O_CREAT, 117 | (mode_t)mode)) == -1) 118 | { 119 | perror ("open"); 120 | goto error; 121 | } 122 | 123 | /* f_size = (strlen (message) * sizeof (char)) + 1; */ 124 | 125 | /* if ((f_size = get_fsize (i_fd)) == -1) */ 126 | /* { */ 127 | /* perror ("fstat"); */ 128 | /* goto error; */ 129 | /* } */ 130 | 131 | /* printf ("size: \t%d bytes\n", f_size); */ 132 | 133 | if ((i = m_write (o_fd, message)) == -1) 134 | { 135 | perror ("m_write"); 136 | goto error; 137 | } 138 | 139 | printf ("mapped: \t%d bytes\n", i); 140 | 141 | /* close (i_fd); */ 142 | close (o_fd); 143 | 144 | 145 | 146 | return 0; 147 | 148 | error: 149 | /* close (i_fd); */ 150 | close (o_fd); 151 | return 1; 152 | } 153 | -------------------------------------------------------------------------------- /net_info.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # network information about a host 4 | # Copyright (C) 2011 Sakis Kasampalis 5 | 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | domain=`hostname -f` || exit 1 20 | ip=`ip add | grep inet | grep brd | tr -s " " | cut -d" " -f3` || exit 1 21 | iface=`lspci | grep Net | cut -d: -f3 | sed 's/^ *//'` || exit 1 22 | 23 | printf "hostname\t${domain}\n" 24 | printf "ip address\t${ip}\t\n" 25 | printf "net. adapter\t${iface}\t\n" 26 | -------------------------------------------------------------------------------- /page_replacement.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (C) Sakis Kasampalis 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | enum state 25 | { 26 | MISS, 27 | HIT 28 | }; 29 | 30 | enum boolean 31 | { 32 | TRUE, 33 | FALSE 34 | }; 35 | 36 | const unsigned int fr_num = 5; 37 | 38 | enum boolean not_exists (const unsigned int n, unsigned int frames[]) 39 | { 40 | int i; 41 | enum boolean found = FALSE; 42 | for (i = 0; i != fr_num; ++i) 43 | { 44 | if (n == frames[i]) 45 | { 46 | found = TRUE; 47 | } 48 | } 49 | return found; 50 | } 51 | 52 | void insert_rnd (const unsigned int n, unsigned int frames[]) 53 | { 54 | const float p = 1 / (float)n; 55 | 56 | int i; 57 | for (i = 0; i != fr_num; ++i) 58 | { 59 | unsigned int ref = -1; 60 | do 61 | { 62 | ref = rand () % n; 63 | } while (TRUE == not_exists (ref, frames)); 64 | assert (-1 != ref); 65 | frames[i] = ref; 66 | } 67 | } 68 | 69 | void page_ref (const unsigned int n, unsigned int frames[]) 70 | { 71 | const float p = 1 / (float)n; 72 | const unsigned int ref = rand () % n; 73 | enum state s = MISS; 74 | 75 | int i; 76 | for (i = 0; i != fr_num; ++i) 77 | { 78 | if (ref == frames[i]) 79 | { 80 | s = HIT; 81 | break; 82 | } 83 | else 84 | { 85 | s = MISS; 86 | frames[i] = ref; 87 | } 88 | } 89 | 90 | printf ("page %d\n", ref); 91 | } 92 | 93 | int main (void) 94 | { 95 | srand (time (NULL)); 96 | const int pages = 5; 97 | unsigned int frames[fr_num]; 98 | insert_rnd (pages, frames); 99 | int i; 100 | for (i = 0; i != fr_num; ++i) 101 | { 102 | printf ("%d ", frames[i]); 103 | } 104 | putchar ('\n'); 105 | /* page_ref (pages, frames); */ 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /page_size.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # page_size.sh Calculate the mean and median of the executable sizes 4 | # Copyright (C) 2011 Sakis Kasampalis 5 | 6 | # This program is free software: you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation, either version 3 of the License, or 9 | # (at your option) any later version. 10 | 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program. If not, see . 18 | 19 | function print_error () 20 | { 21 | printf "ERROR: ${@}\n" >&2 22 | } 23 | 24 | function print_usage () 25 | { 26 | printf "USAGE: ${@}\n" >&2 27 | } 28 | 29 | if [ $# -lt 1 ] ; then 30 | print_error "Insufficient Arguments." 31 | print_usage "`basename $0` [directory1] [directory2] ..." 32 | exit 1 33 | fi 34 | 35 | tot_size=0 36 | tot_cnt=0 37 | median=0 38 | n_dirs=0 39 | 40 | for i in "$@" 41 | do 42 | # TODO: add privilege control (if the dir can be read, etc.) 43 | if [ -d "$i" ] ; then 44 | cnt=`find $i -executable | wc -l` 45 | size=`find $i -executable | xargs du -s | awk '{ print $1 }' | head -n 1` 46 | results=`find $i -executable | xargs du -s | awk '{ print $1 }' | wc -l` 47 | med_pos=`echo "$results / 2" | bc` 48 | med_pos=`echo "+$med_pos"` # to be tail-compatible 49 | cur_median=`find $i -executable | xargs du -s | awk '{ print $1 }' \ 50 | | sort -n | tail -n $med_pos | head -n 1` 51 | median=`echo "$median + $cur_median" | bc` 52 | tot_size=`echo "$tot_size + $size" | bc` 53 | tot_cnt=`echo "$tot_cnt + $cnt" | bc` 54 | n_dirs=`echo "$n_dirs + 1" | bc` 55 | else 56 | print_error "$i: Invalid directory" 57 | fi 58 | done 59 | 60 | mean=`echo "$tot_size / $tot_cnt" | bc` 61 | median=`echo "$median / $n_dirs" | bc` 62 | 63 | if [ $tot_size -gt 0 ] ; then 64 | echo "total files: $tot_cnt" 65 | echo "total size: $tot_size bytes" 66 | echo "mean size: $mean bytes" 67 | echo "median size: $median bytes" 68 | fi 69 | -------------------------------------------------------------------------------- /producer.c: -------------------------------------------------------------------------------- 1 | /* 2 | The producer-consumer problem using pthreads 3 | compile with: cc -lpthread 4 | */ 5 | 6 | #include 7 | #include 8 | #define MAX 10 9 | 10 | pthread_mutex_t the_mutex; 11 | pthread_cond_t condc, condp; 12 | int buffer = 0; 13 | 14 | void *producer (void *ptr) 15 | { 16 | int i; 17 | 18 | for (i = 1; i <= MAX; ++i) 19 | { 20 | pthread_mutex_lock (&the_mutex); /* critical region access */ 21 | while (buffer != 0) /* no need to produce, sleep */ 22 | { 23 | pthread_cond_wait (&condp, &the_mutex); 24 | } 25 | buffer = i; 26 | printf ("producing %d\n", buffer); 27 | pthread_cond_signal (&condc); /* wake up the consumer */ 28 | pthread_mutex_unlock (&the_mutex); 29 | } 30 | puts ("end of producer"); 31 | pthread_exit (0); 32 | } 33 | 34 | void *consumer (void *ptr) 35 | { 36 | int i; 37 | 38 | for (i = 1; i <= MAX; ++i) 39 | { 40 | pthread_mutex_lock (&the_mutex); /* critical region access */ 41 | while (buffer == 0) /* nothing to consume, sleep... */ 42 | { 43 | pthread_cond_wait (&condc, &the_mutex); 44 | } 45 | buffer = 0; 46 | printf ("consuming %d\n", i); 47 | pthread_cond_signal (&condp); /* wake up the producer */ 48 | pthread_mutex_unlock (&the_mutex); 49 | } 50 | puts ("end of consumer"); 51 | pthread_exit (0); 52 | } 53 | 54 | int main (void) 55 | { 56 | pthread_t pro, con; 57 | 58 | pthread_mutex_init (&the_mutex, 0); 59 | pthread_cond_init (&condc, 0); 60 | pthread_cond_init (&condp, 0); 61 | 62 | pthread_create (&con, 0, consumer, 0); 63 | pthread_create (&pro, 0, producer, 0); 64 | 65 | pthread_join (pro, 0); 66 | pthread_join (con, 0); 67 | 68 | pthread_cond_destroy (&condc); 69 | pthread_cond_destroy (&condp); 70 | pthread_mutex_destroy (&the_mutex); 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /pthread_ex.c: -------------------------------------------------------------------------------- 1 | /* 2 | Example of using POSIX threads 3 | compile with: cc -lpthread 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #define N_THREADS 5 11 | 12 | void *print_hello (void *id) 13 | { 14 | printf ("hello thread %d\n", id); 15 | pthread_exit (NULL); 16 | } 17 | 18 | int main (void) 19 | { 20 | pthread_t threads[N_THREADS]; 21 | 22 | int status, i; 23 | 24 | for (i = 0; i < N_THREADS; ++i) 25 | { 26 | printf ("creating thread %d\n", i); 27 | status = pthread_create (&threads[i], NULL, print_hello, (void *) i); 28 | 29 | if (status != 0) 30 | { 31 | printf ("cannot create thread, error code %d\n", status); 32 | exit (-1); 33 | } 34 | } 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /race.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | function print_usage () 4 | { 5 | printf "USAGE: ${@}\n" >&2 6 | } 7 | 8 | function print_error () 9 | { 10 | printf "ERROR: ${@}\n" >&2 11 | } 12 | 13 | if [ $# -ne 1 ] ; then 14 | print_usage "`basename $0` file" 15 | exit 0 16 | fi 17 | 18 | if [ ! -f "$1" ] ; then 19 | print_error "file $1 does not exist" 20 | exit 0 21 | fi 22 | 23 | if [ -f "$1.lock" ] ; then 24 | exit 0 25 | else 26 | ln "$1" "$1.lock" 27 | fi 28 | 29 | i=0 30 | until [ $i -eq 1000 ] ; 31 | do 32 | LAST_NUM=`tail -n 1 "$1"` 33 | NUM=$((LAST_NUM + 1)) 34 | echo $NUM >> $1 2>/dev/null 35 | i=$((i + 1)) 36 | done 37 | 38 | rm -f "$1.lock" 39 | -------------------------------------------------------------------------------- /rbits: -------------------------------------------------------------------------------- 1 | 0111 2 | 1011 3 | 1010 4 | 1101 5 | 0010 6 | 1010 7 | 1100 8 | 0001 9 | -------------------------------------------------------------------------------- /relocate.c: -------------------------------------------------------------------------------- 1 | /* 2 | relocate.c Simulate memory relocation using fixed addresses 3 | sample execution: ./relocate asm.o 5 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | int main (int argc, char *argv[]) 10 | { 11 | const unsigned int MAX_CHARS = 10; 12 | const unsigned int MAX_REL = 8; 13 | const unsigned int MAX_LINE = 30; 14 | const char DELIM[] = " "; 15 | const int ERROR = -1; 16 | 17 | if (argc != 3) 18 | { 19 | fprintf (stderr, "Usage: %s [file] [address]\n", argv[0]); 20 | return ERROR; 21 | } 22 | 23 | /* input file */ 24 | const size_t LEN = strnlen (argv[1], MAX_CHARS); 25 | char i_file[LEN + 2]; 26 | i_file[LEN] = 0; 27 | strncpy (i_file, argv[1], LEN); 28 | 29 | FILE *fp = NULL; 30 | if (NULL == (fp = fopen(i_file, "r+"))) 31 | { 32 | fprintf (stderr, "Invalid file: %s\n", i_file); 33 | return ERROR; 34 | } 35 | 36 | /* relocation value */ 37 | const size_t RLEN = strnlen (argv[2], MAX_REL); 38 | char r_addr[RLEN + 2]; 39 | r_addr[LEN] = 0; 40 | strncpy (r_addr, argv[2], RLEN); 41 | unsigned int i = 0; 42 | if (0 == (i = atoi (r_addr))) 43 | { 44 | fprintf (stderr, "Invalid argument: %s\n", r_addr); 45 | return ERROR; 46 | } 47 | 48 | /* read the contents */ 49 | char line[MAX_LINE + 2]; 50 | while (NULL != fgets (line, MAX_LINE, fp)) 51 | { 52 | char *word = NULL; 53 | 54 | /* split a single line into strings */ 55 | word = strtok (line, DELIM); 56 | unsigned int j = 0; 57 | unsigned int first = 0; 58 | while (word != NULL) 59 | { 60 | /* no need to do something */ 61 | if (0 == (j = atoi (word))) 62 | { 63 | printf ("%s", word); 64 | } 65 | /* should relocate */ 66 | else 67 | { 68 | printf ("%d ", (j+i)); 69 | } 70 | 71 | /* pretty print */ 72 | if (0 == first) 73 | { 74 | putchar ('\t'); 75 | ++first; 76 | } 77 | 78 | /* always last call */ 79 | word = strtok (NULL, DELIM); 80 | } 81 | } 82 | 83 | fclose (fp); 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /rev_bytes.c: -------------------------------------------------------------------------------- 1 | /* Reverse the bytes of a file. */ 2 | 3 | #include 4 | #include 5 | #define NELEMS(arr) (sizeof(arr)) / (sizeof(arr[0])) 6 | 7 | size_t get_fsize (FILE *f) 8 | { 9 | size_t n = 0, c; 10 | rewind (f); 11 | while (!feof (f)) 12 | { 13 | c = getc (f); 14 | if (-1 != c) 15 | { 16 | ++n; 17 | } 18 | } 19 | rewind (f); 20 | return n; 21 | } 22 | 23 | int main (void) 24 | { 25 | FILE *startp; 26 | int c; 27 | int i; 28 | char *bytes; 29 | size_t fsize; 30 | 31 | startp = fopen ("filea", "r+"); 32 | 33 | if (NULL == startp) 34 | { 35 | perror ("fopen"); 36 | return -1; 37 | } 38 | 39 | fsize = get_fsize (startp); 40 | bytes = (char *) malloc (fsize); 41 | 42 | if (NULL == bytes) 43 | { 44 | perror ("malloc"); 45 | return -1; 46 | } 47 | 48 | /* save the bytes in an array */ 49 | i = 0; 50 | while (!feof (startp)) 51 | { 52 | c = bytes[i] = getc (startp); 53 | if (-1 != c) 54 | { 55 | ++i; 56 | /* printf ("%o ", c); */ 57 | } 58 | } 59 | 60 | /* write the reversed bytes in place */ 61 | rewind (startp); 62 | for (i = NELEMS (bytes) - 1; i >= 0; --i) 63 | { 64 | fputc (bytes[i], startp); 65 | } 66 | 67 | free (bytes); 68 | fclose (startp); 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /secure.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # find all SUID/SGID programs 4 | printf "searching for SUID/SGID programs...\n" 5 | find / -type f \( -perm -04000 -o -perm -02000 \) \-exec ls -lg {} \; 2>/dev/null 6 | 7 | # locate all group & world-writable files 8 | printf "\nsearching for group/world writable files...\n" 9 | find / -type f \( -perm -2 -o -perm -20 \) -exec ls -lg {} \; 2>/dev/null 10 | 11 | # locate all group & world-writable directories 12 | printf "\nsearching for group/world writable directories...\n" 13 | find / -type d \( -perm -2 -o -perm -20 \) -exec ls -ldg {} \; 2>/dev/null 14 | 15 | # locate files on your system that do not have an owner 16 | printf "\nsearching for files without owner...\n" 17 | find / -nouser -o -nogroup 2>/dev/null 18 | -------------------------------------------------------------------------------- /shell.c: -------------------------------------------------------------------------------- 1 | /* 2 | shell emulation (currently incomplete) 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define TRUE 1 11 | #define FALSE !TRUE 12 | #define MAXLEN 100 13 | 14 | int 15 | main (void) 16 | { 17 | char s[MAXLEN]; 18 | 19 | while (TRUE) 20 | { 21 | printf ("%s ", "$"); 22 | fgets (s, MAXLEN, stdin); 23 | /* printf ("%s", s); */ 24 | 25 | pid_t proc; /* process id */ 26 | int *status; /* waitpid status */ 27 | 28 | if ((proc = fork ()) != 0) 29 | { 30 | /* printf ("%s %u\n", "created process", proc); */ 31 | waitpid (-1, status, 0); 32 | } 33 | else 34 | { 35 | /* save the command and the arguments */ 36 | /* TODO: use getopts for the arguments */ 37 | char cmd[MAXLEN]; 38 | if (sscanf (s, "%s", cmd) > 0) 39 | { 40 | /* printf ("%s\n", cmd); */ 41 | char *const parm[] = { cmd, NULL }; 42 | execve (cmd, parm, 0); 43 | } 44 | } 45 | } 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /syscalls.c: -------------------------------------------------------------------------------- 1 | /* 2 | syscalls.c Test the MINIX 3 (POSIX-compatible) system calls. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | int mknod (const char *, mode_t, dev_t); 23 | int brk (void *); 24 | 25 | static void 26 | handler (int signum) 27 | { 28 | printf ("\nsignal %d caught, %s\n", signum, 29 | signum == SIGINT ? "exiting..." : "ignoring..."); 30 | 31 | if (signum == SIGINT) 32 | { 33 | exit (0); 34 | } 35 | } 36 | 37 | 38 | /** 39 | * Most system calls should be executed 40 | * individually (comment the rest). Comments 41 | * are folded using Emacs. Don't spend all 42 | * your time trying to cleanup manually... 43 | * 44 | * @return 0 on success. Another value otherwise 45 | */ 46 | int 47 | main (void) 48 | { 49 | pid_t proc; 50 | int fd; 51 | const char dname[] = "tty007"; 52 | const char fname[] = "file_1"; 53 | const char fname2[] = "file_2"; 54 | const char msg[] = "bravo!\n"; 55 | const mode_t mode = S_IRUSR | S_IWUSR; 56 | int i; 57 | char *ptr; 58 | /* struct sigaction action; */ 59 | struct stat file_stat; 60 | int status; 61 | 62 | /* -- process management -- */ 63 | 64 | /* child process creation */ 65 | /* if ((proc = fork ()) != 0) */ 66 | /* { */ 67 | /* int status; */ 68 | 69 | /* printf ("created child process %u in group %u\n", getpid (), getpgrp ()); */ 70 | 71 | /* /\* send a kill signal to the child process *\/ */ 72 | /* int s; */ 73 | /* if (s = kill (getpid (), SIGKILL) != 0) */ 74 | /* { */ 75 | /* perror ("getpid"); */ 76 | /* } */ 77 | 78 | /* /\* waiting for the child process to finish *\/ */ 79 | /* waitpid (proc, &status, 0); */ 80 | /* printf ("process %u ended\n", getpid ()); */ 81 | /* } */ 82 | 83 | /* replace the image of a process */ 84 | /* int out = 0; */ 85 | /* char *const args[] = {"uname", "-a", NULL}; */ 86 | /* char *const env[] = {NULL}; */ 87 | /* execve ("/bin/uname", args, env); */ 88 | /* perror ("execve"); /\* execve normally never returns *\/ */ 89 | 90 | /* terminate execution */ 91 | /* exit (3); */ 92 | 93 | /* change the size of the data segment */ 94 | /* ptr = (char *) malloc (1); */ 95 | /* if (brk (ptr + 30) == -1) */ 96 | /* { */ 97 | /* perror ("brk"); */ 98 | /* } */ 99 | 100 | /* -- signal handling -- */ 101 | 102 | /* Set up the structure to specify the action. */ 103 | /* action.sa_handler = handler; */ 104 | /* sigemptyset (&action.sa_mask); */ 105 | /* action.sa_flags = 0; */ 106 | 107 | /* /\* disable the default signal actions *\/ */ 108 | /* sigaction (SIGINT, &action, NULL); */ 109 | /* sigaction (SIGHUP, &action, NULL); */ 110 | /* sigaction (SIGTERM, &action, NULL); */ 111 | /* sigaction (SIGQUIT, &action, NULL); */ 112 | 113 | /* alarm a signal */ 114 | /* alarm (3); */ 115 | 116 | /* wait for signals */ 117 | /* while (1) */ 118 | /* { */ 119 | /* /\* pause the process *\/ */ 120 | /* pause (); */ 121 | /* } */ 122 | 123 | /* -- file management -- */ 124 | 125 | /* create a file (thank you ken) */ 126 | /* if (fd = creat (fname, 0664) != -1) */ 127 | /* { */ 128 | /* printf ("created file %s\n", fname); */ 129 | /* } */ 130 | 131 | /* /\* create an i-node (typically superuser only) *\/ */ 132 | /* if (fd = mknod (dname, 020744, 0x0407) != -1) */ 133 | /* { */ 134 | /* printf ("created device file %s\n", dname); */ 135 | /* } */ 136 | /* else */ 137 | /* { */ 138 | /* perror ("mknod"); */ 139 | /* } */ 140 | 141 | /* /\* open a file for read/write *\/ */ 142 | /* if ((fd = open (fname, O_RDWR | O_CREAT, mode)) != -1) */ 143 | /* { */ 144 | /* printf ("opened file %s\n", fname); */ 145 | 146 | /* /\* seek to the end of file (to append) *\/ */ 147 | /* lseek(fd, 0L, SEEK_END); */ 148 | 149 | /* /\* write to the file *\/ */ 150 | /* if ((i = write (fd, msg, strlen (msg))) == -1) */ 151 | /* { */ 152 | /* perror ("write"); */ 153 | /* return 1; */ 154 | /* } */ 155 | 156 | /* /\* close the file *\/ */ 157 | /* close (fd); */ 158 | 159 | /* /\* get file status *\/ */ 160 | /* if (stat (fname, &file_stat) == -1) */ 161 | /* { */ 162 | /* perror ("stat"); */ 163 | /* } */ 164 | /* printf ("Last file access: %s", ctime (&file_stat.st_atime)); */ 165 | /* printf("Mode: %lo (octal)\n", (unsigned long) file_stat.st_mode); */ 166 | /* } */ 167 | 168 | /* ioctl example (TODO: find a better one) */ 169 | /* if (fd = open ("/dev/ttyS0", O_RDONLY) == -1) 170 | { 171 | perror ("open"); 172 | } 173 | if (ioctl(fd, TIOCMGET, &status) == -1) 174 | { 175 | printf("TIOCMGET failed: %s\n", 176 | strerror(errno)); 177 | } 178 | else { 179 | if (status & TIOCM_DTR) 180 | puts("TIOCM_DTR is not set"); 181 | else 182 | puts("TIOCM_DTR is set"); 183 | } 184 | close(fd);*/ 185 | 186 | /* check accessibility of a file */ 187 | if (access (fname, F_OK) == -1) /* check that file exists */ 188 | { 189 | perror("access"); 190 | } 191 | if (access (fname, R_OK) == -1) /* check that file can be read */ 192 | { 193 | perror ("access"); 194 | } 195 | else 196 | { 197 | printf ("File %s can be read\n", fname); 198 | } 199 | 200 | /* rename a file */ 201 | if (rename (fname, fname2) == -1) 202 | { 203 | perror ("rename"); 204 | } 205 | 206 | /* fcntl example */ 207 | 208 | 209 | return 0; 210 | } 211 | -------------------------------------------------------------------------------- /tlb.c: -------------------------------------------------------------------------------- 1 | /* 2 | demonstrate the TLB misses by parsing a large array 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | int main (void) 10 | { 11 | const unsigned long long size = 100000999LLU; 12 | long long *data; 13 | data = (long long *) calloc (size, sizeof (long long)); 14 | 15 | if (NULL == data) 16 | { 17 | fprintf (stderr, "cannot allocate memory\n"); 18 | return 1; 19 | } 20 | 21 | time_t start, stop; 22 | double diff = 0; 23 | 24 | time (&start); 25 | int i; 26 | for (i = 0; i != size; ++i) 27 | { 28 | data[i] = i * 4; 29 | } 30 | time (&stop); 31 | 32 | diff = difftime (stop, start); 33 | printf ("it took %.2lf seconds to parse the array\n", diff); 34 | 35 | free (data); 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /trace.c: -------------------------------------------------------------------------------- 1 | /* 2 | Example of tracing a system call 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | int main (void) 11 | { 12 | long counter = 0; /* machine instruction counter */ 13 | int wait_val; /* child's return value */ 14 | int pid; /* child's process id */ 15 | 16 | /* tracing a system call */ 17 | puts ("Please wait"); 18 | 19 | switch (pid = fork ()) 20 | { 21 | case -1: 22 | perror ("fork"); 23 | break; 24 | case 0: /* child process starts */ 25 | ptrace (PTRACE_TRACEME, 0, 0, 0); 26 | /* 27 | * must be called in order to allow the 28 | * control over the child process 29 | */ 30 | execl ("/bin/ls", "ls", NULL); 31 | /* 32 | * executes the program and causes 33 | * the child to stop and send a signal 34 | * to the parent, the parent can now 35 | * switch to PTRACE_SINGLESTEP 36 | */ 37 | break; 38 | /* child process ends */ 39 | default: /* parent process starts */ 40 | wait (&wait_val); 41 | /* 42 | * parent waits for child to stop at next 43 | * instruction (execl()) 44 | */ 45 | while (wait_val == 1407) 46 | { 47 | counter++; 48 | if (ptrace (PTRACE_SINGLESTEP, pid, 0, 0) != 0) 49 | perror ("ptrace"); 50 | /* 51 | * switch to singlestep tracing and 52 | * release child 53 | * if unable call error. 54 | */ 55 | wait (&wait_val); 56 | /* wait for next instruction to complete */ 57 | } 58 | /* 59 | * continue to stop, wait and release until 60 | * the child is finished; wait_val != 1407 61 | * Low=0177L and High=05 (SIGTRAP) 62 | */ 63 | } 64 | printf ("Number of machine instructions : %lld\n", counter); 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /user.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # enumerate the user database 4 | 5 | user_f=/etc/passwd 6 | group_f=/etc/group 7 | 8 | while read line 9 | do 10 | uname=`echo ${line} | cut -d: -f 1` 11 | uid=`echo ${line} | cut -d: -f 3` 12 | printf "groups of ${uname} (${uid})\n" 13 | groups=`grep ${uname} ${group_f} | cut -d: -f 1` 14 | printf "${groups}\n\n" 15 | done < ${user_f} 16 | --------------------------------------------------------------------------------