LINUX.ORG.RU

Помогите реализовать блочный ввод- вывод.


0

1

Код:

#define _LARGEFILE64_SOURCE
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h> 
#include <sys/types.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include "getopt.h"
char* itoa(unsigned int val);
void dchk(int f);
int ferr();
int usage();
int main(int argc, char** argv){
	register int ch, filenum;//filenum- FILE NUMber;
	int longIndex;
	register short sht=0, shn=0, shcc=0, num=0, num_nonblank=0;
	//sht- SHow Tabulation; shn- SHow '\n' symbol(carriage return); shcc- SHow Control Characters; num- NUMber;
	static const struct option longOpts[] = {
	{ "show-nonprinting", no_argument, NULL, 'v' },
	{ "show-tabs", no_argument, NULL, 'T' },
	{ "show-ends", no_argument, NULL, 'E' },
	{ "show-all", no_argument, NULL, 'A' },
	{ "number", no_argument, NULL, 'n' },
	{ "version", no_argument, NULL, 0 },
    { NULL, no_argument, NULL, 0 }
	};
	while((ch=getopt_long(argc, argv, "ETAethuni",longOpts,&longIndex))!= -1){
        switch (ch) {
				case 'n':
                    num = 1;
                    break;
                case 'i':
                    num_nonblank = 1;
                    break;
                case 'E':
                    shn = 1;
                    break;
                case 'T':
                    sht=1;
                    break;
                case 'A':{
					shn=1;
					sht=1;
					shcc=1;
					break;
					}
                case 'v':
                	shcc=1;
                	break;
                case 'e':{
                	shcc=1;
                	shn=1;
                	break;
					}
                case 't':{
                	shcc=1;
                	sht=1;
                	break;
					}
				case '?':
				case 'h':
					usage();
				case 'u':
					break;
				case 0:if(strcmp( "version",longOpts[longIndex].name)==0){
					write(STDOUT_FILENO,"sysccat version 0.1\n",20);
					_exit(0);
					}
					else usage();
                }
        }
	argv+=optind;
	argc-=optind;
	if(argc==0)usage();
//if no options defined
	if(!sht&&!shn&&!shcc&&!num)for(filenum=0;filenum<argc;++filenum){
												int fd=open(argv[filenum],O_RDONLY);
												if(fd<0)ferr();
												dchk(fd);
												off_t filesize=lseek(fd,0,SEEK_END);
												lseek(fd,0,SEEK_SET);
												char *c;
												c=malloc(4096);
												while(4096<filesize){
													read(fd,c,4096);
													write(STDOUT_FILENO,c,4096);
													filesize-=4096;
												}
												free(c);
												c=malloc(filesize);
												read(fd,c,filesize);
												write(STDOUT_FILENO,c,filesize);
												free(c);
												close(fd);
												}
//if any option defined
		else for(filenum=0;filenum<argc;++filenum){
			char a;
			int fd=open(argv[filenum],O_RDONLY);
			if(fd<0)ferr();
			dchk(fd);
			if(num)write(STDOUT_FILENO,"1: ",3);
			register int numline=1;//numline- NUMber of Line
			while(read(fd,&a,1)>0){
				if(num&&a=='\n'){
								if(read(fd,&a,1)==0){
													if(shn)write(STDOUT_FILENO,"$",1);
													write(STDOUT_FILENO,&a,1);
													}
								else{
									if(shn)write(STDOUT_FILENO,"$",1);
									write(STDOUT_FILENO,"\n",1);
									++numline;
									write(STDOUT_FILENO,itoa(numline),strlen(itoa(numline)));
									write(STDOUT_FILENO,": ",2);
									lseek(fd, -1, SEEK_CUR);
									}
				}
				else if(sht&&a=='\t')write(STDOUT_FILENO,"^I",2);
					else if(shn&&a=='\n')write(STDOUT_FILENO,"$\n",2);
						else if(shcc&&iscntrl(a)&&a!='\n'&&a!='\t'){
																	a+=64;
																	write(STDOUT_FILENO,"^",1);
																	write(STDOUT_FILENO,&a,1);
																	}
							else write(STDOUT_FILENO,&a,1);
			}
		close(fd);
	}
	_exit(0);
}
int usage(){
	write(STDOUT_FILENO,"Usage: sysccat [OPTIONS]... [FILE]...\n"
	"-h or --help Displays this info and exit.\n"
	"-n or --number Numbers the output strings.\n"
	"--version Displays version and exit.\n"
	"-v or --show-nonprinting Displays non-printing(control) characters, except for tabulation and carriage return/end-of-line symbols.\n"
	"-A, -vET or --show-all Displays all control characters.\n"
	"-t or -vT Displays all control characters, except for carriage return/end-of-line symbol.\n"
	"-u Ignored; for POSIX compatibility.\n"
	"-e or -vE Displays all control characters, except for tabulation symbol.\n",547);
	_exit(0);
	}
