Random small examples in C

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Post Reply
Message
Author
Ibidem
Posts: 549
Joined: Wed 26 May 2010, 03:31
Location: State of Jefferson

Random small examples in C

#1 Post by Ibidem »

I've been playing around trying to understand some of the less frequently used C functions, and thought I might as well post some examples.
All of them should compile via "make $SHORT" where $SHORT is the name without the ".c" extension...at least on Alpine Linux, or other musl-based systems.
On glibc-based distros like Puppy, some might require CFLAGS="-D_XOPEN_SOURCE=700 -D_BSD_SOURCE" to compile.

I'm releasing all of these as public domain.

Readdir example:

Code: Select all

#include <dirent.h>
#include <stdio.h>

int main(int argc,char **argv)
{
	DIR *crd;
	struct dirent *cre;
	char crt[2] = "?";
	char **dirs = (char *[]){".", NULL};
	if (argc-1) dirs = argv + 1;

	for( ; *dirs; dirs++) {
		crd = opendir(dirs[0]);
		if (!crd) continue;
		do {
			if ((cre = readdir(crd)) != NULL) {
				if (cre->d_type == DT_BLK) { 
					*crt = 'b';
				} else if (cre->d_type == DT_CHR) {
					*crt = 'c';
				} else if (cre->d_type == DT_DIR) {
					*crt = 'd';
				} else if (cre->d_type == DT_FIFO) {
					*crt = 'p';
				} else if (cre->d_type == DT_LNK) {
					*crt = 'l';
				} else if (cre->d_type == DT_REG) {
					*crt = 'f';
				} else if (cre->d_type == DT_SOCK) {
					*crt = 's';
				} else { *crt ='?'; }

				printf("%lld\t%s\t%s\n", cre->d_ino, crt, 
					cre->d_name);
			}
		} while (cre);
		closedir(crd);
	}
	return 0;	
}
This is roughly equivalent to ls -a -i, with the distinction that it also prints the file type (as used by find -type); according to the documentation, the type detection may only work on certain Linux filesystems, such as ext*, btrfs, and xfs...but it works on vfat per my tests, so I'm not sure what the story is.
If it can't detect file type, you get '?'.
Last edited by Ibidem on Fri 05 Dec 2014, 01:18, edited 1 time in total.

Ibidem
Posts: 549
Joined: Wed 26 May 2010, 03:31
Location: State of Jefferson

#2 Post by Ibidem »

An nftw example.
This will read temperatures from certain sensors (some don't use sysfs the same way...).

I never quite made this one do what I wanted; some drivers report temps as tenths of a degree, some as thousandths.

Code: Select all

#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 700
#endif

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


struct tempfix {
	char *modname;
	char *unitspec;
	int D_to_dC;
	int A_to_dC;
};

struct tempfix tempfixes[] = {
	{"acerhdf", NULL, 100, 0 },
	NULL
};

int showtemp(const char *fpath, const struct stat *st, int typeflag, struct FTW *ftwbuf)
{
	int dfd, cfile;
	char modpath[4096], *modname, *tempbuf = 0;
	ssize_t bytes;

	if (typeflag != FTW_SL)
		return 0;
	dfd = open(fpath, O_RDONLY);
	if (dfd < 0)
		return 0;
	//open temp, read
	cfile = openat(dfd, "temp", O_RDONLY);
	if (cfile > -1){
		tempbuf = malloc(16);
		if (!tempbuf)
			return -1;
		bytes = read(cfile, tempbuf, 15);
		if (bytes > 0) {
			tempbuf[bytes] = 0;
			puts(tempbuf);
		}
		free(tempbuf);
		close(cfile);
	}
	close(dfd);
	return 0;
	//todo: fixup temp	
}

int main(int argc, char **argv)
{
	nftw("/sys/class", showtemp, 512, FTW_PHYS|FTW_MOUNT);
	return 0;
}
...
And here's a similar (but more functional) example that uses glob() instead of nftw():

Code: Select all

#include <glob.h>
#include <stdio.h>

int main(void)
{
	int i, temp;
	glob_t temps;
	FILE *fp;
	
	i = glob("/sys/class/*/*/temp", 0, NULL, &temps);
	glob("/sys/class/thermal/*/temp*_input", i?0:GLOB_APPEND, NULL, &temps);
	for(i=0; i < temps.gl_pathc; i++) {
		if ((fp = fopen(temps.gl_pathv[i],"r")) != NULL) {
			if (fscanf(fp, "%d", &temp)) {
				if ((temp>999||temp<-999) && !(temp%100))
					temp /= 100;
				printf("Thermal %d: %d.%d degrees C\n", i,
					temp/10, temp%10);
			}
			fclose(fp);
		}

	}
	globfree(&temps);
	return 0;
}
I wrote these while working on acpi -t for toybox.

Post Reply