open() O_EXCL 参数讲解

O_EXCL参数详解
本文详细解析了Linux系统调用open()中的O_EXCL参数作用。当与O_CREAT结合使用时,若目标文件已存在,则打开操作将失败,确保文件创建的原子性和唯一性。文章深入探讨了该参数在多线程环境下的应用及与符号链接交互时的行为。

open() O_EXCL 参数讲解

fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);

O_EXCL一般和O_CREAT同时出现, 意思是如果filename不存在, 则新建之.
如果已经存在, 则打开文件失败: fd < 0.

O_EXCL
If O_CREAT and O_EXCL are set, open() shall fail if the file exists. The check for the existence of the file and the creation of the file if it does not exist shall be atomic with respect to other threads executing open() naming the same filename in the same directory with O_EXCL and O_CREAT set. If O_EXCL and O_CREAT are set, and path names a symbolic link, open() shall fail and set errno to [EEXIST], regardless of the contents of the symbolic link. If O_EXCL is set and O_CREAT is not set, the result is undefined.

https://linux.die.net/man/3/open

为我用伪代码的形式讲解下述这个perl代码,我要放在ppt里,所以越伪越好,重点在于讲明白功能: #! /usr/bin/perl -w use warnings; use strict; #============================================================================= # FileName: int_fail_log_2_scan_cell.pl # Desc: use to locate the error scan cell # Usage: # Author: JustinMei # Email: JustinMei@zhaoxin.com # Telephone: 6910 # Version: 0.0.1 # LastChange: 2025-09-30 # History: #============================================================================= my $argv; my $pat_type; my $scan_cell; my $scan_chain; my $pad_map; my $fail_log; my $shift_cyc; my $shift_dummy_cyc; my $load_unload_cyc; my $capture_cyc; my $pat0_shift; my $out_log; my $pipe_stage; my $excel_log; my $excel_wafer; my $excel_corner; my $excel_die_id; my $excel_pattern; my $excel_freq; my $excel_volt; my $excel_temp; my $excel_fail_reg; my $excel_fail_pat_num; my $excel_fail_scanout; my $excel_fail_chain_offset; my $excel_fail_pat_exp; my $excel_fail_pat_got; my $excel_fail_pat_body; our %padmap; while ($argv = shift @ARGV) { if($argv eq '-pat_type') { $pat_type = shift @ARGV; }elsif($argv eq '-scan_cell') { $scan_cell = shift @ARGV; }elsif($argv eq '-scan_chain') { $scan_chain = shift @ARGV; }elsif($argv eq '-pad_map') { $pad_map = shift @ARGV; }elsif($argv eq '-fail_log') { $fail_log = shift @ARGV; }elsif($argv eq '-shift_cyc') { $shift_cyc = shift @ARGV; }elsif($argv eq '-load_unload_cyc') { $load_unload_cyc = shift @ARGV; }elsif($argv eq '-capture_cyc') { $capture_cyc = shift @ARGV; }elsif($argv eq '-pipe_stage') { $pipe_stage = shift @ARGV; }elsif($argv eq '-shift_dummy_cyc') { $shift_dummy_cyc = shift @ARGV; }elsif($argv eq '-pat0_shift') { $pat0_shift = shift @ARGV; }elsif($argv eq '-out_log') { $out_log = shift @ARGV; }elsif($argv eq '-excel_log') { $excel_log = shift @ARGV; }elsif($argv eq '-excel_wafer') { $excel_wafer = shift @ARGV; }elsif($argv eq '-excel_corner') { $excel_corner = shift @ARGV; }elsif($argv eq '-excel_die_id') { $excel_die_id = shift @ARGV; }elsif($argv eq '-excel_pattern') { $excel_pattern = shift @ARGV; }elsif($argv eq '-excel_freq') { $excel_freq = shift @ARGV; }elsif($argv eq '-excel_volt') { $excel_volt = shift @ARGV; }elsif($argv eq '-excel_temp') { $excel_temp = shift @ARGV; }else{ print "ERROR: parameter error !!!\n"; } } my $line; my $idx; my $fmc; my $fpga; my $fpc_dm4; my $fpc_dm5; my $fpc_ddr5; my $hdr; my $zdi_pad; my $ccd_pad; my $pad; my $atpg_pad; my %PAD_IDX; my %FT2CP_PAD; my %FT2ATPG_PAD; open(MAPPING, "$pad_map")||die "open mapping file failed!($pad_map)\n"; while($line = <MAPPING>){ #1_idx #2_FMC #3_H0_IOD_DDR #4_H0_IOD_ATPG1 #5_H1_IOD_DDR #6_H1_IOD_ATPG1 #7_H2_IOD_DDR #8_H2_IOD_ATPG1 #9_H3_IOD_DDR #10_H3_IOD_ATPG1 if($line =~ /^(\d+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/) { $idx = $1; $fmc = $2; $pad = "NA"; $atpg_pad = "NA"; $ccd_pad = "NA"; if ($pat_type eq "H0_IOD") { $pad = $3; $atpg_pad = $4; } if ($pat_type eq "H1_IOD") { $pad = $5; $atpg_pad = $6; } if ($pat_type eq "H2_IOD") { $pad = $7; $atpg_pad = $8; } if ($pat_type eq "H3_IOD") { $pad = $9; $atpg_pad = $10; } if(exists $PAD_IDX{$idx}) { print STDOUT "Error, $idx is exists in $pat_type\n"; } else { $PAD_IDX{$idx} = $pad; } $pad =~ s/^I_//g; $pad =~ s/^O_//g; $FT2CP_PAD{$pad} = $ccd_pad; $FT2ATPG_PAD{$pad} = $atpg_pad; } } close (MAPPING); my $chain_name; my $chain_output_pad; my %CHAIN_PAD; open(CHAIN,"$scan_chain") || die "Can't open the file: $scan_chain"; while($line = <CHAIN>) { chomp($line); if($line=~/chain = (\S+).*output = '\/(\S+)'/) { $chain_name=$1; $chain_output_pad=$2; $CHAIN_PAD{$chain_output_pad}=$chain_name; } } close (CHAIN); #open($input,"gzip -dc $scan_cell | ") || die("Could not open $scan_cell"); open(SCANCELL,"$scan_cell") || die("Could not open $scan_cell"); my %file_handles; my $chain_cell_rpt; while ($line = <SCANCELL>) { chomp($line); if($line=~/(\d+)\s+(\S+)\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+(\S+)/) { $chain_name=$2; if (exists $file_handles{$chain_name}) { print {$file_handles{$chain_name}} "$line\n"; } else{ open($chain_cell_rpt,">$scan_cell.$chain_name.txt") || die("Could not write $!"); print {$chain_cell_rpt} "$line\n"; $file_handles{$chain_name} = $chain_cell_rpt; } } } close (SCANCELL); foreach my $chain_cell_rpt (values %file_handles) { close $chain_cell_rpt; } my @PAT_NAME; my @PAT_CYCLE; my $pat_name; my $pat_cycle; open(FAIL_LOG, "$fail_log")||die "open fail log file failed!($fail_log)\n"; $idx=0; $PAT_CYCLE[$idx]=0; while($line = <FAIL_LOG>){ if ($line =~ /^(\S+) has (\d+) cycle/) { $pat_name = $1; $pat_cycle = $2; push @PAT_NAME, $pat_name; $pat_cycle = $pat_cycle + $PAT_CYCLE[$idx]; push @PAT_CYCLE, $pat_cycle; $idx++; } } close (FAIL_LOG); my $fail_cycle; my $fail_pad; my $fail_chain; my $exp; my $got; my $org_exp; my $org_got; my $fail_pattern_num; my $fail_scan_cell_num; my $append_cycle=0; my $fail_cycle_file; my $cell_inv_flag; my $cell_qpin_flag; my $cell_name; my $cell_full_name; my $tmp_line; my $match_flag; my $gen_fail_log=0; my $fail_num=0; open(FAIL_LOG, "$fail_log")||die "open fail log file failed!($fail_log)\n"; open(OUT_LOG, ">$out_log")||die "open fail log file failed!($fail_log)\n"; #open(EXCEL_LOG, ">>$excel_log")||die "open fail log file failed!($fail_log)\n"; while($line = <FAIL_LOG>){ if ($line =~ /^\s+(\d+)\s+(\S+)\s+exp=(\S)\s+got=(\S)/) { chomp($line); $fail_cycle = $1; $fail_pad = $2; $exp=$3; $got=$4; $org_exp=$3; $org_got=$4; $idx = 0; $append_cycle=0; $fail_cycle_file=0; $fail_num++; if ($fail_num > 500) { print OUT_LOG "$line\n"; next; } while ($fail_cycle > $PAT_CYCLE[$idx]) { $idx++; } $pat_name=$PAT_NAME[$idx-1]; $fail_cycle_file = $fail_cycle - $PAT_CYCLE[$idx-1]; if ($pat0_shift eq "yes") { $fail_pattern_num = int (($fail_cycle_file + 1) / ($load_unload_cyc + $shift_cyc + $shift_dummy_cyc + $capture_cyc)) - 1 - 1; #$fail_scan_cell_num = ($fail_cycle_file + 1) % ($load_unload_cyc + $shift_cyc + $shift_dummy_cyc + $capture_cyc) - 1 - $load_unload_cyc - $pipe_stage + $capture_cyc; $fail_scan_cell_num = ($fail_cycle_file + 1) % ($load_unload_cyc + $shift_cyc + $shift_dummy_cyc + $capture_cyc) - 1 - $load_unload_cyc - $pipe_stage; } else { $fail_pattern_num = int (($fail_cycle_file + 1) / ($load_unload_cyc + $shift_cyc + $shift_dummy_cyc + $capture_cyc)) - 1; $fail_scan_cell_num = ($fail_cycle_file + 1) % ($load_unload_cyc + $shift_cyc + $shift_dummy_cyc + $capture_cyc) - 1 - $load_unload_cyc - $pipe_stage; } $atpg_pad=$FT2ATPG_PAD{$fail_pad}; $chain_output_pad = $atpg_pad; #if (exists $FT2CP_PAD{$fail_pad}) { # if ($FT2CP_PAD{$fail_pad} eq "NA") { # $chain_output_pad = $fail_pad; # } else { # $chain_output_pad = $FT2CP_PAD{$fail_pad}; # } #} else { # print STDOUT "Error, can not mapping FT pad $fail_pad to CP pad, please check!\n"; #} $chain_name=$CHAIN_PAD{$chain_output_pad}; open(CELL,"< $scan_cell.$chain_name.txt") || die "Can't open the file: $scan_cell.$chain_name.txt"; $match_flag=0; $cell_full_name="NA"; while($tmp_line = <CELL>){ # 29636 zdi_1 MASTER (FF-LE) TFFF 42097406 /CCD_CPTEST29 F HDN6BULT08_FSDPQ_DY2_1 /zdi_ccd/zdil_x32/zdi_dll_zdi/r_inst_scan_obs_rxreq24/\sq_reg[4] U1 (SI,Q) if ($tmp_line =~ /^\s*$fail_scan_cell_num\s+$chain_name\s+MASTER\s+\S+\s+(\S)(\S)(\S)(\S)\s+\d+\s+\S+\s+\S\s+\S+\s+(.*)\s+\S+\s+\(\S+,\S+\)/) { $cell_inv_flag=$2; $cell_qpin_flag=$4; $cell_name = $5; $cell_name =~ s/\s+$//g; if ($cell_qpin_flag eq "T") { $cell_full_name = $cell_name . "/QN"; } else { $cell_full_name = $cell_name . "/Q"; } if ($cell_inv_flag eq "T") { my $tmp = $exp; $exp = $got; $got = $exp; } if ($got eq "H") { $got="1'b1"; } else { $got="1'b0"; } $match_flag=1; $gen_fail_log=1; last; } } close (CELL); if ($match_flag == 0) { print STDOUT "Error, can not find $chain_name $fail_scan_cell_num fail cell name, please check!\n"; } my $tmp_str="$cell_full_name"." = "."$got"; printf OUT_LOG "%-30s\t; # %-150s\t # %-5s\t%-12s\t%-8s\t%s\t%s\t; #atpg_pad=%-12s\tchain=%-25s\tpat_name=%s\n", "$line", "$tmp_str", "$fail_pattern_num", "$chain_output_pad", "$fail_scan_cell_num", "$org_exp", "$org_got", "$atpg_pad", "$chain_name", "$pat_name"; printf STDOUT "%-30s\t; # %-150s\t # %-5s\t%-12s\t%-8s\t%s\t%s\t; #atpg_pad=%-12s\tchain=%-25s\tpat_name=%s\n", "$line", "$tmp_str", "$fail_pattern_num", "$chain_output_pad", "$fail_scan_cell_num", "$org_exp", "$org_got", "$atpg_pad", "$chain_name", "$pat_name"; $excel_fail_reg=$cell_name; $excel_fail_pat_num=$fail_pattern_num; $excel_fail_scanout=$chain_output_pad; $excel_fail_chain_offset=$fail_scan_cell_num; $excel_fail_pat_exp=$org_exp; $excel_fail_pat_got=$org_got; $excel_fail_pat_body=$pat_name; #printf EXCEL_LOG "$excel_wafer\t$excel_corner\t$excel_die_id\t$excel_pattern\t$excel_volt\t$excel_freq\t$excel_temp\t$excel_fail_reg\t$excel_fail_pat_num\t$excel_fail_scanout\t$excel_fail_chain_offset\t$excel_fail_pat_exp\t$excel_fail_pat_got\t$excel_fail_pat_body\n"; } else { print OUT_LOG "$line"; } } close (FAIL_LOG); close (OUT_LOG); if ($gen_fail_log == 0) { unlink "$out_log"; #printf EXCEL_LOG "$excel_wafer\t$excel_corner\t$excel_die_id\t$excel_pattern\t$excel_volt\t$excel_freq\t$excel_temp\tall_pattern_pass\n"; }
最新发布
10-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值