文章目录

  • 1、编译优化
    • makefiel
  • 2、文件基本操作编程
    • 使用Linux系统调用编写一个完成文件拷贝的C程序。比较拷贝得到的文件与源文件的大小和内容(命令diff,cmp)。
    • 编写C程序完成:创建一个新文件,输入一段数据,然后随机移动指针接着插入一段数据。完成后,查看该文件的大小和内容。怎样获取当前文件的读写指针位置?
  • 3、编写拷贝命令,实现文件或目录的复制
  • 4、gdb 调试工具

1、编译优化

//代码#include <stdio.h>
int main(void)
{double counter;
double result;
double temp;
for (counter = 0; counter < 2000.0 * 2000.0 * 2000.0 / 20.0 + 2020;
counter += (5 -1) / 4) {temp = counter / 1979;
result = counter;
}
printf(Result is %lf\\n, result);
return 0;
}

gdb调试:

优化后

未优化

优化分析:

  • 代码分析

  • 执行分析

  • 大小分析

区别:-O优化会改变文件大小,会更小一点。优化后的代码执行时间会更短;优化后的代码会把数据全部存入xmm寄存器,计算时直接从寄存器读取数据;未优化的代码会把一些数据放在栈中来读取。栈中读取和寄存器读取,显然寄存器会更快。

makefiel

一个工程中的源文件不计数,其按类型功能模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

2、文件基本操作编程

使用Linux系统调用编写一个完成文件拷贝的C程序。比较拷贝得到的文件与源文件的大小和内容(命令diff,cmp)。

代码

#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include<unistd.h>int main(){
int f1,f1_l,f2; //f1:文件a.txt的句柄;f2:文件b.txt的句柄;f1_l:a.txt文件内容的长度。
char buf[1024]={};//这个用于暂时存储被复制的文件内容//打开源文件,读取文件内容
f1=open("a.txt",O_RDWR);
f1_l=read(f1,buf,1024);//这里打开目标文件,如果没有就创建一个,且权限为777,然后将内容复制到目标文件
f2=open("b.txt",O_RDWR | O_CREAT,0777);
write(f2,buf,f1_l);close(f1);
close(f2);}

执行结果:

​ 用ls去查看,发现文件大小没有不同,只是两者权限不同。权限设置的是777,但是由于用户的默认权限掩码,

0022,所以创建出来的权限就是0777-0022=0755。

​ 用diff去比较,

diff会针对文本内容逐行进行对比,如果有不同就会显示出这有差别的两行,这里看到文本内容上并没有什么差别。

​ 用cmp去对比,

cmp会逐个字符去比较,会告诉有差异的字符的位置,第几行第几个字符。不加参数的情况下它只会显示出第一个有差异的位置。-l参数会帮助显示出所有有差异的位置。这里也没有不同。

编写C程序完成:创建一个新文件,输入一段数据,然后随机移动指针接着插入一段数据。完成后,查看该文件的大小和内容。怎样获取当前文件的读写指针位置?

代码

#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>int main(){int fd,loc;char name[10]="\0";char context[1024]="\0";char tip[]="mkanewdir!";//插入字符串内容//创建一个新文件printf("文件名:");gets(name);fd=creat(name,0777);//输入一段内容写入新文件中printf("内容:");gets(context);write(fd,context,sizeof(context));//插入字符串lseek(fd,2,SEEK_SET);write(fd,tip,strlen(context)+8);//读取文件指针位置loc=lseek(fd,0,SEEK_CUR);printf("当前文件读写指针的位置:%d。",loc);close(fd);
}

获取字符串长度的话就是lseek,SEEK_CUR锁定到当前位置,偏移量为0,就可以得到当前位置了。这里有尝试用tell函数,但是编译时显示没有定义这样一个函数。不知道是我的gcc太老了还是啥。

这里文件的大小就是总的字符串长度。

3、编写拷贝命令,实现文件或目录的复制

