Please enable JavaScript to view this site.

A-Shell Reference

Navigation: Development Topics > Miscellaneous Topics

Create Directories From Apps

Scroll Prev Top Next More

There is often some confusion around the topic of creating directories, generally relating to one or more of the following:

DevPPN-style vs. native-style syntax (e.g. DSK9:[23,4] vs /vm/miame/dsk9/023004 or C:\vm\data\dsk9\023004).
Checking if the directory exists, vs. creating it.
SYSTAT.LIT vs. native OS commands vs. XCALLs

It's not possible to answer every related and imaginable question, but here are a few notes that might fill in the blanks for those unsure about the best approach (particularly since the various components may be scattered all over the documentation):

SYSACT.LIT: One option for creating a directory (using AMOS-style syntax) is just to use SYSTAT.LIT, either manually or via a command file. This is the only method that includes the option to create a password for the directory. The main downsides are that: a) it's dangerous, since you can too-easily delete directories this way; and b) if you wanted to do it under program control, you'd have to create a command file and then shell out to it, which introduces a fair amount of additional complexity.

Checking if the directory already exists: If working with AMOS-style syntax, you can use MX_CHKPPN. Otherwise, if your directory spec is already in native form, you can use MX_FINDFIRST. However, in either case, it isn't clear that there is any performance advantage to checking first if the directory exists, vs. just trying to create it. (The operation to create it will internally determine if it exists and just return with an appropriate status code.)

MX_MKPATH: this is the most straightforward approach, regardless of operating system, but does require that you convert your directory spec to native syntax. To do that, you can use MX_FSPEC, but it requires that you set up some map statements and pay attention to several details. A simpler approach is to use the function Fn'FQFS$ in SOSLIB:[907,10], which takes a full or partial AMOS-style filespec or relative native filespec (e.g. ".") and returns the corresponding Fully Qualified native File Spec.

As with MK_FSPEC, it may require a dummy file.ext (typically one uses "z.z"), which you can then strip from the end if you just want the directory, as is the case here. So here's an example of using Fn'FQFS$() and MK_MKPATH to create the AMOS-style directory "TMZ0:[15,37]":

++include sosfunc:fnfqfs.bsi

...

MAP1 NATIVEDIR$,S,260

MAP1 STATUS,F

...

NATIVEDIR$ = Fn'FQFS$("TMZ0:Z.Z[15,37]")[1,-5]    ! cvt to native and chop off "/z.z"

XCALL MIAMEX, MX_MKPATH, LOCAL, STATUS

IF STATUS # 0 and STATUS # -1 and STATUS # 183 THEN

    <handle error - unable to create directory>

ENDIF

 

Note that for Unix, the "directory already exists" error will be -1, while for Windows it will 183.

Use MX_RMPATH to delete a directory.

HOSTEX: Another option (again requiring a native spec) is to use XCALL HOSTEX to access an operating system shell command to check for and/or create the directory. (This will definitely require determining which platform you are on first so you can use the appropriate commands, and thus is probably less sensible than one of the above methods which will handle most of that problem for you.) Here we check for the existence of the TMZ0:Z.Z[15,37] directory under Linux and then create it if necessary. (Assume that we have already converted it to the native syntax using a technique like the one shown above.)

MAP1 STDOUT$,S,200

...

XCALL HOSTEX,"stat "+NATIVEDIR$+" >/dev/null 2>&1",STATUS

if STATUS # 0 then

    XCALL HOSTEX,"mkdir "+NATIVEDIR$+" >&1",STATUS,STDOUT$

    if STATUS # 0 then

        ? "Error: ";STDOUT$

    endif

endif

 

In the above code, we captured the stdout and stderr from the mkdir command into the parameter STDOUT$ so that we could display the error message if the command failed.

DEVICEs: In all of the above cases, there is an assumption that for the directory to be created, the parent already exists. The parent of a PPN under AMOS terminology would be called a DEVICE. These DEVICEs (which are just directories from the host operating system's perspective) may be created like any other directory. But in order to then reference PPNs within that DEVICE using AMOS-style syntax, the DEVICE must be defined in miame.ini using a DEVICE statement, which see for details.