CSC 271 – Software I: Utilities and Internals An Introduction to File I/O in Linux Credited to Dr. Robert Siegfried and Beginning Linux Programming by.

Slides:



Advertisements
Similar presentations
© Original by Donald Acton; Changes by George Tsiknis Unix I/O Related Text Sections: 2nd Ed: and st Ed: and
Advertisements

January 13, Csci 2111: Data and File Structures Week1, Lecture 2 Basic File Processing Operations.
January 13, Files – Chapter 2 Basic File Processing Operations.
CS 241 Section Week #5 2/23/12. 2 Topics This Section MP4 overview Function Pointers Pthreads File I/O.
4.1 Operating Systems Lecture 11 UNIX Pipes Read Handout "An Introduction to Concurrency..."
1 Files and Directories Hua LiSystems ProgrammingCS2690Files and Directories.
Today’s topic: –File operations –I/O redirection –Inter-process communication through pipes.
CS 311 – Lecture 09 Outline Introduction to Systems programming – System calls – Categories of system calls Error Management System calls File Handling.
Exec function Exec function: - replaces the current process (its code, data, stack & heap segments) with a new program - the new program starts executing.
Files. System Calls for File System Accessing files –Open, read, write, lseek, close Creating files –Create, mknod.
1 Advanced programming in UNIX 1 File I/O Hua LiSystems ProgrammingCS2690File I/O.
CS 311 – Lecture 10 Outline Review open() and close() Difference between fopen() and open() File management system calls – read() – write() – lseek() –
Files and Directories Hua LiSystems ProgrammingCS2690Files and Directories Spring 2003Page 1 of 60.
7/15/2015B.RamamurthyPage 1 File System B. Ramamurthy.
CS 311 – Lecture 12 Outline File management system calls Stat() Directory Information  Opendir()  Readdir()  Closedir() Truncate() and remove() Lecture.
1 Unix File System API Operating System Hebrew University Spring 2007.
POSIX: Files Introduction to Operating Systems: Discussion 1 Read Solaris System Interface Guide: Ch. 5.1 Basic File I/O.
Chapter 39 Virtsualization of Storage: File and Directory Chien-Chung Shen CIS, UD
Adv. UNIX: lowIO/161 Advanced UNIX v Objectives –look at low-level operations for handling files Special Topics in Comp. Eng. 2 Semester.
Fundamentals CIS 552. Fundamentals Low-level I/O (read/write using system calls)  Opening/Creating files  Reading & Writing files  Moving around in.
Week 12 - Friday.  What did we talk about last time?  Exam 2 post mortem  Low level file I/O.
Advanced UNIX progamming Fall 2002 Instructor: Ashok Srinivasan Lecture 5 Acknowledgements: The syllabus and power point presentations are modified versions.
1 UNIX System Programming v Objectives –look at how to program with directories –briefly describe the UNIX file system Directories and File System.
Operating Systems Recitation 1, March th, 2002.
22. FILE INPUT/OUTPUT. File Pointers and Streams Declarations of functions that perform file I/O appear in. Each function requires a file pointer as a.
Pipes A pipe is a simple, synchronized way of passing information between processes A pipe is a special file/buffer that stores a limited amount of data.
CS252: Systems Programming Ninghui Li Based on Slides by Prof. Gustavo Rodriguez-Rivera Topic 8: Opening Files and Starting Processes.
Directory structure. Slide 2 Directory Structure  A directory ‘file’ is a sequence of lines; each line holds an i-node number and a file name.  The.
UNIX Files File organization and a few primitives.
File IO and command line input CSE 2451 Rong Shi.
Files & File system. A Possible File System Layout Tanenbaum, Modern Operating Systems 3 e, (c) 2008 Prentice-Hall, Inc. All rights reserved
Files and Directories File types stat functions for file information
Week 12 - Wednesday.  What did we talk about last time?  File I/O  Binary trees  Lab 11.
Navigating Directories
Lecture 3 Introduction to Unix Systems Programming: Unix File I/O System Calls.
Today’s topic Access and manipulate meta data for files –File type, ownership, access permissions, access time, etc How to determine if a file is not there?
CSCI 330 UNIX and Network Programming Unit VII: I/O Management I.
Laface 2007 File system 2.1 Operating System Design Filesystem system calls buffer allocation algorithms getblk brelse bread breada bwrite iget iput bmap.
Programming with UNIX File Systems (Chap 3, 4. in the book “Advanced Programming in the UNIX Environment”) Acknowledgement : Prof. Y. Moon at Kangwon Nat’l.
NCHU System & Network Lab Lab 14 File and Directory.
CSCI 330 UNIX and Network Programming
CSE333 SECTION 3. Important Dates Jan 27 th – Homework 1 Due Feb 6 th – Midterm.
January 7, 2003Serguei Mokhov, 1 File I/O System Calls Reference COMP 229, 444, 5201 Revision 1.2 Date: July 21, 2004.
Copyright ©: Nahrstedt, Angrave, Abdelzaher1 Tarek Abdelzaher Vikram Adve CS241 Systems Programming System Calls and I/O.
CS 241 Section Week #8 (10/29/09). Outline MP5 Overview Files & I/O UNIX File Systems inodes Directories Links.
Library Functions The UNIX system provides a large number of C functions as libraries. Some of these implement frequently used operations, while others.
File I/O open close lseek read and write – unbuffered I/O dup and dup2.
CSC 660: Advanced Operating SystemsSlide #1 CSC 660: Advanced OS Virtual Filesystem.
CSCI 330 UNIX and Network Programming Unit VIII: I/O Management II.
OS interface: file and I/O system calls File operations in C/C++? –fopen(), fread(), fwrite(), fclose(), fseek() in C f.open(…), f.close(…) in C++ I/O.
CS 241 Section Week #5 9/22/11. 2 Topics This Section File I/O Advanced C.
File Subsystem in Linux by Dr P.Padmanabham Professor (CSE)&Director Bharat Institute of Engineering &Technology Hyderabad Mobile
C Programming Day 2. 2 Copyright © 2005, Infosys Technologies Ltd ER/CORP/CRS/LA07/003 Version No. 1.0 Union –mechanism to create user defined data types.
Week 12 - Friday.  What did we talk about last time?  Exam 2 post mortem.
File table: a list of opened files Each entry contains: – Index: file descriptors – Pointer to the file in memory – Access mode File descriptor is a positive.
Using System Calls (Unix) Have to tell compiler (if C/C++) where to find the headers, etc. – i.e., the “include” files May have to tell compiler where.
Files in UNIX u UNIX deals with two different classes of files:  Special Files  Regular Files u Regular files are just ordinary data files on disk -
Chapter 22 – part a Stream refer to any source of input or any destination for output. Many small programs, obtain all their input from one stream usually.
Week 12 - Wednesday CS222.
Operating System Hebrew University Spring 2004
An overview of the kernel structure
CSE 333 – Section 3 POSIX I/O Functions.
File Structure Related system calls
File I/O (1) Prof. Ikjun Yeom TA – Mugyo
File I/O (1) Prof. Ikjun Yeom TA – Hoyoun
CSE 333 – Section 3 POSIX I/O Functions.
CSE 333 – Section 3 POSIX I/O Functions.
Chien-Chung Shen CIS, UD
FILE I/O File Descriptors I/O Efficiency File Sharing
Week 12 - Wednesday CS222.
Presentation transcript:

