Website hosting service by Active-Venture.com
  

 Back to Index

Open à la C

If you want the convenience of the shell, then Perl's open is definitely the way to go. On the other hand, if you want finer precision than C's simplistic fopen(3S) provides, then you should look to Perl's sysopen, which is a direct hook into the open(2) system call. That does mean it's a bit more involved, but that's the price of precision.

sysopen takes 3 (or 4) arguments.

 
    sysopen HANDLE, PATH, FLAGS, [MASK]  

The HANDLE argument is a filehandle just as with open. The PATH is a literal path, one that doesn't pay attention to any greater-thans or less-thans or pipes or minuses, nor ignore white space. If it's there, it's part of the path. The FLAGS argument contains one or more values derived from the Fcntl module that have been or'd together using the bitwise "|" operator. The final argument, the MASK, is optional; if present, it is combined with the user's current umask for the creation mode of the file. You should usually omit this.

Although the traditional values of read-only, write-only, and read-write are 0, 1, and 2 respectively, this is known not to hold true on some systems. Instead, it's best to load in the appropriate constants first from the Fcntl module, which supplies the following standard flags:

 
    O_RDONLY            Read only
    O_WRONLY            Write only
    O_RDWR              Read and write
    O_CREAT             Create the file if it doesn't exist
    O_EXCL              Fail if the file already exists
    O_APPEND            Append to the file
    O_TRUNC             Truncate the file
    O_NONBLOCK          Non-blocking access  

Less common flags that are sometimes available on some operating systems include O_BINARY, O_TEXT, O_SHLOCK, O_EXLOCK, O_DEFER, O_SYNC, O_ASYNC, O_DSYNC, O_RSYNC, O_NOCTTY, O_NDELAY and O_LARGEFILE. Consult your open(2) manpage or its local equivalent for details. (Note: starting from Perl release 5.6 the O_LARGEFILE flag, if available, is automatically added to the sysopen() flags because large files are the default.)

Here's how to use sysopen to emulate the simple open calls we had before. We'll omit the || die $! checks for clarity, but make sure you always check the return values in real code. These aren't quite the same, since open will trim leading and trailing white space, but you'll get the idea:

To open a file for reading:

 
    open(FH, "< $path");
    sysopen(FH, $path, O_RDONLY);  

To open a file for writing, creating a new file if needed or else truncating an old file:

 
    open(FH, "> $path");
    sysopen(FH, $path, O_WRONLY | O_TRUNC | O_CREAT);  

To open a file for appending, creating one if necessary:

 
    open(FH, ">> $path");
    sysopen(FH, $path, O_WRONLY | O_APPEND | O_CREAT);  

To open a file for update, where the file must already exist:

 
    open(FH, "+< $path");
    sysopen(FH, $path, O_RDWR);  

And here are things you can do with sysopen that you cannot do with a regular open. As you see, it's just a matter of controlling the flags in the third argument.

To open a file for writing, creating a new file which must not previously exist:

 
    sysopen(FH, $path, O_WRONLY | O_EXCL | O_CREAT);  

To open a file for appending, where that file must already exist:

 
    sysopen(FH, $path, O_WRONLY | O_APPEND);  

To open a file for update, creating a new file if necessary:

 
    sysopen(FH, $path, O_RDWR | O_CREAT);  

To open a file for update, where that file must not already exist:

 
    sysopen(FH, $path, O_RDWR | O_EXCL | O_CREAT);  

To open a file without blocking, creating one if necessary:

 
    sysopen(FH, $path, O_WRONLY | O_NONBLOCK | O_CREAT);  

Permissions à la mode

If you omit the MASK argument to sysopen, Perl uses the octal value 0666. The normal MASK to use for executables and directories should be 0777, and for anything else, 0666.

Why so permissive? Well, it isn't really. The MASK will be modified by your process's current umask. A umask is a number representing disabled permissions bits; that is, bits that will not be turned on in the created files' permissions field.

For example, if your umask were 027, then the 020 part would disable the group from writing, and the 007 part would disable others from reading, writing, or executing. Under these conditions, passing sysopen 0666 would create a file with mode 0640, since 0666 &~ 027 is 0640.

You should seldom use the MASK argument to sysopen(). That takes away the user's freedom to choose what permission new files will have. Denying choice is almost always a bad thing. One exception would be for cases where sensitive or private data is being stored, such as with mail folders, cookie files, and internal temporary files.

 

 

 

Domain name registration service & domain search - 
Register cheap domain name from $7.95 and enjoy free domain services 
 

Cheap domain name search service -
Domain name services at just
$8.95/year only
 

Register domain name -
Buy domain name registration and cheap domain transfer at low, affordable price.

© 2002-2004 Active-Venture.com Web Site Hosting Service

 

[ Computers do not solve problems, they execute solutions.   ]

 

 
 
 

Disclaimer: This documentation is provided only for the benefits of our web hosting customers.
For authoritative source of the documentation, please refer to http://www.perldoc.com