PageRenderTime 27ms CodeModel.GetById 9ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 0ms

/tools/tty.c

http://datacard.googlecode.com/
C | 179 lines | 134 code | 23 blank | 22 comment | 25 complexity | 61167d76a8d9d333668019075d414b87 MD5 | raw file
  1#include <stdio.h>
  2#include <termios.h>			/* struct termios tcgetattr() tcsetattr()  */
  3#include <fcntl.h>			/* O_RDWR O_NOCTTY */
  4#include <sys/stat.h>			/* S_IRUSR | S_IRGRP | S_IROTH */
  5#include <string.h>			/* strrchr() */
  6#include <limits.h>			/* PATH_MAX */
  7#include <stdlib.h>			/* realpath() */
  8#include <unistd.h>			/* getpid() */
  9#include <errno.h>			/* errno */
 10#include <signal.h>			/* kill() */
 11
 12#/* return length of lockname */
 13static int lock_build(const char * devname, char * buf, unsigned length)
 14{
 15	const char * basename;
 16	char resolved_path[PATH_MAX];
 17
 18	/* follow symlinks */
 19	if(realpath(devname, resolved_path) != NULL)
 20		devname = resolved_path;
 21	
 22/*
 23	while(1)
 24	{
 25		len = readlink(devname, symlink, sizeof(symlink) - 1);
 26		if(len <= 0)
 27			break;
 28		symlink[len] = 0;
 29		if(symlink[0] == '/')
 30			devname = symlink;
 31		else
 32		{
 33			// TODO
 34			memmove()
 35			memcpy(symlink, devname);
 36		}
 37	}
 38*/
 39
 40	basename = strrchr(devname, '/');
 41	if(basename)
 42		basename++;
 43	else
 44		basename = devname;
 45
 46	/* TODO: use asterisk build settings for /var/lock */
 47	return snprintf(buf, length, "/var/lock/LOCK..%s", basename);
 48}
 49
 50#/* return 0 on error */
 51static int lock_create(const char * lockfile)
 52{
 53	int fd;
 54	int len = 0;
 55	char pidb[21];
 56	
 57	fd = open(lockfile, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IRGRP | S_IROTH);
 58	if(fd >= 0)
 59	{
 60		len = snprintf(pidb, sizeof(pidb), "%d", getpid());
 61		len = write(fd, pidb, len);
 62		close(fd);
 63	}
 64	return len;
 65}
 66
 67#/* return pid of owner, 0 if free */
 68static int lock_try(const char * devname)
 69{
 70	int fd;
 71	int len;
 72	int pid = 0;
 73	char name[256];
 74	char pidb[21];
 75
 76	lock_build(devname, name, sizeof(name));
 77
 78	/* FIXME: rise condition: some time between lock check and got lock */
 79	fd = open(name, O_RDONLY);
 80	if(fd >= 0)
 81	{
 82		len = read(fd, pidb, sizeof(pidb) - 1);
 83		if(len > 0)
 84		{
 85			pidb[len] = 0;
 86			len = strtol(pidb, NULL, 10);
 87			if(kill(len, 0) == 0) 
 88				pid = len;
 89		}
 90		close(fd);
 91	}
 92	if(pid == 0)
 93	{
 94		unlink(name);
 95		lock_create(name);
 96	}
 97	return pid;
 98}
 99
100int opentty (const char* dev)
101{
102	int		pid;
103	int		fd;
104	struct termios	term_attr;
105
106	fd = open (dev, O_RDWR | O_NOCTTY);
107
108	if (fd < 0)
109	{
110		return -1;
111	}
112	
113	if (tcgetattr (fd, &term_attr) != 0)
114	{
115		close(fd);
116		return -1;
117	}
118
119	term_attr.c_cflag = B115200 | CS8 | CREAD | CRTSCTS;
120	term_attr.c_iflag = 0;
121	term_attr.c_oflag = 0;
122	term_attr.c_lflag = 0;
123	term_attr.c_cc[VMIN] = 1;
124	term_attr.c_cc[VTIME] = 0;
125
126	if (tcsetattr (fd, TCSAFLUSH, &term_attr) != 0)
127	{
128	}
129
130	pid = lock_try(dev);
131	if(pid != 0)
132	{
133		close(fd);
134		return -1;
135	}
136
137	return fd;
138}
139
140#/* */
141void closetty(const char * dev, int fd)
142{
143	char name[256];
144
145	close(fd);
146
147	/* remove lock */
148	lock_build(dev, name, sizeof(name));
149	unlink(name);
150}
151
152#/* */
153size_t write_all (int fd, const char* buf, size_t count)
154{
155	ssize_t out_count;
156	size_t total = 0;
157	unsigned errs = 10;
158	
159	while (count > 0)
160	{
161		out_count = write (fd, buf, count);
162		if (out_count <= 0)
163		{
164			if(errno == EINTR || errno == EAGAIN)
165			{
166				errs--;
167				if(errs != 0)
168					continue;
169			}
170			break;
171		}
172//		fprintf(stdout, "%*s", out_count, buf);
173		errs = 10;
174		count -= out_count;
175		buf += out_count;
176		total += out_count;
177	}
178	return total;
179}