Sponsored Content
Top Forums UNIX for Advanced & Expert Users Writing Custom Builtins for KSH93 Post 302471264 by fpmurphy on Friday 12th of November 2010 11:21:21 AM
Old 11-12-2010
This might help you ....

Extracted from a blog post KSH93 Custom Builtins II I wrote a couple of years ago:

Example 5 Using name-value routines to access ksh93 internals

The purpose of this custom builtin is to set the value of a specified variable (argument 1) to the size of the specified file (argument 2).
Code:
$ statsize myfilesize /usr/bin/ksh
$ print ${myfilesize}
1157295
$

This example uses the libast nval(3) name-value routines to access the internals of ksh93 and set up a variable with the specifed name (i.e. myfilesize) and value of 1157295 as returned by stat(2) for the file /usr/bin/ksh. See the nval(3) documentation for more detailed information.

Code:
#include <shell.h>
#include <nval.h>

#define SH_DICT "statsize"

static const char usage_statsize[] =
   [-?\n@(#)$Id: stat 2008-05-03 $\n]"
   [-author?Finnbarr P. Murphy <fpmATiisc.com>]"
   [-licence?http://www.opensource.org/licenses/cpl1.0.txt]"
   [+NAME?statsize - assign size of file to variable]"
   [+DESCRIPTION?\bstat\b assigns the size of the specified file"
      "(in bytes) to the specified variable.]"
   "[+OPTIONS?none.]"
   "\n"
   "[+EXIT STATUS?] {"
      "[+0?Success.]"
      "[+>0?An error occurred.]"
   "[+SEE ALSO?\bstat\b(2)]"
;

int
b_statsize(int argc, char *argv[], void *extra)
{
   Namval_t *nvp = (Namval_t *)NULL;
   Shell_t *shp = (Shell_t *)NULL;
   struct stat st;
   long d;
   register int n;

   while (n = optget(argv, usage_statsize)) switch(n) {
      case ':':
        error(2, "%s", opt_info.arg);
        break;
      case '?':
        errormsg(SH_DICT, ERROR_usage(2), "%s",
           opt_info.arg);
        break;
   }
   argc -= opt_info.index;
   argv += opt_info.index;

   if (argc != 2)
      errormsg(SH_DICT, ERROR_usage(2), "%s",
         optusage((char*)0));

   /* get current shell context */
   shp = sh_getinterp();

   /* retrieve information about file */
   stat(argv[1], &st);
   /* assign size of file to long */
   d = (long) st.st_size;

   /* access the variables tree and add specified variable */
   nvp = nv_open(argv[0], shp->var_tree,
          NV_NOARRAY|NV_VARNAME|NV_NOASSIGN);
   if (!nv_isnull(nvp))
      nv_unset(nvp);
   nv_putval(nvp, (char *)&d, NV_INTEGER|NV_RDONLY);
   nv_close(nvp);

   return(0);
}

This custom builtin can easily be extended to provide much more information about a file using command line options. I will leave it as an exercise for you the reader.

Example 6 Print out detailed information about a specified shell variable.

Code:
$ showvar HOME
Value: /home/fpm, Flags: 12288 NV_EXPORT NV_IMPORT
$ integer i=123
$ showvar i
Value: 123, Flags: 10 NV_UINT64 NV_UTOL

See the libast header <nval.h> for detailed information about the different flags which can be associated with each variable. Note that some flags are overloaded so that they mean different things according to how they are OR’ed with other flags.

Code:
#include <shell.h>
#include <nval.h>

#define SH_DICT "showvar"

static const char usage_showvar[] =
   "[-?\n@(#)$Id: showvar 2008-05-04 $\n]"
   "[-author?Finnbarr P. Murphy <fpmATiisc.com>]"
   "[-licence?http://www.opensource.org/licenses/cpl1.0.txt]"
   "[+NAME?showvar - display variable details]"
   "[+DESCRIPTION?\bshowvar\b displays details about the
                   specified variable.]"
   "[+OPTIONS?none.]"
   "\n"
   "\nvariable_name\n"
   "\n"
   "[+EXIT STATUS?] {"
        "[+0?Success.]"
        "[+>0?An error occurred.]"
   "}"
   "[+SEE ALSO?\bstat\b(2)]"
;

struct Flag {
   int flag;
   char *name;
};

/* Note: not a complete list of all possible flags */
struct Flag Flags[] = {
   NV_ARRAY,   "NV_ARRAY",
   NV_BINARY,  "NV_BINARY",
   NV_EXPORT,  "NV_EXPORT",
   NV_HOST,    "NV_HOST",
   NV_IMPORT,  "NV_IMPORT",
   NV_LJUST,   "NV_LJUST",
   NV_LTOU,    "NV_LTOU",
   NV_RAW,     "NV_RAW",
   NV_RDONLY,  "NV_RDONLY",
   NV_REF,     "NV_REF",
   NV_RJUST,   "NV_RJUST",
   NV_TABLE,   "NV_TABLE",
   NV_TAGGED,  "NV_TAGGED",
   NV_UTOL,    "NV_UTOL",
   NV_ZFILL,   "NV_ZFILL",
   0,(char *)NULL
};

struct Flag IntFlags[] = {
   NV_LTOU|NV_UTOL|NV_INTEGER,   "NV_UINT64",
   NV_LTOU|NV_RJUST|NV_INTEGER,  "NV_UINT16",
   NV_RJUST|NV_ZFILL|NV_INTEGER, "NV_FLOAT",
   NV_UTOL|NV_ZFILL|NV_INTEGER,  "NV_LDOUBLE",
   NV_RJUST|NV_INTEGER,          "NV_INT16",
   NV_LTOU|NV_INTEGER,           "NV_UINT32",
   NV_UTOL|NV_INTEGER,           "NV_INT64",
   NV_RJUST,                     "NV_SHORT",
   NV_UTOL,                      "NV_LONG",
   NV_LTOU,                      "NV_UNSIGN",
   NV_ZFILL,                     "NV_DOUBLE",
   NV_LJUST,                     "NV_EXPNOTE",
   NV_INTEGER,                   "NV_INT32(NV_INTEGER)",
   0,(char *)NULL
};

int
b_showvar(int argc, char *argv[], void *extra)
{
    Shell_t *shp = (Shell_t *)NULL;
    Namval_t *nvp = (Namval_t *)NULL;
    char *ptr = (char *)NULL;
    int i;

    while (i = optget(argv, usage_showvar)) switch(i) {
         case ':':
           error(2, "%s", opt_info.arg);
           break;
         case '?':
           errormsg(SH_DICT, ERROR_usage(2), "%s", opt_info.arg);
           break;
    }
    argc -= opt_info.index;
    argv += opt_info.index;

    if (argc != 1)
        errormsg(SH_DICT, ERROR_usage(2), "%s", optusage((char*)0));

    /* get current shell context */
    shp = sh_getinterp();

    if ((nvp = nv_search(*argv, shp->var_tree, 0)) == NULL) {
           errormsg(SH_DICT, ERROR_exit(1),
              "%s: variable not found", *argv);
        return(1);
    }

    if ((ptr = nv_getval(nvp)) == NULL) {
        errormsg(SH_DICT, ERROR_exit(3),
                "%s: variable is NULL", *argv);
        return(1);
    }

    sfprintf(sfstdout,
             "Value: %s, Flags: %d", ptr, (int)nvp->nvflag);
    if ((int)nvp->nvflag & NV_INTEGER) {
       for (i=0; IntFlags[i].name != NULL; i++) {
          if ((int)nvp->nvflag & IntFlags[i].flag) {
              sfprintf(sfstdout, " %s", IntFlags[i].name);
              break;
          }
       }
    }
    for (i=0; Flags[i].name != NULL; i++) {
        if ((int)nvp->nvflag & Flags[i].flag)
            sfprintf(sfstdout, " %s", Flags[i].name);
    }

    sfprintf(sfstdout,"\n");
    nv_close(nvp);

    return(0);
}

This User Gave Thanks to fpmurphy For This Post:
 

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

ksh93 deprecation...

Any means of running ksh93 in a ksh88-mode? Might sound odd, but I want/need to restrict U/Win-developed scripts to correspond to the ksh88 version on my Solaris environment(s). Thanks. (2 Replies)
Discussion started by: curleb
2 Replies

2. Shell Programming and Scripting

ksh88 or ksh93

Hi all! Does anybody know how can I check if any UNIX installation has implemented ksh88 or ksh93? Thanks in advance. Néstor. (3 Replies)
Discussion started by: Nestor
3 Replies

3. Shell Programming and Scripting

program name and function name builtins

Hi Is there a way to get the program/script name or function name usng built ins. Like in many languages arg holds the program name regards (2 Replies)
Discussion started by: xiamin
2 Replies

4. Programming

pthread_mutex_lock in ANSI C vs using Atomic builtins of GCC

I have a program which has 7-8 threads, and lots of shared variables; these variables (and also they may not the primitive type, they may be enum or struct ), then they may read/write by different threads at the same time. Now, my design is like this, typedef unsigned short int UINT16;... (14 Replies)
Discussion started by: sehang
14 Replies

5. Shell Programming and Scripting

Ksh93 vs. Pdksh88: Custom PS1 prompt not working

Greetings! I have to work with a NFS user id between two hosts: A running Ksh 93 and B running pdksh 88. My problem has to do with the custom prompt I created on A: it works like a charm and display colors: PS1="$'\E But I switch over to B, it all goes to hell (private info... (4 Replies)
Discussion started by: alan
4 Replies

6. UNIX for Dummies Questions & Answers

Why does /bin contain binaries for builtins?

Why do shell builtins like echo and pwd have binaries in /bin? When I do which pwd, I get the one in /bin. that means that I am not using the builtin version? What determines which one gets used? Is the which command a definitive way to determine what is being run when I enter pwd? (16 Replies)
Discussion started by: glev2005
16 Replies

7. UNIX for Dummies Questions & Answers

Shell and bash builtins...

Not sure if this is the right forum but I have collated a listing of shell and bash builtins. Builtins is a loose word and may include the '/bin' drawer/folder/directory but NOT any others in the path list. In the case of my Macbook Pro, OSX 10.7.5 the enabled internals is also listed... ... (1 Reply)
Discussion started by: wisecracker
1 Replies

8. UNIX for Advanced & Expert Users

Ksh93 on Linux compatible with ksh93 on AIX

Hi Experts, I have several shell scripts that have been developed on a Linux box for korn ksh93. If we want to run this software on an AIX 6.1 box that runs ksh88 by default can we just change the she-bang line to reference /bin/ksh93 which ships with AIX as its "enhanced shell" to ensure... (6 Replies)
Discussion started by: Keith Turley
6 Replies

9. Programming

Help w/ writing a custom Linux shell using x86 assembly (NASM)

Hello world, I thought this might be a great start to help me with an assignment I have that requires me to write an assembly program that mimics a 32 bit Linux command shell: When launched, your program will perform the following steps in a loop: 1. Print a prompt, specifically “$ “... (1 Reply)
Discussion started by: turtle13
1 Replies

10. AIX

Ksh93/AIX compatibility

Hi everyone ! Im trying to know from wich version of AIX KSH93 is available ? Internet tell me 6.x and 7.x AIX are available, bue what about 5.x ? Is KSH93 available on AIX 5.x ? Is it the same way to manipulate variables as KSH93 on 7.x ? Thanks for your support and have a nice day ! (2 Replies)
Discussion started by: majinfrede
2 Replies
All times are GMT -4. The time now is 08:37 AM.
Unix & Linux Forums Content Copyright 1993-2022. All Rights Reserved.
Privacy Policy