Computer-Science

Basic file system calls: open, read, write

1. open

x = open("/aa/bb", O_RDWR, 00777);

or

char fname[20];
strcpy(fname, "/aa/bb");
x = open(fname, O_RDWR, 00777); // fname contains "/aa/bb"



2. read

y = read(x, buf, 10);

3. write

y = write(x, buf, 10);

ํŒŒ์ผ์— ์ง์ ‘์ ์œผ๋กœ string์„ write ํ•  ์ˆ˜ ์žˆ๋‹ค.

y = write(x, "hello", 5);

string ํ˜• ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด์„œ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

char buf[10];
strcpy(buf, "hello");
y = write(x, buf, 5);

4. standard input, standard output, standard error

y = read(0, buf, 10);   // read 10 bytes from the standard input file (keyboard in default)
// and store them in buf
y = write(1, buf, 10);  // write 10 bytes from buf in the standard output file (terminal in default)
y = write(2, buf, 10);  // write 10 bytes from buf in the standard error file (terminal in default)

5. manuals for system call

$ man 2 open
$ man 2 read
$ man 2 write

man์˜ mannual์—๋Š” ๊ฐ ์‹œ์Šคํ…œ ํ˜ธ์ถœ์— ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ํŒŒ์ผ์— ๋Œ€ํ•œ ์„ค๋ช…์ด ๋‚˜์™€ ์žˆ๋‹ค.

6. Exercise

6-0) Reading 20 bytes from file โ€œf1โ€ and display them in the terminal using printf.

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(){
     int x, y;
     char buf[50];

     x=open("f1", O_RDONLY, 00777); // open f1 in the current directory
     y=read(x, buf, 20); // read max 20 bytes. return actual number of bytes read in y.
     buf[y]=0; // make buf a string
     printf("%s\n", buf); // and display
     return 0;
}

6-1) Reading 20 bytes from file โ€œf1โ€ and display them in the terminal using write.

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(){
     int x, y;
     char buf[50];

     x=open("f1", O_RDONLY, 00777); // open f1 in the current directory
     y=read(x, buf, 20); // read max 20 bytes. return actual number of bytes read in y.
     write(1, buf, y); // write y bytes in buf to the terminal.
     return 0;
}

6-2) Copying 20 bytes from file โ€œf1โ€ to โ€œf2โ€. Check โ€œf2โ€ with โ€œcat f2โ€.

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(){
     int x1, x2, y;
     char buf[50];

    x1=open("f1", O_RDONLY, 00777); // open f1 for reading
    x2=open("f2", O_RDWR | O_CREAT | O_TRUNC, 00777); // open f2 for writing
    y=read(x1, buf, 20); // read max 20 bytes. return actual number of bytes read in y.
    write(x2, buf, y); // write y bytes in buf to f2
    return 0;

}

6-3) Same as above, but copy all data from f1 to f2. Check โ€œf2โ€ with โ€œcat f2โ€.

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(){
     int x1, x2, y;
     char buf[50];

     x1=open("f1", O_RDONLY, 00777); // open f1 for reading
     x2=open("f2", O_RDWR | O_CREAT | O_TRUNC, 00777); // open f2 for writing
     for(;;){
          y=read(x1, buf, 20); // read max 20 bytes from f1
          if (y==0) break; // if end-of-file, get out
          write(x2, buf, y); // write to f2
     }

     return 0;
}

7. gdb

gcc -g -o myx x.c
gdb commands
b main : break point on main
r : start the program
n : execute the next statement (if function, execute the function and return)
s : execute the next statement (if function, enter the function and execute the
first statement of it and stop)
p x1 : show the value of variable x1
p arr1 : show the contents of array arr1
x/10xb arr1 : show 10 bytes (in hexa) starting from the address of arr1
help : show all commands
help print : show the explanation about print command
q : quit

8. error handling

         x=open("/aa/bb", โ€ฆ.);
         y=open("f2", โ€ฆ.);
         printf("x:%d y:%d\n", x, y);

