Если вы используете функцию POSIX 2008 getline()
, то вы выбрасываете полезную информацию (она возвращает длину строки, которую читает, поэтому, если вы захватите эту информацию, вы не захотите нужен strlen()
в цикле.
Если код блокирует вызов getline()
, это, вероятно, означает, что восходящий сокет не закрыт, но данные больше не отправляются. Ваш отправляющий код должен закрыть сокет, чтобы этот код мог обнаружить EOF.
Или, поскольку вы обсуждаете «пустую строку», то, возможно, ваш код должен проверять строку, содержащую только \r\n
(или, может быть, просто \n
) и прерывать цикл; ваш код не делает этого в данный момент.
Ваш цикл также имеет квадратичное поведение, поскольку вы постоянно используете strcat()
. Лучше держать вкладки в конце строки и просто strcpy()
новые данные после старых, а затем настроить указатель на конец строки.
При дальнейшем рассмотрении отмечу, что вы используете fdopen()
для открытия потока файлов на основе дескриптора файла, но вы не закрываете его и не возвращаете поток файлов вызывающей стороне для закрытия. Это приводит к проблеме утечки.
Полезное правило : если вы выделяете ресурс, вы должны освободить его или передать обратно для освобождения.
Я рекомендую изменить интерфейс на использование уже открытого FILE *
и ввести fdopen()
в вызывающем коде. В качестве альтернативы, если вам больше не понадобится дескриптор файла, вы можете сохранить текущий интерфейс и использовать fclose()
перед возвратом, но это также закроет базовый дескриптор файла.
Этот код работает для меня (MacOS X 10.7.2; XCode 4.2.1):
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern char *getMessage(FILE *);
char *getMessage(FILE *fp)
{
char *block = 0;
size_t size = 0;
size_t buffersize = 0;
char *buffer = 0;
ssize_t newlen;
while ((newlen = getline(&buffer, &buffersize, fp)) > 0)
{
printf("Buffer length: %ld\n", (long)newlen);
block = realloc(block, size + newlen + 1);
strcat(&block[size], buffer);
size += newlen;
if (strcmp(buffer, "\r\n") == 0)
break;
}
printf("Block length: %zd\n", size);
if (size > 0)
printf("<<%s>>\n", block);
return block;
}
int main(void)
{
char *msg;
while ((msg = getMessage(stdin)) != 0)
{
printf("Double check: <<%s>>\n", msg);
free(msg);
}
return 0;
}
Я протестировал его с файлом с окончанием строки в стиле DOS в качестве стандартного ввода, с пустой строкой в качестве последней строки и с непустой строкой. Две пустые строки подряд тоже вроде бы были в порядке.