CSC 271 – Software I: Utilities and Internals An Introduction to File I/O in Linux Credited to Dr. Robert Siegfried and Beginning Linux Programming by Neil Matthew

File Descriptors All system calls for I/O operations refer to open files using a file descriptor (a nonnegative integer). File descriptors are used to refer to files, pipes, sockets, terminals, etc. When programs are running, there will usually be at least 3 standard file descriptors: –0 stdin (standard input) –1 stdout (standard output –2 stderr (standard error

Four Key System Calls There are four key system calls for file I/O: fd = open(pathname, flags, mode); numRead = read(fd, buffer, count); numwritten = write(fd, buffer, count); status = close(fd); flags specified whether the file is open for reading, writing or obth. mode specifies permissions to be placed on the file.

File Access Flags Access ModeDescription O_RDONLY Open the file for reading only O_WRONLY Open the file for writing only O_RDWR Open the file for both reading and writing For use with : fd = open(pathname, flags, mode);

File Access Flags (continued) Access ModeDescription O_TRUNC Truncate the opened file, if it previously existed. Data written to the file descriptor will replace previous contents of the file. O_APPEND Append to an existing file. Data written to the file descriptor will be added to the end of the file. O_CREAT If the filename that you provide to open does not exist, a new file will be created, provided that the directory containing it exists and that the process has permission to create files in that directory. If the file already exists, it is opened instead. O_EXCL Specify O_EXCL with O_CREAT to force creation of a new file. If the file already exists, the open call will fail.

Flags vs Modes fd = open(pathname, flags, mode); –Flags: The flags determine how the file can be accessed by the program and whether the file will be created. Ex: O_CREAT means create the file, and O_APPEND means only allow access after the end of the file, and O_RDONLY means the program will only read –Mode: The mode determines what permissions the created file will modify from the UMASK – system defaults. You see these in ls

File Creation modes fd = open(pathname, flags, mode); But Umask can disallow OwnerGroupOthers Read Permission S_IRUSRS_IRGRPS_IROTH Write Permission S_IWUSRS_IWGRPS_IWOTH Execute Permission S_IXUSRS_IXGRPS_IXOTH

UMASK Mask for new files Different per user See with umask command Ours: 0022 Ignore first leading 0 Second digit – user permission Third digit – group permission Fourth digit – other permission

UMASK Permission bits: - Add them –0 –no permissions disallowed –4 read disallowed –2 write disallowed –1 execute disallowed Added –3 means write and execute –7 means all disallowed

create-file.c #include int main (int argc, char* argv[]) { /* * The path at which to create the new * file. */ char* path = argv[1];

/* The permissions for the new file. */ mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH; /* Create the file. */ int fd = open (path, O_WRONLY | O_EXCL | O_CREAT, mode); if (fd == -1) { /* An error occurred. Print an error message and bail. */ perror ("open"); return 1; } return 0; }

close() It is generally a good idea to close files with close() when you are done with them. In some cases, it’s not necessary to call close explicitly because Linux closes all open file descriptors when a process terminates. Once you close a file descriptor, you should no longer use it.

close() Closing a file descriptor may cause Linux to take a particular action. Example: –When you close a file descriptor for a network socket, Linux closes the network connection between the two computers communicating through the socket.

timestamp.c #include /* * Return a character string representing the * current date and time. */

char* get_timestamp () { time_t now = time (NULL); return asctime (localtime (&now)); } int main (int argc, char* argv[]) { /* * The file to which to append the * timestamp. */ char* filename = argv[1]; /* Get the current timestamp. */ char* timestamp = get_timestamp ();

/* * Open the file for writing. If it * exists, append to it; otherwise, * create a new file. */ int fd = open (filename, O_WRONLY | O_CREAT | O_APPEND, 0666); /* * Compute the length of the timestamp * string. */ size_t length = strlen (timestamp);

/* Write the timestamp to the file. */ write (fd, timestamp, length); /* All done. */ close (fd); return 0; }

write() write() returns the number of bytes that were actually written, or -1 if an error occurred. For certain kinds of file descriptors, the number of bytes actually written may be less than the number of bytes requested. In this case, it’s up to you to call write again to write the rest of the data.

write-all.c #include /* * Write all of COUNT bytes from BUFFER to file * descriptor FD. * Returns -1 on error, or the number of bytes * written. */

ssize_t write_all (int fd, const void* buffer, size_t count) { size_t left_to_write = count; while (left_to_write > 0) { size_t written = write (fd, buffer, count); if (written == -1) /* An error occurred; bail. */ return -1; else /* * Keep count of how much more we need to * write. */

left_to_write -= written; } /* * We should have written no more than COUNT * bytes! */ assert (left_to_write == 0); /* * The number of bytes written is exactly * COUNT. */ return count; }

char buf[] = {"This is the beginning of a very special" "relationship"}; int main(void) { int fd, byteswrote; fd = open ("newfilefilename", O_WRONLY | O_CREAT | O_APPEND, 0666); byteswrote = write_all(fd, buf, 52); }

read() read() is the system call for reading data. Like write(), it takes a file descriptor, a pointer to a buffer, and a count specifying how many bytes are read from the file descriptor into the buffer. read() returns -1 on error or it returns the number of bytes actually read.

hexdump.c #include int main (int argc, char* argv[]) { unsigned char buffer[16]; size_t offset = 0; size_t bytes_read; int i;

/* Open the file for reading. */ int fd = open (argv[1], O_RDONLY); /* * Read from the file, one chunk at a * time. Continue until read "comes up * short", that is, reads less than we * asked for. * This indicates that we.ve hit the end * of the file. */ do { /* Read the next line's worth of bytes */ bytes_read = read (fd, buffer, sizeof (buffer));

/* * Print the offset in the file, followed * by the bytes themselves. */ printf ("0x%06x : ", (int)offset); for (i = 0; i < bytes_read; ++i) printf ("%02x ", buffer[i]); printf ("\n"); /* * Keep count of our position in the * file. */ offset += bytes_read; } while (bytes_read == sizeof (buffer));

/* All done. */ close (fd); return 0; }