char* itoa(unsigned int val){
	static char buf[11];
	short i=10;
	for(;val&&i;--i,val/=10)buf[i]=val%10+48;
	return &buf[i+1];
}
int ferr(){
	write(STDERR_FILENO,strerror(errno),strlen(strerror(errno)));
	write(STDERR_FILENO,".\n",2);
	_exit(1);
}
void dchk(int f){
	struct stat fs;
	fstat(f,&fs);
	if(S_ISDIR(fs.st_mode)){
		write(STDERR_FILENO,"It's a directory.\n",18);
		close(f);
		_exit(1);
		}
}
Блочный ввод-вывод нужно реализовать в части, начинающейся после //if any option defined Пока ничего путного в голову не пришло- индуизмы одни. Заранее спасибо.
P.S.: #include «getopt.h» ибо у меня свой getopt_long- с блэкджеком, шлюхами и не требующий #define _GNU_SOURCE, базирующийся на коде этой функции из Open и Net BSD.

★★★

Последнее исправление: Dorif (всего исправлений: 1)
Ответ на: комментарий от pathfinder

> Это ничего не изменит. Попробуй считать гигабайт из COM-порта. Буфер драйвера не резиновый и как правило небольшого размера.

да причём тут размер буфера? блок данных, превышающий размер буфера драйвера последовательного порта (4к в линуксе) спокойно выдается целиком.

arsi ★★★★★
()
Ответ на: комментарий от Doug

Нафиг ЛИСП. Нет. я уважаю этот язык, но это не мой инструмент. поэтому мне бесполезно приводить лисповские примеры. Нафиг писать? Чтоб понять, как. И да: Си- конструктор. В нём есть минимум «кирпичей», из которых потом уже можно что- то собрать. Посему по дефолту блочного i/o нету.

Dorif ★★★
() автор топика
Ответ на: комментарий от Dorif

>Нафиг лишний sizeof

Он будет посчитан, в данном случае, при компиляции. Меньше значений вписывать руками - меньше вероятность ошибки.

anon_666
()
Ответ на: комментарий от anon_666

Пруф, что его не будут считать при каждом запуске проги? Вроде же должно при каждом запуске считаться.

Dorif ★★★
() автор топика
Ответ на: комментарий от Dorif
$ echo '#include <stdio.h>
int main(){ char v[] = "ololo"; printf("%s %d\n", v, sizeof(v)); }' |gcc -xc -masm=intel -S -

Листинг:

  .file ""
  .intel_syntax noprefix
  .section  .rodata
.LC0:
  .string "%s %d\n"
  .text
.globl main
  .type main, @function
main:
.LFB0:
  .cfi_startproc
  push  rbp
  .cfi_def_cfa_offset 16
  mov rbp, rsp
  .cfi_offset 6, -16
  .cfi_def_cfa_register 6
  sub rsp, 16
  mov DWORD PTR [rbp-16], 1819241583
  mov WORD PTR [rbp-12], 111
  mov eax, OFFSET FLAT:.LC0
  lea rcx, [rbp-16]
  mov edx, 6                         ;3-й, уже посчитаный «sizeof»
  mov rsi, rcx                       ;2-й
  mov rdi, rax                       ;1-й аргумент
  mov eax, 0
  call  printf
  leave
  .cfi_def_cfa 7, 8
  ret
  .cfi_endproc
.LFE0:
  .size main, .-main
  .ident  "GCC: (GNU) 4.5.2"
  .section  .note.GNU-stack,"",@progbits

anon_666
()
Ответ на: комментарий от Dorif

Какой нахуй ЛИСП? ЛИСП с конца 70х не используется нигде. А это Common Lisp.

Инструмент под задачу надо выбирать, а не пытаться натянуть один язык(который только и знаешь, хехе), на все задачи(это быдлокодерский подход).

Но CL, например - метаязык, так что его можно, в принципе, на любую задачу натянуть(именно потому, что это метаязык, фабрика языков под задачу).
А вот Си - нет, и он не конструктор никакой, он - низкоуровневое говнецо, которое и со своей то задачей(низкоуровневое программирование с минимальной абстракцией от конкретной платформы) справляется дерьмово.

Чтобы понять как писать, и что писать, надо начинать изучение программизма с нормальных высокоуровневых языков, а не со всякого кривого низкоуровневого дерьма.

Блочное I/O там есть - read/write/fread/fwrite. Или ты про то блочное I/O, которое про прямую работу с диском? Я из того говнокода не пойму нихуя. В последнем случае, это пиздец в квадрате - научись сначала писать нормальный код.

Doug
()
Ответ на: комментарий от Doug

