LINUX.ORG.RU

C память

 ,


0

1
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <stdio.h>
/* Печать элемента базы данных пользователей */
static void print_pwent (const struct passwd *pw) {
 printf ("Имя пользователя: %s\n", pw->pw_name);
 printf ("Идентификатор пользователя: %d\n", pw->pw_uid);
 printf ("Идентификатор группы: %d\n", pw->pw_gid);
 printf ("Начальный каталог: %s\n", pw->pw_dir);
 printf ("Начальная программа: %s\n", pw->pw_shell);
}
int main (void) {
 char *lgnm;           /* Имя текущего пользователя */
 struct passwd *pw;    /* Данные о текущем пользователе */
 /* Поиск и печать информации о текущем пользователе */
 if ((lgnm = getlogin ()) == NULL || (pw = getpwnam (lgnm)) == NULL) {
   fprintf (stderr, "\nНе удалось найти информацию о текущем пользователе\n");
   return 1;
 }
 printf ("\nИнформация о текущем пользователе\n");
 print_pwent (pw);
 /* То же для пользователя root */
 if ((pw = getpwuid ((uid_t) 0)) == NULL) {
   fprintf (stderr, "\nНе удалось найти информацию о пользователе root\n");
   return 1;
 }
 printf ("\nИнформация о пользователе root\n");
 print_pwent (pw);
 return 0;
}

При вызове getpwnam память под pw выделяется внутри функции, как я понимаю, но не ясно где она освобождается?


Если в мане это не оговаривается, то и волновать тебя это не особенно должно. Во всех остальных случаях, смотри сырцы.

Я заглянул. Тебе возвращают указатель на статическую память. Освобождать ничего не надо.

beastie ★★★★★ ()

Мне вот больше интересно, что за традиция именовать системные вызовы а-ля lolgetpwnkill1996? В экран давно влезает больше 80 символов.

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

Когда придумывали - не влезало.

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

getpwnam.c

#include <pwd.h>


#define LOOKUP_TYPE struct passwd
#define FUNCTION_NAME   getpwnam
#define DATABASE_NAME   passwd
#define ADD_PARAMS  const char *name
#define ADD_VARIABLES   name
#define BUFLEN      NSS_BUFLEN_PASSWD

#include "../nss/getXXbyYY.c"

getXXbyYY.c — здесь у меня начался баттхёрт... Объясните, пожалуйста, на пальцах что это и как это читать? )

#include <assert.h>
#include <errno.h>
#include <bits/libc-lock.h>
#include <stdlib.h>
#include <resolv.h>

#include "nsswitch.h"

/*******************************************************************\
|* Here we assume several symbols to be defined:		   *|
|*								   *|
|* LOOKUP_TYPE   - the return type of the function		   *|
|*								   *|
|* FUNCTION_NAME - name of the non-reentrant function		   *|
|*								   *|
|* DATABASE_NAME - name of the database the function accesses	   *|
|*		   (e.g., host, services, ...)			   *|
|*								   *|
|* ADD_PARAMS    - additional parameter, can vary in number	   *|
|*								   *|
|* ADD_VARIABLES - names of additional parameter		   *|
|*								   *|
|* BUFLEN	 - length of buffer allocated for the non	   *|
|*		   reentrant version				   *|
|*								   *|
|* Optionally the following vars can be defined:		   *|
|*								   *|
|* NEED_H_ERRNO  - an extra parameter will be passed to point to   *|
|*		   the global `h_errno' variable.		   *|
|*								   *|
\*******************************************************************/

/* To make the real sources a bit prettier.  */
#define REENTRANT_NAME APPEND_R (FUNCTION_NAME)
#define APPEND_R(name) APPEND_R1 (name)
#define APPEND_R1(name) name##_r
#define INTERNAL(name) INTERNAL1 (name)
#define INTERNAL1(name) __##name

/* Sometimes we need to store error codes in the `h_errno' variable.  */
#ifdef NEED_H_ERRNO
# define H_ERRNO_PARM , int *h_errnop
# define H_ERRNO_VAR , &h_errno_tmp
# define H_ERRNO_VAR_P &h_errno_tmp
#else
# define H_ERRNO_PARM
# define H_ERRNO_VAR
# define H_ERRNO_VAR_P NULL
#endif

#ifdef HAVE_AF
# define AF_VAL af
#else
# define AF_VAL AF_INET
#endif