Moving Around a File A file descriptor remembers its position in a file. As you read from or write to the file descriptor, its position advances corresponding to the number of bytes you read or write. Sometimes, however, you’ll need to move around a file without reading or writing data.

lseek() The lseek call enables you to reposition a file descriptor in a file. Usage #include off_t lseek(int fd, off_t offset, int whence); lseek returns the new position, as an offset from the beginning of the file, whose type is off_t. If an error occurs, lseek returns -1. You can’t use lseek with some types of file descriptors, such as socket file descriptors.

lseek() (continued) If the third argument is SEEK_SET, lseek interprets the second argument as a position, in bytes, from the start of the file. If the third argument is SEEK_CUR, lseek interprets the second argument as an offset, which may be positive or negative, from the current position. n If the third argument is SEEK_END, lseek interprets the second argument as an offset from the end of the file.A positive value indicates a position beyond the end of the file.

lseek() and Large Files Using this behavior of lseek, it’s possible to create extremely large files that occupy almost no disk space. lseek-huge.c takes as command-line arguments a filename and a target file size, in kilobytes. It opens a new file, advances past the end of the file using lseek, and then writes a single 0 byte before closing the file.

lseek-huge.c #include int main (int argc, char* argv[]) { int zero = 0; const int kilobyte = 1024; char* filename = argv[1]; size_t length = (size_t) atoi (argv[2]) * kilobyte;

