Hey List,

I've been playing with stat() and lstat() in the past few days and
things seem to be weird.

I made two test programs to demonstrate the problem.  The first is
written in C and behaves correctly, the second is written in C# and is
quite abnormal.  I attached both of them.


Let's see the test results on a socket file:


$ stattest-c /home/laci/.gnome-system-monitor.laci
filename: /home/laci/.gnome-system-monitor.laci

stat
        is_file: false
        is_dir: false
        is_fifo: false
        is_sock: true
        is_chardev: false
        is_blockdev: false

lstat
        is_file: false
        is_dir: false
        is_fifo: false
        is_sock: true
        is_chardev: false
        is_blockdev: false

$ mono StatTest.exe /home/laci/.gnome-system-monitor.laci
filename: /home/laci/.gnome-system-monitor.laci

stat
        is_file: true
        is_dir: true
        is_fifo: false
        is_sock: true
        is_chardev: false
        is_blockdev: false

lstat
        is_file: true
        is_dir: true
        is_fifo: false
        is_sock: true
        is_chardev: false
        is_blockdev: false

Somebody could explain what's wrong with
Mono.Unix.Native.Syscall.(l)stat?

Thanks in advance!

-- 
Laci

    Blog: http://monda.hu/~laci/blog
    Home: http://mondalaci.objectis.net

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>

void dostat(mode_t mode)
{
    printf("\tis_file: %s\n", S_ISREG(mode) ? "true" : "false");
    printf("\tis_dir: %s\n", S_ISDIR(mode) ? "true" : "false");
    printf("\tis_fifo: %s\n", S_ISFIFO(mode) ? "true" : "false");
    printf("\tis_sock: %s\n", S_ISSOCK(mode) ? "true" : "false");
    printf("\tis_chardev: %s\n", S_ISCHR(mode) ? "true" : "false");
    printf("\tis_blockdev: %s\n\n", S_ISBLK(mode) ? "true" : "false");
}

int main(int argc, char *argv[])
{
    if (argc == 1) {
	printf("You should provide a filename to stat.\n");
	exit(1);
    }

    char *filename = argv[1];
    struct stat *st = (struct stat*)malloc(sizeof(stat));
    mode_t mode;
    
    printf("filename: %s\n\n", filename);

    printf("stat\n");
    stat(filename, st);
    mode = st->st_mode;
    dostat(mode);

    printf("lstat\n");
    lstat(filename, st);
    mode = st->st_mode;
    dostat(mode);
}
using System;
using MUN = Mono.Unix.Native;

public class StatText {
    public static void Main(string[] argv)
    {
	if (argv.Length == 0) {
	    Console.WriteLine("You need to provide to filename to stat.");
	    System.Environment.Exit(1);
	}

	string filename = argv[0];
	MUN.Stat stat;

	Console.WriteLine("filename: {0}\n", filename);

	Console.WriteLine("stat");
	MUN.Syscall.stat(filename, out stat);
	dostat(stat);

	Console.WriteLine("lstat");
	MUN.Syscall.lstat(filename, out stat);
	dostat(stat);
    }
    
    static void dostat(MUN.Stat stat)
    {
	bool is_file = (stat.st_mode & MUN.FilePermissions.S_IFREG) == MUN.FilePermissions.S_IFREG;
	bool is_dir = (stat.st_mode & MUN.FilePermissions.S_IFDIR) == MUN.FilePermissions.S_IFDIR;
	bool is_fifo = (stat.st_mode & MUN.FilePermissions.S_IFIFO) == MUN.FilePermissions.S_IFIFO;
	bool is_sock = (stat.st_mode & MUN.FilePermissions.S_IFSOCK) == MUN.FilePermissions.S_IFSOCK;
	bool is_chardev = (stat.st_mode & MUN.FilePermissions.S_IFCHR) == MUN.FilePermissions.S_IFCHR;
	bool is_blockdev = (stat.st_mode & MUN.FilePermissions.S_IFBLK) == MUN.FilePermissions.S_IFBLK;

	Console.WriteLine("\tis_file: {0}", is_file ? "true" : "false");
	Console.WriteLine("\tis_dir: {0}", is_dir ? "true" : "false");
	Console.WriteLine("\tis_fifo: {0}", is_fifo ? "true" : "false");
	Console.WriteLine("\tis_sock: {0}", is_sock ? "true" : "false");
	Console.WriteLine("\tis_chardev: {0}", is_chardev ? "true" : "false");
	Console.WriteLine("\tis_blockdev: {0}\n", is_blockdev ? "true" : "false");
    }
}
_______________________________________________
Mono-list maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-list

Reply via email to