/* Prototype for reentrant version we use here.  */
extern int INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf,
				      char *buffer, size_t buflen,
				      LOOKUP_TYPE **result H_ERRNO_PARM);

/* We need to protect the dynamic buffer handling.  */
__libc_lock_define_initialized (static, lock);

/* This points to the static buffer used.  */
libc_freeres_ptr (static char *buffer);


LOOKUP_TYPE *
FUNCTION_NAME (ADD_PARAMS)
{
  static size_t buffer_size;
  static LOOKUP_TYPE resbuf;
  LOOKUP_TYPE *result;
#ifdef NEED_H_ERRNO
  int h_errno_tmp = 0;
#endif

  /* Get lock.  */
  __libc_lock_lock (lock);

  if (buffer == NULL)
    {
      buffer_size = BUFLEN;
      buffer = (char *) malloc (buffer_size);
    }

#ifdef HANDLE_DIGITS_DOTS
  if (buffer != NULL)
    {
      if (__nss_hostname_digits_dots (name, &resbuf, &buffer,
				      &buffer_size, 0, &result, NULL, AF_VAL,
				      H_ERRNO_VAR_P))
	goto done;
    }
#endif

  while (buffer != NULL
	 && (INTERNAL (REENTRANT_NAME) (ADD_VARIABLES, &resbuf, buffer,
					buffer_size, &result H_ERRNO_VAR)
	     == ERANGE)
#ifdef NEED_H_ERRNO
	 && h_errno_tmp == NETDB_INTERNAL
#endif
	 )
    {
      char *new_buf;
      buffer_size *= 2;
      new_buf = (char *) realloc (buffer, buffer_size);
      if (new_buf == NULL)
	{
	  /* We are out of memory.  Free the current buffer so that the
	     process gets a chance for a normal termination.  */
	  free (buffer);
	  __set_errno (ENOMEM);
	}
      buffer = new_buf;
    }

  if (buffer == NULL)
    result = NULL;

#ifdef HANDLE_DIGITS_DOTS
done:
#endif
  /* Release lock.  */
  __libc_lock_unlock (lock);

#ifdef NEED_H_ERRNO
  if (h_errno_tmp != 0)
    __set_h_errno (h_errno_tmp);
#endif

  return result;
}

nss_interface_function (FUNCTION_NAME)

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

glibc не читается - glibc выкидывается нахрен, особенно это бесполезное, лапшеобразное говно.

Оно, как и половина посикса уже давно протухло и проще написать эту getpwnam() самому.

#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <stdio.h>
#include <error.h>
#include <errno.h>
/* Печать элемента базы данных пользователей */

static void print_pwent (const struct passwd *pw) {
  printf ("Имя пользователя: %s\n", pw->pw_name);
  printf ("Идентификатор пользователя: %d\n", pw->pw_uid);
  printf ("Идентификатор группы: %d\n", pw->pw_gid);
  printf ("Начальный каталог: %s\n", pw->pw_dir);
  printf ("Начальная программа: %s\n", pw->pw_shell);
}
int main (void) {
  struct passwd * pw, * root_pw;    /* Данные о текущем пользователе */
  /* Поиск и печать информации о текущем пользователе */
  
  if(!(pw = getpwnam(getlogin())))
    error(1, errno, "Не удалось найти информацию о текущем пользователе");

  
  /* То же для пользователя root */
  if (!(root_pw = getpwnam("root")))
    error(1, errno, "Не удалось найти информацию о пользователе root");
  
  printf ("\nИнформация о пользователе root:\n");  
  print_pwent(root_pw);
  printf ("\nИнформация о пользователе не root:\n");  
  print_pwent (pw);
  return 0;
}

Банальный тест даёт ответ, да и в мане написанно.

И да, бесполезные касты - это одна из тех вещей, которые делают из либц нечитаемое говно. А так же лапша из скобок и набор кастылей, вместо нормально юза самой libc.

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

Круто! Шаблоны на чистой Сишечке! Только-только начал читать «Дизайн и эволюцию C++», и там как раз описывается, как тов Страуструп на первых порах шаблонные классы на макросах делал. Я думал, эта дичь так в тех временах и осталась, а тут эвона как!

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

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

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

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

Они юзаются, да и не только шаблоны, а много чего ещё - запиливается 95% новомодных фичей.

Только эта лапша не нужна уже лет 100, ибо это делается через воид и вкладываются в функцию-обертку - конпелятор делает инлайн с алиасингом и вуаля - у тебя новая функция.

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

