⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filestat.c

📁 地震波正演和显示模块
💻 C
字号:

/*********************** self documentation **********************/
/***************************************************************************
FILESTAT - Functions to determine and output the type of a file from file
		 descriptor

filestat - determine type of file from file descriptor
printstat - print the FileType as a string

****************************************************************************
Function Prototypes:
FileType filestat(int fd);
char *printstat(int fd);

****************************************************************************
filestat:
Input:
fd		file descriptor

Returns:	FileType filestat(fd)

****************************************************************************
printstat:
Input:
fd		file descriptor

Returns:	char *printstat(fd)

****************************************************************************
Notes:

Example:
	FileType ftype;
	...
	ftype = filestat(STDOUT)
	if (ftype = TTY) {
		...


BADFILETYPE is the error return and it is up to the calling program to
check for it.

FileType is defined in par.h as:
typedef enum {BADFILETYPE = -1,
   TTY, DISK, DIRECTORY, TAPE, PIPE, FIFO, SOCKET, SYMLINK} FileType;

SOCKETS and SYMLINKS are unlikely to be used.


***************************************************************************/
/**************** end self doc ********************************/

#ifndef __USE_BSD
#define __USE_BSD 1
#endif

#include "../include/par.h"
#include <sys/stat.h>

#ifdef __S_IFMT
#define S_IFMT __S_IFMT
#endif
#ifdef __S_IFREG
#define S_IFREG __S_IFREG
#endif
#ifdef __S_IFDIR
#define S_IFDIR __S_IFDIR
#endif
#ifdef __S_IFIFO
#define S_IFIFO __S_IFIFO
#endif
#ifdef __S_IFSOCK
#define S_IFSOCK __S_IFSOCK
#endif
#ifdef __S_IFLNK
#define S_IFLNK __S_IFLNK
#endif

#ifndef major	/* major() is a macro for getting the major device number */
#include <sys/sysmacros.h>
#endif

/* determine type of file (DISK, PIPE, ...) */
FileType filestat(int fd)
{
	struct stat sfd;	/* for passed fd	*/
	struct stat sdn;	/* for /dev/null	*/
	struct stat smt;	/* for tape devices	*/


	if (-1 == fstat(fd, &sfd))  return BADFILETYPE;

	/* UNIX subroutine */
	if (isatty(fd))  return TTY;

	/* Standard stat test for regular file */
	if ((sfd.st_mode & S_IFMT) == S_IFREG) return DISK;

	/* Standard stat test for directory */
	if ((sfd.st_mode & S_IFMT) == S_IFDIR) return DIRECTORY;

	/* Only pipes have 0 links (might be FIFO too, so this test first) */
	if (!sfd.st_nlink) return PIPE;

	/* Standard stat test for FIFO */
	if ((sfd.st_mode & S_IFMT) == S_IFIFO) return FIFO;

	/* Standard stat test for socket */
	if ((sfd.st_mode & S_IFMT) == S_IFSOCK) return SOCKET;

	/* Standard stat test for symbolic link */
	if ((sfd.st_mode & S_IFMT) == S_IFLNK) return SYMLINK;

	/* Detect tape by comparing its major device number to	*/
	/* /dev/rmt0 (this is not quite portable).  		*/
	if (0 == stat("/dev/rmt0", &smt) &&
	     major(sfd.st_rdev) == major(smt.st_rdev)) return TAPE;
	if (0 == stat("/dev/mt0", &smt) &&
	     major(sfd.st_rdev) == major(smt.st_rdev)) return TAPE;

	/* Detect file as /dev/null by its device number and	*/
	/* classify it as a disk file.				*/
	if (0 == stat("/dev/null", &sdn) &&
		sfd.st_rdev == sdn.st_rdev) return DISK;

	/* error return */
	return BADFILETYPE;
}


/* Supply ascii string describing type of file */
char *printstat(int fd)
{
	switch (filestat(fd)) {
		case TTY:	return "TTY";
		case DISK:	return "DISK";
		case DIRECTORY:	return "DIRECTORY";
		case TAPE:	return "TAPE";
		case PIPE:	return "PIPE";
		case FIFO:	return "FIFO";
		case SOCKET:	return "SOCKET";
		case SYMLINK:	return "SYMLINK";
		default:	return "BADFILETYPE";
	}
}


#ifdef TEST

/* Test driver for function filestat
 *
 * Here are some tests using filestat to analyse STDIN, STDOUT and
 * the first command line argument along with the expected results:
 *	filestat filestat.c
 *		expect: TTY, TTY, DISK
 *	filestat <filestat.c /usr/local | cat
 *		expect: DISK, PIPE, DIRECTORY
 *	cat filestat.c | filestat filestat.c >/usr/tmp/junkxxx
 *		expect: PIPE, DISK, DISK
 *	filestat /dev/null
 *		expect: TTY, TTY, DISK
 *	filestat
 *		expect: TTY, TTY, "no filename given"
 */

