PostgreSQL Source Code git master
pg_get_line.c File Reference
#include "postgres.h"
#include <setjmp.h>
#include "common/string.h"
#include "lib/stringinfo.h"
Include dependency graph for pg_get_line.c:

Go to the source code of this file.

Functions

char * pg_get_line (FILE *stream, PromptInterruptContext *prompt_ctx)
 
bool pg_get_line_buf (FILE *stream, StringInfo buf)
 
bool pg_get_line_append (FILE *stream, StringInfo buf, PromptInterruptContext *prompt_ctx)
 

Function Documentation

◆ pg_get_line()

char * pg_get_line ( FILE *  stream,
PromptInterruptContext prompt_ctx 
)

Definition at line 59 of file pg_get_line.c.

60{
62
64
65 if (!pg_get_line_append(stream, &buf, prompt_ctx))
66 {
67 /* ensure that free() doesn't mess up errno */
68 int save_errno = errno;
69
70 pfree(buf.data);
71 errno = save_errno;
72 return NULL;
73 }
74
75 return buf.data;
76}
void pfree(void *pointer)
Definition: mcxt.c:1521
bool pg_get_line_append(FILE *stream, StringInfo buf, PromptInterruptContext *prompt_ctx)
Definition: pg_get_line.c:124
static char * buf
Definition: pg_test_fsync.c:72
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97

References buf, initStringInfo(), pfree(), and pg_get_line_append().

Referenced by get_su_pwd(), pipe_read_line(), and simple_prompt_extended().

◆ pg_get_line_append()

bool pg_get_line_append ( FILE *  stream,
StringInfo  buf,
PromptInterruptContext prompt_ctx 
)

Definition at line 124 of file pg_get_line.c.

126{
127 int orig_len = buf->len;
128
129 if (prompt_ctx && sigsetjmp(*((sigjmp_buf *) prompt_ctx->jmpbuf), 1) != 0)
130 {
131 /* Got here with longjmp */
132 prompt_ctx->canceled = true;
133 /* Discard any data we collected before detecting error */
134 buf->len = orig_len;
135 buf->data[orig_len] = '\0';
136 return false;
137 }
138
139 /* Loop until newline or EOF/error */
140 for (;;)
141 {
142 char *res;
143
144 /* Enable longjmp while waiting for input */
145 if (prompt_ctx)
146 *(prompt_ctx->enabled) = true;
147
148 /* Read some data, appending it to whatever we already have */
149 res = fgets(buf->data + buf->len, buf->maxlen - buf->len, stream);
150
151 /* Disable longjmp again, then break if fgets failed */
152 if (prompt_ctx)
153 *(prompt_ctx->enabled) = false;
154
155 if (res == NULL)
156 break;
157
158 /* Got data, so update buf->len */
159 buf->len += strlen(buf->data + buf->len);
160
161 /* Done if we have collected a newline */
162 if (buf->len > orig_len && buf->data[buf->len - 1] == '\n')
163 return true;
164
165 /* Make some more room in the buffer, and loop to read more data */
167 }
168
169 /* Check for I/O errors and EOF */
170 if (ferror(stream) || buf->len == orig_len)
171 {
172 /* Discard any data we collected before detecting error */
173 buf->len = orig_len;
174 buf->data[orig_len] = '\0';
175 return false;
176 }
177
178 /* No newline at EOF, but we did collect some data */
179 return true;
180}
void enlargeStringInfo(StringInfo str, int needed)
Definition: stringinfo.c:337
volatile sig_atomic_t * enabled
Definition: string.h:21

References buf, PromptInterruptContext::canceled, PromptInterruptContext::enabled, enlargeStringInfo(), PromptInterruptContext::jmpbuf, and res.

Referenced by pg_get_line(), pg_get_line_buf(), and tokenize_auth_file().

◆ pg_get_line_buf()

bool pg_get_line_buf ( FILE *  stream,
StringInfo  buf 
)

Definition at line 95 of file pg_get_line.c.

96{
97 /* We just need to drop any data from the previous call */
99 return pg_get_line_append(stream, buf, NULL);
100}
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:126

References buf, pg_get_line_append(), and resetStringInfo().

Referenced by ecpg_filter_source(), ecpg_filter_stderr(), filter_read_item(), read_quoted_string(), readfile(), SortTocFromFile(), and tsearch_readline().