#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/vfs.h>long int dir_list[100][100][100];
long int dir_dst[100][100][100];
int loc=0,i=0,count=0,off=0;
int alow,sum=0;int ls();
void copy_file();
void copy_dir();
void samename(mode_t mode);
void counter();
int main(int num,char* name[])
{struct stat fl_str,fl_dst;struct statfs size;sprintf(dir_list[0][0],name[1]);//参数存如数组中sprintf(dir_dst[0][0],name[2]);stat(dir_list[0][0],&fl_str);stat(dir_dst[0][0],&fl_dst);samename(fl_str.st_mode);//同名判断statfs(dir_dst[0][0],&size);alow=4*size.f_bavail;switch(num){case 3://文件复制if(S_ISREG(fl_str.st_mode)&&((fl_str.st_size/1000)<alow)){copy_file();}elseprintf("磁盘大小不足,复制中止!");break;case 4://目录复制if(S_ISDIR(fl_str.st_mode)&&!strcmp(name[3],"-r")){ls();}elseprintf("复制目录格式有误!复制中止!\n格式:源路径 目标路径 -r");break;}}int ls()//遍历目录,递归复制
{char dst[100];DIR* dir_ptr[100];struct dirent* direntp;    struct stat type;while(off<2){while((dir_ptr[loc] = opendir(dir_list[loc][0]))!=NULL){while((direntp = readdir(dir_ptr[loc])) != NULL){if(!strcmp(direntp->d_name,"..")||!strcmp(direntp->d_name,".")){continue;}sprintf(dir_list[loc][++i],"%s/%s",dir_list[loc][0],direntp->d_name);sprintf(dir_dst[loc][i],"%s/%s",dir_dst[loc][0],direntp->d_name);stat(dir_list[loc][i], &type);if(S_ISREG(type.st_mode)){if(off==0)sum+=type.st_size;elsecopy_file();}else if(S_ISDIR(type.st_mode)){++count;strcpy(dir_list[count][0],dir_list[loc][i]);strcpy(dir_dst[count][0],dir_dst[loc][i]);if(off==0)sum+=type.st_size;elsecopy_dir();}}if(count>=loc){loc++;i=0;}}switch(off){case 0:if((sum/1000)>alow){perror("ERROR:磁盘容量不足,停止复制!\n");_exit(2);}elseprintf("复制成功!\n目录大小:%2dkb,可使用剩余磁盘容量:%2dkb。\n",sum/1000,alow-sum/1000);break;case 1:break;  }off++;loc=0,i=0,count=0;}
}void copy_file()//复制文件
{int fl_str,fl_dst,len;char context[10240];fl_str=open(dir_list[loc][i],O_RDONLY);len=read(fl_str,context,10240);fl_dst=open(dir_dst[loc][i],O_RDWR|O_CREAT,0644);write(fl_dst,context,len);close(fl_str);close(fl_dst);
}void copy_dir()//复制目录
{mkdir(dir_dst[loc][i],0777);
}void samename(mode_t mode)//同名判断
{if(access(dir_dst[0][0],F_OK)==0){perror("ERROR:有同名文件存在,停止复制!\n");_exit(2);}else if(S_ISREG(mode)){creat(dir_dst[0][0],0644);}else if(S_ISDIR(mode)){copy_dir();}
}
//这个代码网上转载
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>int is_dir(char *path);                         //判断是否是目录  是返回1 否则返回0
int copy_file(char *srcPath, char *destPath);   //复制文件  成功返回0 否则返回 -1
int copy_folder(char *srcPath, char *destPath); //复制文件夹  成功返回0 否则返回 -1int main(int argc, char *argv[]) // argv[1] 源文件  argv[2] 目标文件
{if (argc != 3){printf("Usage srcfile destfile\n");return -1;}char *srcPath = argv[1];char *destPath = argv[2];if (is_dir(srcPath)) //文件夹的拷贝{copy_folder(srcPath, destPath);}else{if (access(destPath, F_OK) == 0) //保证destPath是未存在的目录{printf("目标文件已存在\n");return -1;}copy_file(srcPath, destPath); //文件进行拷贝}return 0;
}
//判断是否是目录  是返回1 否则返回0
int is_dir(char *path)
{struct stat st;stat(path, &st);if (S_ISDIR(st.st_mode))return 1;elsereturn 0;
}//复制文件  成功返回0 否则返回 -1
int copy_file(char *srcPath, char *destPath)
{char Buf[1024] = {0};int count_read = 0;long fp_src_ltell = 0, fp_src_atell = 0;FILE *fp_src = fopen(srcPath, "r");  //只读方式打开FILE *fp_dst = fopen(destPath, "w"); //只写方式打开if (fp_dst == NULL || fp_src == NULL){printf("文件打开有问题\n");return -1;}while (1){memset(Buf, 0, sizeof(Buf));fp_src_ltell = ftell(fp_src); //上一次文件指针位置count_read = fread(Buf, sizeof(Buf), 1, fp_src);fp_src_atell = ftell(fp_src); //当前文件指针位置if (count_read < 1)           //异常或到达末尾结束{if (feof(fp_src)){long temp = fp_src_atell - fp_src_ltell;fwrite(Buf, temp, 1, fp_dst); //成功return 0;}else if (ferror(fp_src)){perror("fread error:");return -1;}}fwrite(Buf, sizeof(Buf), 1, fp_dst);}return 0;
}//复制文件夹
int copy_folder(char *srcPath, char *destPath)
{char newsrcPath[4096];char newdestPath[4096];if (mkdir(destPath, 0777)) //如果不存在就用mkdir函数来创建{printf("目标文件已存在\n");return -1;}DIR *srcDp = opendir(srcPath);if (srcDp == NULL){printf("打开文件夹[%s]失败!\n", srcPath);return -1;}struct dirent *srcDirent = NULL;int flag = 0;while (srcDirent = readdir(srcDp)){flag++;if (flag > 2) //去除隐藏文件 . ..{bzero(newsrcPath, sizeof(newsrcPath)); //清空bzero(newdestPath, sizeof(newdestPath));sprintf(newsrcPath, "%s/%s", srcPath, srcDirent->d_name); //保存新的文件路径sprintf(newdestPath, "%s/%s", destPath, srcDirent->d_name);if (srcDirent->d_type == DT_DIR) //文件夹的拷贝copy_folder(newsrcPath, newdestPath);else //普通文件copy_file(newsrcPath, newdestPath);}}return 0;
}
//cp.c源码
/* cp.c  -- file copying (main routines)Copyright (C) 1989-2022 Free Software Foundation, Inc.This program is free software: you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation, either version 3 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program.  If not, see <https://www.gnu.org/licenses/>.Written by Torbjorn Granlund, David MacKenzie, and Jim Meyering. */#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include <getopt.h>
#include <selinux/label.h>#include "system.h"
#include "argmatch.h"
#include "backupfile.h"
#include "copy.h"
#include "cp-hash.h"
#include "die.h"
#include "error.h"
#include "filenamecat.h"
#include "ignore-value.h"
#include "quote.h"
#include "stat-time.h"
#include "targetdir.h"
#include "utimens.h"
#include "acl.h"/* The official name of this program (e.g., no 'g' prefix).  */
#define PROGRAM_NAME "cp"#define AUTHORS \proper_name ("Torbjorn Granlund"), \proper_name ("David MacKenzie"), \proper_name ("Jim Meyering")/* Used by do_copy, make_dir_parents_private, and re_protectto keep a list of leading directories whose protectionsneed to be fixed after copying. */
struct dir_attr
{struct stat st;bool restore_mode;size_t slash_offset;struct dir_attr *next;
};/* For long options that have no equivalent short option, use anon-character as a pseudo short option, starting with CHAR_MAX + 1.  */
enum
{ATTRIBUTES_ONLY_OPTION = CHAR_MAX + 1,COPY_CONTENTS_OPTION,NO_PRESERVE_ATTRIBUTES_OPTION,PARENTS_OPTION,PRESERVE_ATTRIBUTES_OPTION,REFLINK_OPTION,SPARSE_OPTION,STRIP_TRAILING_SLASHES_OPTION,UNLINK_DEST_BEFORE_OPENING
};/* True if the kernel is SELinux enabled.  */
static bool selinux_enabled;/* If true, the command "cp x/e_file e_dir" uses "e_dir/x/e_file"as its destination instead of the usual "e_dir/e_file." */
static bool parents_option = false;/* Remove any trailing slashes from each SOURCE argument.  */
static bool remove_trailing_slashes;static char const *const sparse_type_string[] =
{"never", "auto", "always", NULL
};
static enum Sparse_type const sparse_type[] =
{SPARSE_NEVER, SPARSE_AUTO, SPARSE_ALWAYS
};
ARGMATCH_VERIFY (sparse_type_string, sparse_type);static char const *const reflink_type_string[] =
{"auto", "always", "never", NULL
};
static enum Reflink_type const reflink_type[] =
{REFLINK_AUTO, REFLINK_ALWAYS, REFLINK_NEVER
};
ARGMATCH_VERIFY (reflink_type_string, reflink_type);static struct option const long_opts[] =
{{"archive", no_argument, NULL, 'a'},{"attributes-only", no_argument, NULL, ATTRIBUTES_ONLY_OPTION},{"backup", optional_argument, NULL, 'b'},{"copy-contents", no_argument, NULL, COPY_CONTENTS_OPTION},{"dereference", no_argument, NULL, 'L'},{"force", no_argument, NULL, 'f'},{"interactive", no_argument, NULL, 'i'},{"link", no_argument, NULL, 'l'},{"no-clobber", no_argument, NULL, 'n'},{"no-dereference", no_argument, NULL, 'P'},{"no-preserve", required_argument, NULL, NO_PRESERVE_ATTRIBUTES_OPTION},{"no-target-directory", no_argument, NULL, 'T'},{"one-file-system", no_argument, NULL, 'x'},{"parents", no_argument, NULL, PARENTS_OPTION},{"path", no_argument, NULL, PARENTS_OPTION},   /* Deprecated.  */{"preserve", optional_argument, NULL, PRESERVE_ATTRIBUTES_OPTION},{"recursive", no_argument, NULL, 'R'},{"remove-destination", no_argument, NULL, UNLINK_DEST_BEFORE_OPENING},{"sparse", required_argument, NULL, SPARSE_OPTION},{"reflink", optional_argument, NULL, REFLINK_OPTION},{"strip-trailing-slashes", no_argument, NULL, STRIP_TRAILING_SLASHES_OPTION},{"suffix", required_argument, NULL, 'S'},{"symbolic-link", no_argument, NULL, 's'},{"target-directory", required_argument, NULL, 't'},{"update", no_argument, NULL, 'u'},{"verbose", no_argument, NULL, 'v'},{GETOPT_SELINUX_CONTEXT_OPTION_DECL},{GETOPT_HELP_OPTION_DECL},{GETOPT_VERSION_OPTION_DECL},{NULL, 0, NULL, 0}
};void
usage (int status)
{if (status != EXIT_SUCCESS)emit_try_help ();else{printf (_("\
Usage: %s [OPTION]... [-T] SOURCE DEST\n\or:  %s [OPTION]... SOURCE... DIRECTORY\n\or:  %s [OPTION]... -t DIRECTORY SOURCE...\n\
"),program_name, program_name, program_name);fputs (_("\
Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n\
"), stdout);emit_mandatory_arg_note ();fputs (_("\-a, --archive                same as -dR --preserve=all\n\--attributes-only        don't copy the file data, just the attributes\n\--backup[=CONTROL]       make a backup of each existing destination file\
\n\-b                           like --backup but does not accept an argument\n\--copy-contents          copy contents of special files when recursive\n\-d                           same as --no-dereference --preserve=links\n\
"), stdout);fputs (_("\-f, --force                  if an existing destination file cannot be\n\opened, remove it and try again (this option\n\is ignored when the -n option is also used)\n\-i, --interactive            prompt before overwrite (overrides a previous -n\
\n\option)\n\-H                           follow command-line symbolic links in SOURCE\n\
"), stdout);fputs (_("\-l, --link                   hard link files instead of copying\n\-L, --dereference            always follow symbolic links in SOURCE\n\
"), stdout);fputs (_("\-n, --no-clobber             do not overwrite an existing file (overrides\n\a previous -i option)\n\-P, --no-dereference         never follow symbolic links in SOURCE\n\
"), stdout);fputs (_("\-p                           same as --preserve=mode,ownership,timestamps\n\--preserve[=ATTR_LIST]   preserve the specified attributes (default:\n\mode,ownership,timestamps), if possible\n\additional attributes: context, links, xattr,\
\n\all\n\
"), stdout);fputs (_("\--no-preserve=ATTR_LIST  don't preserve the specified attributes\n\--parents                use full source file name under DIRECTORY\n\
"), stdout);fputs (_("\-R, -r, --recursive          copy directories recursively\n\--reflink[=WHEN]         control clone/CoW copies. See below\n\--remove-destination     remove each existing destination file before\n\attempting to open it (contrast with --force)\
\n"), stdout);fputs (_("\--sparse=WHEN            control creation of sparse files. See below\n\--strip-trailing-slashes  remove any trailing slashes from each SOURCE\n\argument\n\
"), stdout);fputs (_("\-s, --symbolic-link          make symbolic links instead of copying\n\-S, --suffix=SUFFIX          override the usual backup suffix\n\-t, --target-directory=DIRECTORY  copy all SOURCE arguments into DIRECTORY\n\-T, --no-target-directory    treat DEST as a normal file\n\
"), stdout);fputs (_("\-u, --update                 copy only when the SOURCE file is newer\n\than the destination file or when the\n\destination file is missing\n\-v, --verbose                explain what is being done\n\-x, --one-file-system        stay on this file system\n\
"), stdout);fputs (_("\-Z                           set SELinux security context of destination\n\file to default type\n\--context[=CTX]          like -Z, or if CTX is specified then set the\n\SELinux or SMACK security context to CTX\n\
"), stdout);fputs (HELP_OPTION_DESCRIPTION, stdout);fputs (VERSION_OPTION_DESCRIPTION, stdout);fputs (_("\
\n\
By default, sparse SOURCE files are detected by a crude heuristic and the\n\
corresponding DEST file is made sparse as well.  That is the behavior\n\
selected by --sparse=auto.  Specify --sparse=always to create a sparse DEST\n\
file whenever the SOURCE file contains a long enough sequence of zero bytes.\n\
Use --sparse=never to inhibit creation of sparse files.\n\
"), stdout);fputs (_("\
\n\
When --reflink[=always] is specified, perform a lightweight copy, where the\n\
data blocks are copied only when modified.  If this is not possible the copy\n\
fails, or if --reflink=auto is specified, fall back to a standard copy.\n\
Use --reflink=never to ensure a standard copy is performed.\n\
"), stdout);emit_backup_suffix_note ();fputs (_("\
\n\
As a special case, cp makes a backup of SOURCE when the force and backup\n\
options are given and SOURCE and DEST are the same name for an existing,\n\
regular file.\n\
"), stdout);emit_ancillary_info (PROGRAM_NAME);}exit (status);
}/* Ensure that parents of CONST_DST_NAME aka DST_DIRFD+DST_RELNAME have thecorrect protections, for the --parents option.  This is doneafter all copying has been completed, to allow permissionsthat don't include user write/execute.ATTR_LIST is a null-terminated linked list of structures thatindicates the end of the filename of each intermediate directoryin CONST_DST_NAME that may need to have its attributes changed.The command 'cp --parents --preserve a/b/c d/e_dir' changes theattributes of the directories d/e_dir/a and d/e_dir/a/b to matchthe corresponding source directories regardless of whether theyexisted before the 'cp' command was given.Return true if the parent of CONST_DST_NAME and any intermediatedirectories specified by ATTR_LIST have the proper permissionswhen done.  */static bool
re_protect (char const *const_dst_name, int dst_dirfd, char const *dst_relname,struct dir_attr *attr_list, const struct cp_options *x)
{struct dir_attr *p;char *dst_name;     /* A copy of CONST_DST_NAME we can change. */char *src_name;        /* The source name in 'dst_name'. */ASSIGN_STRDUPA (dst_name, const_dst_name);src_name = dst_name + (dst_relname - const_dst_name);for (p = attr_list; p; p = p->next){dst_name[p->slash_offset] = '\0';/* Adjust the times (and if possible, ownership) for the copy.chown turns off set[ug]id bits for non-root,so do the chmod last.  */if (x->preserve_timestamps){struct timespec timespec[2];timespec[0] = get_stat_atime (&p->st);timespec[1] = get_stat_mtime (&p->st);if (utimensat (dst_dirfd, src_name, timespec, 0)){error (0, errno, _("failed to preserve times for %s"),quoteaf (dst_name));return false;}}if (x->preserve_ownership){if (lchownat (dst_dirfd, src_name, p->st.st_uid, p->st.st_gid) != 0){if (! chown_failure_ok (x)){error (0, errno, _("failed to preserve ownership for %s"),quoteaf (dst_name));return false;}/* Failing to preserve ownership is OK. Still, try to preservethe group, but ignore the possible error. */ignore_value (lchownat (dst_dirfd, src_name, -1, p->st.st_gid));}}if (x->preserve_mode){if (copy_acl (src_name, -1, dst_name, -1, p->st.st_mode) != 0)return false;}else if (p->restore_mode){if (lchmodat (dst_dirfd, src_name, p->st.st_mode) != 0){error (0, errno, _("failed to preserve permissions for %s"),quoteaf (dst_name));return false;}}dst_name[p->slash_offset] = '/';}return true;
}/* Ensure that the parent directory of CONST_DIR exists, forthe --parents option.SRC_OFFSET is the index in CONST_DIR (which is a destinationdirectory) of the beginning of the source directory name.Create any leading directories that don't already exist.DST_DIRFD is a file descriptor for the target directory.If VERBOSE_FMT_STRING is nonzero, use it as a printf formatstring for printing a message after successfully making a directory.The format should take two string arguments: the names of thesource and destination directories.Creates a linked list of attributes of intermediate directories,*ATTR_LIST, for re_protect to use after calling copy.Sets *NEW_DST if this function creates parent of CONST_DIR.Return true if parent of CONST_DIR exists as a directory with the properpermissions when done.  *//* FIXME: Synch this function with the one in ../lib/mkdir-p.c.  */static bool
make_dir_parents_private (char const *const_dir, size_t src_offset,int dst_dirfd,char const *verbose_fmt_string,struct dir_attr **attr_list, bool *new_dst,const struct cp_options *x)
{struct stat stats;char *dir;       /* A copy of CONST_DIR we can change.  */char *src;     /* Source name in DIR.  */char *dst_dir;    /* Leading directory of DIR.  */idx_t dirlen = dir_len (const_dir);*attr_list = NULL;/* Succeed immediately if the parent of CONST_DIR must already exist,as the target directory has already been checked.  */if (dirlen <= src_offset)return true;ASSIGN_STRDUPA (dir, const_dir);src = dir + src_offset;dst_dir = alloca (dirlen + 1);memcpy (dst_dir, dir, dirlen);dst_dir[dirlen] = '\0';char const *dst_reldir = dst_dir + src_offset;while (*dst_reldir == '/')dst_reldir++;/* XXX: If all dirs are present at the destination,no permissions or security contexts will be updated.  */if (fstatat (dst_dirfd, dst_reldir, &stats, 0) != 0){/* A parent of CONST_DIR does not exist.Make all missing intermediate directories. */char *slash;slash = src;while (*slash == '/')slash++;dst_reldir = slash;while ((slash = strchr (slash, '/'))){struct dir_attr *new;bool missing_dir;*slash = '\0';missing_dir = fstatat (dst_dirfd, dst_reldir, &stats, 0) != 0;if (missing_dir || x->preserve_ownership || x->preserve_mode|| x->preserve_timestamps){/* Add this directory to the list of directories whosemodes might need fixing later. */struct stat src_st;int src_errno = (stat (src, &src_st) != 0? errno: S_ISDIR (src_st.st_mode)? 0: ENOTDIR);if (src_errno){error (0, src_errno, _("failed to get attributes of %s"),quoteaf (src));return false;}new = xmalloc (sizeof *new);new->st = src_st;new->slash_offset = slash - dir;new->restore_mode = false;new->next = *attr_list;*attr_list = new;}/* If required set the default context for created dirs.  */if (! set_process_security_ctx (src, dir,missing_dir ? new->st.st_mode : 0,missing_dir, x))return false;if (missing_dir){mode_t src_mode;mode_t omitted_permissions;mode_t mkdir_mode;/* This component does not exist.  We must set*new_dst and new->st.st_mode inside this loop because,for example, in the command 'cp --parents ../a/../b/c e_dir',make_dir_parents_private creates only e_dir/../a if./b already exists. */*new_dst = true;src_mode = new->st.st_mode;/* If the ownership or special mode bits might change,omit some permissions at first, so unauthorized userscannot nip in before the file is ready.  */omitted_permissions = (src_mode& (x->preserve_ownership? S_IRWXG | S_IRWXO: x->preserve_mode? S_IWGRP | S_IWOTH: 0));/* POSIX says mkdir's behavior is implementation-defined when(src_mode & ~S_IRWXUGO) != 0.  However, common practice isto ask mkdir to copy all the CHMOD_MODE_BITS, letting mkdirdecide what to do with S_ISUID | S_ISGID | S_ISVTX.  */mkdir_mode = x->explicit_no_preserve_mode ? S_IRWXUGO : src_mode;mkdir_mode &= CHMOD_MODE_BITS & ~omitted_permissions;if (mkdirat (dst_dirfd, dst_reldir, mkdir_mode) != 0){error (0, errno, _("cannot make directory %s"),quoteaf (dir));return false;}else{if (verbose_fmt_string != NULL)printf (verbose_fmt_string, src, dir);}/* We need search and write permissions to the new directoryfor writing the directory's contents. Check if thesepermissions are there.  */if (fstatat (dst_dirfd, dst_reldir, &stats, AT_SYMLINK_NOFOLLOW)){error (0, errno, _("failed to get attributes of %s"),quoteaf (dir));return false;}if (! x->preserve_mode){if (omitted_permissions & ~stats.st_mode)omitted_permissions &= ~ cached_umask ();if (omitted_permissions & ~stats.st_mode|| (stats.st_mode & S_IRWXU) != S_IRWXU){new->st.st_mode = stats.st_mode | omitted_permissions;new->restore_mode = true;}}mode_t accessible = stats.st_mode | S_IRWXU;if (stats.st_mode != accessible){/* Make the new directory searchable and writable.The original permissions will be restored later.  */if (lchmodat (dst_dirfd, dst_reldir, accessible) != 0){error (0, errno, _("setting permissions for %s"),quoteaf (dir));return false;}}}else if (!S_ISDIR (stats.st_mode)){error (0, 0, _("%s exists but is not a directory"),quoteaf (dir));return false;}else*new_dst = false;/* For existing dirs, set the security context as per that alreadyset for the process global context.  */if (! *new_dst&& (x->set_security_context || x->preserve_security_context)){if (! set_file_security_ctx (dir, false, x)&& x->require_preserve_context)return false;}*slash++ = '/';/* Avoid unnecessary calls to 'stat' when givenfile names containing multiple adjacent slashes.  */while (*slash == '/')slash++;}}/* We get here if the parent of DIR already exists.  */else if (!S_ISDIR (stats.st_mode)){error (0, 0, _("%s exists but is not a directory"), quoteaf (dst_dir));return false;}else{*new_dst = false;}return true;
}/* Scan the arguments, and copy each by calling copy.Return true if successful.  */static bool
do_copy (int n_files, char **file, char const *target_directory,bool no_target_directory, struct cp_options *x)
{struct stat sb;bool new_dst = false;bool ok = true;if (n_files <= !target_directory){if (n_files <= 0)error (0, 0, _("missing file operand"));elseerror (0, 0, _("missing destination file operand after %s"),quoteaf (file[0]));usage (EXIT_FAILURE);}sb.st_mode = 0;int target_dirfd = AT_FDCWD;if (no_target_directory){if (target_directory)die (EXIT_FAILURE, 0,_("cannot combine --target-directory (-t) ""and --no-target-directory (-T)"));if (2 < n_files){error (0, 0, _("extra operand %s"), quoteaf (file[2]));usage (EXIT_FAILURE);}}else if (target_directory){target_dirfd = target_directory_operand (target_directory, &sb);if (! target_dirfd_valid (target_dirfd))die (EXIT_FAILURE, errno, _("target directory %s"),quoteaf (target_directory));}else{char const *lastfile = file[n_files - 1];int fd = target_directory_operand (lastfile, &sb);if (target_dirfd_valid (fd)){target_dirfd = fd;target_directory = lastfile;n_files--;}else{int err = errno;if (err == ENOENT)new_dst = true;/* The last operand LASTFILE cannot be opened as a directory.If there are more than two operands, report an error.Also, report an error if LASTFILE is known to be a directoryeven though it could not be opened, which can happen ifopening failed with EACCES on a platform lacking O_PATH.In this case use stat to test whether LASTFILE is adirectory, in case opening a non-directory with (O_SEARCH| O_DIRECTORY) failed with EACCES not ENOTDIR.  */if (2 < n_files|| (O_PATHSEARCH == O_SEARCH && err == EACCES&& (sb.st_mode || stat (lastfile, &sb) == 0)&& S_ISDIR (sb.st_mode)))die (EXIT_FAILURE, err, _("target %s"), quoteaf (lastfile));}}if (target_directory){/* cp file1...filen edirCopy the files 'file1' through 'filen'to the existing directory 'edir'. *//* Initialize these hash tables only if we'll need them.The problems they're used to detect can arise only ifthere are two or more files to copy.  */if (2 <= n_files){dest_info_init (x);src_info_init (x);}for (int i = 0; i < n_files; i++){char *dst_name;bool parent_exists = true;  /* True if dir_name (dst_name) exists. */struct dir_attr *attr_list;char *arg_in_concat = NULL;char *arg = file[i];/* Trailing slashes are meaningful (i.e., maybe worth preserving)only in the source file names.  */if (remove_trailing_slashes)strip_trailing_slashes (arg);if (parents_option){char *arg_no_trailing_slash;/* Use 'arg' without trailing slashes in constructing destinationfile names.  Otherwise, we can end up trying to create adirectory using a name with trailing slash, which fails onNetBSD 1.[34] systems.  */ASSIGN_STRDUPA (arg_no_trailing_slash, arg);strip_trailing_slashes (arg_no_trailing_slash);/* Append all of 'arg' (minus any trailing slash) to 'dest'.  */dst_name = file_name_concat (target_directory,arg_no_trailing_slash,&arg_in_concat);/* For --parents, we have to make sure that the directorydir_name (dst_name) exists.  We may have to create a fewleading directories. */parent_exists =(make_dir_parents_private(dst_name, arg_in_concat - dst_name, target_dirfd,(x->verbose ? "%s -> %s\n" : NULL),&attr_list, &new_dst, x));while (*arg_in_concat == '/')arg_in_concat++;}else{char *arg_base;/* Append the last component of 'arg' to 'target_directory'.  */ASSIGN_STRDUPA (arg_base, last_component (arg));strip_trailing_slashes (arg_base);/* For 'cp -R source/.. dest', don't copy into 'dest/..'. */arg_base += STREQ (arg_base, "..");dst_name = file_name_concat (target_directory, arg_base,&arg_in_concat);}if (!parent_exists){/* make_dir_parents_private failed, so don't evenattempt the copy.  */ok = false;}else{bool copy_into_self;ok &= copy (arg, dst_name, target_dirfd, arg_in_concat,new_dst, x, &copy_into_self, NULL);if (parents_option)ok &= re_protect (dst_name, target_dirfd, arg_in_concat,attr_list, x);}if (parents_option){while (attr_list){struct dir_attr *p = attr_list;attr_list = attr_list->next;free (p);}}free (dst_name);}}else /* !target_directory */{char const *source = file[0];char const *dest = file[1];bool unused;if (parents_option){error (0, 0,_("with --parents, the destination must be a directory"));usage (EXIT_FAILURE);}/* When the force and backup options have been specified andthe source and destination are the same name for an existingregular file, convert the user's command, e.g.,'cp --force --backup foo foo' to 'cp --force foo fooSUFFIX'where SUFFIX is determined by any version control options used.  */if (x->unlink_dest_after_failed_open&& x->backup_type != no_backups&& STREQ (source, dest)&& !new_dst&& (sb.st_mode != 0 || stat (dest, &sb) == 0) && S_ISREG (sb.st_mode)){static struct cp_options x_tmp;dest = find_backup_file_name (AT_FDCWD, dest, x->backup_type);/* Set x->backup_type to 'no_backups' so that the normal backupmechanism is not used when performing the actual copy.backup_type must be set to 'no_backups' only *after* the abovecall to find_backup_file_name -- that function usesbackup_type to determine the suffix it applies.  */x_tmp = *x;x_tmp.backup_type = no_backups;x = &x_tmp;}ok = copy (source, dest, AT_FDCWD, dest, -new_dst, x, &unused, NULL);}return ok;
}static void
cp_option_init (struct cp_options *x)
{cp_options_default (x);x->copy_as_regular = true;x->dereference = DEREF_UNDEFINED;x->unlink_dest_before_opening = false;x->unlink_dest_after_failed_open = false;x->hard_link = false;x->interactive = I_UNSPECIFIED;x->move_mode = false;x->install_mode = false;x->one_file_system = false;x->reflink_mode = REFLINK_AUTO;x->preserve_ownership = false;x->preserve_links = false;x->preserve_mode = false;x->preserve_timestamps = false;x->explicit_no_preserve_mode = false;x->preserve_security_context = false; /* -a or --preserve=context.  */x->require_preserve_context = false;  /* --preserve=context.  */x->set_security_context = NULL;       /* -Z, set sys default context. */x->preserve_xattr = false;x->reduce_diagnostics = false;x->require_preserve_xattr = false;x->data_copy_required = true;x->require_preserve = false;x->recursive = false;x->sparse_mode = SPARSE_AUTO;x->symbolic_link = false;x->set_mode = false;x->mode = 0;/* Not used.  */x->stdin_tty = false;x->update = false;x->verbose = false;/* By default, refuse to open a dangling destination symlink, becausein general one cannot do that safely, give the current semantics ofopen's O_EXCL flag, (which POSIX doesn't even allow cp to use, btw).But POSIX requires it.  */x->open_dangling_dest_symlink = getenv ("POSIXLY_CORRECT") != NULL;x->dest_info = NULL;x->src_info = NULL;
}/* Given a string, ARG, containing a comma-separated list of argumentsto the --preserve option, set the appropriate fields of X to ON_OFF.  */
static void
decode_preserve_arg (char const *arg, struct cp_options *x, bool on_off)
{enum File_attribute{PRESERVE_MODE,PRESERVE_TIMESTAMPS,PRESERVE_OWNERSHIP,PRESERVE_LINK,PRESERVE_CONTEXT,PRESERVE_XATTR,PRESERVE_ALL};static enum File_attribute const preserve_vals[] ={PRESERVE_MODE, PRESERVE_TIMESTAMPS,PRESERVE_OWNERSHIP, PRESERVE_LINK, PRESERVE_CONTEXT, PRESERVE_XATTR,PRESERVE_ALL};/* Valid arguments to the '--preserve' option. */static char const *const preserve_args[] ={"mode", "timestamps","ownership", "links", "context", "xattr", "all", NULL};ARGMATCH_VERIFY (preserve_args, preserve_vals);char *arg_writable = xstrdup (arg);char *s = arg_writable;do{/* find next comma */char *comma = strchr (s, ',');enum File_attribute val;/* If we found a comma, put a NUL in its place and advance.  */if (comma)*comma++ = 0;/* process S.  */val = XARGMATCH (on_off ? "--preserve" : "--no-preserve",s, preserve_args, preserve_vals);switch (val){case PRESERVE_MODE:x->preserve_mode = on_off;x->explicit_no_preserve_mode = !on_off;break;case PRESERVE_TIMESTAMPS:x->preserve_timestamps = on_off;break;case PRESERVE_OWNERSHIP:x->preserve_ownership = on_off;break;case PRESERVE_LINK:x->preserve_links = on_off;break;case PRESERVE_CONTEXT:x->require_preserve_context = on_off;x->preserve_security_context = on_off;break;case PRESERVE_XATTR:x->preserve_xattr = on_off;x->require_preserve_xattr = on_off;break;case PRESERVE_ALL:x->preserve_mode = on_off;x->preserve_timestamps = on_off;x->preserve_ownership = on_off;x->preserve_links = on_off;x->explicit_no_preserve_mode = !on_off;if (selinux_enabled)x->preserve_security_context = on_off;x->preserve_xattr = on_off;break;default:abort ();}s = comma;}while (s);free (arg_writable);
}int
main (int argc, char **argv)
{int c;bool ok;bool make_backups = false;char const *backup_suffix = NULL;char *version_control_string = NULL;struct cp_options x;bool copy_contents = false;char *target_directory = NULL;bool no_target_directory = false;char const *scontext = NULL;initialize_main (&argc, &argv);set_program_name (argv[0]);setlocale (LC_ALL, "");bindtextdomain (PACKAGE, LOCALEDIR);textdomain (PACKAGE);atexit (close_stdin);selinux_enabled = (0 < is_selinux_enabled ());cp_option_init (&x);while ((c = getopt_long (argc, argv, "abdfHilLnprst:uvxPRS:TZ",long_opts, NULL))!= -1){switch (c){case SPARSE_OPTION:x.sparse_mode = XARGMATCH ("--sparse", optarg,sparse_type_string, sparse_type);break;case REFLINK_OPTION:if (optarg == NULL)x.reflink_mode = REFLINK_ALWAYS;elsex.reflink_mode = XARGMATCH ("--reflink", optarg,reflink_type_string, reflink_type);break;case 'a':/* Like -dR --preserve=all with reduced failure diagnostics.  */x.dereference = DEREF_NEVER;x.preserve_links = true;x.preserve_ownership = true;x.preserve_mode = true;x.preserve_timestamps = true;x.require_preserve = true;if (selinux_enabled)x.preserve_security_context = true;x.preserve_xattr = true;x.reduce_diagnostics = true;x.recursive = true;break;case 'b':make_backups = true;if (optarg)version_control_string = optarg;break;case ATTRIBUTES_ONLY_OPTION:x.data_copy_required = false;break;case COPY_CONTENTS_OPTION:copy_contents = true;break;case 'd':x.preserve_links = true;x.dereference = DEREF_NEVER;break;case 'f':x.unlink_dest_after_failed_open = true;break;case 'H':x.dereference = DEREF_COMMAND_LINE_ARGUMENTS;break;case 'i':x.interactive = I_ASK_USER;break;case 'l':x.hard_link = true;break;case 'L':x.dereference = DEREF_ALWAYS;break;case 'n':x.interactive = I_ALWAYS_NO;break;case 'P':x.dereference = DEREF_NEVER;break;case NO_PRESERVE_ATTRIBUTES_OPTION:decode_preserve_arg (optarg, &x, false);break;case PRESERVE_ATTRIBUTES_OPTION:if (optarg == NULL){/* Fall through to the case for 'p' below.  */}else{decode_preserve_arg (optarg, &x, true);x.require_preserve = true;break;}FALLTHROUGH;case 'p':x.preserve_ownership = true;x.preserve_mode = true;x.preserve_timestamps = true;x.require_preserve = true;break;case PARENTS_OPTION:parents_option = true;break;case 'r':case 'R':x.recursive = true;break;case UNLINK_DEST_BEFORE_OPENING:x.unlink_dest_before_opening = true;break;case STRIP_TRAILING_SLASHES_OPTION:remove_trailing_slashes = true;break;case 's':x.symbolic_link = true;break;case 't':if (target_directory)die (EXIT_FAILURE, 0,_("multiple target directories specified"));target_directory = optarg;break;case 'T':no_target_directory = true;break;case 'u':x.update = true;break;case 'v':x.verbose = true;break;case 'x':x.one_file_system = true;break;case 'Z':/* politely decline if we're not on a selinux-enabled kernel.  */if (selinux_enabled){if (optarg)scontext = optarg;else{x.set_security_context = selabel_open (SELABEL_CTX_FILE,NULL, 0);if (! x.set_security_context)error (0, errno, _("warning: ignoring --context"));}}else if (optarg){error (0, 0,_("warning: ignoring --context; ""it requires an SELinux-enabled kernel"));}break;case 'S':make_backups = true;backup_suffix = optarg;break;case_GETOPT_HELP_CHAR;case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);default:usage (EXIT_FAILURE);}}if (x.hard_link && x.symbolic_link){error (0, 0, _("cannot make both hard and symbolic links"));usage (EXIT_FAILURE);}if (x.interactive == I_ALWAYS_NO)x.update = false;if (make_backups && x.interactive == I_ALWAYS_NO){error (0, 0,_("options --backup and --no-clobber are mutually exclusive"));usage (EXIT_FAILURE);}if (x.reflink_mode == REFLINK_ALWAYS && x.sparse_mode != SPARSE_AUTO){error (0, 0, _("--reflink can be used only with --sparse=auto"));usage (EXIT_FAILURE);}x.backup_type = (make_backups? xget_version (_("backup type"),version_control_string): no_backups);set_simple_backup_suffix (backup_suffix);if (x.dereference == DEREF_UNDEFINED){if (x.recursive && ! x.hard_link)/* This is compatible with FreeBSD.  */x.dereference = DEREF_NEVER;elsex.dereference = DEREF_ALWAYS;}if (x.recursive)x.copy_as_regular = copy_contents;/* Ensure -Z overrides -a.  */if ((x.set_security_context || scontext)&& ! x.require_preserve_context)x.preserve_security_context = false;if (x.preserve_security_context && (x.set_security_context || scontext))die (EXIT_FAILURE, 0,_("cannot set target context and preserve it"));if (x.require_preserve_context && ! selinux_enabled)die (EXIT_FAILURE, 0,_("cannot preserve security context ""without an SELinux-enabled kernel"));/* FIXME: This handles new files.  But what about existing files?I.e., if updating a tree, new files would have the specified context,but shouldn't existing files be updated for consistency like this?if (scontext && !restorecon (NULL, dst_path, 0))error (...);*/if (scontext && setfscreatecon (scontext) < 0)die (EXIT_FAILURE, errno,_("failed to set default file creation context to %s"),quote (scontext));#if !USE_XATTRif (x.require_preserve_xattr)die (EXIT_FAILURE, 0, _("cannot preserve extended attributes, cp is ""built without xattr support"));
#endif/* Allocate space for remembering copied and created files.  */hash_init ();ok = do_copy (argc - optind, argv + optind,target_directory, no_target_directory, &x);main_exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
}

