Project 2: I/O and Library

Implement three routines: insert, delete, and extract w/o issues when operating in the middle of a file.

1. System calls

open(), lseek(), read(), write().

ftruncate() to modify file size.

See detail in UNIX manual document.


2. Writing header file

A standard set of instructions to make programming easier. A header file is generally used to define all of the functions, variables and constants contained in any function library that you might want to use.

#ifndef _UFSEXT_H_
#define _UFSEXT_H_
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

int insert(int fd, void *buf, size_t bytes, size_t offset);
int extract(int fd, void *buf, size_t bytes, size_t offset);
int delete(int fd, size_t bytes, size_t offset);
#endif

3. Makefile

all: shared 

libufsext.so: //Create dynamic library
	gcc -fPIC -c insert.c
	gcc -fPIC -c delete.c
	gcc -fPIC -c extract.c
	gcc -shared -o libufsext.so insert.o delete.o extract.o

shared:libufsext.so  //link test programs to the dynamic library
	gcc -o inserttst inserttst.c -L. -lufsext
	gcc -o deletetst deletetst.c -L. -lufsext
	gcc -o extracttst extracttst.c -L. -lufsext
	gcc -o mixtest mixtest.c -L. -lufsext

libufsext.a: //Create static library
	gcc -c insert.c
	gcc -c delete.c
	gcc -c extract.c
	ar -cq libufsext.a insert.o delete.o extract.o

static:libufsext.a //link test programs to the static library
	gcc -o inserttst inserttst.c libufsext.a
	gcc -o deletetst deletetst.c libufsext.a
	gcc -o extracttst extracttst.c libufsext.a
	gcc -o mixtest mixtest.c libufsext.a
	
test: //set current environment
	LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. ./inserttst
	LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. ./deletetst
	LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. ./extracttst

clean: 
	rm -f *.o inserttst deletetst extracttst mixtest libufsext.a libufsext.so
Static libraries: Separate object files combined into single library file. Object code incorporated into executable at link time. Use 
ar (see manual page)
ar -cq libufsext.a insert.o delete.o extract.o

to create library and add functions.

Dynamic library: Stub included in binary program image for each library-routine reference. Stub is code to locate memory-resident routine or load it if library routine not present. Stub replaces itself with address of routine and executes routine 

gcc -shared -o libufsext.so insert.o delete.o extract.o\


4.Secure programming 

Check every function invoked and return -1 if error occurs. Free allocated memory in every possible case. (More attention on pointer usage.)

#include "ufsext.h"
int extract(int fd, void *buf, size_t bytes, size_t offset){
    char *tmp;
	int length=lseek(fd, 0L,SEEK_END);
	if(offset>length){
		printf("Out of the file.\n");
		free(buf);
		return -1;
	}
	
	if(length<=0){
		printf("Cannot extract from empty file,\n");
		free(buf);
		return -1;
	}
	
	if(bytes < 0 || offset < 0){
		printf("Invaild inputs\n");
		free(buf);
		return -1;
	}
	
    if(lseek(fd, offset, SEEK_SET)==-1){
		perror("lseek");
		free(buf);
		return -1;
	}
	
	if(read(fd,buf,bytes)==-1){
		perror("read");
		free(buf);
		return -1;
	}
	
	if(lseek(fd, (offset + bytes), SEEK_SET) == -1){
		free(buf);
		perror("lseek");
		return -1;
	}
	
    if(!(tmp=malloc((length-offset-bytes+1)*sizeof(char)))){
		perror("malloc");
		free(buf);
		return -1;
	}
	memset(tmp, 0, (length-offset-bytes+1));
	
    if(read(fd, tmp, length-offset-bytes)==-1){
		perror("read");
		free(buf);
		free(tmp);
		return -1;
	}
	
    if(lseek(fd, offset, SEEK_SET)==-1){
		perror("lseek");
		free(buf);
		free(tmp);
		return -1;
	}
    
    if(write(fd, tmp, length-offset-bytes)==-1){
		perror("write");
		free(buf);
		free(tmp);
		return -1;
	}
	free(tmp);
	
    if(ftruncate(fd, length-bytes)==-1){
		perror("ftruncate");
		return -1;
	}
    return bytes;
}
#include "ufsext.h"

int main(int argc, char *argv[]){
	char filename[] = "testExtract.txt";
	int fd = 0;
	int ret = 0;
	void *buf; 

	fd = open(filename, O_EXCL|O_RDWR);
	if(fd == -1){
		perror("open");
		exit(EXIT_FAILURE);
	}
	
	int length=lseek(fd, 0L,SEEK_END);
	buf = malloc(length * sizeof(char));
	if(!buf){
		perror("malloc");
		exit(EXIT_FAILURE);
	}
	memset(buf, 0, length);

	ret = extract(fd, buf, 2, 4);
	if (ret == -1){
		printf("extract Error\n");
		free(buf);
		exit(EXIT_FAILURE);
	}
	else{	
		printf("Prints %s\n",buf);
		printf("extract Successful, extract %d bytes of data\n\n", ret);
	}

	ret = extract(fd, buf, 2, 4);
	if (ret == -1){
		printf("extract Error\n");
		free(buf);
		exit(EXIT_FAILURE);
	}
	else{
		printf("Prints %s\n",buf);
		printf("extract Successful, extract %d bytes of data\n\n", ret);
	}

	ret = extract(fd, buf, 2, 0);
	if (ret == -1){
		printf("extract Error\n");
		free(buf);
		exit(EXIT_FAILURE);
	}
	else{
		printf("Prints %s\n",buf);
		printf("extract Successful, extract %d bytes of data\n\n", ret);
	}
	free(buf);
	close(fd);
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值