Может подскажете где почитать про динамические_библиотеки&&данные. Понятно что при загрузке динамической либы общий для разных процессов только код и константные переменные, а статические и локальные переменные, используемые либой, уже привязываются к процессу компануемому с ней. Хочется поподробнее изучить этот момент.

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

Затрудняюсь ответить. Единственное, что на ум приходит — это классика. (Не смотря на название, прочесть её и линуксоидам стоит.) Но это не совсем то, что ты ищешь.

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

Много где, но везде в той или иной степени поверхностно.
Бовет, Чезати. Ядро Linux. (Daniel P. Bovet, Marco Cesati. Understanding the Linux Kernel, 3e)
Стивенс, Раго. UNIX Профессиональное программирование. (W. Richard Stevens, Stephen A. Rago. Advanced Programming in the UNIX® Environment: 2e)
Роберт Лав (Robert Love), несколько книг.

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

Мне вот больше интересно, что за традиция именовать системные вызовы а-ля lolgetpwnkill1996? В экран давно влезает больше 80 символов.

The creat() Function

Yes, this function's name is missing an e. Ken Thompson, the creator of Unix, once joked that the missing letter was his largest regret in the design of Unix.

Из Linux System Programming, Robert Love.

Да и всяко лучше чем CreateToolhelp32Snapshot и подобные.

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

лучшеб потеринга читали, чем этот шлак.

Поттеринг это системд ? Это вот это виндовс чудо предлагается как тру ??? http://cgit.freedesktop.org/systemd/systemd/tree/src/core/execute.c?id=v204#n980

int exec_spawn(ExecCommand *command,
               char **argv,
               ExecContext *context,
               int fds[], unsigned n_fds,
               char **environment,
               bool apply_permissions,
               bool apply_chroot,
               bool apply_tty_stdin,
               bool confirm_spawn,
               CGroupBonding *cgroup_bondings,
               CGroupAttribute *cgroup_attributes,
               const char *cgroup_suffix,
               const char *unit_id,
               int idle_pipe[2],
               pid_t *ret)

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

В экран давно влезает больше 80 символов.

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

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

Может подскажете где почитать про динамические_библиотеки&&данные. Понятно что при загрузке динамической либы общий для разных процессов только код и константные переменные, а статические и локальные переменные, используемые либой, уже привязываются к процессу компануемому с ней. Хочется поподробнее изучить этот момент.

Упрощенно:

Образ из файла мапится в память процесса в так называемом режиме copy-on-write.

Динамический линкёр вносит в образ правки для связи с образами других файлов. Т.е., собственно, и выполняет линковку.

Всё, образ готов к работе.

Режим copy-on-write означает, что те страницы памяти, которые не изменялись, отображены прямо их файла, т.е. общие для всех процессов. В том числе и та часть образ, которая является секцией данных («статические переменные») тоже общая. Но когда программы пытается модифицировать любой байт такой страницы памяти, ядро копирует эту страницу и заменяет в памяти процесса оригинал на копию. Таким образом каждый процесс получает свою независимую копию данных.

Что касается локальных переменных, они лежат на стеке, это к динамической линковке отношения не имеет.

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

В экран давно влезает больше 80 символов.

это требование не позволяет делать множество вложенных ифов, свитчей и прочих форов.

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

Прикольно. А вызывать так:

exec_spawn("./myprog", NULL, NULL, NULL, 0, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL);

?

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

@#$%^&!

Я думал, такое в поделках студентов второго курса встречается.

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

влезать то влезает, но вот читать горизонтальную простыню всё равно нифига не удобно.

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

ДА ДЕТКА!

Поделие поцтеринга всё больше и больше напоминает winapi и dcom в худших их проявлениях.

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

Знаешь сколько я тебе говна найду в другом не сустемд. В целом сустемд написана более-менее и уровень осиляторства фичей там намного выше.

Ну не осилил пацан енумы, структуры и прочее, а так же заболел С++ - что с него взять? Булы юзают только укенные питушки, которых покусал С++.

Всё остальное - это гнилые последствия гнилого юникса, неосилятрства и протухшей лет 30назад сишки.

Ты читай дальше свою ссылку - это наиболее вменяемый код, котрый хоть и тупая лапша, но выглядит более-мнее.

Всякие:

  if (err >= 0)
    err = shift_fds(fds, n_fds);
  if (err >= 0)
    err = flags_fds(fds, n_fds, context->non_blocking);