4、gdb 调试工具

  • file

    在gdb内装载可执行程序 (gdb)a1.out

  • b

    下断点,b main (主函数处下断点),b 0x70123456(在某个地址处下断点)

  • start

    直接执行程序到main()函数第一条指令

  • r

    执行程序,一般就是在下好断点之后执行r运行到断点处,然后分析。

  • n

    单步执行,它不会进入函数内部,遇到一个函数它会直接执行,并返回函数结果。

  • s

    步进,进入函数内部。

  • display

    查看变量值,display a,就会显示a的值。

  • l

    查看源码,如果编译时加入了-g参数,就可以用l去查看源码。

  • info break

    查看有哪些断点

  • d

    删除断点

  • q

    退出

shell C语言编程相关推荐

  1. 用linux下的C语言编程万年历,shell编程万年历月历和对应c语言程序.docx

    shell编程万年历月历和对应c语言程序.docx 下载提示(请认真阅读)1.请仔细阅读文档,确保文档完整性,对于不预览.不比对内容而直接下载带来的问题本站不予受理. 2.下载的文档,不会出现我们的网 ...

  2. C 语言编程 — GDB 调试工具

    目录 文章目录 目录 前文列表 代码调试 GDB 启动 GDB 交互命令 运行程序 暂停程序 设置断点 设置观察点 设置捕捉点 打印信息 查询运行信息 分割窗口 前文列表 <程序编译流程与 GC ...

  3. vim切换编程语言_把 Vim 打造成源代码编辑器 - C 语言编程透视

    前言 程序开发过程中,源代码的编辑主要是为了实现算法,结果则是一些可阅读的.便于检错的.可移植的文本文件.如何产生一份良好的源代码,这不仅需要一些良好的编辑工具,还需要开发人员养成良好的编程修养. L ...

  4. Perl/CGI脚本语言编程学习资料及开发工具下载大全

    Practical Extraction and Report Language Perl 最初的设计者为拉里·沃尔(Larry Wall),它于1987年12月18日发表.Perl借取了C.sed. ...

  5. Linux下C语言编程-进程的创建

    Linux下C语言编程-进程的创建 作者:hoyt 1.进程的概念 Linux操作系统是面向多用户的.在同一时间可以有许多用户向操作系统发出各种命令.那么操作系统是怎么实现多用户的环境呢?在现代的操作 ...

  6. linux c语言 ppt,linux操作系统下c语言编程入门.ppt

    linux操作系统下c语言编程入门.ppt Linux操作系统下C语言编程入门 CNT Linux操作系统简介基础知识进程介绍文件操作时间概念消息管理线程操作网络编程Linux下C开发工具介绍 一 L ...

  7. linux系统下c语言编程的,Linux操作系统下C语言编程从零开始

    这里向大家介绍一下在Linux/UNIX 的机器上,进行 C/C++ 编程的一些入门级知识. · 所需具备的背景知识 · 开发所需的基本环境 · 获得帮助的途径 · 通过一个实例了解基本步骤 Prer ...

  8. 精通unix下c语言与项目实践,《精通Unix下C语言编程与项目实践》读书笔记(2)...

    51CTO博客开发社区大管家小废物simeon技术专栏王乾De技术Blog[爱生活,爱学习]sery李晨光网管小王 "聂隐娘",三十三剑客之一,裴铏所撰<传奇>中人物. ...

  9. 实验linux下的编程,实验四 Linux下的C语言编程;

    <实验四 Linux下的C语言编程;>由会员分享,可在线阅读,更多相关<实验四 Linux下的C语言编程;(5页珍藏版)>请在人人文库网上搜索. 1.实验四Linux 下的 C ...