Честно: не вижу между ними разницы. Может пояснишь? Ну, про инструменты согласен. Поэтому на всякий случай под рукой ещё несколько мануалов по другим языкам. А мне низкоуровневое программирование и нужно.) И пофиг. что думают о Си. но мне он нравится.) Про прямую работу с диском. Вот после высокоуровневых языков низкоуровневые учить тяжелее. Привыкаешь. что за тебя всё фреймворк делает, отвыкаешь сам писать. А про код: это- не индуизм. Вы индуизмов не видели. Привожу пример: «лапша-код» на Pascal с двумя readln; в конце. И это код нашей училки. Я от него чуть не повесился.

Dorif ★★★
() автор топика
Ответ на: комментарий от arsi

Из манов (termios)

Значения этих символов все различны, за исключением символов VTIME, VMIN, которые могут иметь те же значения, что и VEOL, VEOF, соответственно. (В нестандартном режиме значение специальных символов заменяются значениями по истечении времени ожидания. MIN представляет собой минимальное число символов, которые должны быть получены при чтении. TIME - десятые доли секунды таймера. Когда оба символа установлены, чтение будет ожидать пока по меньшей мере один символ не будет получен, и тогда возвращает либо MIN полученных символов, либо время TIME прошедшее с момента получения последнего символа. Если установлено только значение MIN, тогда операция чтение не будет возвращаться пока не будет получено MIN количество символов. Если установлено только значение TIME, то операция чтения будет возвращать любой по крайней мере один полученный символ или произойдет истечение времени ожидания. Если ничего не установлено, то операция чтения немедленно завершается, и будут доступны только уже принятые символы.

RAW-режим, VMIN и VTIME не установлены. Мы сможем за один раз считать байт больше, чем размер буфера?

pathfinder ★★★★
()
Ответ на: комментарий от Dorif

>Честно: не вижу между ними разницы. Может пояснишь?

Читай PCL, и так далее. Сравнивать робот-трансформер с лопатой, и пояснять между ними разницу мне как-то сильно влом.

Ну, про инструменты согласен. Поэтому на всякий случай под рукой ещё несколько мануалов по другим языкам.


Не надо под рукой иметь манулы, надо пробовать писать. Писать, блеать, программы. На стольких языках, на сколько времени хватает.

А мне низкоуровневое программирование и нужно.


Нет, тебе не нужно.

И пофиг. что думают о Си. но мне он нравится.


Это потому что с другим ничем не знаком.

Про прямую работу с диском.


Ни в коем случае не лезь в железо пока форматировать код и ясно выражать в нем свои мысли не научишься.

Вот после высокоуровневых языков низкоуровневые учить тяжелее.


Нет, как раз наоборот.

Привыкаешь. что за тебя всё фреймворк делает, отвыкаешь сам писать.


1) При чем тут фреймворки вообще? Я про сами языки. Можно подумать, что для сей нет говнофреймворков(GTK, COM, etc).
2) Писать все самому, ака велосипедить, это нахуй не надо, и вообще вредно.

А про код: это- не индуизм. Вы индуизмов не видели. Привожу пример: «лапша-код» на Pascal с двумя readln; в конце.


Нет, видел, и еще побольше тебя.

И это код нашей училки.


Охуеть. Вот будешь дрочить сишечку, вырастешь таким же говнокодером, ни на что неспособным, и вынужден будешь идти в говновуз/школу преподавать. Изучай концепции и технологии, а не ковыряйся в говне - пока свободное время есть.

Я от него чуть не повесился.


Поздравляю.

Doug
()
Ответ на: комментарий от Doug

Я знаком и с другими языками. С Java, например. Но всё равно люблю С. И никому не кажется, что он сам себе противоречит? К тому же: нафига никуда не релизуемому сырцу, который уж никак не считается даже чем- то типа пре-альфы форматирование? Вообще: нафига дрочить на форматирование? Код нужно понимать в любой форме, а не только в отформатированной «по вашим канонам».

Dorif ★★★
() автор топика
Ответ на: комментарий от arsi

ССЗБ. установи VTIME и читай больше размера буфера ;)

Ты вроде говорил про неустановленные таймауты.

Из манов (termios)

MIN == 0; TIME > 0: TIME specifies the limit for a timer in tenths of a second. The timer is started when read(2) is called. read(2) returns either when at least one byte of data is available, or when the timer expires. If the timer expires without any input becoming available, read(2) returns 0.

pathfinder ★★★★
()
Ответ на: комментарий от Doug

>и вынужден будешь идти в говновуз/школу преподавать. Изучай концепции и технологии

Я так понимаю, что вы тот уникальный человек, что со знанием «концепций и технологий» сумели в жизни стать чем-нибудь большим, чем преподавателем говновуза/школы? :-)

anonymous
()
Ответ на: комментарий от anonymous

> О, ты вернулся. Хоть ненадолго в девелопменте станет веселее.

ненадолго


Вы очень точно уловили суть происходящего. При всем моем уважении к господину Lovesan, учитывая то, как он себя тут ведет, «веселее» тут будет действительно очень и очень недолго.

shylent
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.