/* Open a new file. */ int fd = open (filename, O_WRONLY | O_CREAT | O_EXCL, 0666); /* * Jump to 1 byte short of where we want * the file to end. */ lseek (fd, length - 1, SEEK_SET); /* Write a single 0 byte. */ write (fd, &zero, 1); /* All done. */ close (fd); return 0; }

lseek() - Example A more common usage of lseek is to move forward (or backward) through a file so that data from a particular location can be read (or rewritten).

change.c #include int main (int argc, char* argv[]) { char* filename = argv[1]; char zee = 'z'; /* Open a new file. */ int fd = open (filename, O_RDWR);

/* * Jump to 1 byte short of where we want * the file to end. */ lseek (fd, 40, SEEK_SET); /* Write a single 0 byte. */ write (fd, &zee, 1); /* All done. */ close (fd); return 0; }

stat() stat() call obtains information about a file. stat() takes two parameters –file descriptor for the file you’re interested in and a pointer to a variable of type struct stat. stat() return 0 if the call is successful and -1 if not.

Useful Fields in struct stat st_mode contains the file’s access permissions and the file type in the higher-order bits. st_uid and st_gid contain uid (user id number) and gid group id number) st_size contains the file size, in bytes. st_atime contains the time when this file was last accessed (read or written). st_mtime contains the time when this file was last modified.