最新文章

  1. [蓝桥杯][2014年第五届真题]生物芯片(数论)
  2. 201671010114 2016-2017-2 《Java程序设计》学习总结
  3. mysql trim 索引_mysql 强大的trim() 函数
  4. 【MATLAB、深度学习】AlexNet及VGG神经网络在MATLAB上的应用
  5. win10下安装mysql5.7.16(解压缩版)
  6. Bootstrap页面布局18 - BS导航路径以及分页器
  7. 手把手教你使用人人开源
  8. 机器学习综述论文笔记:Machine Learning: A Review of Learning Types
  9. Latex——插入罗马字母或更改字体为公式体
  10. [AHK]如何更改键盘快捷方式,在 Windows 10 中的虚拟桌面之间切换
  11. 胭脂茉莉点评推荐上海大学法院李本教授诗集《秋月曲》诗歌6首
  12. Could not find a package configuration file provided by “std_msg“ with any of the following names:
  13. 扑克牌中的顺子。从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王可以看成任意数字。
  14. CocosCreator之KUOKUO分享-俄罗斯方块
  15. 程序员考试下午题知识点总结
  16. 计算机平面设计教程,计算机平面设计实用教程 培训课件.ppt
  17. java项目-第94期基于ssm的在线答题系统-计算机毕业设计
  18. BUUCTF-Crypto-凯撒密码爆破+中文电码+md5+猪圈密码WP
  19. 高分辨轨道阱液质联用质谱仪-HFX
  20. vue springboot 会员收银系统 (1)

热门文章

  1. 网页版视频怎么加快播放速度
  2. 表横竖转换(行列转换)PIVOT 和 UNPIVOT 用法
  3. ln: creating symbolic link XXXXXX : Operation not supported
  4. Vue报错:implicitly has an ‘any‘ type解决方法
  5. apktool下载及“安装”(windows系统)
  6. WIFI AP和STATION
  7. 数据结构课程设计【C++实现】
  8. 6月19,观世音菩萨成道
  9. netcat工具简单使用
  10. css如何设置滚动条,设置滚动条需要用到的参数