Whamcloud - gitweb
import older libsysio snapshot.
[fs/lustre-release.git] / libsysio / tests / sysio_tests.c
1 #define _BSD_SOURCE
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <getopt.h>
7 #include <errno.h>
8 #include <ctype.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <sys/statvfs.h>
12 #include <fcntl.h>
13 #include <sys/queue.h>
14 #include <dirent.h>
15
16 #include "sysio.h"
17 #include "mount.h"
18 #include "test.h"
19 #include "test_driver.h"
20
21 /*
22  * ###################################################
23  * # Test functions                                  #
24  * #  These functions are used to test libsysio.     #
25  * #  Eventually, there should be one of these for   #
26  * #  every function document in sysio.h             #
27  * ###################################################
28  */
29 int initilize_sysio()
30 {
31   char *wd;
32  
33   /* 
34    * Attempt to set the cwd by getting it out of the
35    * user's environment.  If that does not work, set
36    * it to /
37    */
38   wd = getenv("PWD");
39   if (wd == NULL) {
40     wd = malloc(5);
41     strcpy(wd, "/");
42   }
43   if (chdir(wd) != 0) {
44     DBG(5, sprintf(output, "%schdir: errno %d\n", output, errno));
45     my_perror(wd);
46     my_errno = errno;
47     last_ret_val = errno;
48     return SUCCESS;
49   }
50
51   DBG(3, sprintf(output, "Your current working directory is %s\n", wd));
52   last_ret_val = 0;
53   return SUCCESS;
54 }
55
56
57 int sysio_list(char *path)
58 {
59   int   fd;
60   size_t        n;
61   struct dirent *buf, *dp;
62   __off_t       base;
63   ssize_t       cc;
64   int numfiles = 0;
65
66   fd = open(path, O_RDONLY);
67   if (fd < 0) {
68     my_errno = errno;
69     last_ret_val = fd;
70     my_perror(path);
71     return SUCCESS;
72   }
73   
74   n = 16 * 1024;
75   buf = malloc(n);
76   if (!buf) {
77     my_perror(path);
78     cc = -1;
79     goto out;
80   }
81   base = 0;
82   DBG(5, sprintf(output, "About to call getdirentries\n"));
83   while ((cc = getdirentries(fd, (char *)buf, n, &base)) > 0) {
84     dp = buf;
85     while (cc > 0) {
86       DBG(4, fprintf(outfp, "\t%s: ino %#08x off %#08x type %#08x\n",
87                      dp->d_name,
88                      (unsigned int)dp->d_ino,
89                      (unsigned int)dp->d_off,
90                      (int )dp->d_type));
91       
92       sprintf(output, "%s\n", dp->d_name);
93       cc -= dp->d_reclen;
94       dp = (struct dirent *)((char *)dp + dp->d_reclen);
95       numfiles++;
96     }
97     printf("Out of inner loop\n");
98     if (!base)
99       break;
100   }
101
102  out:
103   if (cc < 0) {
104     DBG(2, sprintf(output, "cc barfed\n"));
105     my_perror(path);
106   }
107   
108   free(buf);
109   {
110     int oerrno = errno;
111     
112     if (close(fd) != 0) {
113       DBG(2,sprintf(output, "close barfed\n"));
114       my_perror(path);
115       if (cc < 0)
116         errno = oerrno;
117       else
118         cc = -1;
119     }
120   }
121
122   last_ret_val = numfiles;
123   my_errno = errno;
124
125   return SUCCESS;
126 }
127
128 int sysio_mount(char *from, char *to)
129 {
130   int   err;
131   char  *s;
132   char  *buf;
133   char  *cp;
134   char  *fstype, *source, *opts, *target;
135
136   err = 0;
137
138   /*
139    * Copy everything to a buffer we can modify.
140    */
141   s = buf = malloc(strlen(from) + 1);
142   if (!buf) {
143     my_perror(from);
144     last_ret_val = -1;
145     my_errno = errno;
146     return SUCCESS;
147   }
148   (void )strcpy(s, from);
149   
150   /*
151    * Eat leading white.
152    */
153    while (*s && *s == ' ' && *s == '\t')
154      s++;
155   /*
156    * Get fstype.
157    */
158    fstype = cp = s;
159    while (*cp && *cp != ':' && *cp != ' ' && *cp != '\t')
160      cp++;
161    if (fstype == cp || *cp != ':') {
162      DBG(1, sprintf(output, "%s: Missing FS type\n", from));
163      err = -1;
164      goto out;
165    }
166   *cp++ = '\0';
167
168   s = cp;
169   /*
170    * Eat leading white.
171    */
172    while (*s && *s == ' ' && *s == '\t')
173      s++;
174   /*
175    * Get source.
176    */
177    source = cp = s;
178    while (*cp && *cp != ' ' && *cp != '\t')
179      cp++;
180    if (source == cp) {
181      DBG(1, sprintf(output, "%s: Missing source\n", from));
182      err = -1;
183      goto out;
184    }
185    if (*cp)
186      *cp++ = '\0';
187
188    s = to;
189    /*
190     * Eat leading white.
191     */
192     while (*s && *s == ' ' && *s == '\t')
193       s++;
194    /*
195     * Get opts.
196     */
197     opts = cp = s;
198     while (*cp && *cp != ' ' && *cp != '\t')
199       cp++;
200     if (opts == cp) {
201       DBG(1,sprintf(output, "%s: Missing target\n", to));
202       err = -1;
203       goto out;
204     }
205     if (*cp)
206       *cp++ = '\0';
207
208     s = cp;
209     /*
210      * Eat leading white.
211      */
212      while (*s && *s == ' ' && *s == '\t')
213        s++;
214     /*
215      * Get target
216      */
217      target = cp = s;
218      while (*cp && *cp != ' ' && *cp != '\t')
219        cp++;
220      if (target == cp) {
221        target = opts;
222        opts = NULL;
223      }
224      if (*cp)
225        *cp++ = '\0';
226
227      err = mount(source, target, fstype, 0, opts);
228      if (err)
229        my_perror(from);
230
231 out:
232      free(buf);
233      last_ret_val = err;
234      my_errno = errno;
235      return SUCCESS;
236 }
237
238 int sysio_chdir(char *newdir) 
239 {
240
241   if (chdir(newdir) != 0) {
242     my_perror(newdir);
243     return -1;
244   }
245   /*  
246   buf = getcwd(NULL, 0);
247   if (!buf) {
248     my_perror(newdir);
249     last_ret_val = -1;
250     my_errno = errno;
251     return SUCCESS;
252   }
253   DBG(4, sprintf(output, "New dir is %s\n", buf));
254
255   free(buf);
256   */
257   return SUCCESS;
258 }
259
260 static mode_t get_mode(char *arg, int type, int start_mode);
261
262 #define SYMBOLIC 0
263 #define DEFINED  1
264 #define NUMERIC  2 
265 /*
266  * Change the permissions on a given file
267  *
268  * sysio_chmod <filename> <permissions>
269  *
270  */
271 int sysio_chmod(char *mode_arg, const char *path) 
272 {
273   int   err;
274   mode_t mode;
275   struct stat st;
276
277   /* Get the current mode */
278   err = stat(path, &st);
279
280   /* Is the new mode symbolic? */
281   if (isalpha(mode_arg[0])) {
282     /* Could be specifying defines */
283     if (mode_arg[0] == 'S')
284       mode = get_mode(mode_arg, DEFINED, st.st_mode);
285     else
286       mode = get_mode(mode_arg, SYMBOLIC, st.st_mode);
287   } else 
288     mode = get_mode(mode_arg, NUMERIC, st.st_mode);
289   DBG(3,sprintf(output, "Using a mode of %o and a file of %s\n", mode, path));
290
291   if (mode == 0) {
292     DBG(2,sprintf(output, "Invalid mode\n"));
293     return INVALID_ARGS;
294   }
295
296   last_ret_val = chmod(path, mode);
297   my_errno = errno;
298   return SUCCESS;
299   
300 }
301
302
303 #define USER_STATE 0 /* Specifies that the users are still being listed */
304 #define MODE_STATE_ADD 1 
305 #define MODE_STATE_REMOVE 2 
306         
307 #define READ    00444
308 #define WRITE   00222
309 #define EXECUTE 00111
310
311 #define OWNER  00700
312 #define GROUP  00070
313 #define OTHER  00007
314
315   
316 mode_t
317 get_mode(char *arg, int type, int start_mode) 
318 {
319   int i, j,digit, total;
320   char c;
321   int state = USER_STATE;
322   int len = strlen(arg);
323   unsigned int users = 0;
324   unsigned int modes = 0;
325
326
327   if (type == DEFINED) {
328     char curr_word[10];
329
330     total = digit = 0;
331     j = 0;
332     DBG(4, sprintf(output, "len is %d\n", len));
333     for (i=0; i < len; i++) {
334       if (arg[i] == '|') {
335         curr_word[j] = '\0';
336         DBG(3, sprintf(output, "Got mode word %s\n", curr_word));
337         digit = get_obj(curr_word);
338         if (digit < 0 ) {
339           DBG(2, sprintf(output, "Unable to understand mode arg %s\n",
340                          curr_word));
341           return -1;
342         } 
343         total |= digit;
344         j = 0;
345       } else 
346         curr_word[j++] = arg[i];
347     }
348     curr_word[j] = '\0';
349     DBG(3, sprintf(output, "Got mode word %s\n", curr_word));
350     digit = get_obj(curr_word);
351     if (digit < 0 ) {
352       DBG(3, sprintf(output, "Unable to understand mode arg %s\n",
353              curr_word));
354       return -1;
355     } 
356     total |= digit;
357     return total;
358   }
359       
360   if (type == SYMBOLIC) {
361     for (i=0; i < len; i++) {
362       c = arg[i];
363       if (state == USER_STATE) {
364         switch(c){
365         case 'u':
366           users |= OWNER;
367           break;
368         case 'g':
369           users |= GROUP;
370           break;
371         case 'o':
372           users |= OTHER;
373           break;
374         case 'a':
375           users |= (OWNER|GROUP|OTHER);
376           break;
377         case '+':
378           state = MODE_STATE_ADD;
379           break;
380         case '-':
381           state = MODE_STATE_REMOVE;
382           break;
383         default:
384           return 0;
385         }
386       } else {
387
388         switch(c){
389         case 'r':
390           modes |= READ;
391           break;
392         case 'w':
393           modes |= WRITE;
394           break;
395         case 'x':
396           modes |= EXECUTE;
397           break;
398         default:
399           return 0;
400         }
401       }
402     }
403
404     if (state == MODE_STATE_ADD) {
405       return (start_mode | (users & modes));
406     } else {
407       return (start_mode & ~(users & modes));
408     }
409
410   } else {
411     /* Digits should be octal digits, so should convert */
412     total = 0;
413     for (i=0; i < len; i++) {
414       c = arg[i];
415       digit = atoi(&c);
416       if (digit > 7)
417         return 0;
418       for (j=len-i-1; j >0; j--)
419         digit *= 8;
420       total += digit;
421     }
422     return total;
423   }
424  
425 }
426
427 /*
428  * Changes the ownership of the file.  The new_id
429  * is of the format owner:group.  Either the owner
430  * or the group may be omitted, but, in order to 
431  * change the group, the : must preced the group.
432  */
433 int sysio_chown(char *new_id, char *file)
434 {
435   char *owner = NULL;
436   char *group = NULL;
437   uid_t o_id=-1, g_id=-1;
438   int len, j, i=0;
439   int state = 0; /* Correspond to getting owner name */
440   
441   len = strlen(new_id);
442   for (i=0; i < len; i++) {
443
444     if (new_id[i] == ':') {
445       /* Group name */
446       if (!group) 
447                                 group = malloc(strlen(new_id) -i +2);
448       state = 1; /* Now getting group name */
449       j = 0;
450       if (owner)
451                                 owner[i] = '\0';
452     }
453                 
454     if (!state) {
455       /* Getting owner name */
456       if (!owner)
457                                 owner = malloc(strlen(new_id) +1 ); 
458       owner[i] = new_id[i];
459     } else {
460       /* Group name */
461       group[j] = new_id[i];
462       j++;
463     }
464   }
465   if (group)
466     group[i] = '\0';
467   else
468     owner[i] = '\0';
469
470   /* Are the owner and/or group symbolic or numeric? */
471   if (owner) {
472     if (isdigit(owner[0])) {
473       /* Numeric -- just convert */
474       o_id = (uid_t) atoi(owner);
475
476                 } else {
477       /* No longer support non-numeric ids */
478                         
479                         DBG(2, sprintf(output, "Error: non-numeric ids unsupported\n"));
480                         return INVALID_ARGS;
481     }
482   }
483
484
485
486   if (group) {
487     if (isdigit(group[0])) {
488       /* Numeric -- just convert */
489       g_id = (uid_t) atoi(group);
490                 } else {
491       /* Don't support group names either */
492                         DBG(2, sprintf(output, "Error: non-numeric ids unsupported\n"));
493                         return INVALID_ARGS;
494     }
495   }
496
497   /* Now issue the syscall */
498   DBG(4, sprintf(output, "Changing owner of file %s to %d (group %d)\n",
499                  file, o_id, g_id));
500  
501   last_ret_val = chown(file, o_id, g_id);
502   my_errno = errno;
503   return SUCCESS;
504 }
505
506 int sysio_open(char *path, int flags)
507 {
508   last_ret_val = open(path, flags);
509   my_errno = errno;
510   DBG(3, sprintf(output, "Returning with errno set to %s (ret val is %d)\n", 
511                  strerror(my_errno), (int)last_ret_val));
512   return SUCCESS;
513 }
514
515 int sysio_open3(char *path, int flags, char *mode_arg)
516 {
517   mode_t mode;
518
519   /* Is the new mode symbolic? */
520   if (isalpha(mode_arg[0])) {
521     /* Could be specifying defines */
522     if (mode_arg[0] == 'S')
523       mode = get_mode(mode_arg, DEFINED, 0);
524     else
525       mode = get_mode(mode_arg, SYMBOLIC, 0);
526   } else 
527     mode = get_mode(mode_arg, NUMERIC, 0);
528   
529   last_ret_val = open(path, flags, mode);
530   my_errno = errno;
531   
532   return SUCCESS;
533 }
534
535 int sysio_close(int fd)
536 {
537
538   last_ret_val = close(fd);
539   my_errno = errno;
540   return SUCCESS;
541 }
542
543 int sysio_fcntl(int fd, struct cmd_map* cmdptr, char *arg)
544 {
545   int fd_new, index, cmd, flag;
546   char *cmdname;
547   void *buf;
548
549   cmd = cmdptr->cmd;
550   cmdname = cmdptr->cmd_name;
551
552   switch(cmd) {
553   case F_DUPFD:
554     fd_new = get_obj(arg);
555     last_ret_val = fcntl(fd, F_DUPFD, fd_new);
556     my_errno = errno;
557     return SUCCESS;
558     break;
559
560   case F_GETFD:
561   case F_GETFL:
562   case F_GETOWN:
563     /* case F_GETSIG:
564        case F_GETLEASE: */
565
566     last_ret_val= fcntl(fd, cmd);
567     my_errno = errno;
568     return SUCCESS;
569     break;
570
571   case F_SETFD:    
572   case F_SETFL:
573   case F_SETOWN:
574     /*case F_SETSIG:
575     case F_SETLEASE:
576     case F_NOTIFY: */
577     flag = atoi(arg);
578     last_ret_val =  fcntl(fd, cmd, flag);
579     my_errno = errno;
580     return SUCCESS;
581     break;
582
583   case F_SETLK:
584   case F_SETLKW:
585   case F_GETLK:
586   
587      /* Get the buffer to hold the lock structure */
588      index = get_obj(arg);
589      if (index < 0) {
590        sprintf(output, "Unable to find buffer %s\n", arg+1);
591        return INVALID_VAR;
592      }
593
594      buf = buflist[index];
595      if (!buf) {
596        sprintf(output, "Buffer at index %d (mapped by %s) is null\n",
597               index, arg);
598        return INVALID_VAR;
599      }
600
601      last_ret_val = fcntl(fd, cmd, (struct flock *)buf);
602      my_errno = errno;
603     return SUCCESS;
604   default:
605     /* THis should be impossible */
606     return INVALID_ARGS;
607   }
608
609   return INVALID_ARGS;
610 }
611
612 void print_stat(struct stat *st)
613 {
614   DBG(3, sprintf(output, "%sstruct stat: \n", output));
615   DBG(3, sprintf(output, "%s  st_dev: %#16x\n", output, (unsigned int)st->st_dev));
616   DBG(3, sprintf(output, "%s  st_ino: %#16x\n", output, (unsigned int) st->st_ino));
617   DBG(3, sprintf(output, "%s  st_mode: %#16x\n", output, st->st_mode));
618   DBG(3, sprintf(output, "%s  st_nlink: %#16x\n", output, (int)st->st_nlink));
619   DBG(3, sprintf(output, "%s  st_uid: %#16x\n", output, st->st_uid));
620   DBG(3, sprintf(output, "%s  st_gid: %#16x\n", output, st->st_gid));
621   DBG(3, sprintf(output, "%s  st_rdev: %#16x\n", output, (int)st->st_rdev));
622   DBG(3, sprintf(output, "%s  st_size: %#16x\n", output, (int) st->st_size));
623   DBG(3, sprintf(output, "%s  st_blksize: %#16x\n", output, (int) st->st_blksize));
624   DBG(3, sprintf(output, "%s  st_blocks: %#16x\n", output, (int) st->st_blocks));
625   DBG(3, sprintf(output, "%s  st_atime: %#16x\n", output, (unsigned int) st->st_atime));
626   DBG(3, sprintf(output, "%s  st_mtime: %#16x\n", output, (unsigned int) st->st_mtime));
627   DBG(3, sprintf(output, "%s  st_ctime: %#16x", output, (unsigned int) st->st_ctime));
628 }
629
630 int sysio_fstat(int fd, void *buf)
631 {
632   int err;
633   struct stat *st = (struct stat *)buf;
634   err = fstat(fd, st); 
635   if (err < 0) {
636     my_perror("fstat");
637   }
638   my_errno = errno;
639   last_ret_val = err;
640   print_stat(st);
641
642   return SUCCESS;
643 }
644
645 int sysio_lstat(char *filename, void *buf)
646 {
647   int err;
648   struct stat *st = (struct stat *)buf;
649   err = lstat(filename, st); 
650   if (err < 0) {
651     my_perror("lstat");
652   }
653
654   my_errno = errno;
655   last_ret_val = err;
656   print_stat(st);
657   return SUCCESS;
658 }
659
660
661 int sysio_stat(char *filename, void *buf)
662 {
663   int err;
664   struct stat *st = (struct stat *)buf;
665
666   err = stat(filename, st); 
667   if (err < 0) {
668     my_perror("stat");
669   }
670
671   my_errno = errno;
672   last_ret_val = err;
673   print_stat(st);
674   return SUCCESS;
675 }
676
677
678 int sysio_getdirentries(int fd, char *buf, size_t nbytes, off_t *basep)
679 {
680   int err;
681   struct dirent *dp;
682
683   err = getdirentries(fd, buf, nbytes, basep); 
684   last_ret_val = err;
685  
686   DBG(4, sprintf(output, "%sRead %d bytes\n", output, err));
687
688   dp = (struct dirent *)buf;
689   while (err > 0) {
690       DBG(3, sprintf(output, "%s\t%s: ino %llu off %llu len %x type %c\n",
691                      output,
692                      dp->d_name,
693                      (unsigned long long )dp->d_ino,
694                      (unsigned long long )dp->d_off,
695                      dp->d_reclen,
696                     (char )dp->d_type));
697       err -= dp->d_reclen;
698       dp = (struct dirent *)((char *)dp + dp->d_reclen);
699   }
700
701   my_errno = errno;
702   return last_ret_val;
703 }
704
705
706 int sysio_mkdir(char *path, char *mode_arg) 
707 {
708   int   err;
709   mode_t mode;
710   struct stat st;
711
712   /* Is the new mode symbolic? */
713   if (isalpha(mode_arg[0])) {
714     /* Could be specifying defines */
715     if (mode_arg[0] == 'S')
716       mode = get_mode(mode_arg, DEFINED, st.st_mode);
717     else
718       mode = get_mode(mode_arg, SYMBOLIC, st.st_mode);
719   } else 
720     mode = get_mode(mode_arg, NUMERIC, st.st_mode);
721
722   DBG(3, sprintf(output, "Using a mode of %o and a file of %s\n", mode, path));
723
724   if (mode == 0) {
725     DBG(2, sprintf(output, "Invalid mode\n"));
726     return INVALID_ARGS;
727   }
728
729   err = mkdir(path, mode);
730   my_errno = errno;
731   last_ret_val = err;
732   return SUCCESS;
733   
734 }
735
736 int sysio_creat(char *path, char *mode_arg) 
737 {
738   mode_t mode;
739   int err;
740
741   /* Is the new mode symbolic? */
742   if (isalpha(mode_arg[0])) {
743     /* Could be specifying defines */
744     if (mode_arg[0] == 'S')
745       mode = get_mode(mode_arg, DEFINED, 0);
746     else
747       mode = get_mode(mode_arg, SYMBOLIC, 0);
748   } else 
749     mode = get_mode(mode_arg, NUMERIC, 0);
750
751   DBG(3, sprintf(output, "Using a mode of %o and a file of %s\n", mode, path));
752
753   if (mode == 0) {
754     DBG(2, sprintf(output, "Invalid mode\n"));
755     return INVALID_ARGS;
756   }
757
758   err = creat(path, mode);
759   my_errno = errno;
760   last_ret_val = err;
761   return SUCCESS;
762 }
763
764 void print_statvfs(struct statvfs *st)
765 {
766   DBG(3, sprintf(output, "%sstruct statvfs: \n", output));
767   DBG(3, sprintf(output, "%s  f_bsize: %x\n", output, (unsigned int) st->f_bsize));
768   DBG(3, sprintf(output, "%s  f_frsize: %x\n", output, (unsigned int) st->f_frsize));
769   DBG(3, sprintf(output, "%s  f_blocks: %x\n", output, (unsigned int) st->f_blocks));
770   DBG(3, sprintf(output, "%s  f_bfree: %x\n", output, (unsigned int) st->f_bfree));
771   DBG(3, sprintf(output, "%s  f_bavail: %x\n", output, (unsigned int) st->f_bavail));
772   DBG(3, sprintf(output, "%s  f_files: %x\n", output, (unsigned int) st->f_files));
773   DBG(3, sprintf(output, "%s  f_ffree: %x\n", output, (unsigned int) st->f_ffree));
774   DBG(3, sprintf(output, "%s  f_favail: %x\n", output, (unsigned int) st->f_favail));
775   DBG(3, sprintf(output, "%s  f_files: %x\n", output, (unsigned int) st->f_files));
776 #if (__GLIBC__  == 2 && __GLIBC_MINOR__ == 1)
777   DBG(3, sprintf(output, "%s  f_fsid: %x\n", output, (unsigned int) st->f_fsid.__val[1]));
778 #else
779  DBG(3, sprintf(output, "%s  f_fsid: %x\n", output, (unsigned int) st->f_fsid));
780 #endif
781   DBG(3, sprintf(output, "%s  f_flag: %x\n", output, (unsigned int) st->f_flag));
782   DBG(3, sprintf(output, "%s  f_fnamemax: %x\n", output, (unsigned int) st->f_namemax));
783 }
784
785
786 int sysio_statvfs(char *filename, void *buf)
787 {
788   int err;
789   struct statvfs *st = (struct statvfs *)buf;
790   
791   err = statvfs(filename, st); 
792   if ( err == -1) { 
793     my_perror("statvfs");
794   }
795
796   my_errno = errno;
797   last_ret_val = err;
798
799   print_statvfs(st);
800   return SUCCESS;
801 }
802
803 int sysio_fstatvfs(int fd, void *buf)
804 {
805   int err;
806   struct statvfs *st = (struct statvfs *)buf;
807
808   err = fstatvfs(fd, st);
809   if (err == -1) { 
810     my_perror("fstatvfs");
811   }
812
813   my_errno = errno;
814   last_ret_val = err;
815
816   print_statvfs(st);
817   return SUCCESS;
818 }
819
820 int sysio_umask(char *mode_arg)
821 {
822   mode_t mode;
823
824    /* Is the new mode symbolic? */
825   if (isalpha(mode_arg[0])) {
826     /* Could be specifying defines */
827     if (mode_arg[0] == 'S')
828       mode = get_mode(mode_arg, DEFINED, 0);
829     else
830       mode = get_mode(mode_arg, SYMBOLIC, 0);
831   } else 
832     mode = get_mode(mode_arg, NUMERIC, 0);
833
834   last_ret_val = umask(mode);
835   my_errno = errno;
836   return SUCCESS;
837 }
838
839 int sysio_mknod(char *path, char *mode_arg, dev_t dev)
840 {
841   int err;
842   int mode;
843
844   mode = get_obj(mode_arg);
845   
846   if (mode < 0) {
847     DBG(2,sprintf(output, "Cant get mode from %s\n", mode_arg));
848     fprintf(stderr, "Cant get mode from %s\n", mode_arg);
849     return INVALID_VAR;
850   }
851
852   err = mknod(path, (mode_t) mode, dev);
853   if (err < 0)
854     my_perror("mknod");
855
856   last_ret_val = err;
857   my_errno = errno;
858   return SUCCESS;
859 }