Конечно умиляют, но if() - это банальное неосиляторство - пацаны не могут думать «как, что и зачем писать» - можно зафигачить лапшу на ифах и форах - фигачим, а если можно и без ифов и форов - дак нам покласть.

Пацаны не осилил ни конпеляторы, ни их фичи и до сих пор пишут лапшу на 100500 строк. Да и пишут под говно, где норм код писать сложно.

Но вон поттеринг молодец - даже форичи юзает.

Ах да, спасибо тебе - благодаря тебе я узнал об cleanup - давно уже хотел такую фичу хотел, а она оказывается есть. Молодец поттеринг - хвалю. Теперь в сишке есть 99% всех фич.

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

Молодец поттеринг - хвалю

Суперхаккиллер1997 и Поцеринг - замечательная пара.

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

я согласен, что местами код хорош, чувак явно умеет писать код, но тонны этих методов с большим кол-вом аргументов выдают, что грамотное апи он придумывать не умеет.
а про cleanup я немного не понял, поясни чего ты там такого увидел, для полноты картины :).

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

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

Он пытается сделать это более-менее низкоуровневым, чтобы не бомбило от всего этого псевдоюниксвей-говна. Уже давно пора всё это выкинуть, но нет же - тащат, а потом у меня бомбит.

Выкинуть явно упоротые конструкции - не делать их нищие аналоги, как делает это уже 100лет мёртвая как бсд, а нормально. Нищеброды даже сишку не осилили, а как меня умиляют кукарекушки, которые кукарекают про крутость anciсишки, на которой ничего нормально написать нереально, ибо говно.

Пора собирать всю мировую илиту, кооперировать во главе с СУХК97 и пилить юникс с нуля, не как это делают питушки своими гнилыми, анскильными, студенчискими ручёнками, а норм - по пацаночке.

Начиная newgen сики, и далее.

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

Суть не в грамотности api - суть в том, что чувак хочет запилить понтово, но ему это недаёт гнилое unix-наследие и прочий шлак. Я не знаю почему он осилив gnuc, нормально юзая всё в одном месте - юзает это нетак в другом. Это либо связанно с его условиями работы - я не знаю как, кто и когда это писал, но это реально странно.

cleanup - это фича гнутой сишки, а гнутую сишку по моей школо-идеологии должен знать каждый сишкик, ибо когда сишик осиливат сишку чуть лучше, чем «дно» - он понимает, что сишка говно.

Сишка не может существовать отдельно от реализации, как это думают многие, ибо в ней очень мало нужных фичей и слишком много неопделённостей. Как прибить сишку к реализации и получить фичи - гнуси.

А клеануп - это аналог деструкторов в сишке. Т.е. на каждое определение можно повесиль функцию, которая будет вызыватся после выхода определния за область видимости. И про него я не знал до сего дня.

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

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

Мой ЯП пилится для илиты, а пилить ЯП для илиты может только топ1 из этой самой илиты - расчём.

Реализуются мои идеи достаточно просто, поэтому проблем с реализацией тут нет.

Я должен досканально убедится, что сишка реально протухла и её нереально спасти без тотальной переделки. И пока я стою перед выбором - запилить обвес над сишкой в виде новомого макрорасширения. Пилить что-то на базе патчинга гцц - мне лень по многим причинам - я уже писал об этом.

Пока думаю. И да, зачем вы баните мой ип? Что вам это даёт? Мало того, что меня забанили низачто а причины - брехня и враньё. Я не юзаю нецензурных слов - кто-то из ваших модераторов говорил: «отборная цензурная ругань». Я не флужу. Я не говорю неправды, а если за это банить - забанить пора 99% кукарекушек на лоре.

Никакой диз"ы я не даю и прочее - о5 ваш тарзан бушует? Никогда не понимал как вообще какой-то админ может модерить девелопмент, да ещё и рассждать о том - прав я или нет. Разбанте там меня, ибо в отлии от модераторов-балаболов я исполняю правила и следую им.

Время идёт, прошло всего отсилы 2года, как я начал программировать из которых я программировал от силы часов 40 - в основном срался на лоре. На топ1 и спасение программира я выделил себе лет 6.

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

Смотрите-ка, илитка раскукарекалась.

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

прошло всего отсилы 2года, как я начал программировать из которых я программировал от силы часов 40

достойно анналов.

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