Use gdb to find the error

Sometimes, perror is better than simple printf:

When there is an error, the system calls usually returns -1. To check what was the error do followings.

#include <errno.h>
     ..........
     x = open(............);
     if (x < 0){ // we have an error
          perror("error in foo\n"); // will show error message
          exit(0); // stop program
     }
................

9. Homework

1) Make a file, โ€œf1โ€, and fill it with more than 20 bytes.

$vi f1
I have a dream
that one day this nation
will rise up and
live out the true
meaning of its creed
that all men are created equal.

2) Try the code in 6-0), 6-1), 6-2), 6-3).

6-0) Reading 20 bytes from file โ€œf1โ€ and display them in the terminal using printf.

6-1) Reading 20 bytes from file โ€œf1โ€ and display them in the terminal using write.

6-2) Copying 20 bytes from file โ€œf1โ€ to โ€œf2โ€. Check โ€œf2โ€ with cat f2.

6-3) Same as above, but copy all data from f1 to f2. Check โ€œf2โ€ with cat f2.

3) Find the byte size of f2 with ls โ€“l f2. Use xxd to find out the actual data stored in f2.

f2์˜ byte size๋Š” 130bytes์ด๋‹ค.

4) Write a program โ€œhw4.cโ€ that opens f2 and shows each byte of it in hexadecimal number, decimal number, and character. Use printf(โ€œ%x %d %c\nโ€, โ€ฆโ€ฆโ€ฆโ€ฆโ€ฆ) to display a number in various format.

       int x, y; char buf[20];
       x=open("f2", O_RDONLY, 00777);      // open f2 for reading
       for(;;){
           y=read(x, buf, 1);  // read next byte
           if (y==0) break;    // we read all, exit the loop
           printf("%x %d %c\n", buf[0], buf[0], buf[0]); // display
       }

5. Compile hw4.c with โ€“g option and run gdb to execute each instruction one by one. Use p or x to check the value of a variable.

    $ gcc -g -o hw4 hw4.c
    $ gdb hw4
    gdb) b main -- stop at main
    gdb) r -- run
    ............
    9 x=open("f2", O_RDONLY, 00777); -- next line to execute
    gdb) list -- show code list
    gdb) n -- execute current line
    11 y=read(x, buf, 1); -- line 9 has been executed. next is line 11
    gdb) p x -- show x
    $1 = 7 -- f2 is now file number 7
    gdb) n
    ..........
    gdb) p y
    $2 = 1 -- we have read 1 byte
    gdb) p buf[0]
    $4 = 73 'I' -- assume we have 'I' in buf[0]
    gdb) x/4xb buf -- show 4 bytes at buf in hexadecimal num
    0x7fffffffe470: 0x49 0x06 0x40 0x00 -- we have 0x49=73='I' in buf[0]
    gdb) n
    ............ โ€“- repeat a few times
    gdb) list -- show rest of code
    gdb) b 15 -- break point at line 15 (after loop)
    gdb) c -- continue to that break point
    gdb) q -- stop gdb

6. Write a program that creates a file and writes โ€œhello thereโ€in it. Use open() and write(). Confirm the result with โ€œcatโ€.

    x = open("f3", O_RDWR | O_CREAT | O_TRUNC, 00777); // create f3
    write(x, "hello there", 11); // write 11 bytes in f3

7. Write a program that makes a copy for file โ€œhw4.cโ€ into another file โ€œcphw4.cโ€. Use open(), read(), and write(). Confirm that they are same with cat and ls -l.

              x1 = open hw4.c as O_RDONLY
              x2 = open cphw4.c as O_RDWR | O_CREAT | O_TRUNC
              for(;;){
                  y = read max 20 bytes from x1 into buf
                  if y is 0, break
                  write y bytes of buf into x2
              }

8. Write a program that makes a copy for file โ€œhw4โ€ (the executable file for โ€œhw4.c) into another file cphw4. Confirm that they are same with xxd and ls -l. Execute cphw4 to see if it runs ok.

