四、LINUX文件系统编程源代码分析
本节中我们将通过一起设计、编写一个UNIX格式文件和DOS/WINDOWS格式文件相互转换的工具软件,通过实践来充分理解如何吃透LINUX文件系统的内核,进行较为深入的文件系统应用程序设计。
整个工具软件包括四个程序:
1) unix2dos.c程序模块;
2) dos2unix.c程序模块;
3) 主程序file_transfer.c;
4) file_transfer.h包含文件。
4.1 unix2dos.c程序模块
unix2dos.c程序模块:用来把UNIX格式的文件转换为DOS/WINDOWS格式的文件。
unix2dos.c程序模块源代码如下所示:
/* $Date: 2001/03/28 12:19:21 $
*
* UNIX to DOS text format conversion.
*
* $Log: unix2dos.c,v $
* Revision 1.1 2001/03/28 12:19:21 vong
* Initial revision
* Written by Haowen Huang
*/
static const char rcsid[] =
$Id: unix2dos.c,v 1.1 2001/03/28 12:19:21 vong Exp $;
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include file_transfer.h
/*
* Convert file named by pathname to DOS
* text format, on standard output:
*/
int
unix2dos(const char *pathname) {
int ch; /* Current input character */
FILE *in = 0; /* Input file */
if ( !(in = fopen(pathname,r)) ) {
fprintf(stderr,Cannot open input file.\n);
return 2;
}
while ( (ch = fgetc(in)) != EOF ) {
if ( ch == '\n' )
putchar('\r');
putchar(ch);
}
fclose(in);
return 0;
}
4.2 dos2unix.c程序模块
dos2unix.c程序模块:用来把DOS/WINDOWS格式的文件转换为UNIX格式的文件。
dos2unix.c程序模块源代码如下所示:
/* $Date: 2001/03/28 12:29:37 $
*
* The DOS to UNIX text conversion:
*
* $Log: dos2unix.c,v $
* Revision 1.1 2001/03/28 12:29:37 vong
* Initial revision
* Written by Haowen Huang
*/
static const char rcsid[] =
$Id: dos2unix.c,v 1.1 2001/03/28 12:29:37 vong Exp $;
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include file_transfer.h
/*
* Convert file named by pathname, to
* UNIX text file format on standard output:
*/
int
dos2unix(const char *pathname) {
int ch; /* Current input character */
int cr_flag; /* True when CR prev. encountered */
FILE *in = 0; /* Input file */
if ( !(in = fopen(pathname,r)) ) {
fprintf(stderr,Cannot open input file.\n);
return 2;
}
cr_flag = 0; /* No CR encountered yet */
while ( (ch = fgetc(in)) != EOF ) {
if ( cr_flag && ch != '\n' ) {
/* This CR did not preceed LF */
putchar('\r');
}
if ( !(cr_flag = ch == '\r') )
putchar(ch);
}
fclose(in);
return 0;
}
4.3 主程序file_transfer.c
主程序file_transfer.c:用来获取需要转换的文件参数,包括文件名、文件路径;支持同时输入多个需要转换的文件。其中对文件路径的处理由函数Basename(const char *path)来完成。我们在这里留给各位读者一个锻炼和实践的机会:本程序的文件路径处理函数Basename(const char *path)是和主程序写在一个文件中的;但从可扩展考虑,如果能够把文件路径处理函数单独写成一个程序模块,程序将更加灵活,请读者自己试试。
file_transfer.c程序模块源代码如下所示:
/* file_transfer.c */
static const char rcsid[] =
$Id: file_transfer.c,v 1.8 2001/03/29 02:29:54 vong Exp $;
/* REVISION HISTORY:
* $Log: file_transfer.c,v $
* Revision 1.8 2001/03/29 02:29:54 vong
* Separated out the text conversion
* functions to make this project
* more modular.
*
* Revision 1.7 2001/03/29 01:31:39 vong
* Now handles multiple input files, plus
* put basename code into its own Basename()
* function.
*
* Revision 1.6 2001/03/29 01:01:28 vong
* Separated conversions into unix2dos() and
* dos2unix() functions.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include file_transfer.h
/*
* Return the pointer to the basename component
* of a pathname:
*/
static char *
Basename(const char *path) {
char *base_name = 0;
if ( ( base_name = strrchr(path,'/') ) != 0 )
++base_name; /* Skip over '/' */
else
base_name = (char *) path; /* No dir. */
return base_name;
}
int
main(int argc,char **argv) {
char *base_name = 0; /* Basename of command */
int rc = 0; /* Command return code */
int (*conv)(const char *pathname); /* Conv. Func. Ptr */
int x;
/*
* Determine the basename of the command name. This
* is necessary since this command could be invoked
* with a pathname. For example, argv[0] could be
* /usr/local/bin/unix_cvrt if it was installed
* in the system that way.
*/
base_name = Basename(argv[0]);
/*
* Check for missing input file:
*/
if ( argc < 2 ) {
fprintf(stderr,Missing input file(s).\n);
return 1;
}
/*
* Now that we know the basename of the command
* name used, we can determine which function we
* must carry out here.
*/
if ( !strcmp(base_name,unix_cvrt) )
conv = unix2dos;
else
conv = dos2unix;
/*
* Perform a text conversion
*/
for ( x=1; x<argc; ++x )
if ( (rc = conv(argv[x])) != 0 )
break; /* An error occured */
return rc;
}
4.4 MakeFile文件
# $Source: /vong/src/chap05/RCS/Makefile,v $
# $Revision: 1.1 $
# $Date: 2001/03/29 22:17:18 $
CC= gcc
STD= _GNU_SOURCE
OBJS= dos_cvrt.o unix2dos.o dos2unix.o
.c.o:
$(CC) -c -Wall $(CFLAGS) -D$(STD) $<
all: dos_cvrt unix_cvrt
dos_cvrt: $(OBJS)
$(CC) $(OBJS) -o dos_cvrt
unix_cvrt: dos_cvrt
rm -f unix_cvrt
ln dos_cvrt unix_cvrt
clean:
rm -f *.o core
clobber: clean
rm -f dos_cvrt unix_cvrt
# End Makefile
附录一 常用的LINUX资源Web 和FTP 站点
下列是一些有用的World Wide Web 和ftp站点。
http://www.postgoods.com/ 专业的电子商务应用技术网站。
http://www.azstarnet.com/~axplinux:这是David Mosberger-Tang的Alpha AXP linux 网络站点,所有的Alpha AXP How To 均可在此找到,并且还包括大量的Linux的指示器和AlphaAXP的特殊信息,如CPU数据表格。
http://www.redhat.com/Red Hat 的网络站点,包括大量的有用的指示器。
ftp://sunsite.unc.edv:大量免费软件的主要汇集点。pub/linux目录下有linux专用软件。
http://www.intel.com:Intel公司的网络站点,是查寻Intel芯片信息的好地方。
http://www.ssc.com/lj/index.html:The Linux Journal 是一本非常好的Linux杂志,值得每年摘录其中优秀的文章。
http://www.blackdown.org/java/linux.html:关于Java和Linux的基本站点。
ftp://tsx-11.mit.edu/ftp/pub/Linux:MIT的Linux ftp站点。
ftp://ftp.cs.helsinki.fi/pub/software/linux/kernel:Linux的核心资源。
http://www.linux.org.uk:UF Linux Use Group 。
http://sunsite.unc.edu/mdw/linux.html:Linux Documentation Project 主页。
http://www.digital.com:Digital Equipment Corporation 的主要网页。
http://altavista.digital.com:DIGITAL公司的Altavista的搜索引擎,是在网络和新闻群中搜寻信息的非常好的站点。
http://www.Linuxhq.com:The Linux HQ 网络站点,存储最新的官方和非官方的patch,即帮助读者得到系统所需的最好的内核资源的建议和网络指示器。
http://www.amd.com:The AMD网络站点。
http://www.cyrix.com:Cyrix的网络站点。 |