UNIX,基础知识,文件IO,文件和目录

时间:2023-02-25 15:56:44

2015.1.27
星期二,早晨阴天,中午下雪了
今天上午老师不上课,
程序语句,记一下:
main(void)
{
int c;
while((c = getc(stdin)) != EOF)
if(putc(c,stdout) == EOF) 将字符写到标准输出
err_sys("output error");
if(ferror(stdin))
err_sys("input error");
exit(0);
}

从标准输入读命令并执行:
int main()
{
char buf[MAXLINE];
pid_t pid;
int status;

printf("%% ");
while(fgets(buf,MAXLINE,stdin) != NULL) get返回的每一行都以换行符终止,后随一个null字符
}
else if(pid == 0)
{
{
if(buf[strlen(buf)-1] == '\n') get返回的每一行都以换行符终止,后随一个null字符
{
buf[strlen(buf)-1] = 0;
}

if((pid = fork()) < 0)
{
err_sys("fork error");
execlp(buf,buf,(char *)0); 从标准输入读入的命令,用新的程序文件替换子进程原先执行的文件
err_sys("couldn't execute:%s",buf);
exit(127);
}

if((pid = waitpid(pid, &status,0)) < 0) waitpid暂停当前进程的执行,知道有信号和子进程结束,0:阻塞父进程,等待子进程退出
err_sys("waitpid error");
}

printf("%% ");
}
exit(0);

}

调用getuid(),getgid()分别打印用户ID和组ID

main()
{
printf("uid = %d, gid = %d\n", getuid(), getgid());
exit(0);
}

signal 设置信号处理方式
void (*signal(int signum,void(*handler)(int)))(int)

函数依据signum指定的信号编号来设置该信号的处理函数,当指定的信号到达时就会跳转到参数handler指定的函数执行。
如果handler不是函数指针,则必须是下列两个常量之一:
SIG_IGN 忽略参数signum指定的信号
SIG_DRL 将参数signum指定的信号重设为核心预设的信号处理方式

日历时间:自1970年1月1日00:00:00以来国际标准时间所进过的秒数累计值,可用于记录文件最后一次修改的时间等

pathconf 的返回值是基于工作目录的的相对路径名的最大长度

int creat(const char *pathname,mode_t mode )

返回值:成功则返回为只写打开的文件描述符,若出错则返回-1

off_t lseek(int filedes,off_t offset, int whence)
返回值:成功则返回新的文件偏移量,出错:-1,具体偏移量根据whence参数设定!

因为偏移量可正可负,判断是否可以设置便宜量是应该测试是否等于-1,偏移量可以大于文件长度,这样下次写的时候
就会产生一个空的,这是允许的。具体在磁盘上的存储区间依据文件系统而定!

打开当前文件的偏移量:
off_t currpos
currpos = lseek(fd,0,SEEK_CUR);

od -c file (-c表示以字符方式打印文件内容)

ssize_t read(int filedes,void *buf,size_t nbytes)
返回值:成功则返回读到的字节数,若读到文件尾则返回0,出错:-1
当从终端设备读时,通常一次最多读一行

int dup (int filedes); == fcnt1(filedes ,F_EUPFD,0) (funt1改变已打开的文件的性质,返回值依据第二个参数变化)
int dup2(int filedes ,int filedes2) == fcnt1(filedes ,F_EUPFD,filedes2)
两个函数都是用来赋值一个现存文件描述符,成功返回新的文件描述符,出错:-1
dup2则可以用filedes2参数指定新的描述符的数值,如果filedes2已经打开,则先将其关闭,如果filedes2==filedes,则返回filedes2,不关闭
dup2是一个原子操作(由多步组成的操作)

为了保证磁盘上实际文件系统与缓冲区高速缓存中内容的一致性,unix系统提供了:sync,fsync,fdatasync
void sync(void)
int fsync(int filedes)
int fdatasync(int filedes) 只对数据有用

fchmod 是对已打开的文件进行操作

wc -c core // 8483248 core
du -s core // 272 core 所占磁盘空间总量,文件有空洞

int link(const char *existingpath,const char *newpath)
创建一个新目录项newpath,它引用现有的文件existingpath,成功返回0,出错:-1

int unlink(const char *pathname)
删除目录项,并将由pathname引用的文件的链接计数减一

main(void)
{
if(open("tempfile",O_RDWR) < 0)
err_sys("open error");
if(unlink("tempfile") < 0)
err_sys("unlink error");
printf("file unlinked\n");
sleep(15);
printf("done\n");
exit(0);

}

int remove(const char *pathname);
解除对一个文件或目录的链接;

int rename(const char *oldname,const char *newname);
文件或目录更改名字,成功返回0,出错:-1

int utime(const char *pathname,const struct utimbuf *time) 成功返回0,出错:-1

struct utimebuf{
time_t actime;
time_t modtime;
}
下面的程序是UNIX环境高级编程上的实例:
程序使用带O_TRUNC选项的open函数将文件长度截短为0,但并不改变其访问时间和修改时间:
先用stat函数得到这些时间,然后截短文件,最后用utime函数复位这两个时间;

#include "apue.h"
#include <fcn1.h>
#include <utime.h>

int main(int argc,char *argv[])
{
int i, fd;
struct stat statbuf;
struct utimbuf timebuf;
for(i = 1;i < argc; i++)
{
if(stat(stgv[i],&statbuf) < 0)
{
err_ret ("%s:stat error",atgv[i]);
continue;
}
if((fd = open(argv[i],O_RDWR | O_TRUNC)) < 0)
{
err_ret("%s:open error",srgv[i]);
continue;
}
close(fd);
timebuf.actime = statbuf.st_atime;
timebuf.modtime = statbuf.st_mtime;
if(utime(argv[i],&timebuf) < 0)
{
err_ret("%s:utime error",argv[i]);
continue;
}
}
exit(0);
}

int mkdir(const char *pathname,mode_t mode);
int rmdir(const char *pathname);

int chdir(const char *pathname); 更改当前目录
int fchdir(int filedes);
四个函数都是成功返回0,出错-1

char *getcwd(char *buf,size_t size); 取得当前的工作目录,成功返回buf,出错:NULL
先用调用getcwd函数把目录保存一下,完成处理后,将保存的路径作为参数传给chdir,这样就回到了系统文件的起点。

main()
{
char *ptr;
int size;
if(chdir("/usr/spool/uucppublic")<0)
{
err_sys("chdir failed");
}
ptr = path_alloc(&size);
if(getcwd(ptr,size) == NULL)
{
err_sys("getcwd failed");
}
printf("cwd = %s\n",ptr);
exit(0);
}

main()
{
if(chdir("/tmp") < 0)
err_sys("chdir failed");
printf("chdir to /tmp succeeded\n");
exit(0);
}

#define hello t = a;\
a = b;\
b = t;

今天看的UNIX环境高级编程就记到这里,看了前面四章,第五章是标准I/O库的函数,涉及到文件流,为了系统点,全部记在明天的日记里,
方便前后只是的连贯性!

**********************************************************************************************************************************************************
**********************************************************************************************************************************************************
**********************************************************************************************************************************************************