9. Repeat 7). But get the name of the files from the user. Confirm that the result of copy with โ€œcatโ€ and โ€œls -lโ€.

Enter src file name
hw4.c
Enter dest file name
newhw4.c
hw4.c is copied into newhw4.c successfully.

10. Write mycat that displays the contents of a user-input file in the terminal in characters. Give a text file and a non-text file to mycat and explain the difference.

$./mycat
Enter file name
f1
The content of f1 is :
I have a dream
that one day this nation
will rise up and
live out the true
meaning of its creed
that all men are created equal.
$./mycat
Enter file name
hw4
.............

11. Write myxxd that displays the contents of a user-input file in the terminal in hexadecimal numbers. Give a text file and a non-text file to myxxd and explain the difference. You need to use printf("%x ", buf[i]) to display a byte in a hexadecimal number. Also declare the buffer as an array of unsigned char. Compare the result from the result of xxd.

$./myxxd
Enter file name
f1
The content of f1 is :
49 20 68 61 ..........
$ xxd f1
..................
$./myxxd
Enter file name
hw4
.............
$ xxd hw4
...............

12. Run following code and display f8 with cat and xxd respectively. Explain the results.

    int x=open("f8", O_CREAT|O_RDWR|O_TRUNC, 00777);
    write(x, "ab", 2);
    int y=10;
    write(x, &y, 4);
    write(x, "cd", 2);
    y=235;
    write(x, &y, 4);

ab
cd๏ฟฝ
00000000: 6162 0a00 0000 6364 eb00 0000            ab....cd....

13. Write a program that divides a given file into three small files of roughly equal size. Use fstat() to find out the size of a file.

    Enter file name to split
    f9
    f9 is split into f91, f92, and f93.

14. What is wrong with following program?

char temp0[20], *temp1[10], *temp2[10];
printf("enter src file name\n");
gets(temp0);
temp1[0]=temp0;
printf("enter dest file name\n");
gets(temp0);
temp2[0]=temp0;
printf("src file:%s dest file:%s\n", temp1[0], temp2[0]);

temp1[0]=temp0;๊ณผ temp2[0]=temp0;๋Š” temp1[0]๊ณผ temp2[0]์— temp0์˜ ์‹œ์ž‘์ง€์  ํฌ์ธํ„ฐ๋ฅผ ๊ธฐ๋กํ•˜๊ฒŒ ํ•˜๋Š” ๋™์ž‘์ด๋‹ค. ์ฆ‰, ๋ฌธ์ž์—ด์„ ๋ณต์‚ฌํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์•„๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋‘ ๋ฒˆ์งธ gets(temp0);์—์„œ temp0 ๊ฐ’์ด ๋ฎ์–ด ์”Œ์›Œ์ ธ temp1[0]๊ณผ temp2[0]์ด ๊ฐ™์€ ๊ฐ’์„ ๊ฐ™๊ฒŒ ๋˜์—ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด strcpy๋กœ ํŒŒ์ผ ๋‚ด์šฉ์„ ๋ณต์‚ฌํ•œ๋‹ค๋ฉด ์›๋ž˜์˜ ์˜๋„๋Œ€๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

15. What is wrong with following program. Find the problem with GDB and fix it.

    int x, x1, y;
    x=open("f1", O_RDONLY, 00777);
    x1=open("f2", O_WRONLY|O_CREAT|O_TRUNC,00777);
    char buf[512];
    int cnt=0;
    for(;;){
        y=read(x,buf,1);
        if (y==0) break;
        cnt++;
    }
    write(x1, buf, cnt);


7. Extra Practice

1. Write a program that adds up the ascii number of a text file and print it.

If โ€œf1โ€ has

ab
c

then, the output should be 61+62+a+63+a=13a in hexadecimal number as follows.

$ ./hexa_sum f1
sum: 13a

See hexa_sum.c (Ref myxxd 11.c and code)