main(int argc, char **argv)
{
	static FileType ftype;
	int fd;


	fprintf(stderr, "Checking filestat ...\n");
	/* Get FileType of stdin	*/
	switch (ftype = filestat(STDIN)) {
	case TTY:
		fprintf(stderr, "FileType(STDIN) = TTY\n");
	break;
	case DISK:
		fprintf(stderr, "FileType(STDIN) = DISK\n");
	break;
	case DIRECTORY:
		fprintf(stderr, "FileType(STDIN) = DIRECTORY\n");
	break;
	case TAPE:
		fprintf(stderr, "FileType(STDIN) = TAPE\n");
	break;
	case PIPE:
		fprintf(stderr, "FileType(STDIN) = PIPE\n");
	break;
	case FIFO:
		fprintf(stderr, "FileType(STDIN) = FIFO\n");
	break;
	case SOCKET:
		fprintf(stderr, "FileType(STDIN) = SOCKET\n");
	break;
	case SYMLINK:
		fprintf(stderr, "FileType(STDIN) = SYMLINK\n");
	break;
	case BADFILETYPE:
		fprintf(stderr, "FileType(STDIN) = BADFILETYPE\n");
	break;
	default:
	    fprintf(stderr, "filestat(stdin) failed: ftype = %d\n", ftype);
	}


	/* Get FileType of stdout	*/
	switch (ftype = filestat(STDOUT)) {
	case TTY:
		fprintf(stderr, "FileType(STDOUT) = TTY\n");
	break;
	case DISK:
		fprintf(stderr, "FileType(STDOUT) = DISK\n");
	break;
	case DIRECTORY:
		fprintf(stderr, "FileType(STDOUT) = DIRECTORY\n");
	break;
	case TAPE:
		fprintf(stderr, "FileType(STDOUT) = TAPE\n");
	break;
	case PIPE:
		fprintf(stderr, "FileType(STDOUT) = PIPE\n");
	break;
	case FIFO:
		fprintf(stderr, "FileType(STDIN) = FIFO\n");
	break;
	case SOCKET:
		fprintf(stderr, "FileType(STDIN) = SOCKET\n");
	break;
	case BADFILETYPE:
		fprintf(stderr, "FileType(STDOUT) = BADFILETYPE\n");
	break;
	default:
	    fprintf(stderr, "filestat(stdout) failed: ftype = %d\n", ftype);
	}

	/* Get FileType of argv[1]	*/
	if (argc == 1) {
		fprintf(stderr, "no filename given\n");
		exit(1);
	}
	if (-1 == (fd = open(argv[1], O_RDONLY))) {
		fprintf(stderr, "can't open %s", argv[1]);
		exit(2);
	}

	switch (ftype = filestat(fd)) {
	case TTY:
		fprintf(stderr, "FileType(fd) = TTY\n");
	break;
	case DISK:
		fprintf(stderr, "FileType(fd) = DISK\n");
	break;
	case DIRECTORY:
		fprintf(stderr, "FileType(fd) = DIRECTORY\n");
	break;
	case TAPE:
		fprintf(stderr, "FileType(fd) = TAPE\n");
	break;
	case PIPE:
		fprintf(stderr, "FileType(fd) = PIPE\n");
	break;
	case FIFO:
		fprintf(stderr, "FileType(STDIN) = FIFO\n");
	break;
	case SOCKET:
		fprintf(stderr, "FileType(STDIN) = SOCKET\n");
	break;
	case BADFILETYPE:
		fprintf(stderr, "FileType(argv[1]) = BADFILETYPE\n");
	break;
	default:
	    fprintf(stderr, "filestat(argv[1]) failed: ftype = %d\n", ftype);
	}


	fprintf(stderr, "Checking printstat ...\n");
	/* Print FileType of stdin	*/
	fprintf(stderr, "FileType(STDIN) = %s\n", printstat(STDIN));


	/* Print FileType of stdout	*/
	fprintf(stderr, "FileType(STDOUT) = %s\n", printstat(STDOUT));


	/* Print FileType of argv[1]	*/
	if (argc == 1) {
		fprintf(stderr, "no filename given\n");
		exit(1);
	}
	if (-1 == (fd = open(argv[1], O_RDONLY))) {
		fprintf(stderr, "can't open %s", argv[1]);
		exit(2);
	}

	fprintf(stderr, "FileType(fd) = %s\n", printstat(fd));

	exit(0);
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -