D.Zou
D.Zou

Reputation: 808

sysopen example doesn't work

I got this perl example that's suppose to demonstrate sysopen and printf, except so far it only demonstrates die.

#! /usr/bin/perl  
$filepath = 'myhtml.html';
sysopen (HTML, $filepath, O_RDWR|O_EXCL|O_CREAT, 0755) 
    or die "$filepath cannot be opened.";
printf HTML "<html>\n";

but when I execute the code it just dies.

myhtml.html cannot be opened. at file_handle.pl line 7.

myhtml.html does not exist, but it should have been created by the O_CREAT flag. shouldn't it?


EDIT

I have edited the code to include the suggestions about use strict and $!. Below is the new code and its result.

#! /usr/bin/perl
use strict; 
$filepath = "myhtml.html";

sysopen (HTML, '$filepath', O_RDWR|O_EXCL|O_CREAT, 0755) 
    or die "$filepath cannot be opened. $!";
printf HTML "<html>\n"; 

output, due to the use strict, gave us a whole bunch of errors:

Global symbol "$filepath" requires explicit package name at file_handle.pl line 3.
Global symbol "$filepath" requires explicit package name at file_handle.pl line 5.
Bareword "O_RDWR" not allowed while "strict subs" in use at file_handle.pl line 5.
Bareword "O_EXCL" not allowed while "strict subs" in use at file_handle.pl line 5.
Bareword "O_CREAT" not allowed while "strict subs" in use at file_handle.pl line 5.
Execution of file_handle.pl aborted due to compilation errors.

EDIT 2

Based on everyone's suggestion and help, here is the final working code:

#! /usr/bin/perl
use strict;
use Fcntl;

my $filepath = "myhtml.html";

sysopen (HTML, $filepath, O_RDWR|O_EXCL|O_CREAT, 0755) 
    or die "$filepath cannot be opened. $!";
printf HTML "<html>\n"; 
....

Upvotes: 4

Views: 7079

Answers (3)

mob
mob

Reputation: 118685

O_RWDR, O_EXCL, and O_CREAT are all constants defined in the Fcntl module. Put the line

use Fcntl;

near the top of your script.

You can limit the imported variables as follows.

# import only needed constants.  
use Fcntl qw(O_CREAT O_WRONLY O_TRUNC);

Upvotes: 11

Sean
Sean

Reputation: 29790

Lots of issues here:

  • Always put use strict; at the top of your program. That would provide a clue.
  • The reason the sysopen failed is in the $! variable. You should generally include it in any die message.
  • As the sysopen entry in man perlfunc explains, the various O_* constants are exported by the Fcntl module. You need to use that module if you want those constants defined. As it is, you're character-wise or-ing together the strings "O_RDWR", "O_EXCL", and "O_CREAT", resulting in another string that sysopen doesn't know what to do with. use strict would prevent this from happening.

Upvotes: 8

Alan Haggai Alavi
Alan Haggai Alavi

Reputation: 74272

myhtml.html file probably already exists. It is probably because a previous execution of the script created it. The O_EXCL flag will cause sysopen to fail if the file exists. Relevant quote from sysopen documentation:

In many systems the O_EXCL flag is available for opening files in exclusive mode. This is not locking: exclusiveness means here that if the file already exists, sysopen() fails.

Upvotes: 1

Related Questions