Useful Fields in struct stat (continued) st_dev contains the major and minor device number of the hardware device –The major device number is shifted left 8 bits; the minor device number occupies the least significant 8 bits. st_ino contains the inode number of this file.

Macros for Determining File Type S_ISBLK (mode) - block device S_ISCHR (mode) - character device S_ISDIR (mode) - directory S_ISFIFO (mode) - fifo (named pipe) S_ISLNK (mode) - symbolic link S_ISREG (mode) - regular file S_ISSOCK (mode) - socket

readfile.c #include /* * Read the contents of FILENAME into a newly * allocated buffer. The size of the buffer is * stored in *LENGTH. Returns the buffer, which * the caller must free. If FILENAME doesn't * correspond to a regular file, returns NULL. */

char* read_file (const char* filename, size_t* length) { int fd; struct stat file_info; char* buffer; /* Open the file. */ fd = open (filename, O_RDONLY); /* Get information about the file. */ fstat (fd, &file_info); *length = file_info.st_size;

/* * Make sure the file is an ordinary * file. */ if (!S_ISREG (file_info.st_mode)) { /* It.s not, so give up. */ close (fd); return NULL; } /* * Allocate a buffer large enough to hold * the file.s contents. */ buffer = (char*) malloc (*length);

/* Read the file into the buffer. */ read (fd, buffer, *length); /* Finish up. */ close (fd); return buffer; }

int main(int argc, char *argv[]) { char filename[40]; size_t length; if (argc == 1) { printf("Enter filename\t?"); gets(filename); } else strcpy(filename, argv[1]); read_file(filename, &length); }

Reading Directories GNU/Linux provides functions for reading the contents of directories. opendir() - returns a DIR* handle, which can be used to access the directory contents. –If an error occurs, the call returns NULL. readdir() - returns a pointer to a struct dirent instance corresponding to the next directory entry. –The struct dirent contains the name of the directory entry. closedir() – closes directory

readdirectory.c #include /* * Return a string that describes the type of the * file system entry PATH. */

const char* get_file_type (const char* path) { struct stat st; lstat (path, &st); if (S_ISLNK (st.st_mode)) return "symbolic link"; else if (S_ISDIR (st.st_mode)) return "directory"; else if (S_ISCHR (st.st_mode)) return "character device"; else if (S_ISBLK (st.st_mode)) return "block device"; else if (S_ISFIFO (st.st_mode)) return "fifo"; else if (S_ISSOCK (st.st_mode)) return "socket";

else if (S_ISREG (st.st_mode)) return "regular file"; else /* * Unexpected. Each entry should be one * of the types above. */ assert (0); }

int main (int argc, char* argv[]) { char* dir_path; DIR* dir; struct dirent* entry; char entry_path[PATH_MAX + 1]; size_t path_len; if (argc >= 2) /* * If a directory was specified * on the command line, use it. */ dir_path = argv[1];

else /* * Otherwise, use the current * directory. */ dir_path = "."; /* * Copy the directory path into * entry_path. */ strncpy (entry_path, dir_path, sizeof (entry_path)); path_len = strlen (dir_path);

/* * If the directory path doesn't end with * a slash, append a slash. */ if (entry_path[path_len - 1] != '/') { entry_path[path_len] = '/'; entry_path[path_len + 1] = '\0'; ++path_len; } /* * Start the listing operation of the * directory specified on the command * line. */ dir = opendir (dir_path);

/* Loop over all directory entries. */ while ((entry = readdir (dir)) != NULL) { const char* type; /* * Build the path to the directory * entry by appending the entry * name to the path name. */ strncpy (entry_path + path_len, entry->d_name, sizeof (entry_path) - path_len); /*Determine the type of the entry*/ type = get_file_type (entry_path);

/* * Print the type and path of the * entry. */ printf ("%-18s: %s\n", type, entry_path); } /* All done. */ closedir (dir); return 0; }

Running readdirectory readdirectory regular file :./ch2.1 directory :./.elinks regular file :./270cl1.pdf regular file :./power.c … … … directory :./testdir regular file :./total.dat